birzha-legalizasia-frontend/src/views/tickets/Main.vue

197 lines
7.4 KiB
Vue

<template>
<div class="intro-y flex flex-col sm:flex-row items-center mt-8">
<h2 class="text-lg font-medium mr-auto">{{ $t("TICKET_LIST") }}</h2>
<div class="w-full sm:w-auto flex mt-4 sm:mt-0">
<button class="btn btn-primary shadow-md mr-2" @click="onCreateTicket">{{ $t("CREATE_TICKET") }}</button>
</div>
</div>
<div>
<div class="intro-y chat grid grid-cols-12 gap-5 mt-5">
<!-- BEGIN: Chat Side Menu -->
<div class="col-span-12 lg:col-span-4 2xl:col-span-3">
<div class="chat__chat-list overflow-y-auto scrollbar-hidden pr-1 pt-1">
<div v-for="(ticket, ticketKey) in ticketList" :key="ticketKey"
class="intro-x cursor-pointer box relative flex items-center p-5"
:class="[{ 'mt-5': ticketKey }, active == ticket.id ? ['bg-slate-200', 'pointer-events-none'] : '']"
@click.capture="goToTicket(ticket.id)">
<div class="ml-2 overflow-hidden w-full">
<div class="flex items-center justify-between">
<a href="javascript:;" class="font-medium">{{ ticket.title }}</a>
<div class="text-xs text-slate-400 ml-3">{{ $t('CREATED') }} {{ normalizeDate(ticket.created_at) }}</div>
</div>
<div class="w-full truncate text-slate-500 mt-0.5">
{{ $t('STATUS') }}: {{ $t(ticket.status.toUpperCase()) }}
</div>
</div>
<div v-if="ticket.last_sender === 'admin'"
class="w-5 h-5 flex items-center justify-center absolute top-0 right-0 text-xs text-white rounded-full bg-primary font-medium -mt-1 -mr-1">
</div>
</div>
</div>
</div>
<!-- END: Chat Side Menu -->
<!-- BEGIN: Chat Content -->
<div class="intro-y col-span-12 lg:col-span-8 2xl:col-span-9">
<div class="chat__box box">
<!-- BEGIN: Chat Active -->
<div v-show="chatBox" class="h-full flex flex-col">
<div class="flex flex-col sm:flex-row border-b border-slate-200/60 dark:border-darkmode-400 px-5 py-4">
<div class="flex items-center">
<div class="ml-3 mr-auto">
<div class="font-medium text-base">{{ $t("TMEX_ADMINS_TEAM") }}</div>
</div>
</div>
</div>
<div class="overflow-y-scroll scrollbar-hidden px-5 pt-5 flex-1 chat_area-inner" ref="chatAreaRef">
<template v-for="ticketMessage in ticketMessageList" :key="ticketMessage.id">
<template v-if="ticketMessage.is_client">
<div class="chat__box__text-box flex items-end float-right mb-4">
<div class="bg-primary px-4 py-3 text-white rounded-l-md rounded-t-md">
{{ ticketMessage.content }}
<div class="mt-1 text-xs text-white text-opacity-80">
{{ normalizeDate(ticketMessage.created_at) }}
</div>
</div>
</div>
<div class="clear-both"></div>
</template>
<template v-else>
<div class="chat__box__text-box flex items-end float-left mb-4">
<div class="bg-slate-100 dark:bg-darkmode-400 px-4 py-3 text-slate-500 rounded-r-md rounded-t-md">
{{ ticketMessage.content }}
<div class="mt-1 text-xs text-slate-500">{{ normalizeDate(ticketMessage.created_at) }}</div>
</div>
</div>
<div class="clear-both"></div>
</template>
</template>
</div>
<div class="pt-4 pb-10 sm:py-4 flex items-center border-t border-slate-200/60 dark:border-darkmode-400">
<textarea
class="chat__box__input form-control dark:bg-darkmode-600 h-16 resize-none border-transparent px-5 py-3 shadow-none focus:border-transparent focus:ring-0"
rows="1" :placeholder="$t('TYPE_TICKET_MESSAGE')" v-model="content"></textarea>
<a href="javascript:;"
class="w-8 h-8 sm:w-10 sm:h-10 block bg-primary text-white rounded-full flex-none flex items-center justify-center mr-5"
:class="[content === '' ? ['opacity-50', 'pointer-events-none'] : '']" @click="sendMessage">
<SendIcon class="w-4 h-4" />
</a>
</div>
</div>
<!-- END: Chat Active -->
<!-- BEGIN: Chat loading -->
<div v-show="isTicketLoading" class="h-full flex items-center">
<div class="mx-auto text-center">
<div class="mt-3">
<div class="font-medium">
<LoadingIcon icon="oval" color="#003197" class="w-20 h-20" />
</div>
</div>
</div>
</div>
<!-- END: Chat loading -->
<!-- BEGIN: Chat Default -->
<div v-show="!chatBox && !isTicketLoading" class="h-full flex items-center">
<div class="mx-auto text-center">
<div class="w-16 h-16 flex-none image-fit rounded-full overflow-hidden mx-auto">
<img alt="TMEX ICON" src="@/assets/images/fav_icon.svg" />
</div>
<div class="mt-3">
<div v-if="user" class="font-medium">
{{ $t("SIMPLE_HELLO") }}, {{ user.firstname }} {{ user.lastname }}!
</div>
<div class="text-slate-500 mt-1" v-html="$t('PLEASE_SELECT_TICKET')">
</div>
</div>
</div>
</div>
<!-- END: Chat Default -->
</div>
</div>
<!-- END: Chat Content -->
</div>
</div>
</template>
<script setup>
import { ref, onBeforeMount, watch, computed } from "vue";
import router from "@/router";
import { useAuthStore, useTicketsStore } from "@/stores";
import { storeToRefs } from 'pinia';
import { normalizeDate } from "@/helpers";
import { useRoute } from "vue-router";
const route = useRoute();
const authStore = useAuthStore();
const ticketsStore = useTicketsStore();
const { user } = storeToRefs(authStore);
const { ticketList, ticketMessageList } = storeToRefs(ticketsStore);
const chatBox = ref(false);
const active = ref(0);
const isTicketLoading = ref(false);
const content = ref("");
const chatAreaRef = ref(); // div element chat
const onCreateTicket = () => router.push({ path: "/ticket-list/create" });
const goToTicket = (ticketId) => router.push({ name: "ticket-list", query: { ticketId: ticketId } });
const showChatBox = async (ticketId) => {
chatBox.value = false;
isTicketLoading.value = true;
await ticketsStore.getTicketMessages(ticketId);
isTicketLoading.value = false;
chatBox.value = true;
active.value = ticketId
scrollToLastMessage();
};
const scrollToLastMessage = () => {
setTimeout(() => {
chatAreaRef.value.scrollTop = chatAreaRef.value.scrollHeight;
}, 0);
};
const sendMessage = async () => {
await ticketsStore.sendMessage(content.value, active.value);
content.value = "";
scrollToLastMessage();
};
onBeforeMount(async () => {
await ticketsStore.getTickets();
if (route.query.ticketId) {
showChatBox(route.query.ticketId);
}
});
watch(
computed(() => route.query),
() => {
if (route.query.ticketId) {
console.log(route.query);
showChatBox(route.query.ticketId);
}
//console.log(route.query.ticketId);
}
);
</script>