emile 9 months ago
parent 5973a3d335
commit 73e1eb7a0a

Binary file not shown.

@ -11,3 +11,4 @@ admin.site.register(ChatMessage)
admin.site.register(ChatMessageAttachment) admin.site.register(ChatMessageAttachment)
admin.site.register(ChatMessageReaction) admin.site.register(ChatMessageReaction)
admin.site.register(ChatMessageSeen) admin.site.register(ChatMessageSeen)
admin.site.register(ChatRoomReview)

@ -53,6 +53,7 @@ class OsitcomVisitor(WebsocketConsumer):
class OsitcomChatRoom(WebsocketConsumer): class OsitcomChatRoom(WebsocketConsumer):
def connect(self): def connect(self):
self.session_id = self.scope['url_route']['kwargs']['session_id'] self.session_id = self.scope['url_route']['kwargs']['session_id']
self.domain = 'https://osina.ositcom.com'
async_to_sync(self.channel_layer.group_add)( async_to_sync(self.channel_layer.group_add)(
self.session_id, self.channel_name self.session_id, self.channel_name
) )
@ -224,6 +225,28 @@ class OsitcomChatRoom(WebsocketConsumer):
self.session_id, event self.session_id, event
) )
if event_type == 'submit_review':
if ChatRoomReview.objects.filter(room=self.chat_room).last():
review = ChatRoomReview.objects.filter(room=self.chat_room).last()
if text_data_json.get('reaction'):
review.reaction = text_data_json.get('reaction')
if text_data_json.get('details'):
review.details = text_data_json.get('details')
review.save()
else:
review = ChatRoomReview.objects.create(
room = self.chat_room,
reaction = text_data_json.get('reaction'),
details = text_data_json.get('details'),
)
event = {
'type': 'submit_review_handler',
'review_id': review.id
}
async_to_sync(self.channel_layer.group_send)(
self.session_id, event
)
@ -233,14 +256,18 @@ class OsitcomChatRoom(WebsocketConsumer):
if self.chat_room: if self.chat_room:
chat_room = self.chat_room chat_room = self.chat_room
chat_room_messages = ChatMessage.objects.filter(room=chat_room).order_by('date_sent') chat_room_messages = ChatMessage.objects.filter(room=chat_room).order_by('date_sent')
review = ChatRoomReview.objects.filter(room=chat_room).last()
else: else:
chat_room = None chat_room = None
chat_room_messages = None chat_room_messages = None
review = None
context = { context = {
'chat_room': chat_room, 'chat_room': chat_room,
'chat_room_messages': chat_room_messages, 'chat_room_messages': chat_room_messages,
'review': review,
'domain': self.domain
} }
if self.client_type == 'mobile_admin': if self.client_type == 'mobile_admin':
@ -293,7 +320,8 @@ class OsitcomChatRoom(WebsocketConsumer):
chat_room = get_object_or_404(ChatRoom, id=event['chat_room_id']) chat_room = get_object_or_404(ChatRoom, id=event['chat_room_id'])
context = { context = {
'chat_room': chat_room, 'chat_room': chat_room,
'session_id':self.session_id 'session_id':self.session_id,
'domain': self.domain
} }
if self.client_type == 'mobile_admin': if self.client_type == 'mobile_admin':
self.send(text_data=json.dumps({ self.send(text_data=json.dumps({
@ -316,6 +344,7 @@ class OsitcomChatRoom(WebsocketConsumer):
context = { context = {
'member': member, 'member': member,
'domain': self.domain
} }
html = render_to_string("partials/typing.html", context=context) html = render_to_string("partials/typing.html", context=context)
@ -332,6 +361,7 @@ class OsitcomChatRoom(WebsocketConsumer):
chat_message = get_object_or_404(ChatMessage, id=event['chat_message_id']) chat_message = get_object_or_404(ChatMessage, id=event['chat_message_id'])
context = { context = {
'chat_message': chat_message, 'chat_message': chat_message,
'domain': self.domain
} }
if self.client_type == 'mobile_admin': if self.client_type == 'mobile_admin':
chat_message_data = model_to_dict(chat_message) chat_message_data = model_to_dict(chat_message)
@ -357,7 +387,8 @@ class OsitcomChatRoom(WebsocketConsumer):
message_attachment = get_object_or_404(ChatMessageAttachment, id=event['message_attachment_id']) message_attachment = get_object_or_404(ChatMessageAttachment, id=event['message_attachment_id'])
context = { context = {
'message_attachment': message_attachment, 'message_attachment': message_attachment,
'file_type': event['file_type'] 'file_type': event['file_type'],
'domain': self.domain
} }
if self.client_type == 'mobile_admin': if self.client_type == 'mobile_admin':
message_attachment_data = model_to_dict(message_attachment) message_attachment_data = model_to_dict(message_attachment)
@ -382,7 +413,8 @@ class OsitcomChatRoom(WebsocketConsumer):
latest_unread_message = get_object_or_404(ChatMessage, id=latest_unread_message_id) latest_unread_message = get_object_or_404(ChatMessage, id=latest_unread_message_id)
context = { context = {
'number_of_unread' : event['number_of_unread'], 'number_of_unread' : event['number_of_unread'],
'latest_unread_message': latest_unread_message 'latest_unread_message': latest_unread_message,
'domain': self.domain
} }
html = render_to_string("partials/unread-messages.html", context=context) html = render_to_string("partials/unread-messages.html", context=context)
self.send(text_data=json.dumps({ self.send(text_data=json.dumps({
@ -403,9 +435,22 @@ class OsitcomChatRoom(WebsocketConsumer):
context = { context = {
'chat_room': self.chat_room, 'chat_room': self.chat_room,
'chat_room_messages': ChatMessage.objects.filter(room=self.chat_room).order_by('date_sent'), 'chat_room_messages': ChatMessage.objects.filter(room=self.chat_room).order_by('date_sent'),
'domain': self.domain
} }
html = render_to_string("ended-chat.html", context=context) html = render_to_string("ended-chat.html", context=context)
self.send(text_data=json.dumps({ self.send(text_data=json.dumps({
'event_type': 'ended_chat', 'event_type': 'ended_chat',
'html': html, 'html': html,
})) }))
def submit_review_handler(self, event):
review = get_object_or_404(ChatRoomReview, id=event['review_id'])
context = {
'review': review,
'chat_room': self.chat_room,
}
html = render_to_string("partials/submitted-review.html", context=context)
self.send(text_data=json.dumps({
'event_type': 'submit_review',
'html': html,
}))

@ -0,0 +1,22 @@
# Generated by Django 4.2.5 on 2024-08-03 08:33
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('osichat', '0019_visitorlog_visitor'),
]
operations = [
migrations.CreateModel(
name='ChatRoomReview',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('reaction', models.CharField(choices=[('Happy', 'Happy'), ('Indifferent', 'Indifferent'), ('Sad', 'Sad')], max_length=50, null=True)),
('room', models.OneToOneField(null=True, on_delete=django.db.models.deletion.CASCADE, to='osichat.chatroom')),
],
),
]

@ -0,0 +1,18 @@
# Generated by Django 4.2.5 on 2024-08-03 08:34
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('osichat', '0020_chatroomreview'),
]
operations = [
migrations.AddField(
model_name='chatroomreview',
name='details',
field=models.TextField(blank=True, null=True),
),
]

@ -46,6 +46,17 @@ class ChatRoomGuest(models.Model):
room = models.OneToOneField(ChatRoom, on_delete=models.CASCADE, null=True) room = models.OneToOneField(ChatRoom, on_delete=models.CASCADE, null=True)
visitor = models.ForeignKey(Visitor, null=True, on_delete=models.CASCADE) visitor = models.ForeignKey(Visitor, null=True, on_delete=models.CASCADE)
class ChatRoomReview(models.Model):
REACTION_CHOICES = (
('Happy', 'Happy'),
('Indifferent', 'Indifferent'),
('Sad', 'Sad'),
)
room = models.OneToOneField(ChatRoom, on_delete=models.CASCADE, null=True)
reaction = models.CharField(max_length=50, choices=REACTION_CHOICES, null=True)
details = models.TextField(null=True, blank=True)
class ChatMember(models.Model): class ChatMember(models.Model):
member = models.ForeignKey(User, on_delete=models.CASCADE) member = models.ForeignKey(User, on_delete=models.CASCADE)
room = models.ForeignKey(ChatRoom, on_delete=models.CASCADE) room = models.ForeignKey(ChatRoom, on_delete=models.CASCADE)

@ -49,7 +49,7 @@
class="w-[25px] h-[25px] rounded-full shadow-md text-white flex justify-center items-center bg-osiblue uppercase text-xs"> class="w-[25px] h-[25px] rounded-full shadow-md text-white flex justify-center items-center bg-osiblue uppercase text-xs">
{% if message.member.staffprofile.image %} {% if message.member.staffprofile.image %}
<img class="w-full h-full rounded-full" <img class="w-full h-full rounded-full"
src="http://192.168.1.111:8000{{message.member.staffprofile.image.url}}"> src="{{domain}}{{message.member.staffprofile.image.url}}">
{% else %} {% else %}
<p>{{message.member.first_name.0}}{{message.member.last_name.0}}</p> <p>{{message.member.first_name.0}}{{message.member.last_name.0}}</p>
{% endif %} {% endif %}
@ -64,7 +64,7 @@
{% if message.chatmessageattachment.is_image %} {% if message.chatmessageattachment.is_image %}
<div <div
class="max-w-[80%] bg-gray-50 p-4 rounded-r-3xl rounded-tl-3xl text-secondosiblue text-sm leading-6 bg-opacity-50 shadow-md border border-gray-100"> class="max-w-[80%] bg-gray-50 p-4 rounded-r-3xl rounded-tl-3xl text-secondosiblue text-sm leading-6 bg-opacity-50 shadow-md border border-gray-100">
<img src="http://192.168.1.111:8000/{{message.chatmessageattachment.attachment}}" class="rounded-md"> <img src="{{domain}}/{{message.chatmessageattachment.attachment}}" class="rounded-md">
</div> </div>
{% else %} {% else %}
<div <div
@ -99,7 +99,7 @@
{% if message.chatmessageattachment.is_image %} {% if message.chatmessageattachment.is_image %}
<div class="w-full flex justify-end"> <div class="w-full flex justify-end">
<div class="max-w-[80%] p-4 rounded-l-3xl rounded-tr-3xl text-white shadow-md text-sm leading-6 bg-opacity-70 bg-osiblue"> <div class="max-w-[80%] p-4 rounded-l-3xl rounded-tr-3xl text-white shadow-md text-sm leading-6 bg-opacity-70 bg-osiblue">
<img src="http://192.168.1.111:8000/{{message.chatmessageattachment.attachment}}" class="rounded-md"> <img src="{{domain}}/{{message.chatmessageattachment.attachment}}" class="rounded-md">
</div> </div>
</div> </div>
{% else %} {% else %}
@ -125,7 +125,7 @@
{% endfor %} {% endfor %}
</div> </div>
<audio id="notification-sound" src="http://192.168.1.111:8000/static/notifications/osichat-notification.mp3" preload="auto"></audio> <audio id="notification-sound" src="{{domain}}/static/notifications/osichat-notification.mp3" preload="auto"></audio>
<div id="typing" class="hidden"></div> <div id="typing" class="hidden"></div>
</div> </div>
@ -161,7 +161,7 @@
<!-- FOOTER --> <!-- FOOTER -->
<div class="w-full rounded-b-md px-3 py-3 flex justify-center items-center gap-1 bg-white"> <div class="w-full rounded-b-md px-3 py-3 flex justify-center items-center gap-1 bg-white">
<img src="http://192.168.1.111:8000/static/images/ositcom_logos/ositcom(o).png" class="w-[20px]"> <img src="{{domain}}/static/images/ositcom_logos/ositcom(o).png" class="w-[20px]">
<p class="text-xs text-secondosiblue">Osichat 2.0 by <a href="https://ositcom.com/" target="_blank" <p class="text-xs text-secondosiblue">Osichat 2.0 by <a href="https://ositcom.com/" target="_blank"
class="hover:text-gray-400 duration-500">Ositcom</a></p> class="hover:text-gray-400 duration-500">Ositcom</a></p>

@ -45,7 +45,7 @@
class="w-[25px] h-[25px] rounded-full shadow-md text-white flex justify-center items-center bg-osiblue uppercase text-xs"> class="w-[25px] h-[25px] rounded-full shadow-md text-white flex justify-center items-center bg-osiblue uppercase text-xs">
{% if message.member.staffprofile.image %} {% if message.member.staffprofile.image %}
<img class="w-full h-full rounded-full" <img class="w-full h-full rounded-full"
src="http://192.168.1.111:8000{{message.member.staffprofile.image.url}}"> src="{{domain}}{{message.member.staffprofile.image.url}}">
{% else %} {% else %}
<p>{{message.member.first_name.0}}{{message.member.last_name.0}}</p> <p>{{message.member.first_name.0}}{{message.member.last_name.0}}</p>
{% endif %} {% endif %}
@ -60,7 +60,7 @@
{% if message.chatmessageattachment.is_image %} {% if message.chatmessageattachment.is_image %}
<div <div
class="max-w-[80%] bg-gray-50 p-4 rounded-r-3xl rounded-tl-3xl text-secondosiblue text-sm leading-6 bg-opacity-50 shadow-md border border-gray-100"> class="max-w-[80%] bg-gray-50 p-4 rounded-r-3xl rounded-tl-3xl text-secondosiblue text-sm leading-6 bg-opacity-50 shadow-md border border-gray-100">
<img src="http://192.168.1.111:8000/{{message.chatmessageattachment.attachment}}" <img src="{{domain}}/{{message.chatmessageattachment.attachment}}"
class="rounded-md"> class="rounded-md">
</div> </div>
{% else %} {% else %}
@ -104,7 +104,7 @@
<div class="w-full flex justify-end"> <div class="w-full flex justify-end">
<div <div
class="max-w-[80%] p-4 rounded-l-3xl rounded-tr-3xl text-white shadow-md text-sm leading-6 bg-opacity-70 bg-osiblue"> class="max-w-[80%] p-4 rounded-l-3xl rounded-tr-3xl text-white shadow-md text-sm leading-6 bg-opacity-70 bg-osiblue">
<img src="http://192.168.1.111:8000/{{message.chatmessageattachment.attachment}}" <img src="{{domain}}/{{message.chatmessageattachment.attachment}}"
class="rounded-md"> class="rounded-md">
</div> </div>
</div> </div>
@ -140,6 +140,8 @@
<!-- REVIEW CONTAINER SENT BY THE BOTT --> <!-- REVIEW CONTAINER SENT BY THE BOTT -->
<div id="reviewContainer">
{% if not chat_room.chatroomreview %}
<div class="w-full flex items-end gap-2"> <div class="w-full flex items-end gap-2">
<div> <div>
<div <div
@ -173,7 +175,7 @@
<p class="text-center text-secondosiblue">Rate your conversation</p> <p class="text-center text-secondosiblue">Rate your conversation</p>
<div class="w-full flex justify-center items-center gap-3"> <div class="w-full flex justify-center items-center gap-3">
<button data-reaction="" class="cursor-pointer hover:scale-105 duration-500 w-fit h-fit rounded-full"> <button data-reaction="Happy" class="cursor-pointer hover:scale-105 duration-500 w-fit h-fit rounded-full reaction-button">
<svg xmlns="http://www.w3.org/2000/svg" class="w-9" <svg xmlns="http://www.w3.org/2000/svg" class="w-9"
xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px"
viewBox="0 0 999 961" style="enable-background:new 0 0 999 961;" xml:space="preserve"> viewBox="0 0 999 961" style="enable-background:new 0 0 999 961;" xml:space="preserve">
@ -232,7 +234,7 @@
</svg> </svg>
</button> </button>
<button data-reaction="" class="cursor-pointer hover:scale-105 duration-500 w-fit h-fit rounded-full"> <button data-reaction="Indifferent" class="cursor-pointer hover:scale-105 duration-500 w-fit h-fit rounded-full reaction-button">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1" x="0px" y="0px" class="w-9" viewBox="0 0 999 961" version="1.1" x="0px" y="0px" class="w-9" viewBox="0 0 999 961"
style="enable-background:new 0 0 999 961;" xml:space="preserve"> style="enable-background:new 0 0 999 961;" xml:space="preserve">
@ -291,7 +293,7 @@
</button> </button>
<button data-reaction="" class="cursor-pointer hover:scale-105 duration-500 w-fit h-fit rounded-full"> <button data-reaction="Sad" class="cursor-pointer hover:scale-105 duration-500 w-fit h-fit rounded-full reaction-button">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1" x="0px" y="0px" class="w-9" viewBox="0 0 999 961" version="1.1" x="0px" y="0px" class="w-9" viewBox="0 0 999 961"
style="enable-background:new 0 0 999 961;" xml:space="preserve"> style="enable-background:new 0 0 999 961;" xml:space="preserve">
@ -372,6 +374,10 @@
</form> </form>
</div> </div>
</div> </div>
{% else %}
{% include 'partials/submitted-review.html' %}
{% endif %}
</div>
</div> </div>
</div> </div>
@ -381,14 +387,14 @@
<div class="px-5"> <div class="px-5">
<button id="startNewConversation" <button id="startNewConversation"
class="w-full px-5 py-2 bg-osiblue border border-osiblue rounded-md text-white cursor-pointer hover:bg-white hover:text-osiblue duration-300"> class="w-full px-5 py-2 bg-osiblue border border-osiblue rounded-md text-white cursor-pointer hover:bg-white hover:text-osiblue duration-300">
Start New Conversation Start a new conversation
</button> </button>
</div> </div>
<!-- FOOTER --> <!-- FOOTER -->
<div class="w-full rounded-b-md px-3 py-3 flex justify-center items-center gap-1 bg-white"> <div class="w-full rounded-b-md px-3 py-3 flex justify-center items-center gap-1 bg-white">
<img src="http://192.168.1.111:8000/static/images/ositcom_logos/ositcom(o).png" class="w-[20px]"> <img src="{{domain}}/static/images/ositcom_logos/ositcom(o).png" class="w-[20px]">
<p class="text-xs text-secondosiblue">Osichat 2.0 by <a href="https://ositcom.com/" target="_blank" <p class="text-xs text-secondosiblue">Osichat 2.0 by <a href="https://ositcom.com/" target="_blank"
class="hover:text-gray-400 duration-500">Ositcom</a></p> class="hover:text-gray-400 duration-500">Ositcom</a></p>

@ -5,7 +5,7 @@
class="w-[25px] h-[25px] rounded-full shadow-md text-white flex justify-center items-center bg-osiblue uppercase text-xs"> class="w-[25px] h-[25px] rounded-full shadow-md text-white flex justify-center items-center bg-osiblue uppercase text-xs">
{% if message_attachment.message.member.staffprofile.image %} {% if message_attachment.message.member.staffprofile.image %}
<img class="w-full h-full rounded-full" <img class="w-full h-full rounded-full"
src="http://192.168.1.111:8000{{message_attachment.message.member.staffprofile.image.url}}"> src="{{domain}}{{message_attachment.message.member.staffprofile.image.url}}">
{% else %} {% else %}
<p>{{message_attachment.message.member.first_name.0}}{{message_attachment.message.member.last_name.0}}</p> <p>{{message_attachment.message.member.first_name.0}}{{message_attachment.message.member.last_name.0}}</p>
{% endif %} {% endif %}
@ -14,7 +14,7 @@
{% if file_type == 'image' %} {% if file_type == 'image' %}
<div <div
class="max-w-[80%] bg-gray-50 p-4 rounded-r-3xl rounded-tl-3xl text-secondosiblue text-sm leading-6 bg-opacity-50 shadow-md border border-gray-100"> class="max-w-[80%] bg-gray-50 p-4 rounded-r-3xl rounded-tl-3xl text-secondosiblue text-sm leading-6 bg-opacity-50 shadow-md border border-gray-100">
<img src="http://192.168.1.111:8000/{{message_attachment.attachment}}" class="rounded-md"> <img src="{{domain}}/{{message_attachment.attachment}}" class="rounded-md">
</div> </div>
{% else %} {% else %}
<div <div
@ -39,7 +39,7 @@
{% if file_type == 'image' %} {% if file_type == 'image' %}
<div class="w-full flex justify-end"> <div class="w-full flex justify-end">
<div class="max-w-[80%] p-4 rounded-l-3xl rounded-tr-3xl text-white shadow-md text-sm leading-6 bg-opacity-70 bg-osiblue"> <div class="max-w-[80%] p-4 rounded-l-3xl rounded-tr-3xl text-white shadow-md text-sm leading-6 bg-opacity-70 bg-osiblue">
<img src="http://192.168.1.111:8000/{{message_attachment.attachment}}" class="rounded-md"> <img src="{{domain}}/{{message_attachment.attachment}}" class="rounded-md">
</div> </div>
</div> </div>
{% else %} {% else %}

@ -5,7 +5,7 @@
class="w-[25px] h-[25px] rounded-full shadow-md text-white flex justify-center items-center bg-osiblue uppercase text-xs"> class="w-[25px] h-[25px] rounded-full shadow-md text-white flex justify-center items-center bg-osiblue uppercase text-xs">
{% if chat_message.member.staffprofile.image %} {% if chat_message.member.staffprofile.image %}
<img class="w-full h-full rounded-full" <img class="w-full h-full rounded-full"
src="http://192.168.1.111:8000{{chat_message.member.staffprofile.image.url}}"> src="{{domain}}{{chat_message.member.staffprofile.image.url}}">
{% else %} {% else %}
<p>{{chat_message.member.first_name.0}}{{chat_message.member.last_name.0}}</p> <p>{{chat_message.member.first_name.0}}{{chat_message.member.last_name.0}}</p>
{% endif %} {% endif %}
@ -20,7 +20,7 @@
{% if chat_message.chatmessageattachment.is_image %} {% if chat_message.chatmessageattachment.is_image %}
<div <div
class="max-w-[80%] bg-gray-50 p-4 rounded-r-3xl rounded-tl-3xl text-secondosiblue text-sm leading-6 bg-opacity-50 shadow-md border border-gray-100"> class="max-w-[80%] bg-gray-50 p-4 rounded-r-3xl rounded-tl-3xl text-secondosiblue text-sm leading-6 bg-opacity-50 shadow-md border border-gray-100">
<img src="http://192.168.1.111:8000/{{chat_message.chatmessageattachment.attachment}}" class="rounded-md"> <img src="{{domain}}/{{chat_message.chatmessageattachment.attachment}}" class="rounded-md">
</div> </div>
{% else %} {% else %}
<div <div
@ -55,7 +55,7 @@
{% if chat_message.chatmessageattachment.is_image %} {% if chat_message.chatmessageattachment.is_image %}
<div class="w-full flex justify-end"> <div class="w-full flex justify-end">
<div class="max-w-[80%] p-4 rounded-l-3xl rounded-tr-3xl text-white shadow-md text-sm leading-6 bg-opacity-70 bg-osiblue"> <div class="max-w-[80%] p-4 rounded-l-3xl rounded-tr-3xl text-white shadow-md text-sm leading-6 bg-opacity-70 bg-osiblue">
<img src="http://192.168.1.111:8000/{{chat_message.chatmessageattachment.attachment}}" class="rounded-md"> <img src="{{domain}}/{{chat_message.chatmessageattachment.attachment}}" class="rounded-md">
</div> </div>
</div> </div>
{% else %} {% else %}

@ -0,0 +1,232 @@
<div class="w-full flex items-end gap-2">
<div>
<div
class="w-[25px] h-[25px] rounded-full shadow-md text-white flex justify-center items-center bg-osiblue">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="w-4" color="#000000"
fill="none">
<path d="M4 15.5C2.89543 15.5 2 14.6046 2 13.5C2 12.3954 2.89543 11.5 4 11.5" stroke="white"
stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
<path d="M20 15.5C21.1046 15.5 22 14.6046 22 13.5C22 12.3954 21.1046 11.5 20 11.5"
stroke="white" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
<path d="M7 7L7 4" stroke="white" stroke-width="1.5" stroke-linejoin="round" />
<path d="M17 7L17 4" stroke="white" stroke-width="1.5" stroke-linejoin="round" />
<circle cx="7" cy="3" r="1" stroke="white" stroke-width="1.5" stroke-linejoin="round" />
<circle cx="17" cy="3" r="1" stroke="white" stroke-width="1.5" stroke-linejoin="round" />
<path
d="M13.5 7H10.5C7.67157 7 6.25736 7 5.37868 7.90898C4.5 8.81796 4.5 10.2809 4.5 13.2069C4.5 16.1329 4.5 17.5958 5.37868 18.5048C6.25736 19.4138 7.67157 19.4138 10.5 19.4138H11.5253C12.3169 19.4138 12.5962 19.5773 13.1417 20.1713C13.745 20.8283 14.6791 21.705 15.5242 21.9091C16.7254 22.1994 16.8599 21.7979 16.5919 20.6531C16.5156 20.327 16.3252 19.8056 16.526 19.5018C16.6385 19.3316 16.8259 19.2898 17.2008 19.2061C17.7922 19.074 18.2798 18.8581 18.6213 18.5048C19.5 17.5958 19.5 16.1329 19.5 13.2069C19.5 10.2809 19.5 8.81796 18.6213 7.90898C17.7426 7 16.3284 7 13.5 7Z"
stroke="white" stroke-width="1.5" stroke-linejoin="round" />
<path d="M9.5 15C10.0701 15.6072 10.9777 16 12 16C13.0223 16 13.9299 15.6072 14.5 15"
stroke="currentColor" stroke-width="1.5" stroke-linecap="round"
stroke-linejoin="round" />
<path d="M9.00896 11H9" stroke="#20336b" stroke-width="2" stroke-linecap="round"
stroke-linejoin="round" />
<path d="M15.009 11H15" stroke="#20336b" stroke-width="2" stroke-linecap="round"
stroke-linejoin="round" />
</svg>
</div>
</div>
<div
class="w-[80%] flex flex-col gap-3 bg-gray-50 px-4 py-3 rounded-r-3xl border-t-2 border-secondosiblue rounded-tl-3xl text-secondosiblue text-sm leading-7 bg-opacity-50 shadow-md">
<p class="text-center text-secondosiblue">Thank you for submitting the rating</p>
<div class="w-full flex justify-center items-center gap-3">
<button data-reaction="Happy" class="reaction-button cursor-pointer hover:scale-105 duration-500 w-fit h-fit rounded-full">
<svg xmlns="http://www.w3.org/2000/svg" class="w-9 {% if review.reaction and not review.reaction == 'Happy' %} grayscale {% endif %}"
xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px"
viewBox="0 0 999 961" style="enable-background:new 0 0 999 961;" xml:space="preserve">
<style type="text/css">
.st0 {
fill: #D62B2B;
}
.st1 {
fill: #FFFFFF;
}
.st2 {
fill: #1A212D;
}
.st3 {
fill: #962A2A;
}
.st4 {
fill: #EFC029;
}
.st5 {
fill: #B79430;
}
.st6 {
fill: #8ACC36;
}
.st7 {
fill: #5D891F;
}
</style>
<g id="background">
</g>
<g id="objects">
<g>
<circle class="st6" cx="482" cy="485" r="470.3" />
<g>
<circle class="st1" cx="292.8" cy="418.6" r="124.3" />
<circle class="st2" cx="302" cy="426.7" r="67.9" />
<circle class="st1" cx="349.2" cy="387.6" r="24.2" />
</g>
<g>
<circle class="st1" cx="671.2" cy="418.6" r="124.3" />
<circle class="st2" cx="662" cy="426.7" r="67.9" />
<circle class="st1" cx="705.8" cy="387.6" r="24.2" />
</g>
<path class="st7"
d="M626.5,612c4.1,0,8.3,1.1,12.2,3.3c11.5,6.7,15.3,21.5,8.6,33c-0.6,1.1-16.2,27.4-45.7,53.3 C561.8,736.6,515,755,466.2,755s-95.6-18.5-135.4-53.4c-29.6-26-45.1-52.2-45.7-53.3c-6.7-11.5-2.9-26.3,8.6-33 c11.5-6.7,26.2-2.9,33,8.6c0.2,0.3,13,21.7,37.1,42.5c31,26.8,65.5,40.4,102.4,40.4s71.4-13.6,102.4-40.4 c24.1-20.9,37-42.3,37.1-42.5C610.2,616.2,618.3,612,626.5,612z" />
</g>
</g>
</svg>
</button>
<button data-reaction="Indifferent" class="reaction-button cursor-pointer hover:scale-105 duration-500 w-fit h-fit rounded-full">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1" x="0px" y="0px" class="w-9 {% if review.reaction and not review.reaction == 'Indifferent' %} grayscale {% endif %}" viewBox="0 0 999 961"
style="enable-background:new 0 0 999 961;" xml:space="preserve">
<style type="text/css">
.st0 {
fill: #D62B2B;
}
.st1 {
fill: #FFFFFF;
}
.st2 {
fill: #1A212D;
}
.st3 {
fill: #962A2A;
}
.st4 {
fill: #EFC029;
}
.st5 {
fill: #B79430;
}
.st6 {
fill: #8ACC36;
}
.st7 {
fill: #5D891F;
}
</style>
<g id="background">
</g>
<g id="objects">
<g>
<circle class="st4" cx="499.5" cy="480.5" r="470.3" />
<g>
<circle class="st1" cx="310.3" cy="414.1" r="124.3" />
<circle class="st2" cx="319.5" cy="422.1" r="67.9" />
<circle class="st1" cx="366.7" cy="383" r="24.2" />
</g>
<g>
<circle class="st1" cx="688.7" cy="414.1" r="124.3" />
<circle class="st2" cx="679.5" cy="422.1" r="67.9" />
<circle class="st1" cx="723.2" cy="383" r="24.2" />
</g>
<rect x="309.9" y="646.4" class="st5" width="379.1" height="48.2" />
</g>
</g>
</svg>
</button>
<button data-reaction="Sad" class="reaction-button cursor-pointer hover:scale-105 duration-500 w-fit h-fit rounded-full">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1" x="0px" y="0px" class="w-9 {% if review.reaction and not review.reaction == 'Sad' %} grayscale {% endif %}" viewBox="0 0 999 961"
style="enable-background:new 0 0 999 961;" xml:space="preserve">
<style type="text/css">
.st0 {
fill: #D62B2B;
}
.st1 {
fill: #FFFFFF;
}
.st2 {
fill: #1A212D;
}
.st3 {
fill: #962A2A;
}
.st4 {
fill: #EFC029;
}
.st5 {
fill: #B79430;
}
.st6 {
fill: #8ACC36;
}
.st7 {
fill: #5D891F;
}
</style>
<g id="background">
</g>
<g id="objects">
<g>
<circle class="st0" cx="499.5" cy="480.5" r="470.3" />
<g>
<circle class="st1" cx="310.3" cy="414.1" r="124.3" />
<circle class="st2" cx="319.5" cy="422.1" r="67.9" />
<circle class="st1" cx="366.7" cy="383" r="24.2" />
</g>
<g>
<circle class="st1" cx="688.7" cy="414.1" r="124.3" />
<circle class="st2" cx="679.5" cy="422.1" r="67.9" />
<circle class="st1" cx="723.2" cy="383" r="24.2" />
</g>
<path class="st3"
d="M336.7,746.1c-4.1,0-8.3-1.1-12.2-3.3c-11.5-6.7-15.3-21.5-8.6-33c0.6-1.1,16.2-27.4,45.7-53.3 c39.8-34.9,86.6-53.4,135.4-53.4c48.8,0,95.6,18.5,135.4,53.4c29.6,26,45.1,52.2,45.7,53.3c6.7,11.5,2.9,26.3-8.6,33 c-11.5,6.7-26.2,2.9-33-8.6c-0.2-0.3-13-21.7-37.1-42.5c-31-26.8-65.5-40.4-102.4-40.4s-71.4,13.6-102.4,40.4 c-24.1,20.9-37,42.3-37.1,42.5C353.1,741.8,345,746.1,336.7,746.1z" />
</g>
</g>
</svg>
</button>
</div>
{% if not review.details %}
<form class="w-full relative" id="sendReview">
{% csrf_token %}
<div
class="w-full bg-white h-fit rounded-md border border-gray-200 flex items-center justify-between">
<input name="details" placeholder="Tell us more..." id="messageInputTag"
class="w-full border-none rounded-md outline-none px-3 py-2 resize-none duration-500">
<div class="h-full right-0 top-0 px-3 flex items-center gap-2 text-osiblue">
<button type="submit" id="submitButton" class="hidden">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
stroke-width="1.5" stroke="currentColor" class="w-5 notFilledSvg">
<path stroke-linecap="round" stroke-linejoin="round"
d="M6 12 3.269 3.125A59.769 59.769 0 0 1 21.485 12 59.768 59.768 0 0 1 3.27 20.875L5.999 12Zm0 0h7.5" />
</svg>
</button>
</div>
</div>
</form>
{% endif %}
</div>
</div>

@ -3,7 +3,7 @@
class="w-[30px] h-[30px] rounded-full shadow-md text-white flex justify-center items-center bg-osiblue uppercase text-xs"> class="w-[30px] h-[30px] rounded-full shadow-md text-white flex justify-center items-center bg-osiblue uppercase text-xs">
{% if member.staffprofile.image %} {% if member.staffprofile.image %}
<img class="w-full h-full rounded-full" <img class="w-full h-full rounded-full"
src="http://192.168.1.111:8000{{member.staffprofile.image.url}}"> src="{{domain}}{{member.staffprofile.image.url}}">
{% else %} {% else %}
<p>{{member.first_name.0}}{{member.last_name.0}}</p> <p>{{member.first_name.0}}{{member.last_name.0}}</p>
{% endif %} {% endif %}

@ -7,7 +7,7 @@
class="w-[30px] h-[30px] rounded-full shadow-md text-white flex justify-center items-center bg-osiblue uppercase text-xs"> class="w-[30px] h-[30px] rounded-full shadow-md text-white flex justify-center items-center bg-osiblue uppercase text-xs">
{% if latest_unread_message.member.staffprofile.image %} {% if latest_unread_message.member.staffprofile.image %}
<img class="w-full h-full rounded-full" <img class="w-full h-full rounded-full"
src="http://192.168.1.111:8000{{latest_unread_message.member.staffprofile.image.url}}"> src="{{domain}}{{latest_unread_message.member.staffprofile.image.url}}">
{% else %} {% else %}
<p>{{latest_unread_message.member.first_name.0}}{{latest_unread_message.member.last_name.0}}</p> <p>{{latest_unread_message.member.first_name.0}}{{latest_unread_message.member.last_name.0}}</p>
{% endif %} {% endif %}
@ -45,7 +45,7 @@
</div> </div>
{% else %} {% else %}
<div class="w-fit bg-opacity-70 bg-osiblue px-3 py-2 rounded-md w-full h-[300px]"> <div class="w-fit bg-opacity-70 bg-osiblue px-3 py-2 rounded-md w-full h-[300px]">
<img src="http://192.168.1.111:8000/{{latest_unread_message.chatmessageattachment.attachment}}" class="w-full h-full object-cover rounded-md"> <img src="{{domain}}/{{latest_unread_message.chatmessageattachment.attachment}}" class="w-full h-full object-cover rounded-md">
</div> </div>
{% endif %} {% endif %}

@ -62,7 +62,7 @@
</div> </div>
<div class="w-full rounded-b-md px-3 pt-3 flex justify-center items-center gap-1 bg-white"> <div class="w-full rounded-b-md px-3 pt-3 flex justify-center items-center gap-1 bg-white">
<img src="http://192.168.1.111:8000/static/images/ositcom_logos/ositcom(o).png" class="w-[20px]"> <img src="{{domain}}/static/images/ositcom_logos/ositcom(o).png" class="w-[20px]">
<p class="text-xs text-secondosiblue">Osichat 2.0 by <a href="https://ositcom.com/" target="_blank" <p class="text-xs text-secondosiblue">Osichat 2.0 by <a href="https://ositcom.com/" target="_blank"
class="hover:text-gray-400 duration-500">Ositcom</a></p> class="hover:text-gray-400 duration-500">Ositcom</a></p>

@ -9,6 +9,9 @@ from osichat.models import *
def utilities(request): def utilities(request):
# Combine protocol and domain
current_url = 'https://osina.ositcom.com'
notes = None notes = None
recent_note = None recent_note = None
user_offline=None user_offline=None
@ -119,5 +122,6 @@ def utilities(request):
'open_tickets': open_tickets, 'open_tickets': open_tickets,
'closed_tickets': closed_tickets, 'closed_tickets': closed_tickets,
'today': today, 'today': today,
'latest_chat_rooms': latest_chat_rooms 'latest_chat_rooms': latest_chat_rooms,
'current_url': current_url
} }

@ -48,7 +48,6 @@
</div> </div>
</div> </div>
{% if tasks %} {% if tasks %}
<!-- TASKS ON DESKTOP --> <!-- TASKS ON DESKTOP -->
<div class="w-full hidden md:flex flex-col gap-5"> <div class="w-full hidden md:flex flex-col gap-5">

@ -636,7 +636,7 @@ def projectdetails(request, project_id):
def chat_room(request, chat_id): def chat_room(request, chat_id):
chat_room = get_object_or_404(ChatRoom, id=chat_id) chat_room = get_object_or_404(ChatRoom, id=chat_id)
chat_messages = ChatMessage.objects.filter(room=chat_room).order_by('date_sent') chat_messages = ChatMessage.objects.filter(room=chat_room).order_by('date_sent')
guest_session_id = chat_room.chatroomguest.session_id guest_session_id = chat_room.chatroomguest.visitor.session_id
return render(request, 'chat_templates/chat-room.html', {'chat_room': chat_room, 'chat_messages': chat_messages, 'guest_session_id': guest_session_id}) return render(request, 'chat_templates/chat-room.html', {'chat_room': chat_room, 'chat_messages': chat_messages, 'guest_session_id': guest_session_id})

@ -1579,6 +1579,14 @@ video {
cursor: pointer; cursor: pointer;
} }
.cursor-none {
cursor: none;
}
.cursor-not-allowed {
cursor: not-allowed;
}
.resize-none { .resize-none {
resize: none; resize: none;
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 929 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 929 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 929 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 937 KiB

@ -1,5 +1,5 @@
const admin_chat_ws_scheme = window.location.protocol === "https:" ? "wss" : "ws"; const admin_chat_ws_scheme = window.location.protocol === "https:" ? "wss" : "ws";
const admin_chat_domain = "192.168.1.111:8000"; const admin_chat_domain = "osina.ositcom.com";
let chatWebSocket = null; let chatWebSocket = null;

@ -1,5 +1,5 @@
const chat_ws_scheme = window.location.protocol === "https:" ? "wss" : "ws"; const chat_ws_scheme = window.location.protocol === "https:" ? "wss" : "ws";
const domain = "192.168.1.111:8000"; const domain = "osina.ositcom.com";
let osichatSocket; let osichatSocket;
let isOpen = false; let isOpen = false;
let chatLoaded = false; let chatLoaded = false;
@ -18,7 +18,7 @@ async function fetchSessionID() {
let session_id = 'Unknown'; let session_id = 'Unknown';
while (session_id === 'Unknown') { while (session_id === 'Unknown') {
try { try {
const response = await fetch('http://192.168.1.111:3000/get-client-session/'); const response = await fetch('https://ositcom.com/get-client-session/');
const data = await response.json(); const data = await response.json();
if (data.session_id) { if (data.session_id) {
session_id = data.session_id; session_id = data.session_id;
@ -122,7 +122,7 @@ function handleLoadChatEvent(data, osichatSocket) {
endChatButton.classList.remove('hidden') endChatButton.classList.remove('hidden')
} }
const sendReviewContainer = document.getElementById('sendReview'); //Case where returned is ended-chat.html const sendReviewContainer = document.getElementById('reviewContainer'); //Case where returned is ended-chat.html
if (sendReviewContainer) { if (sendReviewContainer) {
const sendReviewScript = document.createElement('script'); const sendReviewScript = document.createElement('script');
sendReviewScript.type = 'text/javascript'; sendReviewScript.type = 'text/javascript';
@ -212,6 +212,7 @@ async function initializeChatWebSocket() {
const currentChat = document.getElementById(`roomContainer`); const currentChat = document.getElementById(`roomContainer`);
if (currentChat) { if (currentChat) {
currentChat.innerHTML = data.html; currentChat.innerHTML = data.html;
scrollBottom();
} }
document.getElementById(`endChatConfirmationContainer`).classList.add('hidden'); document.getElementById(`endChatConfirmationContainer`).classList.add('hidden');
document.getElementById(`endChat`).classList.add('hidden'); document.getElementById(`endChat`).classList.add('hidden');
@ -220,6 +221,16 @@ async function initializeChatWebSocket() {
sendReviewScript.src = `http://${domain}/static/js/osichat/send-review.js`; sendReviewScript.src = `http://${domain}/static/js/osichat/send-review.js`;
currentChat.appendChild(sendReviewScript); currentChat.appendChild(sendReviewScript);
break; break;
case 'submit_review':
const submitReview = document.getElementById(`reviewContainer`);
if (submitReview) {
submitReview.innerHTML = data.html;
}
const reviewScript = document.createElement('script');
reviewScript.type = 'text/javascript';
reviewScript.src = `http://${domain}/static/js/osichat/send-review.js`;
submitReview.appendChild(reviewScript);
break;
default: default:
console.log('Unknown event type:', data.event_type); console.log('Unknown event type:', data.event_type);
} }

@ -21,7 +21,6 @@
const eventMessage = { const eventMessage = {
event_type: 'end_chat', event_type: 'end_chat',
}; };
osichatSocket.send(JSON.stringify(eventMessage)); osichatSocket.send(JSON.stringify(eventMessage));
}); });

@ -1,7 +1,7 @@
(function () { (function () {
const messageInput = document.getElementById('messageInputTag'); const messageInput = document.getElementById('messageInputTag');
const submitButton = document.getElementById('submitButton'); const submitButton = document.getElementById('submitButton');
if (messageInput){
messageInput.addEventListener('input', function () { messageInput.addEventListener('input', function () {
if (messageInput.value.trim() !== "") { if (messageInput.value.trim() !== "") {
submitButton.classList.remove('hidden'); submitButton.classList.remove('hidden');
@ -9,6 +9,39 @@
submitButton.classList.add('hidden'); submitButton.classList.add('hidden');
} }
}); });
}
document.querySelectorAll('.reaction-button').forEach(button => {
button.addEventListener('click', function() {
const reaction = this.getAttribute('data-reaction');
const eventMessage = {
event_type: 'submit_review',
reaction: reaction
};
osichatSocket.send(JSON.stringify(eventMessage));
});
});
if (document.getElementById('sendReview')){
document.getElementById('sendReview').addEventListener('submit', function(event) {
event.preventDefault();
const details = document.getElementById('messageInputTag').value.trim();
if (details) {
const eventMessage = {
event_type: 'submit_review',
details: details
};
osichatSocket.send(JSON.stringify(eventMessage));
} else {
console.error('Details cannot be empty');
}
});
}

@ -1,5 +1,5 @@
(function () { (function () {
const imageDomain = "http://192.168.1.111:8000"; const imageDomain = "https://osina.ositcom.com";
// TO TRIGGER TEH FILE UPLOADER WHEN CLICKING ON THE UPLOAD FILE SVG // TO TRIGGER TEH FILE UPLOADER WHEN CLICKING ON THE UPLOAD FILE SVG
document.getElementById('svgFileUpload').addEventListener('click', function () { document.getElementById('svgFileUpload').addEventListener('click', function () {

@ -1,11 +1,11 @@
const visitors_ws_scheme = window.location.protocol === "https:" ? "wss" : "ws"; const visitors_ws_scheme = window.location.protocol === "https:" ? "wss" : "ws";
const my_domain = "192.168.1.111:8000"; const my_domain = "osina.ositcom.com";
async function fetchClientData() { async function fetchClientData() {
let clientData = { client_ip: 'Unknown', client_country: 'Unknown' }; let clientData = { client_ip: 'Unknown', client_country: 'Unknown' };
while (clientData.client_ip === 'Unknown') { while (clientData.client_ip === 'Unknown') {
try { try {
const response = await fetch('http://192.168.1.111:8000/get-client-ip/'); const response = await fetch('https://osina.ositcom.com/get-client-ip/');
const data = await response.json(); const data = await response.json();
if (data.ip) { if (data.ip) {
clientData = { clientData = {
@ -25,7 +25,7 @@ async function fetchVisitorsSession() {
let session_id = 'Unknown'; let session_id = 'Unknown';
while (session_id === 'Unknown') { while (session_id === 'Unknown') {
try { try {
const response = await fetch('http://192.168.1.111:3000/get-client-session/'); const response = await fetch('https://ositcom.com/get-client-session/');
const data = await response.json(); const data = await response.json();
if (data.session_id) { if (data.session_id) {
session_id = data.session_id; session_id = data.session_id;

Loading…
Cancel
Save