@happyvertical/smrt-sales 0.40.41 → 0.40.43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +2 -1
- package/README.md +27 -0
- package/agents/crm.md +3 -0
- package/agents/svelte.md +3 -1
- package/dist/agreements.js +1 -1
- package/dist/chunks/{__smrt-register__-BwVcbipw.js → __smrt-register__-CSOh6enh.js} +2 -2
- package/dist/chunks/{__smrt-register__-BwVcbipw.js.map → __smrt-register__-CSOh6enh.js.map} +1 -1
- package/dist/chunks/{crm-DwEz7E2r.js → crm-B8XqwUBg.js} +472 -7
- package/dist/chunks/crm-B8XqwUBg.js.map +1 -0
- package/dist/commissions.js +1 -1
- package/dist/crm/collections/SalesActivityCollection.d.ts +2 -2
- package/dist/crm/collections/SalesActivityCollection.d.ts.map +1 -1
- package/dist/crm/index.d.ts +2 -0
- package/dist/crm/index.d.ts.map +1 -1
- package/dist/crm/models/SalesActivity.d.ts +17 -0
- package/dist/crm/models/SalesActivity.d.ts.map +1 -1
- package/dist/crm/services/LeadWorkflowService.d.ts +164 -0
- package/dist/crm/services/LeadWorkflowService.d.ts.map +1 -0
- package/dist/crm.js +3 -3
- package/dist/index.js +3 -3
- package/dist/manifest.json +10 -2
- package/dist/referrals.js +1 -1
- package/dist/smrt-knowledge.json +11 -10
- package/dist/svelte/__tests__/types.test.js +30 -1
- package/dist/svelte/components/LeadDetail.svelte +512 -0
- package/dist/svelte/components/LeadDetail.svelte.d.ts +31 -0
- package/dist/svelte/components/LeadDetail.svelte.d.ts.map +1 -0
- package/dist/svelte/index.d.ts +5 -3
- package/dist/svelte/index.d.ts.map +1 -1
- package/dist/svelte/index.js +3 -2
- package/dist/svelte/types.d.ts +44 -1
- package/dist/svelte/types.d.ts.map +1 -1
- package/dist/svelte/types.js +17 -0
- package/package.json +6 -6
- package/dist/chunks/crm-DwEz7E2r.js.map +0 -1
|
@@ -0,0 +1,512 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* LeadDetail — callback-driven Lead follow-up and timeline surface.
|
|
4
|
+
*
|
|
5
|
+
* This component is deliberately presentational: host applications supply
|
|
6
|
+
* plain view models and connect callbacks to `LeadWorkflowService` (or their
|
|
7
|
+
* own authorization boundary). It performs no data fetching and imports no
|
|
8
|
+
* CRM model classes.
|
|
9
|
+
*/
|
|
10
|
+
import {
|
|
11
|
+
Form,
|
|
12
|
+
FormGroup,
|
|
13
|
+
Input,
|
|
14
|
+
Select,
|
|
15
|
+
Textarea,
|
|
16
|
+
} from '@happyvertical/smrt-ui/forms';
|
|
17
|
+
import { Badge, Button } from '@happyvertical/smrt-ui/ui';
|
|
18
|
+
import { formatDate } from '../format.js';
|
|
19
|
+
import type {
|
|
20
|
+
LeadDetailView,
|
|
21
|
+
LeadHumanActivityDraft,
|
|
22
|
+
LeadNextActionDraft,
|
|
23
|
+
SalesActivityView,
|
|
24
|
+
SalesRepOptionView,
|
|
25
|
+
} from '../types.js';
|
|
26
|
+
import {
|
|
27
|
+
isOverdue,
|
|
28
|
+
leadStatusBadgeVariant,
|
|
29
|
+
leadWorkflowActionsFor,
|
|
30
|
+
} from '../types.js';
|
|
31
|
+
|
|
32
|
+
export interface Props {
|
|
33
|
+
/** Lead header and contact data. */
|
|
34
|
+
lead: LeadDetailView;
|
|
35
|
+
/** Complete chronological, merge-aware trail supplied by the host. */
|
|
36
|
+
activities?: SalesActivityView[];
|
|
37
|
+
/** Assignable sales representatives. */
|
|
38
|
+
reps?: SalesRepOptionView[];
|
|
39
|
+
/** Disable every mutation affordance while the host is busy. */
|
|
40
|
+
busy?: boolean;
|
|
41
|
+
/** BCP 47 locale for timeline dates. */
|
|
42
|
+
locale?: string;
|
|
43
|
+
/** Assign or reassign the Lead owner. */
|
|
44
|
+
onAssign?: (leadId: string, repId: string) => void;
|
|
45
|
+
/** Start a new Lead or reopen a disqualified Lead. */
|
|
46
|
+
onStartWorking?: (leadId: string) => void;
|
|
47
|
+
/** Disqualify with a required reason. */
|
|
48
|
+
onDisqualify?: (leadId: string, reason: string) => void;
|
|
49
|
+
/** Record a human note, call, email, or meeting. */
|
|
50
|
+
onRecordActivity?: (leadId: string, draft: LeadHumanActivityDraft) => void;
|
|
51
|
+
/** Schedule a dated next action. */
|
|
52
|
+
onScheduleNextAction?: (leadId: string, draft: LeadNextActionDraft) => void;
|
|
53
|
+
/** Complete one currently open next-action task. */
|
|
54
|
+
onCompleteNextAction?: (leadId: string, taskId: string) => void;
|
|
55
|
+
/** Delegate qualification to the host's existing LeadCollection lifecycle. */
|
|
56
|
+
onQualify?: (leadId: string) => void;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
let {
|
|
60
|
+
lead,
|
|
61
|
+
activities = [],
|
|
62
|
+
reps = [],
|
|
63
|
+
busy = false,
|
|
64
|
+
locale,
|
|
65
|
+
onAssign,
|
|
66
|
+
onStartWorking,
|
|
67
|
+
onDisqualify,
|
|
68
|
+
onRecordActivity,
|
|
69
|
+
onScheduleNextAction,
|
|
70
|
+
onCompleteNextAction,
|
|
71
|
+
onQualify,
|
|
72
|
+
}: Props = $props();
|
|
73
|
+
|
|
74
|
+
const actions = $derived(leadWorkflowActionsFor(lead.status));
|
|
75
|
+
const humanActivityKinds = ['note', 'call', 'email', 'meeting'] as const;
|
|
76
|
+
|
|
77
|
+
let selectedRepId = $state('');
|
|
78
|
+
let disqualificationReason = $state('');
|
|
79
|
+
let humanActivityKind = $state<(typeof humanActivityKinds)[number]>('note');
|
|
80
|
+
let humanActivitySummary = $state('');
|
|
81
|
+
let nextActionSummary = $state('');
|
|
82
|
+
let nextActionDueAt = $state('');
|
|
83
|
+
|
|
84
|
+
// Hosts can retain this component while selecting another Lead. Clear every
|
|
85
|
+
// draft in that case so no owner, reason, or activity for the old Lead can be
|
|
86
|
+
// submitted against the new one.
|
|
87
|
+
$effect(() => {
|
|
88
|
+
lead.id;
|
|
89
|
+
selectedRepId = '';
|
|
90
|
+
disqualificationReason = '';
|
|
91
|
+
humanActivityKind = 'note';
|
|
92
|
+
humanActivitySummary = '';
|
|
93
|
+
nextActionSummary = '';
|
|
94
|
+
nextActionDueAt = '';
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
function submitAssignment() {
|
|
98
|
+
if (selectedRepId) onAssign?.(lead.id, selectedRepId);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function submitDisqualification() {
|
|
102
|
+
const reason = disqualificationReason.trim();
|
|
103
|
+
if (!reason) return;
|
|
104
|
+
onDisqualify?.(lead.id, reason);
|
|
105
|
+
disqualificationReason = '';
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function submitHumanActivity() {
|
|
109
|
+
const summary = humanActivitySummary.trim();
|
|
110
|
+
if (!summary) return;
|
|
111
|
+
onRecordActivity?.(lead.id, { activityKind: humanActivityKind, summary });
|
|
112
|
+
humanActivitySummary = '';
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function submitNextAction() {
|
|
116
|
+
const summary = nextActionSummary.trim();
|
|
117
|
+
if (!summary || !nextActionDueAt) return;
|
|
118
|
+
onScheduleNextAction?.(lead.id, { summary, dueAt: nextActionDueAt });
|
|
119
|
+
nextActionSummary = '';
|
|
120
|
+
nextActionDueAt = '';
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function isOpenTask(activity: SalesActivityView): boolean {
|
|
124
|
+
return (
|
|
125
|
+
activity.activityKind === 'task' &&
|
|
126
|
+
activity.dueAt != null &&
|
|
127
|
+
activity.dueAt !== '' &&
|
|
128
|
+
!activity.completedAt
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
</script>
|
|
132
|
+
|
|
133
|
+
<article class="sales-lead-detail">
|
|
134
|
+
<header class="head">
|
|
135
|
+
<div>
|
|
136
|
+
<h2 class="head__name">{lead.name}</h2>
|
|
137
|
+
{#if lead.organizationName}
|
|
138
|
+
<p class="head__organization">{lead.organizationName}</p>
|
|
139
|
+
{/if}
|
|
140
|
+
</div>
|
|
141
|
+
<Badge variant={leadStatusBadgeVariant(lead.status)} size="sm">
|
|
142
|
+
{lead.status}
|
|
143
|
+
</Badge>
|
|
144
|
+
</header>
|
|
145
|
+
|
|
146
|
+
<dl class="facts">
|
|
147
|
+
<div class="facts__item">
|
|
148
|
+
<dt>Contact</dt>
|
|
149
|
+
<dd>{lead.contactName ?? '—'}</dd>
|
|
150
|
+
</div>
|
|
151
|
+
<div class="facts__item">
|
|
152
|
+
<dt>Email</dt>
|
|
153
|
+
<dd>{lead.email ?? '—'}</dd>
|
|
154
|
+
</div>
|
|
155
|
+
<div class="facts__item">
|
|
156
|
+
<dt>Phone</dt>
|
|
157
|
+
<dd>{lead.phone ?? '—'}</dd>
|
|
158
|
+
</div>
|
|
159
|
+
<div class="facts__item">
|
|
160
|
+
<dt>Owner</dt>
|
|
161
|
+
<dd>{lead.ownerName ?? 'Unassigned'}</dd>
|
|
162
|
+
</div>
|
|
163
|
+
</dl>
|
|
164
|
+
|
|
165
|
+
{#if lead.status === 'merged' && lead.mergedIntoId}
|
|
166
|
+
<p class="merged-note">This lead was merged into <code>{lead.mergedIntoId}</code>.</p>
|
|
167
|
+
{/if}
|
|
168
|
+
|
|
169
|
+
{#if actions.canAssign || actions.canStartWorking || actions.canDisqualify || actions.canQualify}
|
|
170
|
+
<section class="controls" aria-label="Lead workflow actions">
|
|
171
|
+
{#if actions.canAssign && onAssign && reps.length > 0}
|
|
172
|
+
<Form class="control-form" onsubmit={submitAssignment}>
|
|
173
|
+
<FormGroup label="Owner">
|
|
174
|
+
<Select
|
|
175
|
+
value={selectedRepId || lead.ownerRepId || ''}
|
|
176
|
+
disabled={busy}
|
|
177
|
+
aria-label={`Assign owner for ${lead.name}`}
|
|
178
|
+
onchange={(event) => {
|
|
179
|
+
selectedRepId = (event.currentTarget as HTMLSelectElement).value;
|
|
180
|
+
}}
|
|
181
|
+
>
|
|
182
|
+
<option value="" disabled>Choose an owner…</option>
|
|
183
|
+
{#each reps as rep (rep.id)}
|
|
184
|
+
<option value={rep.id}>{rep.name}</option>
|
|
185
|
+
{/each}
|
|
186
|
+
</Select>
|
|
187
|
+
</FormGroup>
|
|
188
|
+
<Button type="submit" variant="secondary" size="sm" disabled={busy || !selectedRepId}>
|
|
189
|
+
Assign
|
|
190
|
+
</Button>
|
|
191
|
+
</Form>
|
|
192
|
+
{/if}
|
|
193
|
+
|
|
194
|
+
{#if actions.canStartWorking && onStartWorking}
|
|
195
|
+
<Button
|
|
196
|
+
variant="primary"
|
|
197
|
+
size="sm"
|
|
198
|
+
disabled={busy}
|
|
199
|
+
onclick={() => onStartWorking?.(lead.id)}
|
|
200
|
+
>
|
|
201
|
+
{lead.status === 'disqualified' ? 'Reopen follow-up' : 'Start working'}
|
|
202
|
+
</Button>
|
|
203
|
+
{/if}
|
|
204
|
+
|
|
205
|
+
{#if actions.canQualify && onQualify}
|
|
206
|
+
<Button variant="secondary" size="sm" disabled={busy} onclick={() => onQualify?.(lead.id)}>
|
|
207
|
+
Qualify
|
|
208
|
+
</Button>
|
|
209
|
+
{/if}
|
|
210
|
+
|
|
211
|
+
{#if actions.canDisqualify && onDisqualify}
|
|
212
|
+
<Form class="control-form control-form--disqualify" onsubmit={submitDisqualification}>
|
|
213
|
+
<FormGroup label="Disqualification reason" required>
|
|
214
|
+
<Textarea
|
|
215
|
+
value={disqualificationReason}
|
|
216
|
+
disabled={busy}
|
|
217
|
+
required
|
|
218
|
+
rows={2}
|
|
219
|
+
oninput={(event) => {
|
|
220
|
+
disqualificationReason = (event.currentTarget as HTMLTextAreaElement).value;
|
|
221
|
+
}}
|
|
222
|
+
/>
|
|
223
|
+
</FormGroup>
|
|
224
|
+
<Button
|
|
225
|
+
type="submit"
|
|
226
|
+
variant="danger"
|
|
227
|
+
size="sm"
|
|
228
|
+
disabled={busy || disqualificationReason.trim() === ''}
|
|
229
|
+
>
|
|
230
|
+
Disqualify
|
|
231
|
+
</Button>
|
|
232
|
+
</Form>
|
|
233
|
+
{/if}
|
|
234
|
+
</section>
|
|
235
|
+
{/if}
|
|
236
|
+
|
|
237
|
+
<section class="timeline" aria-label="Lead activity timeline">
|
|
238
|
+
<h3>Activity timeline</h3>
|
|
239
|
+
{#if activities.length === 0}
|
|
240
|
+
<p class="empty">No activity recorded yet.</p>
|
|
241
|
+
{:else}
|
|
242
|
+
<ol class="timeline__list">
|
|
243
|
+
{#each activities as activity (activity.id)}
|
|
244
|
+
{@const openTask = isOpenTask(activity)}
|
|
245
|
+
<li class="timeline__item" class:next-action={openTask}>
|
|
246
|
+
<div class="timeline__content">
|
|
247
|
+
<span class="timeline__kind">{activity.activityKind}</span>
|
|
248
|
+
<span class="timeline__summary">{activity.summary}</span>
|
|
249
|
+
</div>
|
|
250
|
+
<div class="timeline__meta">
|
|
251
|
+
{#if activity.createdAt}
|
|
252
|
+
<span>recorded {formatDate(activity.createdAt, locale)}</span>
|
|
253
|
+
{/if}
|
|
254
|
+
{#if activity.dueAt}
|
|
255
|
+
<span class:overdue={openTask && isOverdue(activity.dueAt)}>
|
|
256
|
+
due {formatDate(activity.dueAt, locale)}
|
|
257
|
+
</span>
|
|
258
|
+
{/if}
|
|
259
|
+
{#if activity.completedAt}
|
|
260
|
+
<span>completed {formatDate(activity.completedAt, locale)}</span>
|
|
261
|
+
{/if}
|
|
262
|
+
{#if activity.actorName}
|
|
263
|
+
<span>by {activity.actorName}</span>
|
|
264
|
+
{/if}
|
|
265
|
+
</div>
|
|
266
|
+
{#if openTask && actions.canCompleteNextAction && onCompleteNextAction}
|
|
267
|
+
<Button
|
|
268
|
+
variant="secondary"
|
|
269
|
+
size="sm"
|
|
270
|
+
disabled={busy}
|
|
271
|
+
onclick={() => onCompleteNextAction?.(lead.id, activity.id)}
|
|
272
|
+
>
|
|
273
|
+
Complete task
|
|
274
|
+
</Button>
|
|
275
|
+
{/if}
|
|
276
|
+
</li>
|
|
277
|
+
{/each}
|
|
278
|
+
</ol>
|
|
279
|
+
{/if}
|
|
280
|
+
</section>
|
|
281
|
+
|
|
282
|
+
{#if actions.canRecordActivity && onRecordActivity}
|
|
283
|
+
<section class="composer" aria-label="Record follow-up activity">
|
|
284
|
+
<h3>Record follow-up</h3>
|
|
285
|
+
<Form class="composer__form" onsubmit={submitHumanActivity}>
|
|
286
|
+
<FormGroup label="Kind">
|
|
287
|
+
<Select
|
|
288
|
+
value={humanActivityKind}
|
|
289
|
+
disabled={busy}
|
|
290
|
+
onchange={(event) => {
|
|
291
|
+
humanActivityKind = (event.currentTarget as HTMLSelectElement)
|
|
292
|
+
.value as (typeof humanActivityKinds)[number];
|
|
293
|
+
}}
|
|
294
|
+
>
|
|
295
|
+
{#each humanActivityKinds as kind (kind)}
|
|
296
|
+
<option value={kind}>{kind}</option>
|
|
297
|
+
{/each}
|
|
298
|
+
</Select>
|
|
299
|
+
</FormGroup>
|
|
300
|
+
<FormGroup label="Summary" required>
|
|
301
|
+
<Textarea
|
|
302
|
+
value={humanActivitySummary}
|
|
303
|
+
disabled={busy}
|
|
304
|
+
required
|
|
305
|
+
rows={2}
|
|
306
|
+
oninput={(event) => {
|
|
307
|
+
humanActivitySummary = (event.currentTarget as HTMLTextAreaElement).value;
|
|
308
|
+
}}
|
|
309
|
+
/>
|
|
310
|
+
</FormGroup>
|
|
311
|
+
<Button
|
|
312
|
+
type="submit"
|
|
313
|
+
variant="secondary"
|
|
314
|
+
size="sm"
|
|
315
|
+
disabled={busy || humanActivitySummary.trim() === ''}
|
|
316
|
+
>
|
|
317
|
+
Record activity
|
|
318
|
+
</Button>
|
|
319
|
+
</Form>
|
|
320
|
+
</section>
|
|
321
|
+
{/if}
|
|
322
|
+
|
|
323
|
+
{#if actions.canScheduleNextAction && onScheduleNextAction}
|
|
324
|
+
<section class="composer" aria-label="Schedule next action">
|
|
325
|
+
<h3>Schedule next action</h3>
|
|
326
|
+
<Form class="composer__form" onsubmit={submitNextAction}>
|
|
327
|
+
<FormGroup label="Summary" required>
|
|
328
|
+
<Input
|
|
329
|
+
value={nextActionSummary}
|
|
330
|
+
disabled={busy}
|
|
331
|
+
required
|
|
332
|
+
oninput={(event) => {
|
|
333
|
+
nextActionSummary = (event.currentTarget as HTMLInputElement).value;
|
|
334
|
+
}}
|
|
335
|
+
/>
|
|
336
|
+
</FormGroup>
|
|
337
|
+
<FormGroup label="Due date" required>
|
|
338
|
+
<Input
|
|
339
|
+
type="date"
|
|
340
|
+
value={nextActionDueAt}
|
|
341
|
+
disabled={busy}
|
|
342
|
+
required
|
|
343
|
+
oninput={(event) => {
|
|
344
|
+
nextActionDueAt = (event.currentTarget as HTMLInputElement).value;
|
|
345
|
+
}}
|
|
346
|
+
/>
|
|
347
|
+
</FormGroup>
|
|
348
|
+
<Button
|
|
349
|
+
type="submit"
|
|
350
|
+
variant="primary"
|
|
351
|
+
size="sm"
|
|
352
|
+
disabled={busy || nextActionSummary.trim() === '' || nextActionDueAt === ''}
|
|
353
|
+
>
|
|
354
|
+
Schedule task
|
|
355
|
+
</Button>
|
|
356
|
+
</Form>
|
|
357
|
+
</section>
|
|
358
|
+
{/if}
|
|
359
|
+
</article>
|
|
360
|
+
|
|
361
|
+
<style>
|
|
362
|
+
.sales-lead-detail {
|
|
363
|
+
display: flex;
|
|
364
|
+
flex-direction: column;
|
|
365
|
+
gap: var(--smrt-spacing-4, 1rem);
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
.head {
|
|
369
|
+
display: flex;
|
|
370
|
+
flex-wrap: wrap;
|
|
371
|
+
align-items: center;
|
|
372
|
+
justify-content: space-between;
|
|
373
|
+
gap: var(--smrt-spacing-2, 0.5rem);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
.head__name,
|
|
377
|
+
h3 {
|
|
378
|
+
margin: 0;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
.head__name {
|
|
382
|
+
font-size: var(--smrt-typography-title-large-size, 1.25rem);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
.head__organization,
|
|
386
|
+
.empty,
|
|
387
|
+
.merged-note {
|
|
388
|
+
margin: var(--smrt-spacing-1, 0.25rem) 0 0;
|
|
389
|
+
color: var(--smrt-color-on-surface-variant, #64748b);
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
.facts {
|
|
393
|
+
display: grid;
|
|
394
|
+
grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
|
|
395
|
+
gap: var(--smrt-spacing-3, 0.75rem);
|
|
396
|
+
margin: 0;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
.facts__item dt,
|
|
400
|
+
.timeline__kind {
|
|
401
|
+
color: var(--smrt-color-on-surface-variant, #64748b);
|
|
402
|
+
font-size: var(--smrt-typography-label-medium-size, 0.75rem);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
.facts__item dd {
|
|
406
|
+
margin: var(--smrt-spacing-1, 0.25rem) 0 0;
|
|
407
|
+
overflow-wrap: anywhere;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
.controls,
|
|
411
|
+
.sales-lead-detail :global(.composer__form) {
|
|
412
|
+
display: flex;
|
|
413
|
+
flex-wrap: wrap;
|
|
414
|
+
align-items: flex-end;
|
|
415
|
+
gap: var(--smrt-spacing-3, 0.75rem);
|
|
416
|
+
padding: var(--smrt-spacing-3, 0.75rem);
|
|
417
|
+
border: 1px solid var(--smrt-color-outline-variant, #d8dde6);
|
|
418
|
+
border-radius: var(--smrt-radius-md, 8px);
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
.sales-lead-detail :global(.control-form) {
|
|
422
|
+
display: flex;
|
|
423
|
+
flex: 1 1 16rem;
|
|
424
|
+
flex-wrap: wrap;
|
|
425
|
+
align-items: flex-end;
|
|
426
|
+
gap: var(--smrt-spacing-2, 0.5rem);
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
.sales-lead-detail :global(.control-form--disqualify) {
|
|
430
|
+
flex-basis: min(100%, 24rem);
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
.sales-lead-detail :global(.form-group) {
|
|
434
|
+
flex: 1 1 10rem;
|
|
435
|
+
margin-bottom: 0;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
h3 {
|
|
439
|
+
margin-bottom: var(--smrt-spacing-2, 0.5rem);
|
|
440
|
+
color: var(--smrt-color-on-surface-variant, #64748b);
|
|
441
|
+
font-size: var(--smrt-typography-title-small-size, 0.875rem);
|
|
442
|
+
letter-spacing: 0.04em;
|
|
443
|
+
text-transform: uppercase;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
.timeline__list {
|
|
447
|
+
display: flex;
|
|
448
|
+
flex-direction: column;
|
|
449
|
+
gap: var(--smrt-spacing-2, 0.5rem);
|
|
450
|
+
margin: 0;
|
|
451
|
+
padding: 0;
|
|
452
|
+
list-style: none;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
.timeline__item {
|
|
456
|
+
display: flex;
|
|
457
|
+
flex-wrap: wrap;
|
|
458
|
+
align-items: center;
|
|
459
|
+
gap: var(--smrt-spacing-2, 0.5rem);
|
|
460
|
+
padding: var(--smrt-spacing-2, 0.5rem);
|
|
461
|
+
border: 1px solid var(--smrt-color-outline-variant, #d8dde6);
|
|
462
|
+
border-radius: var(--smrt-radius-sm, 4px);
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
.timeline__item.next-action {
|
|
466
|
+
border-color: var(--smrt-color-primary, #2563eb);
|
|
467
|
+
background: var(--smrt-color-primary-container, #eff6ff);
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
.timeline__content {
|
|
471
|
+
display: grid;
|
|
472
|
+
flex: 1 1 14rem;
|
|
473
|
+
gap: var(--smrt-spacing-1, 0.25rem);
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
.timeline__kind {
|
|
477
|
+
letter-spacing: 0.04em;
|
|
478
|
+
text-transform: uppercase;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
.timeline__summary {
|
|
482
|
+
overflow-wrap: anywhere;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
.timeline__meta {
|
|
486
|
+
display: flex;
|
|
487
|
+
flex: 1 1 12rem;
|
|
488
|
+
flex-wrap: wrap;
|
|
489
|
+
gap: var(--smrt-spacing-2, 0.5rem);
|
|
490
|
+
color: var(--smrt-color-on-surface-variant, #64748b);
|
|
491
|
+
font-size: var(--smrt-typography-body-small-size, 0.75rem);
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
.timeline__meta .overdue {
|
|
495
|
+
color: var(--smrt-color-error, #dc2626);
|
|
496
|
+
font-weight: var(--smrt-typography-weight-semibold, 600);
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
@media (max-width: 40rem) {
|
|
500
|
+
.sales-lead-detail :global(.control-form),
|
|
501
|
+
.sales-lead-detail :global(.composer__form) {
|
|
502
|
+
align-items: stretch;
|
|
503
|
+
flex-direction: column;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
.sales-lead-detail :global(.form-group),
|
|
507
|
+
.sales-lead-detail :global(.control-form),
|
|
508
|
+
.sales-lead-detail :global(.control-form--disqualify) {
|
|
509
|
+
width: 100%;
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
</style>
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { LeadDetailView, LeadHumanActivityDraft, LeadNextActionDraft, SalesActivityView, SalesRepOptionView } from '../types.js';
|
|
2
|
+
export interface Props {
|
|
3
|
+
/** Lead header and contact data. */
|
|
4
|
+
lead: LeadDetailView;
|
|
5
|
+
/** Complete chronological, merge-aware trail supplied by the host. */
|
|
6
|
+
activities?: SalesActivityView[];
|
|
7
|
+
/** Assignable sales representatives. */
|
|
8
|
+
reps?: SalesRepOptionView[];
|
|
9
|
+
/** Disable every mutation affordance while the host is busy. */
|
|
10
|
+
busy?: boolean;
|
|
11
|
+
/** BCP 47 locale for timeline dates. */
|
|
12
|
+
locale?: string;
|
|
13
|
+
/** Assign or reassign the Lead owner. */
|
|
14
|
+
onAssign?: (leadId: string, repId: string) => void;
|
|
15
|
+
/** Start a new Lead or reopen a disqualified Lead. */
|
|
16
|
+
onStartWorking?: (leadId: string) => void;
|
|
17
|
+
/** Disqualify with a required reason. */
|
|
18
|
+
onDisqualify?: (leadId: string, reason: string) => void;
|
|
19
|
+
/** Record a human note, call, email, or meeting. */
|
|
20
|
+
onRecordActivity?: (leadId: string, draft: LeadHumanActivityDraft) => void;
|
|
21
|
+
/** Schedule a dated next action. */
|
|
22
|
+
onScheduleNextAction?: (leadId: string, draft: LeadNextActionDraft) => void;
|
|
23
|
+
/** Complete one currently open next-action task. */
|
|
24
|
+
onCompleteNextAction?: (leadId: string, taskId: string) => void;
|
|
25
|
+
/** Delegate qualification to the host's existing LeadCollection lifecycle. */
|
|
26
|
+
onQualify?: (leadId: string) => void;
|
|
27
|
+
}
|
|
28
|
+
declare const LeadDetail: import("svelte").Component<Props, {}, "">;
|
|
29
|
+
type LeadDetail = ReturnType<typeof LeadDetail>;
|
|
30
|
+
export default LeadDetail;
|
|
31
|
+
//# sourceMappingURL=LeadDetail.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LeadDetail.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/LeadDetail.svelte.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EACV,cAAc,EACd,sBAAsB,EACtB,mBAAmB,EACnB,iBAAiB,EACjB,kBAAkB,EACnB,MAAM,aAAa,CAAC;AAQrB,MAAM,WAAW,KAAK;IACpB,oCAAoC;IACpC,IAAI,EAAE,cAAc,CAAC;IACrB,sEAAsE;IACtE,UAAU,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACjC,wCAAwC;IACxC,IAAI,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAC5B,gEAAgE;IAChE,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,wCAAwC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yCAAyC;IACzC,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnD,sDAAsD;IACtD,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,yCAAyC;IACzC,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACxD,oDAAoD;IACpD,gBAAgB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,sBAAsB,KAAK,IAAI,CAAC;IAC3E,oCAAoC;IACpC,oBAAoB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,mBAAmB,KAAK,IAAI,CAAC;IAC5E,oDAAoD;IACpD,oBAAoB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAChE,8EAA8E;IAC9E,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACtC;AAmQD,QAAA,MAAM,UAAU,2CAAwC,CAAC;AACzD,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;AAChD,eAAe,UAAU,CAAC"}
|
package/dist/svelte/index.d.ts
CHANGED
|
@@ -21,6 +21,7 @@ import AttributionConflictQueue from './components/AttributionConflictQueue.svel
|
|
|
21
21
|
import CommissionBreakdown from './components/CommissionBreakdown.svelte';
|
|
22
22
|
import CommissionExpenseSummary from './components/CommissionExpenseSummary.svelte';
|
|
23
23
|
import ExecutedAgreementsList from './components/ExecutedAgreementsList.svelte';
|
|
24
|
+
import LeadDetail from './components/LeadDetail.svelte';
|
|
24
25
|
import LeadList from './components/LeadList.svelte';
|
|
25
26
|
import OpportunityBoard from './components/OpportunityBoard.svelte';
|
|
26
27
|
import OpportunityDetail from './components/OpportunityDetail.svelte';
|
|
@@ -30,11 +31,12 @@ import ReferralLinkManager from './components/ReferralLinkManager.svelte';
|
|
|
30
31
|
import ReferralStatusList from './components/ReferralStatusList.svelte';
|
|
31
32
|
import ReferrerEarningsSummary from './components/ReferrerEarningsSummary.svelte';
|
|
32
33
|
import SalesDashboard from './components/SalesDashboard.svelte';
|
|
33
|
-
export { AttributionConflictQueue, CommissionBreakdown, CommissionExpenseSummary, ExecutedAgreementsList, LeadList, OpportunityBoard, OpportunityDetail, PayoutBatchReview, PayoutHistoryList, ReferralLinkManager, ReferralStatusList, ReferrerEarningsSummary, SalesDashboard, };
|
|
34
|
+
export { AttributionConflictQueue, CommissionBreakdown, CommissionExpenseSummary, ExecutedAgreementsList, LeadDetail, LeadList, OpportunityBoard, OpportunityDetail, PayoutBatchReview, PayoutHistoryList, ReferralLinkManager, ReferralStatusList, ReferrerEarningsSummary, SalesDashboard, };
|
|
34
35
|
export type AttributionConflictQueueProps = ComponentProps<typeof AttributionConflictQueue>;
|
|
35
36
|
export type CommissionBreakdownProps = ComponentProps<typeof CommissionBreakdown>;
|
|
36
37
|
export type CommissionExpenseSummaryProps = ComponentProps<typeof CommissionExpenseSummary>;
|
|
37
38
|
export type ExecutedAgreementsListProps = ComponentProps<typeof ExecutedAgreementsList>;
|
|
39
|
+
export type LeadDetailProps = ComponentProps<typeof LeadDetail>;
|
|
38
40
|
export type LeadListProps = ComponentProps<typeof LeadList>;
|
|
39
41
|
export type OpportunityBoardProps = ComponentProps<typeof OpportunityBoard>;
|
|
40
42
|
export type OpportunityDetailProps = ComponentProps<typeof OpportunityDetail>;
|
|
@@ -45,6 +47,6 @@ export type ReferralStatusListProps = ComponentProps<typeof ReferralStatusList>;
|
|
|
45
47
|
export type ReferrerEarningsSummaryProps = ComponentProps<typeof ReferrerEarningsSummary>;
|
|
46
48
|
export type SalesDashboardProps = ComponentProps<typeof SalesDashboard>;
|
|
47
49
|
export { EMPTY_VALUE_PLACEHOLDER, formatCents, formatDate, formatPercent, } from './format.js';
|
|
48
|
-
export type { AgreementVersionView, AttributionAward, AttributionCandidateView, AttributionExceptionView, AwardValidation, BoardColumn, ClosedOpportunityOutcome, CommissionAdjustmentView, CommissionExpenseRowView, CommissionExpenseTotals, CommissionFormulaParts, CommissionRowView, CommissionTraceView, ConversionLinkView, CreateReferralLinkDraft, CurrencyAmount, DateInput, EarnerBalance, LeadListItemView, NextActionView, OpportunityCardView, OpportunityDetailView, PayoutActions, PayoutBatchReviewItemView, PayoutTimelineStep, PayoutView, PipelineStageView, RecordActivityDraft, ReferralLinkView, ReferralStatusView, SalesActivityView, SalesRepOptionView, StagePipelineSummary, StatusBadgeVariant, } from './types.js';
|
|
49
|
-
export { AWARD_FRACTION_TOLERANCE, adjacentStageIds, agreementStatusBadgeVariant, buildShareUrl, canQualifyLead, commissionStatusBadgeVariant, equalSplitAwards, formatCommissionFormula, formatPlanRef, groupOpportunitiesByStage, isHttpUrl, isOverdue, leadStatusBadgeVariant, openOpportunityCount, openPipelineTotals, opportunityStatusBadgeVariant, payoutActionsFor, payoutStatusBadgeVariant, payoutStatusTimeline, pipelineValueByStage, referralLinkStatusBadgeVariant, referralStatusBadgeVariant, sumExpenseRowsByCurrency, uniqueCandidateReferrerIds, validateAwards, winRate, } from './types.js';
|
|
50
|
+
export type { AgreementVersionView, AttributionAward, AttributionCandidateView, AttributionExceptionView, AwardValidation, BoardColumn, ClosedOpportunityOutcome, CommissionAdjustmentView, CommissionExpenseRowView, CommissionExpenseTotals, CommissionFormulaParts, CommissionRowView, CommissionTraceView, ConversionLinkView, CreateReferralLinkDraft, CurrencyAmount, DateInput, EarnerBalance, LeadDetailView, LeadHumanActivityDraft, LeadListItemView, LeadNextActionDraft, LeadWorkflowActions, NextActionView, OpportunityCardView, OpportunityDetailView, PayoutActions, PayoutBatchReviewItemView, PayoutTimelineStep, PayoutView, PipelineStageView, RecordActivityDraft, ReferralLinkView, ReferralStatusView, SalesActivityView, SalesRepOptionView, StagePipelineSummary, StatusBadgeVariant, } from './types.js';
|
|
51
|
+
export { AWARD_FRACTION_TOLERANCE, adjacentStageIds, agreementStatusBadgeVariant, buildShareUrl, canQualifyLead, commissionStatusBadgeVariant, equalSplitAwards, formatCommissionFormula, formatPlanRef, groupOpportunitiesByStage, isHttpUrl, isOverdue, leadStatusBadgeVariant, leadWorkflowActionsFor, openOpportunityCount, openPipelineTotals, opportunityStatusBadgeVariant, payoutActionsFor, payoutStatusBadgeVariant, payoutStatusTimeline, pipelineValueByStage, referralLinkStatusBadgeVariant, referralStatusBadgeVariant, sumExpenseRowsByCurrency, uniqueCandidateReferrerIds, validateAwards, winRate, } from './types.js';
|
|
50
52
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/svelte/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/svelte/index.ts"],"names":[],"mappings":"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"}
|
package/dist/svelte/index.js
CHANGED
|
@@ -20,6 +20,7 @@ import AttributionConflictQueue from './components/AttributionConflictQueue.svel
|
|
|
20
20
|
import CommissionBreakdown from './components/CommissionBreakdown.svelte';
|
|
21
21
|
import CommissionExpenseSummary from './components/CommissionExpenseSummary.svelte';
|
|
22
22
|
import ExecutedAgreementsList from './components/ExecutedAgreementsList.svelte';
|
|
23
|
+
import LeadDetail from './components/LeadDetail.svelte';
|
|
23
24
|
import LeadList from './components/LeadList.svelte';
|
|
24
25
|
import OpportunityBoard from './components/OpportunityBoard.svelte';
|
|
25
26
|
import OpportunityDetail from './components/OpportunityDetail.svelte';
|
|
@@ -30,8 +31,8 @@ import ReferralStatusList from './components/ReferralStatusList.svelte';
|
|
|
30
31
|
import ReferrerEarningsSummary from './components/ReferrerEarningsSummary.svelte';
|
|
31
32
|
import SalesDashboard from './components/SalesDashboard.svelte';
|
|
32
33
|
// Components
|
|
33
|
-
export { AttributionConflictQueue, CommissionBreakdown, CommissionExpenseSummary, ExecutedAgreementsList, LeadList, OpportunityBoard, OpportunityDetail, PayoutBatchReview, PayoutHistoryList, ReferralLinkManager, ReferralStatusList, ReferrerEarningsSummary, SalesDashboard, };
|
|
34
|
+
export { AttributionConflictQueue, CommissionBreakdown, CommissionExpenseSummary, ExecutedAgreementsList, LeadDetail, LeadList, OpportunityBoard, OpportunityDetail, PayoutBatchReview, PayoutHistoryList, ReferralLinkManager, ReferralStatusList, ReferrerEarningsSummary, SalesDashboard, };
|
|
34
35
|
// Formatting helpers
|
|
35
36
|
export { EMPTY_VALUE_PLACEHOLDER, formatCents, formatDate, formatPercent, } from './format.js';
|
|
36
37
|
// View models and pure helpers
|
|
37
|
-
export { AWARD_FRACTION_TOLERANCE, adjacentStageIds, agreementStatusBadgeVariant, buildShareUrl, canQualifyLead, commissionStatusBadgeVariant, equalSplitAwards, formatCommissionFormula, formatPlanRef, groupOpportunitiesByStage, isHttpUrl, isOverdue, leadStatusBadgeVariant, openOpportunityCount, openPipelineTotals, opportunityStatusBadgeVariant, payoutActionsFor, payoutStatusBadgeVariant, payoutStatusTimeline, pipelineValueByStage, referralLinkStatusBadgeVariant, referralStatusBadgeVariant, sumExpenseRowsByCurrency, uniqueCandidateReferrerIds, validateAwards, winRate, } from './types.js';
|
|
38
|
+
export { AWARD_FRACTION_TOLERANCE, adjacentStageIds, agreementStatusBadgeVariant, buildShareUrl, canQualifyLead, commissionStatusBadgeVariant, equalSplitAwards, formatCommissionFormula, formatPlanRef, groupOpportunitiesByStage, isHttpUrl, isOverdue, leadStatusBadgeVariant, leadWorkflowActionsFor, openOpportunityCount, openPipelineTotals, opportunityStatusBadgeVariant, payoutActionsFor, payoutStatusBadgeVariant, payoutStatusTimeline, pipelineValueByStage, referralLinkStatusBadgeVariant, referralStatusBadgeVariant, sumExpenseRowsByCurrency, uniqueCandidateReferrerIds, validateAwards, winRate, } from './types.js';
|