| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 |
- <script setup>
- import { computed, onUnmounted, ref } from "vue";
- import ChatWindow from "../../components/ChatWindow.vue";
- import LayoutSistema from "../../layout/LayoutSistema.vue";
- import { useChat } from "../../composables/useChat.js";
- import BaseButton from "../../components/base/BaseButton.vue";
- const {
- messages: chatMessages,
- loading: chatLoading,
- error: chatError,
- send: sendMessage,
- clearError,
- cancelCurrentStream,
- activeConversationId,
- exportConversation
- } = useChat();
- onUnmounted(() => cancelCurrentStream());
- const exportando = ref(false);
- async function onExport() {
- if (!activeConversationId.value || exportando.value) return;
- exportando.value = true;
- try {
- await exportConversation(activeConversationId.value);
- } finally {
- exportando.value = false;
- }
- }
- const landingDraft = ref("");
- const isLanding = computed(() => {
- const ms = chatMessages.value ?? [];
- if (ms.length === 0) return true;
- if (ms.length === 1 && ms[0]?.role === "assistant") return true;
- return false;
- });
- async function onLandingSend() {
- const text = landingDraft.value;
- if (!text.trim()) return;
- landingDraft.value = "";
- await sendMessage(text);
- }
- </script>
- <template>
- <LayoutSistema>
- <div v-if="isLanding" class="min-h-[calc(100vh-var(--layout-header-height))] flex items-center justify-center pb-12 md:pb-16">
- <div class="w-full max-w-[720px]">
- <div class="text-3xl font-extrabold tracking-tight">Como posso ajudar?</div>
- <div class="mt-2 text-sm text-gray-500 dark:text-gray-400">
- Digite sua pergunta abaixo. Você também pode alimentar a base pela barra lateral.
- </div>
- <div class="mt-6 rounded-2xl border border-gray-200 bg-white/70 p-4 shadow-sm backdrop-blur-md dark:border-white/10 dark:bg-white/[0.04]">
- <textarea
- v-model="landingDraft"
- rows="3"
- placeholder="Digite sua pergunta..."
- class="min-h-20 resize-none border-0 bg-transparent shadow-none focus:ring-0 !outline-none"
- style="resize: none"
- @keydown.enter.exact.prevent="onLandingSend"
- />
- <div class="mt-3 flex items-center justify-between gap-3">
- <span class="text-xs text-gray-400 dark:text-gray-500">Enter para enviar · Shift+Enter para nova linha</span>
- <BaseButton :disabled="chatLoading || !landingDraft.trim()" @click="onLandingSend">
- <svg class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
- <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>
- Enviar
- </BaseButton>
- </div>
- </div>
- <div v-if="chatError" class="mt-3 flex items-center justify-between gap-2 rounded-xl border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-600 dark:border-red-500/30 dark:bg-red-500/10 dark:text-red-300">
- <span>Erro: {{ chatError }}</span>
- <button type="button" class="shrink-0 rounded p-0.5 opacity-60 hover:opacity-100 transition-opacity" aria-label="Fechar erro" @click="clearError">
- <svg class="h-3.5 w-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
- <path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12" />
- </svg>
- </button>
- </div>
- </div>
- </div>
- <div v-else class="relative h-full w-full">
- <div class="relative flex h-full w-full flex-col p-4 md:p-6">
- <div class="mb-2 flex items-center justify-end">
- <button
- v-if="activeConversationId"
- type="button"
- class="inline-flex items-center gap-1.5 rounded-lg border border-gray-200 bg-white/60 px-2.5 py-1.5 text-xs font-medium text-gray-500 transition-colors hover:bg-white hover:text-gray-700 disabled:opacity-50 dark:border-white/10 dark:bg-white/5 dark:text-white/50 dark:hover:bg-white/10 dark:hover:text-white/80"
- :disabled="exportando || chatLoading"
- @click="onExport"
- >
- <svg class="h-3.5 w-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
- <path stroke-linecap="round" stroke-linejoin="round" d="M3 16.5v2.25A2.25 2.25 0 0 0 5.25 21h13.5A2.25 2.25 0 0 0 21 18.75V16.5M16.5 12 12 16.5m0 0L7.5 12m4.5 4.5V3" />
- </svg>
- {{ exportando ? "Exportando..." : "Exportar .md" }}
- </button>
- </div>
- <ChatWindow class="flex-1 min-h-1" :messages="chatMessages" :loading="chatLoading" :error="chatError" @send="sendMessage" @clearError="clearError" />
- </div>
- </div>
- </LayoutSistema>
- </template>
|