|
|
@@ -3,7 +3,6 @@ import { computed } from "vue";
|
|
|
import { useRoute, useRouter } from "vue-router";
|
|
|
import {
|
|
|
ChevronLeft,
|
|
|
- ChevronRight,
|
|
|
Plus,
|
|
|
History,
|
|
|
Search,
|
|
|
@@ -26,12 +25,31 @@ const router = useRouter();
|
|
|
const route = useRoute();
|
|
|
|
|
|
const { activeConversationId, newConversation } = useChat();
|
|
|
-const { sidebarRecolhida, classeItemSidebar, classeIcon, classeRotulo } = useSidebar();
|
|
|
+const { sidebarRecolhida, classeItemSidebar, classeIcon, classeRotulo, alterarSidebar } = useSidebar();
|
|
|
|
|
|
const { isAdmin } = useAuth();
|
|
|
|
|
|
const rotaAtiva = computed(() => String(route.name ?? ""));
|
|
|
|
|
|
+function ariaAtual(ativo) {
|
|
|
+ return ativo ? "page" : undefined;
|
|
|
+}
|
|
|
+
|
|
|
+const itensChat = [
|
|
|
+ { rota: "conversas-historico", icon: History, label: "Histórico" },
|
|
|
+ { rota: "conversas-pesquisar", icon: Search, label: "Pesquisar" },
|
|
|
+ { rota: "conversas-whatsapp", icon: MessageCircle, label: "Atendimento WhatsApp" },
|
|
|
+];
|
|
|
+
|
|
|
+const itensBiblioteca = [
|
|
|
+ { rota: "documentos-carregar", icon: Upload, label: "Carregar documento" },
|
|
|
+ { rota: "documentos", icon: FileText, label: "Documentos" },
|
|
|
+ { rota: "avaliacoes", icon: Star, label: "Avaliações" },
|
|
|
+ { rota: "ranking-atendentes", icon: Trophy, label: "Ranking de atendentes" },
|
|
|
+ { rota: "atendimentos-nao-resolvidos", icon: TriangleAlert, label: "Não resolvidos" },
|
|
|
+ { rota: "golden-set", icon: CircleCheck, label: "Golden set" },
|
|
|
+];
|
|
|
+
|
|
|
function irPara(nome) {
|
|
|
router.push({ name: nome });
|
|
|
}
|
|
|
@@ -44,7 +62,7 @@ async function novaConversa() {
|
|
|
|
|
|
<template>
|
|
|
<aside
|
|
|
- class="col-start-1 row-start-2 relative z-10 flex min-h-0 min-w-0 flex-col overflow-hidden rounded-[28px] border border-gray-200 bg-white/70 p-3 shadow-sm backdrop-blur-md dark:border-white/10 dark:bg-abyss-900 dark:shadow-[0_18px_50px_rgba(0,0,0,0.35)] max-layout:row-start-3 max-layout:max-h-[45vh] max-layout:overflow-y-auto"
|
|
|
+ class="col-start-1 row-start-2 relative z-10 flex min-h-0 min-w-0 flex-col overflow-hidden rounded-[28px] border border-gray-200 bg-white/70 p-3 shadow-sm backdrop-blur-md dark:border-white/10 dark:bg-abyss-900 dark:shadow-[0_18px_50px_rgba(0,0,0,0.35)] max-layout:row-start-3 max-layout:max-h-[45vh] max-layout:overflow-y-auto max-layout:[mask-image:linear-gradient(to_bottom,black_calc(100%-24px),transparent_100%)]"
|
|
|
>
|
|
|
<div
|
|
|
:class="
|
|
|
@@ -55,14 +73,18 @@ async function novaConversa() {
|
|
|
>
|
|
|
<button
|
|
|
type="button"
|
|
|
- class="inline-flex h-9 w-9 items-center justify-center rounded-xl border border-gray-200 bg-white/60 text-gray-600 transition-colors hover:bg-white/80 hover:text-gray-900 focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background dark:border-white/10 dark:bg-white/5 dark:text-white/70 dark:hover:bg-white/10 dark:hover:text-white"
|
|
|
+ class="inline-flex h-9 w-9 items-center justify-center rounded-xl border border-gray-200 bg-white/60 text-gray-600 transition-all duration-200 ease-in-out hover:bg-white/80 hover:text-gray-900 focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background active:scale-90 dark:border-white/10 dark:bg-white/5 dark:text-white/70 dark:hover:bg-white/10 dark:hover:text-white"
|
|
|
:aria-label="
|
|
|
sidebarRecolhida ? 'Expandir sidebar' : 'Recolher sidebar'
|
|
|
"
|
|
|
:title="sidebarRecolhida ? 'Expandir sidebar' : 'Recolher sidebar'"
|
|
|
- @click="sidebarRecolhida = !sidebarRecolhida"
|
|
|
+ @click="alterarSidebar"
|
|
|
>
|
|
|
- <BaseIcon :icon="sidebarRecolhida ? ChevronRight : ChevronLeft" class="h-5 w-5" />
|
|
|
+ <BaseIcon
|
|
|
+ :icon="ChevronLeft"
|
|
|
+ class="h-5 w-5 transition-transform duration-200 ease-in-out"
|
|
|
+ :class="{ 'rotate-180': sidebarRecolhida }"
|
|
|
+ />
|
|
|
</button>
|
|
|
</div>
|
|
|
|
|
|
@@ -72,11 +94,12 @@ async function novaConversa() {
|
|
|
>
|
|
|
Chat
|
|
|
</div>
|
|
|
- <nav class="grid gap-1">
|
|
|
+ <nav class="grid gap-1" aria-label="Chat">
|
|
|
<button
|
|
|
type="button"
|
|
|
:class="classeItemSidebar(rotaAtiva === 'home' && !activeConversationId)"
|
|
|
:title="sidebarRecolhida ? 'Nova conversa' : ''"
|
|
|
+ :aria-current="ariaAtual(rotaAtiva === 'home' && !activeConversationId)"
|
|
|
@click="novaConversa"
|
|
|
>
|
|
|
<BaseIcon :icon="Plus" :class="classeIcon(rotaAtiva === 'home' && !activeConversationId)" />
|
|
|
@@ -84,42 +107,27 @@ async function novaConversa() {
|
|
|
</button>
|
|
|
|
|
|
<button
|
|
|
+ v-for="item in itensChat"
|
|
|
+ :key="item.rota"
|
|
|
type="button"
|
|
|
- :class="classeItemSidebar(rotaAtiva === 'conversas-historico')"
|
|
|
- :title="sidebarRecolhida ? 'Histórico' : ''"
|
|
|
- @click="irPara('conversas-historico')"
|
|
|
- >
|
|
|
- <BaseIcon :icon="History" :class="classeIcon(rotaAtiva === 'conversas-historico')" />
|
|
|
- <span :class="classeRotulo">Histórico</span>
|
|
|
- </button>
|
|
|
-
|
|
|
- <button
|
|
|
- type="button"
|
|
|
- :class="classeItemSidebar(rotaAtiva === 'conversas-pesquisar')"
|
|
|
- :title="sidebarRecolhida ? 'Pesquisar' : ''"
|
|
|
- @click="irPara('conversas-pesquisar')"
|
|
|
- >
|
|
|
- <BaseIcon :icon="Search" :class="classeIcon(rotaAtiva === 'conversas-pesquisar')" />
|
|
|
- <span :class="classeRotulo">Pesquisar</span>
|
|
|
- </button>
|
|
|
-
|
|
|
- <button
|
|
|
- type="button"
|
|
|
- :class="classeItemSidebar(rotaAtiva === 'conversas-whatsapp')"
|
|
|
- :title="sidebarRecolhida ? 'Atendimento WhatsApp' : ''"
|
|
|
- @click="irPara('conversas-whatsapp')"
|
|
|
+ :class="classeItemSidebar(rotaAtiva === item.rota)"
|
|
|
+ :title="sidebarRecolhida ? item.label : ''"
|
|
|
+ :aria-current="ariaAtual(rotaAtiva === item.rota)"
|
|
|
+ @click="irPara(item.rota)"
|
|
|
>
|
|
|
- <BaseIcon :icon="MessageCircle" :class="classeIcon(rotaAtiva === 'conversas-whatsapp')" />
|
|
|
- <span :class="classeRotulo">Atendimento WhatsApp</span>
|
|
|
+ <BaseIcon :icon="item.icon" :class="classeIcon(rotaAtiva === item.rota)" />
|
|
|
+ <span :class="classeRotulo">{{ item.label }}</span>
|
|
|
</button>
|
|
|
</nav>
|
|
|
|
|
|
-
|
|
|
<ListaConversas v-if="!sidebarRecolhida" />
|
|
|
|
|
|
-
|
|
|
- <div class="mt-auto flex-shrink-0 grid gap-1 pt-2">
|
|
|
- <div class="my-1 h-px bg-black/10 dark:bg-white/10" />
|
|
|
+ <div
|
|
|
+ class="mt-auto flex-shrink-0 grid gap-1 pt-2"
|
|
|
+ role="navigation"
|
|
|
+ aria-label="Biblioteca e sistema"
|
|
|
+ >
|
|
|
+ <div class="my-1 h-px bg-black/10 dark:bg-white/10" role="separator" />
|
|
|
<template v-if="isAdmin">
|
|
|
<div
|
|
|
v-if="!sidebarRecolhida"
|
|
|
@@ -129,66 +137,19 @@ async function novaConversa() {
|
|
|
</div>
|
|
|
|
|
|
<button
|
|
|
+ v-for="item in itensBiblioteca"
|
|
|
+ :key="item.rota"
|
|
|
type="button"
|
|
|
- :class="classeItemSidebar(rotaAtiva === 'documentos-carregar')"
|
|
|
- :title="sidebarRecolhida ? 'Carregar documento' : ''"
|
|
|
- @click="irPara('documentos-carregar')"
|
|
|
- >
|
|
|
- <BaseIcon :icon="Upload" :class="classeIcon(rotaAtiva === 'documentos-carregar')" />
|
|
|
- <span :class="classeRotulo">Carregar documento</span>
|
|
|
- </button>
|
|
|
-
|
|
|
- <button
|
|
|
- type="button"
|
|
|
- :class="classeItemSidebar(rotaAtiva === 'documentos')"
|
|
|
- :title="sidebarRecolhida ? 'Documentos' : ''"
|
|
|
- @click="irPara('documentos')"
|
|
|
- >
|
|
|
- <BaseIcon :icon="FileText" :class="classeIcon(rotaAtiva === 'documentos')" />
|
|
|
- <span :class="classeRotulo">Documentos</span>
|
|
|
- </button>
|
|
|
-
|
|
|
- <button
|
|
|
- type="button"
|
|
|
- :class="classeItemSidebar(rotaAtiva === 'avaliacoes')"
|
|
|
- :title="sidebarRecolhida ? 'Avaliações' : ''"
|
|
|
- @click="irPara('avaliacoes')"
|
|
|
- >
|
|
|
- <BaseIcon :icon="Star" :class="classeIcon(rotaAtiva === 'avaliacoes')" />
|
|
|
- <span :class="classeRotulo">Avaliações</span>
|
|
|
- </button>
|
|
|
-
|
|
|
- <button
|
|
|
- type="button"
|
|
|
- :class="classeItemSidebar(rotaAtiva === 'ranking-atendentes')"
|
|
|
- :title="sidebarRecolhida ? 'Ranking de atendentes' : ''"
|
|
|
- @click="irPara('ranking-atendentes')"
|
|
|
- >
|
|
|
- <BaseIcon :icon="Trophy" :class="classeIcon(rotaAtiva === 'ranking-atendentes')" />
|
|
|
- <span :class="classeRotulo">Ranking de atendentes</span>
|
|
|
- </button>
|
|
|
-
|
|
|
- <button
|
|
|
- type="button"
|
|
|
- :class="classeItemSidebar(rotaAtiva === 'atendimentos-nao-resolvidos')"
|
|
|
- :title="sidebarRecolhida ? 'Não resolvidos' : ''"
|
|
|
- @click="irPara('atendimentos-nao-resolvidos')"
|
|
|
- >
|
|
|
- <BaseIcon :icon="TriangleAlert" :class="classeIcon(rotaAtiva === 'atendimentos-nao-resolvidos')" />
|
|
|
- <span :class="classeRotulo">Não resolvidos</span>
|
|
|
- </button>
|
|
|
-
|
|
|
- <button
|
|
|
- type="button"
|
|
|
- :class="classeItemSidebar(rotaAtiva === 'golden-set')"
|
|
|
- :title="sidebarRecolhida ? 'Golden set' : ''"
|
|
|
- @click="irPara('golden-set')"
|
|
|
+ :class="classeItemSidebar(rotaAtiva === item.rota)"
|
|
|
+ :title="sidebarRecolhida ? item.label : ''"
|
|
|
+ :aria-current="ariaAtual(rotaAtiva === item.rota)"
|
|
|
+ @click="irPara(item.rota)"
|
|
|
>
|
|
|
- <BaseIcon :icon="CircleCheck" :class="classeIcon(rotaAtiva === 'golden-set')" />
|
|
|
- <span :class="classeRotulo">Golden set</span>
|
|
|
+ <BaseIcon :icon="item.icon" :class="classeIcon(rotaAtiva === item.rota)" />
|
|
|
+ <span :class="classeRotulo">{{ item.label }}</span>
|
|
|
</button>
|
|
|
|
|
|
- <div class="my-1 h-px bg-black/10 dark:bg-white/10" />
|
|
|
+ <div class="my-1 h-px bg-black/10 dark:bg-white/10" role="separator" />
|
|
|
</template>
|
|
|
<div
|
|
|
v-if="!sidebarRecolhida"
|
|
|
@@ -201,6 +162,7 @@ async function novaConversa() {
|
|
|
type="button"
|
|
|
:class="classeItemSidebar(rotaAtiva === 'configuracoes')"
|
|
|
:title="sidebarRecolhida ? 'Configurações' : ''"
|
|
|
+ :aria-current="ariaAtual(rotaAtiva === 'configuracoes')"
|
|
|
@click="irPara('configuracoes')"
|
|
|
>
|
|
|
<BaseIcon :icon="SlidersHorizontal" :class="classeIcon(rotaAtiva === 'configuracoes')" />
|