Track person import source and previous names; add source report and edit UX.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -47,6 +47,19 @@ const callFollowUp = ref('');
|
||||
const noteBody = ref('');
|
||||
const followUpAt = ref('');
|
||||
const followUpBody = ref('');
|
||||
const editing = ref(false);
|
||||
const editForm = ref({
|
||||
title: '',
|
||||
contactName: '',
|
||||
mobile: '',
|
||||
phone: '',
|
||||
city: '',
|
||||
region: '',
|
||||
source: '',
|
||||
instagram: '',
|
||||
trade: '',
|
||||
notes: '',
|
||||
});
|
||||
|
||||
function formatDate(value: string | null | undefined) {
|
||||
if (!value) return '—';
|
||||
@@ -88,6 +101,53 @@ async function load() {
|
||||
}
|
||||
}
|
||||
|
||||
function startEdit() {
|
||||
if (!lead.value) return;
|
||||
editing.value = true;
|
||||
editForm.value = {
|
||||
title: lead.value.title,
|
||||
contactName: lead.value.contactName ?? '',
|
||||
mobile: lead.value.mobile,
|
||||
phone: lead.value.phone ?? '',
|
||||
city: lead.value.city ?? '',
|
||||
region: lead.value.region ?? '',
|
||||
source: lead.value.source ?? '',
|
||||
instagram: lead.value.instagram ?? '',
|
||||
trade: lead.value.trade ?? '',
|
||||
notes: lead.value.notes ?? '',
|
||||
};
|
||||
}
|
||||
|
||||
async function saveEdit() {
|
||||
if (!editForm.value.title.trim() || !editForm.value.mobile.trim()) {
|
||||
error.value = 'عنوان و موبایل الزامی است.';
|
||||
return;
|
||||
}
|
||||
busy.value = true;
|
||||
error.value = '';
|
||||
try {
|
||||
await api.patch(`/leads/${id.value}`, {
|
||||
title: editForm.value.title.trim(),
|
||||
contactName: editForm.value.contactName.trim() || null,
|
||||
mobile: editForm.value.mobile.trim(),
|
||||
phone: editForm.value.phone.trim() || null,
|
||||
city: editForm.value.city.trim() || null,
|
||||
region: editForm.value.region.trim() || null,
|
||||
source: editForm.value.source.trim() || null,
|
||||
instagram: editForm.value.instagram.trim() || null,
|
||||
trade: editForm.value.trade.trim() || null,
|
||||
notes: editForm.value.notes.trim() || null,
|
||||
});
|
||||
okMsg.value = 'لید ویرایش شد.';
|
||||
editing.value = false;
|
||||
await load();
|
||||
} catch (e) {
|
||||
error.value = apiError(e, 'ویرایش لید ناموفق بود.');
|
||||
} finally {
|
||||
busy.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function changeStage() {
|
||||
if (!stageId.value || stageId.value === lead.value?.stageId) return;
|
||||
busy.value = true;
|
||||
@@ -226,6 +286,15 @@ onMounted(load);
|
||||
:back-to="{ name: 'leads' }"
|
||||
>
|
||||
<template #actions>
|
||||
<UiButton
|
||||
v-if="lead && !editing"
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
:disabled="busy"
|
||||
@click="startEdit"
|
||||
>
|
||||
ویرایش
|
||||
</UiButton>
|
||||
<UiButton
|
||||
v-if="lead && !lead.convertedPersonId"
|
||||
variant="primary"
|
||||
@@ -255,7 +324,45 @@ onMounted(load);
|
||||
<div class="layout">
|
||||
<div class="main">
|
||||
<UiCard title="اطلاعات لید">
|
||||
<dl class="meta">
|
||||
<div v-if="editing" class="edit-grid">
|
||||
<UiField label="عنوان" required>
|
||||
<UiInput v-model="editForm.title" />
|
||||
</UiField>
|
||||
<UiField label="مالک/مخاطب">
|
||||
<UiInput v-model="editForm.contactName" />
|
||||
</UiField>
|
||||
<UiField label="موبایل" required>
|
||||
<UiInput v-model="editForm.mobile" dir="ltr" />
|
||||
</UiField>
|
||||
<UiField label="تلفن">
|
||||
<UiInput v-model="editForm.phone" dir="ltr" />
|
||||
</UiField>
|
||||
<UiField label="شهر">
|
||||
<UiInput v-model="editForm.city" />
|
||||
</UiField>
|
||||
<UiField label="منطقه">
|
||||
<UiInput v-model="editForm.region" />
|
||||
</UiField>
|
||||
<UiField label="منبع">
|
||||
<UiInput v-model="editForm.source" />
|
||||
</UiField>
|
||||
<UiField label="اینستاگرام">
|
||||
<UiInput v-model="editForm.instagram" dir="ltr" />
|
||||
</UiField>
|
||||
<UiField label="صنف">
|
||||
<UiInput v-model="editForm.trade" />
|
||||
</UiField>
|
||||
<UiField label="یادداشت" class="full">
|
||||
<UiInput v-model="editForm.notes" />
|
||||
</UiField>
|
||||
<div class="edit-actions full">
|
||||
<UiButton size="sm" :loading="busy" @click="saveEdit">ذخیره</UiButton>
|
||||
<UiButton size="sm" variant="ghost" :disabled="busy" @click="editing = false">
|
||||
انصراف
|
||||
</UiButton>
|
||||
</div>
|
||||
</div>
|
||||
<dl v-else class="meta">
|
||||
<div><dt>نام</dt><dd>{{ lead.title }}</dd></div>
|
||||
<div><dt>مالک/مخاطب</dt><dd>{{ lead.contactName || '—' }}</dd></div>
|
||||
<div><dt>موبایل</dt><dd dir="ltr">{{ lead.mobile }}</dd></div>
|
||||
@@ -384,6 +491,20 @@ onMounted(load);
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.edit-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: 0.75rem 1rem;
|
||||
}
|
||||
.edit-grid .full {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
.edit-actions {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.meta {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
|
||||
Reference in New Issue
Block a user