From 693faa86219573dcf1ddf0c8b2a5b1e816e4c179 Mon Sep 17 00:00:00 2001 From: Ruslan Bakiev <572431+veikab@users.noreply.github.com> Date: Wed, 18 Feb 2026 21:50:41 +0700 Subject: [PATCH] Seed 20 Odoo+AI prospects and enforce model-only chat responses --- Frontend/app.vue | 170 +++++++++++++---- Frontend/prisma/seed.mjs | 212 +++++++++++---------- Frontend/server/agent/langgraphCrmAgent.ts | 68 +++++-- 3 files changed, 293 insertions(+), 157 deletions(-) diff --git a/Frontend/app.vue b/Frontend/app.vue index b551a27..c177b78 100644 --- a/Frontend/app.vue +++ b/Frontend/app.vue @@ -100,6 +100,7 @@ const tabs: { id: TabId; label: string }[] = [ ]; const selectedTab = ref("communications"); +const pilotSettingsOpen = ref(false); function dayKey(date: Date) { const y = date.getFullYear(); @@ -221,6 +222,19 @@ const loginPassword = ref(""); const loginError = ref(null); const loginBusy = ref(false); +const userMood = computed(() => { + const hour = new Date().getHours(); + if (hour < 12) return "⚡"; + if (hour < 18) return "🚀"; + return "🌙"; +}); + +const userInitial = computed(() => { + const name = authMe.value?.user?.name?.trim(); + if (!name) return "U"; + return name.charAt(0).toUpperCase(); +}); + const activeChatConversation = computed(() => { const activeId = authMe.value?.conversation.id; if (!activeId) return null; @@ -734,6 +748,13 @@ watchEffect(() => { const selectedDocument = computed(() => documents.value.find((item) => item.id === selectedDocumentId.value)); +function openPilotDocument(docId: string) { + if (!docId) return; + selectedTab.value = "documents"; + selectedDocumentId.value = docId; + pilotSettingsOpen.value = false; +} + const peopleLeftMode = ref("contacts"); const peopleListMode = ref<"contacts" | "deals">("contacts"); const peopleSearch = ref(""); @@ -1049,6 +1070,12 @@ function openDealThread(deal: Deal) { } function openThreadFromCalendarItem(event: CalendarEvent) { + if (!event.contact?.trim()) { + selectedTab.value = "communications"; + peopleLeftMode.value = "calendar"; + pickDate(event.start.slice(0, 10)); + return; + } openCommunicationThread(event.contact); selectedCommChannel.value = "All"; } @@ -1179,8 +1206,8 @@ async function decideFeedCard(card: FeedCard, decision: "accepted" | "rejected")