Add Ask Mento, customer mood, and Pipecat speech-to-text.
Ship assistant answers, contact moods, voice dictation, and the related CRM UI so these can be deployed to production. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { useAuthStore } from '@/stores/auth';
|
||||
import { api } from '@/lib/api';
|
||||
import { formatMoney } from '@/lib/money';
|
||||
@@ -13,21 +12,27 @@ import HomeAiAssistant from '@/components/dashboard/HomeAiAssistant.vue';
|
||||
import HomeRecentActivities from '@/components/dashboard/HomeRecentActivities.vue';
|
||||
import HomeMiniPipeline from '@/components/dashboard/HomeMiniPipeline.vue';
|
||||
import HomeTopCustomers from '@/components/dashboard/HomeTopCustomers.vue';
|
||||
import axios from 'axios';
|
||||
import type {
|
||||
ActivityDto,
|
||||
AskMentoResponse,
|
||||
AskMentoSourceDto,
|
||||
HomeDashboardDto,
|
||||
PaginatedResponse,
|
||||
PipelineBoardDto,
|
||||
} from '@mento/shared';
|
||||
|
||||
const auth = useAuthStore();
|
||||
const router = useRouter();
|
||||
|
||||
const loading = ref(true);
|
||||
const home = ref<HomeDashboardDto | null>(null);
|
||||
const activities = ref<ActivityDto[]>([]);
|
||||
const board = ref<PipelineBoardDto | null>(null);
|
||||
const askQuery = ref('');
|
||||
const asking = ref(false);
|
||||
const askAnswer = ref('');
|
||||
const askError = ref('');
|
||||
const askSources = ref<AskMentoSourceDto[]>([]);
|
||||
|
||||
const firstName = computed(() => {
|
||||
const parts = auth.user?.fullName?.trim().split(/\s+/) ?? [];
|
||||
@@ -72,10 +77,28 @@ function formatTrendAmount(value: number) {
|
||||
return formatMoney(value, home.value?.currency ?? 'IRR');
|
||||
}
|
||||
|
||||
function submitAsk() {
|
||||
const q = askQuery.value.trim();
|
||||
if (!q) return;
|
||||
void router.push({ name: 'notes', query: { q } });
|
||||
async function submitAsk(preset?: string) {
|
||||
const q = (preset || askQuery.value).trim();
|
||||
if (!q || asking.value) return;
|
||||
if (preset) askQuery.value = preset;
|
||||
asking.value = true;
|
||||
askError.value = '';
|
||||
askAnswer.value = '';
|
||||
askSources.value = [];
|
||||
try {
|
||||
const { data } = await api.post<AskMentoResponse>('/ai/ask', { question: q });
|
||||
askAnswer.value = data.answer;
|
||||
askSources.value = data.sources ?? [];
|
||||
} catch (e) {
|
||||
if (axios.isAxiosError(e)) {
|
||||
const msg = (e.response?.data as { message?: string | string[] })?.message;
|
||||
askError.value = Array.isArray(msg) ? msg.join('، ') : (msg ?? 'پرسش ناموفق بود');
|
||||
} else {
|
||||
askError.value = 'پرسش ناموفق بود';
|
||||
}
|
||||
} finally {
|
||||
asking.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
@@ -128,7 +151,14 @@ onMounted(async () => {
|
||||
:format-amount="formatTrendAmount"
|
||||
/>
|
||||
<HomeSourcesChart :sources="home?.sources ?? []" />
|
||||
<HomeAiAssistant v-model:ask-query="askQuery" @ask="submitAsk" />
|
||||
<HomeAiAssistant
|
||||
v-model:ask-query="askQuery"
|
||||
:asking="asking"
|
||||
:answer="askAnswer"
|
||||
:error="askError"
|
||||
:sources="askSources"
|
||||
@ask="submitAsk"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="bottom-grid">
|
||||
|
||||
Reference in New Issue
Block a user