ConversasHistoricoView.vue 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. <script setup>
  2. import { computed } from "vue";
  3. import { useRouter } from "vue-router";
  4. import LayoutSistema from "../../layout/LayoutSistema.vue";
  5. import { useChat } from "../../composables/useChat.js";
  6. const router = useRouter();
  7. const { conversations, activeConversationId, setActiveConversation, deleteConversation } = useChat();
  8. const items = computed(() =>
  9. (conversations.value ?? []).slice().sort((a, b) => Number(b.updatedAt ?? 0) - Number(a.updatedAt ?? 0))
  10. );
  11. function formatarData(ts) {
  12. try {
  13. return new Date(Number(ts ?? 0)).toLocaleString("pt-BR", {
  14. day: "2-digit", month: "2-digit", year: "numeric",
  15. hour: "2-digit", minute: "2-digit"
  16. });
  17. } catch {
  18. return "";
  19. }
  20. }
  21. function abrirConversa(id) {
  22. setActiveConversation(id);
  23. router.push({ name: "home" });
  24. }
  25. function excluirConversa(id) {
  26. deleteConversation(id);
  27. }
  28. </script>
  29. <template>
  30. <LayoutSistema>
  31. <section class="rounded-2xl border border-gray-200 bg-gray-100/50 p-6 shadow-sm backdrop-blur-md dark:border-gray-700 dark:bg-secondary/50">
  32. <div class="flex items-start justify-between gap-4">
  33. <div>
  34. <h2 class="text-lg font-semibold text-gray-900 dark:text-gray-100">Histórico</h2>
  35. <p class="mt-1 text-sm text-gray-500 dark:text-gray-400">{{ items.length }} conversa{{ items.length === 1 ? '' : 's' }}</p>
  36. </div>
  37. </div>
  38. <div v-if="!items.length" class="mt-8 flex flex-col items-center gap-3 py-8 text-center">
  39. <div class="flex h-14 w-14 items-center justify-center rounded-2xl border border-dashed border-gray-300 dark:border-gray-600">
  40. <svg class="h-6 w-6 text-gray-400 dark:text-gray-500" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8">
  41. <path stroke-linecap="round" stroke-linejoin="round" d="M12 6v6l4 2" />
  42. <path stroke-linecap="round" stroke-linejoin="round" d="M21 12a9 9 0 1 1-3.2-6.9" />
  43. </svg>
  44. </div>
  45. <div class="text-sm font-medium text-gray-500 dark:text-gray-400">Nenhuma conversa ainda</div>
  46. <div class="text-xs text-gray-400 dark:text-gray-500">Suas conversas aparecerão aqui após a primeira mensagem.</div>
  47. </div>
  48. <div v-else class="mt-4 grid gap-2">
  49. <div v-for="c in items" :key="c.id" class="grid grid-cols-[1fr_auto] items-stretch gap-2">
  50. <button
  51. type="button"
  52. class="rounded-xl border p-3 text-left transition-colors"
  53. :class="
  54. c.id === activeConversationId
  55. ? 'border-primary/40 bg-primary/5 dark:border-primary/30 dark:bg-primary/10'
  56. : 'border-gray-200 bg-background/60 hover:border-gray-400 dark:border-gray-700 dark:bg-background/10 dark:hover:border-gray-500'
  57. "
  58. @click="abrirConversa(c.id)"
  59. >
  60. <div class="flex items-center gap-2">
  61. <div
  62. v-if="c.id === activeConversationId"
  63. class="h-1.5 w-1.5 shrink-0 rounded-full bg-primary"
  64. />
  65. <div class="truncate text-sm font-semibold text-gray-900 dark:text-gray-100">{{ c.title || 'Nova conversa' }}</div>
  66. </div>
  67. <div class="mt-1 text-xs text-gray-500 dark:text-gray-400">
  68. {{ formatarData(c.updatedAt) }} · {{ c.messageCount ?? 0 }} msgs
  69. </div>
  70. </button>
  71. <button
  72. type="button"
  73. class="rounded-xl border border-gray-200 bg-background/60 px-3 py-2 text-gray-400 transition-colors hover:border-red-300 hover:bg-red-50 hover:text-red-600 dark:border-gray-700 dark:bg-background/10 dark:text-gray-500 dark:hover:border-red-500/40 dark:hover:bg-red-500/10 dark:hover:text-red-400"
  74. title="Excluir conversa"
  75. @click="excluirConversa(c.id)"
  76. >
  77. <svg class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8">
  78. <path stroke-linecap="round" stroke-linejoin="round" d="M3 6h18" />
  79. <path stroke-linecap="round" stroke-linejoin="round" d="M19 6l-1 14H6L5 6" />
  80. <path stroke-linecap="round" stroke-linejoin="round" d="M9 6V4h6v2" />
  81. </svg>
  82. </button>
  83. </div>
  84. </div>
  85. </section>
  86. </LayoutSistema>
  87. </template>