@happyvertical/smrt-sales 0.39.2

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.
Files changed (201) hide show
  1. package/AGENTS.md +87 -0
  2. package/CLAUDE.md +1 -0
  3. package/LICENSE +7 -0
  4. package/dist/.tsbuildinfo +1 -0
  5. package/dist/__smrt-register__.d.ts +2 -0
  6. package/dist/__smrt-register__.d.ts.map +1 -0
  7. package/dist/chunks/__smrt-register__-kWdT7LOt.js +6 -0
  8. package/dist/chunks/__smrt-register__-kWdT7LOt.js.map +1 -0
  9. package/dist/chunks/commissions-BCxqOKVM.js +2181 -0
  10. package/dist/chunks/commissions-BCxqOKVM.js.map +1 -0
  11. package/dist/chunks/crm-DwEz7E2r.js +1428 -0
  12. package/dist/chunks/crm-DwEz7E2r.js.map +1 -0
  13. package/dist/chunks/referrals-BY47p70T.js +2880 -0
  14. package/dist/chunks/referrals-BY47p70T.js.map +1 -0
  15. package/dist/commissions/collections/CommissionAdjustmentCollection.d.ts +26 -0
  16. package/dist/commissions/collections/CommissionAdjustmentCollection.d.ts.map +1 -0
  17. package/dist/commissions/collections/CommissionCollection.d.ts +43 -0
  18. package/dist/commissions/collections/CommissionCollection.d.ts.map +1 -0
  19. package/dist/commissions/collections/CommissionPayoutCollection.d.ts +19 -0
  20. package/dist/commissions/collections/CommissionPayoutCollection.d.ts.map +1 -0
  21. package/dist/commissions/collections/CommissionPlanCollection.d.ts +46 -0
  22. package/dist/commissions/collections/CommissionPlanCollection.d.ts.map +1 -0
  23. package/dist/commissions/collections/EarnerCollection.d.ts +14 -0
  24. package/dist/commissions/collections/EarnerCollection.d.ts.map +1 -0
  25. package/dist/commissions/collections/EarningEventCollection.d.ts +27 -0
  26. package/dist/commissions/collections/EarningEventCollection.d.ts.map +1 -0
  27. package/dist/commissions/collections/index.d.ts +11 -0
  28. package/dist/commissions/collections/index.d.ts.map +1 -0
  29. package/dist/commissions/index.d.ts +20 -0
  30. package/dist/commissions/index.d.ts.map +1 -0
  31. package/dist/commissions/models/Commission.d.ts +150 -0
  32. package/dist/commissions/models/Commission.d.ts.map +1 -0
  33. package/dist/commissions/models/CommissionAdjustment.d.ts +62 -0
  34. package/dist/commissions/models/CommissionAdjustment.d.ts.map +1 -0
  35. package/dist/commissions/models/CommissionPayout.d.ts +119 -0
  36. package/dist/commissions/models/CommissionPayout.d.ts.map +1 -0
  37. package/dist/commissions/models/CommissionPlan.d.ts +117 -0
  38. package/dist/commissions/models/CommissionPlan.d.ts.map +1 -0
  39. package/dist/commissions/models/Earner.d.ts +49 -0
  40. package/dist/commissions/models/Earner.d.ts.map +1 -0
  41. package/dist/commissions/models/EarningEvent.d.ts +89 -0
  42. package/dist/commissions/models/EarningEvent.d.ts.map +1 -0
  43. package/dist/commissions/models/index.d.ts +11 -0
  44. package/dist/commissions/models/index.d.ts.map +1 -0
  45. package/dist/commissions/money.d.ts +42 -0
  46. package/dist/commissions/money.d.ts.map +1 -0
  47. package/dist/commissions/services/CommissionBalanceService.d.ts +14 -0
  48. package/dist/commissions/services/CommissionBalanceService.d.ts.map +1 -0
  49. package/dist/commissions/services/CommissionCalculationService.d.ts +142 -0
  50. package/dist/commissions/services/CommissionCalculationService.d.ts.map +1 -0
  51. package/dist/commissions/services/CommissionPayoutService.d.ts +134 -0
  52. package/dist/commissions/services/CommissionPayoutService.d.ts.map +1 -0
  53. package/dist/commissions/services/CommissionSettlementService.d.ts +42 -0
  54. package/dist/commissions/services/CommissionSettlementService.d.ts.map +1 -0
  55. package/dist/commissions/services/index.d.ts +9 -0
  56. package/dist/commissions/services/index.d.ts.map +1 -0
  57. package/dist/commissions/types.d.ts +243 -0
  58. package/dist/commissions/types.d.ts.map +1 -0
  59. package/dist/commissions.d.ts +2 -0
  60. package/dist/commissions.d.ts.map +1 -0
  61. package/dist/commissions.js +3 -0
  62. package/dist/crm/collections/LeadCollection.d.ts +79 -0
  63. package/dist/crm/collections/LeadCollection.d.ts.map +1 -0
  64. package/dist/crm/collections/OpportunityCollection.d.ts +42 -0
  65. package/dist/crm/collections/OpportunityCollection.d.ts.map +1 -0
  66. package/dist/crm/collections/OpportunityConversionCollection.d.ts +26 -0
  67. package/dist/crm/collections/OpportunityConversionCollection.d.ts.map +1 -0
  68. package/dist/crm/collections/PipelineDefinitionCollection.d.ts +46 -0
  69. package/dist/crm/collections/PipelineDefinitionCollection.d.ts.map +1 -0
  70. package/dist/crm/collections/PipelineStageCollection.d.ts +22 -0
  71. package/dist/crm/collections/PipelineStageCollection.d.ts.map +1 -0
  72. package/dist/crm/collections/SalesActivityCollection.d.ts +24 -0
  73. package/dist/crm/collections/SalesActivityCollection.d.ts.map +1 -0
  74. package/dist/crm/collections/SalesRepresentativeCollection.d.ts +19 -0
  75. package/dist/crm/collections/SalesRepresentativeCollection.d.ts.map +1 -0
  76. package/dist/crm/index.d.ts +27 -0
  77. package/dist/crm/index.d.ts.map +1 -0
  78. package/dist/crm/models/Lead.d.ts +135 -0
  79. package/dist/crm/models/Lead.d.ts.map +1 -0
  80. package/dist/crm/models/Opportunity.d.ts +111 -0
  81. package/dist/crm/models/Opportunity.d.ts.map +1 -0
  82. package/dist/crm/models/OpportunityConversion.d.ts +66 -0
  83. package/dist/crm/models/OpportunityConversion.d.ts.map +1 -0
  84. package/dist/crm/models/PipelineDefinition.d.ts +58 -0
  85. package/dist/crm/models/PipelineDefinition.d.ts.map +1 -0
  86. package/dist/crm/models/PipelineStage.d.ts +66 -0
  87. package/dist/crm/models/PipelineStage.d.ts.map +1 -0
  88. package/dist/crm/models/SalesActivity.d.ts +76 -0
  89. package/dist/crm/models/SalesActivity.d.ts.map +1 -0
  90. package/dist/crm/models/SalesRepresentative.d.ts +60 -0
  91. package/dist/crm/models/SalesRepresentative.d.ts.map +1 -0
  92. package/dist/crm/types.d.ts +228 -0
  93. package/dist/crm/types.d.ts.map +1 -0
  94. package/dist/crm.d.ts +2 -0
  95. package/dist/crm.d.ts.map +1 -0
  96. package/dist/crm.js +3 -0
  97. package/dist/index.d.ts +4 -0
  98. package/dist/index.d.ts.map +1 -0
  99. package/dist/index.js +5 -0
  100. package/dist/manifest.json +9340 -0
  101. package/dist/referrals/collections/AttributionExceptionCollection.d.ts +17 -0
  102. package/dist/referrals/collections/AttributionExceptionCollection.d.ts.map +1 -0
  103. package/dist/referrals/collections/AttributionPolicyCollection.d.ts +50 -0
  104. package/dist/referrals/collections/AttributionPolicyCollection.d.ts.map +1 -0
  105. package/dist/referrals/collections/ReferralAgreementCollection.d.ts +48 -0
  106. package/dist/referrals/collections/ReferralAgreementCollection.d.ts.map +1 -0
  107. package/dist/referrals/collections/ReferralCollection.d.ts +25 -0
  108. package/dist/referrals/collections/ReferralCollection.d.ts.map +1 -0
  109. package/dist/referrals/collections/ReferralLinkCollection.d.ts +96 -0
  110. package/dist/referrals/collections/ReferralLinkCollection.d.ts.map +1 -0
  111. package/dist/referrals/collections/ReferralProgramCollection.d.ts +18 -0
  112. package/dist/referrals/collections/ReferralProgramCollection.d.ts.map +1 -0
  113. package/dist/referrals/collections/ReferralTermSnapshotCollection.d.ts +13 -0
  114. package/dist/referrals/collections/ReferralTermSnapshotCollection.d.ts.map +1 -0
  115. package/dist/referrals/collections/ReferralTouchCollection.d.ts +30 -0
  116. package/dist/referrals/collections/ReferralTouchCollection.d.ts.map +1 -0
  117. package/dist/referrals/collections/ReferrerCollection.d.ts +17 -0
  118. package/dist/referrals/collections/ReferrerCollection.d.ts.map +1 -0
  119. package/dist/referrals/index.d.ts +38 -0
  120. package/dist/referrals/index.d.ts.map +1 -0
  121. package/dist/referrals/models/AttributionException.d.ts +85 -0
  122. package/dist/referrals/models/AttributionException.d.ts.map +1 -0
  123. package/dist/referrals/models/AttributionPolicy.d.ts +128 -0
  124. package/dist/referrals/models/AttributionPolicy.d.ts.map +1 -0
  125. package/dist/referrals/models/Referral.d.ts +112 -0
  126. package/dist/referrals/models/Referral.d.ts.map +1 -0
  127. package/dist/referrals/models/ReferralAgreement.d.ts +125 -0
  128. package/dist/referrals/models/ReferralAgreement.d.ts.map +1 -0
  129. package/dist/referrals/models/ReferralLink.d.ts +71 -0
  130. package/dist/referrals/models/ReferralLink.d.ts.map +1 -0
  131. package/dist/referrals/models/ReferralProgram.d.ts +57 -0
  132. package/dist/referrals/models/ReferralProgram.d.ts.map +1 -0
  133. package/dist/referrals/models/ReferralTermSnapshot.d.ts +61 -0
  134. package/dist/referrals/models/ReferralTermSnapshot.d.ts.map +1 -0
  135. package/dist/referrals/models/ReferralTouch.d.ts +55 -0
  136. package/dist/referrals/models/ReferralTouch.d.ts.map +1 -0
  137. package/dist/referrals/models/Referrer.d.ts +69 -0
  138. package/dist/referrals/models/Referrer.d.ts.map +1 -0
  139. package/dist/referrals/services/AttributionService.d.ts +248 -0
  140. package/dist/referrals/services/AttributionService.d.ts.map +1 -0
  141. package/dist/referrals/services/ReferralCommissionService.d.ts +91 -0
  142. package/dist/referrals/services/ReferralCommissionService.d.ts.map +1 -0
  143. package/dist/referrals/services/ReferralQualificationService.d.ts +135 -0
  144. package/dist/referrals/services/ReferralQualificationService.d.ts.map +1 -0
  145. package/dist/referrals/types.d.ts +226 -0
  146. package/dist/referrals/types.d.ts.map +1 -0
  147. package/dist/referrals.d.ts +2 -0
  148. package/dist/referrals.d.ts.map +1 -0
  149. package/dist/referrals.js +3 -0
  150. package/dist/smrt-knowledge.json +5501 -0
  151. package/dist/svelte/__tests__/format.test.js +68 -0
  152. package/dist/svelte/__tests__/types.test.js +349 -0
  153. package/dist/svelte/components/AttributionConflictQueue.svelte +361 -0
  154. package/dist/svelte/components/AttributionConflictQueue.svelte.d.ts +15 -0
  155. package/dist/svelte/components/AttributionConflictQueue.svelte.d.ts.map +1 -0
  156. package/dist/svelte/components/CommissionBreakdown.svelte +251 -0
  157. package/dist/svelte/components/CommissionBreakdown.svelte.d.ts +11 -0
  158. package/dist/svelte/components/CommissionBreakdown.svelte.d.ts.map +1 -0
  159. package/dist/svelte/components/CommissionExpenseSummary.svelte +186 -0
  160. package/dist/svelte/components/CommissionExpenseSummary.svelte.d.ts +13 -0
  161. package/dist/svelte/components/CommissionExpenseSummary.svelte.d.ts.map +1 -0
  162. package/dist/svelte/components/ExecutedAgreementsList.svelte +136 -0
  163. package/dist/svelte/components/ExecutedAgreementsList.svelte.d.ts +11 -0
  164. package/dist/svelte/components/ExecutedAgreementsList.svelte.d.ts.map +1 -0
  165. package/dist/svelte/components/LeadList.svelte +224 -0
  166. package/dist/svelte/components/LeadList.svelte.d.ts +19 -0
  167. package/dist/svelte/components/LeadList.svelte.d.ts.map +1 -0
  168. package/dist/svelte/components/OpportunityBoard.svelte +230 -0
  169. package/dist/svelte/components/OpportunityBoard.svelte.d.ts +17 -0
  170. package/dist/svelte/components/OpportunityBoard.svelte.d.ts.map +1 -0
  171. package/dist/svelte/components/OpportunityDetail.svelte +472 -0
  172. package/dist/svelte/components/OpportunityDetail.svelte.d.ts +27 -0
  173. package/dist/svelte/components/OpportunityDetail.svelte.d.ts.map +1 -0
  174. package/dist/svelte/components/PayoutBatchReview.svelte +285 -0
  175. package/dist/svelte/components/PayoutBatchReview.svelte.d.ts +21 -0
  176. package/dist/svelte/components/PayoutBatchReview.svelte.d.ts.map +1 -0
  177. package/dist/svelte/components/PayoutHistoryList.svelte +245 -0
  178. package/dist/svelte/components/PayoutHistoryList.svelte.d.ts +11 -0
  179. package/dist/svelte/components/PayoutHistoryList.svelte.d.ts.map +1 -0
  180. package/dist/svelte/components/ReferralLinkManager.svelte +216 -0
  181. package/dist/svelte/components/ReferralLinkManager.svelte.d.ts +17 -0
  182. package/dist/svelte/components/ReferralLinkManager.svelte.d.ts.map +1 -0
  183. package/dist/svelte/components/ReferralStatusList.svelte +118 -0
  184. package/dist/svelte/components/ReferralStatusList.svelte.d.ts +11 -0
  185. package/dist/svelte/components/ReferralStatusList.svelte.d.ts.map +1 -0
  186. package/dist/svelte/components/ReferrerEarningsSummary.svelte +106 -0
  187. package/dist/svelte/components/ReferrerEarningsSummary.svelte.d.ts +11 -0
  188. package/dist/svelte/components/ReferrerEarningsSummary.svelte.d.ts.map +1 -0
  189. package/dist/svelte/components/SalesDashboard.svelte +192 -0
  190. package/dist/svelte/components/SalesDashboard.svelte.d.ts +29 -0
  191. package/dist/svelte/components/SalesDashboard.svelte.d.ts.map +1 -0
  192. package/dist/svelte/format.d.ts +46 -0
  193. package/dist/svelte/format.d.ts.map +1 -0
  194. package/dist/svelte/format.js +75 -0
  195. package/dist/svelte/index.d.ts +50 -0
  196. package/dist/svelte/index.d.ts.map +1 -0
  197. package/dist/svelte/index.js +37 -0
  198. package/dist/svelte/types.d.ts +422 -0
  199. package/dist/svelte/types.d.ts.map +1 -0
  200. package/dist/svelte/types.js +376 -0
  201. package/package.json +89 -0
@@ -0,0 +1,186 @@
1
+ <script lang="ts">
2
+ /**
3
+ * CommissionExpenseSummary — operator reconciliation of commission expense
4
+ * vs. payouts (#1933).
5
+ *
6
+ * Renders pre-aggregated reconciliation rows and per-currency totals:
7
+ * accrued commission expense, adjustments, amounts settled via payouts, and
8
+ * the outstanding net accrual. This is COMMISSION EXPENSE owed to earners —
9
+ * deliberately separate from client invoices and client revenue/margin.
10
+ */
11
+ import { formatCents } from '../format.js';
12
+ import type { CommissionExpenseRowView } from '../types.js';
13
+ import { sumExpenseRowsByCurrency } from '../types.js';
14
+
15
+ export interface Props {
16
+ /** Pre-aggregated reconciliation rows (per period/program/plan). */
17
+ rows?: CommissionExpenseRowView[];
18
+ /** Heading context, e.g. `June 2026`. */
19
+ periodLabel?: string;
20
+ /** BCP 47 locale for money formatting. */
21
+ locale?: string;
22
+ }
23
+
24
+ let { rows = [], periodLabel, locale }: Props = $props();
25
+
26
+ const totals = $derived(sumExpenseRowsByCurrency(rows));
27
+ </script>
28
+
29
+ <div class="sales-expense-summary">
30
+ <header class="head">
31
+ <h3>Commission expense{periodLabel ? ` — ${periodLabel}` : ''}</h3>
32
+ <p class="note">
33
+ Amounts owed to earners (operator reconciliation). This is commission
34
+ expense — distinct from client invoices and client revenue.
35
+ </p>
36
+ </header>
37
+
38
+ {#if rows.length === 0}
39
+ <p class="empty">Nothing to reconcile for this period.</p>
40
+ {:else}
41
+ <dl class="tiles">
42
+ {#each totals as total (total.currency)}
43
+ <div class="tile">
44
+ <dt>Expense ({total.currency})</dt>
45
+ <dd>{formatCents(total.commissionExpenseCents, total.currency, locale)}</dd>
46
+ </div>
47
+ <div class="tile">
48
+ <dt>Adjustments ({total.currency})</dt>
49
+ <dd class:negative={total.adjustmentCents < 0}>
50
+ {formatCents(total.adjustmentCents, total.currency, locale)}
51
+ </dd>
52
+ </div>
53
+ <div class="tile">
54
+ <dt>Paid out ({total.currency})</dt>
55
+ <dd>{formatCents(total.payoutCents, total.currency, locale)}</dd>
56
+ </div>
57
+ <div class="tile tile--net">
58
+ <dt>Net accrued ({total.currency})</dt>
59
+ <dd class:negative={total.netAccruedCents < 0}>
60
+ {formatCents(total.netAccruedCents, total.currency, locale)}
61
+ </dd>
62
+ </div>
63
+ {/each}
64
+ </dl>
65
+
66
+ <table>
67
+ <thead>
68
+ <tr>
69
+ <th scope="col">Segment</th>
70
+ <th scope="col" class="num">Expense</th>
71
+ <th scope="col" class="num">Adjustments</th>
72
+ <th scope="col" class="num">Paid out</th>
73
+ <th scope="col" class="num">Net accrued</th>
74
+ </tr>
75
+ </thead>
76
+ <tbody>
77
+ {#each rows as row (row.id)}
78
+ {@const net = row.commissionExpenseCents + row.adjustmentCents - row.payoutCents}
79
+ <tr>
80
+ <td>{row.label}</td>
81
+ <td class="num">
82
+ {formatCents(row.commissionExpenseCents, row.currency, locale)}
83
+ </td>
84
+ <td class="num" class:negative={row.adjustmentCents < 0}>
85
+ {formatCents(row.adjustmentCents, row.currency, locale)}
86
+ </td>
87
+ <td class="num">{formatCents(row.payoutCents, row.currency, locale)}</td>
88
+ <td class="num net" class:negative={net < 0}>
89
+ {formatCents(net, row.currency, locale)}
90
+ </td>
91
+ </tr>
92
+ {/each}
93
+ </tbody>
94
+ </table>
95
+ {/if}
96
+ </div>
97
+
98
+ <style>
99
+ .sales-expense-summary {
100
+ display: flex;
101
+ flex-direction: column;
102
+ gap: var(--smrt-spacing-3, 0.75rem);
103
+ width: 100%;
104
+ overflow-x: auto;
105
+ }
106
+
107
+ .head h3 {
108
+ margin: 0;
109
+ font-size: var(--smrt-typography-title-medium-size, 1rem);
110
+ }
111
+
112
+ .note {
113
+ margin: var(--smrt-spacing-1, 0.25rem) 0 0;
114
+ color: var(--smrt-color-on-surface-variant, #64748b);
115
+ font-size: var(--smrt-typography-body-small-size, 0.8125rem);
116
+ }
117
+
118
+ .empty {
119
+ margin: 0;
120
+ color: var(--smrt-color-on-surface-variant, #64748b);
121
+ font-style: italic;
122
+ }
123
+
124
+ .tiles {
125
+ display: grid;
126
+ grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
127
+ gap: var(--smrt-spacing-3, 0.75rem);
128
+ margin: 0;
129
+ }
130
+
131
+ .tile {
132
+ background: var(--smrt-color-surface, #fff);
133
+ border: 1px solid var(--smrt-color-outline-variant, #d8dde6);
134
+ border-radius: var(--smrt-radius-md, 8px);
135
+ padding: var(--smrt-spacing-3, 0.75rem);
136
+ }
137
+
138
+ .tile--net {
139
+ border-color: var(--smrt-color-primary, #2563eb);
140
+ }
141
+
142
+ .tile dt {
143
+ color: var(--smrt-color-on-surface-variant, #64748b);
144
+ font-size: var(--smrt-typography-label-medium-size, 0.75rem);
145
+ text-transform: uppercase;
146
+ letter-spacing: 0.04em;
147
+ }
148
+
149
+ .tile dd {
150
+ margin: var(--smrt-spacing-1, 0.25rem) 0 0;
151
+ font-weight: var(--smrt-typography-weight-bold, 700);
152
+ }
153
+
154
+ .negative {
155
+ color: var(--smrt-color-error, #dc2626);
156
+ }
157
+
158
+ table {
159
+ width: 100%;
160
+ border-collapse: collapse;
161
+ font-size: var(--smrt-typography-body-medium-size, 0.875rem);
162
+ }
163
+
164
+ th {
165
+ padding: var(--smrt-spacing-2, 0.5rem) var(--smrt-spacing-3, 0.75rem);
166
+ text-align: left;
167
+ font-weight: var(--smrt-typography-weight-semibold, 600);
168
+ background: var(--smrt-color-surface-container, #f3f4f6);
169
+ border-bottom: 1px solid var(--smrt-color-outline-variant, #d8dde6);
170
+ white-space: nowrap;
171
+ }
172
+
173
+ td {
174
+ padding: var(--smrt-spacing-2, 0.5rem) var(--smrt-spacing-3, 0.75rem);
175
+ border-bottom: 1px solid var(--smrt-color-outline-variant, #d8dde6);
176
+ }
177
+
178
+ .num {
179
+ text-align: right;
180
+ white-space: nowrap;
181
+ }
182
+
183
+ .net {
184
+ font-weight: var(--smrt-typography-weight-semibold, 600);
185
+ }
186
+ </style>
@@ -0,0 +1,13 @@
1
+ import type { CommissionExpenseRowView } from '../types.js';
2
+ export interface Props {
3
+ /** Pre-aggregated reconciliation rows (per period/program/plan). */
4
+ rows?: CommissionExpenseRowView[];
5
+ /** Heading context, e.g. `June 2026`. */
6
+ periodLabel?: string;
7
+ /** BCP 47 locale for money formatting. */
8
+ locale?: string;
9
+ }
10
+ declare const CommissionExpenseSummary: import("svelte").Component<Props, {}, "">;
11
+ type CommissionExpenseSummary = ReturnType<typeof CommissionExpenseSummary>;
12
+ export default CommissionExpenseSummary;
13
+ //# sourceMappingURL=CommissionExpenseSummary.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CommissionExpenseSummary.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/CommissionExpenseSummary.svelte.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAI5D,MAAM,WAAW,KAAK;IACpB,oEAAoE;IACpE,IAAI,CAAC,EAAE,wBAAwB,EAAE,CAAC;IAClC,yCAAyC;IACzC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0CAA0C;IAC1C,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAsFD,QAAA,MAAM,wBAAwB,2CAAwC,CAAC;AACvE,KAAK,wBAAwB,GAAG,UAAU,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAC5E,eAAe,wBAAwB,CAAC"}
@@ -0,0 +1,136 @@
1
+ <script lang="ts">
2
+ /**
3
+ * ExecutedAgreementsList — referrer agreement versions (#1933).
4
+ *
5
+ * Table of agreement versions: version, status, effective window, the pinned
6
+ * commission plan (`key@version`), clearing days, approval mode, and the
7
+ * executed-artifact evidence (URL + content hash) when the agreement has been
8
+ * executed.
9
+ */
10
+ import { Badge } from '@happyvertical/smrt-ui/ui';
11
+ import { formatDate } from '../format.js';
12
+ import type { AgreementVersionView } from '../types.js';
13
+ import { agreementStatusBadgeVariant, formatPlanRef } from '../types.js';
14
+
15
+ export interface Props {
16
+ /** Agreement versions, newest first by convention. */
17
+ agreements?: AgreementVersionView[];
18
+ /** BCP 47 locale for date formatting. */
19
+ locale?: string;
20
+ }
21
+
22
+ let { agreements = [], locale }: Props = $props();
23
+ </script>
24
+
25
+ <div class="sales-agreements">
26
+ {#if agreements.length === 0}
27
+ <p class="empty">No agreements yet.</p>
28
+ {:else}
29
+ <table>
30
+ <thead>
31
+ <tr>
32
+ <th scope="col">Version</th>
33
+ <th scope="col">Status</th>
34
+ <th scope="col">Effective</th>
35
+ <th scope="col">Commission plan</th>
36
+ <th scope="col" class="num">Clearing</th>
37
+ <th scope="col">Approval</th>
38
+ <th scope="col">Executed artifact</th>
39
+ </tr>
40
+ </thead>
41
+ <tbody>
42
+ {#each agreements as agreement (agreement.id)}
43
+ <tr>
44
+ <td>v{agreement.version}</td>
45
+ <td>
46
+ <Badge variant={agreementStatusBadgeVariant(agreement.status)} size="sm">
47
+ {agreement.status}
48
+ </Badge>
49
+ </td>
50
+ <td>
51
+ {formatDate(agreement.effectiveFrom, locale)}
52
+
53
+ {#if agreement.effectiveTo}
54
+ {formatDate(agreement.effectiveTo, locale)}
55
+ {:else}
56
+ open-ended
57
+ {/if}
58
+ </td>
59
+ <td>
60
+ <code>{formatPlanRef(agreement.planKey, agreement.planVersion)}</code>
61
+ </td>
62
+ <td class="num">{agreement.clearingDays} days</td>
63
+ <td>{agreement.approvalMode}</td>
64
+ <td>
65
+ {#if agreement.artifactUrl}
66
+ <a href={agreement.artifactUrl} target="_blank" rel="noopener noreferrer">
67
+ executed copy
68
+ </a>
69
+ {#if agreement.artifactHash}
70
+ <code class="hash" title={agreement.artifactHash}>
71
+ {agreement.artifactHash.slice(0, 12)}…
72
+ </code>
73
+ {/if}
74
+ {:else}
75
+
76
+ {/if}
77
+ </td>
78
+ </tr>
79
+ {/each}
80
+ </tbody>
81
+ </table>
82
+ {/if}
83
+ </div>
84
+
85
+ <style>
86
+ .sales-agreements {
87
+ width: 100%;
88
+ overflow-x: auto;
89
+ }
90
+
91
+ .empty {
92
+ margin: 0;
93
+ color: var(--smrt-color-on-surface-variant, #64748b);
94
+ font-style: italic;
95
+ }
96
+
97
+ table {
98
+ width: 100%;
99
+ border-collapse: collapse;
100
+ font-size: var(--smrt-typography-body-medium-size, 0.875rem);
101
+ }
102
+
103
+ th {
104
+ padding: var(--smrt-spacing-2, 0.5rem) var(--smrt-spacing-3, 0.75rem);
105
+ text-align: left;
106
+ font-weight: var(--smrt-typography-weight-semibold, 600);
107
+ background: var(--smrt-color-surface-container, #f3f4f6);
108
+ border-bottom: 1px solid var(--smrt-color-outline-variant, #d8dde6);
109
+ white-space: nowrap;
110
+ }
111
+
112
+ td {
113
+ padding: var(--smrt-spacing-2, 0.5rem) var(--smrt-spacing-3, 0.75rem);
114
+ border-bottom: 1px solid var(--smrt-color-outline-variant, #d8dde6);
115
+ vertical-align: top;
116
+ }
117
+
118
+ .num {
119
+ text-align: right;
120
+ white-space: nowrap;
121
+ }
122
+
123
+ code {
124
+ font-family: var(--smrt-font-family-mono, ui-monospace, monospace);
125
+ font-size: var(--smrt-typography-body-small-size, 0.8125rem);
126
+ }
127
+
128
+ .hash {
129
+ margin-left: var(--smrt-spacing-1, 0.25rem);
130
+ color: var(--smrt-color-on-surface-variant, #64748b);
131
+ }
132
+
133
+ a {
134
+ color: var(--smrt-color-primary, #2563eb);
135
+ }
136
+ </style>
@@ -0,0 +1,11 @@
1
+ import type { AgreementVersionView } from '../types.js';
2
+ export interface Props {
3
+ /** Agreement versions, newest first by convention. */
4
+ agreements?: AgreementVersionView[];
5
+ /** BCP 47 locale for date formatting. */
6
+ locale?: string;
7
+ }
8
+ declare const ExecutedAgreementsList: import("svelte").Component<Props, {}, "">;
9
+ type ExecutedAgreementsList = ReturnType<typeof ExecutedAgreementsList>;
10
+ export default ExecutedAgreementsList;
11
+ //# sourceMappingURL=ExecutedAgreementsList.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExecutedAgreementsList.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/ExecutedAgreementsList.svelte.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAIxD,MAAM,WAAW,KAAK;IACpB,sDAAsD;IACtD,UAAU,CAAC,EAAE,oBAAoB,EAAE,CAAC;IACpC,yCAAyC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAwED,QAAA,MAAM,sBAAsB,2CAAwC,CAAC;AACrE,KAAK,sBAAsB,GAAG,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC;AACxE,eAAe,sBAAsB,CAAC"}
@@ -0,0 +1,224 @@
1
+ <script lang="ts">
2
+ /**
3
+ * LeadList — CRM lead worklist (#1924).
4
+ *
5
+ * Presentational table of leads with owner assignment (rep picker), a qualify
6
+ * action, status badges, and the open next action per lead. Merged leads show
7
+ * a merged-into indicator instead of actions. All data arrives via props and
8
+ * all actions are delegated to callbacks.
9
+ */
10
+ import { Select } from '@happyvertical/smrt-ui/forms';
11
+ import { Badge, Button } from '@happyvertical/smrt-ui/ui';
12
+ import { formatDate } from '../format.js';
13
+ import type { LeadListItemView, SalesRepOptionView } from '../types.js';
14
+ import { canQualifyLead, isOverdue, leadStatusBadgeVariant } from '../types.js';
15
+
16
+ export interface Props {
17
+ /** Leads to display. */
18
+ leads?: LeadListItemView[];
19
+ /** Assignable sales representatives for the owner picker. */
20
+ reps?: SalesRepOptionView[];
21
+ /** Disable actions while a mutation is in flight. */
22
+ busy?: boolean;
23
+ /** BCP 47 locale for date formatting. */
24
+ locale?: string;
25
+ /** Assign (or reassign) a lead to a representative. */
26
+ onAssign?: (leadId: string, repId: string) => void;
27
+ /** Qualify a lead into an opportunity. */
28
+ onQualify?: (leadId: string) => void;
29
+ }
30
+
31
+ let {
32
+ leads = [],
33
+ reps = [],
34
+ busy = false,
35
+ locale,
36
+ onAssign,
37
+ onQualify,
38
+ }: Props = $props();
39
+
40
+ function handleAssign(leadId: string, event: Event) {
41
+ const value = (event.currentTarget as HTMLSelectElement).value;
42
+ if (value) onAssign?.(leadId, value);
43
+ }
44
+ </script>
45
+
46
+ <div class="sales-lead-list">
47
+ {#if leads.length === 0}
48
+ <p class="sales-lead-list__empty">No leads yet.</p>
49
+ {:else}
50
+ <table>
51
+ <thead>
52
+ <tr>
53
+ <th scope="col">Lead</th>
54
+ <th scope="col">Contact</th>
55
+ <th scope="col">Source</th>
56
+ <th scope="col">Owner</th>
57
+ <th scope="col">Status</th>
58
+ <th scope="col">Next action</th>
59
+ <th scope="col"><span class="visually-hidden">Actions</span></th>
60
+ </tr>
61
+ </thead>
62
+ <tbody>
63
+ {#each leads as lead (lead.id)}
64
+ {@const merged = lead.status === 'merged'}
65
+ <tr class:merged>
66
+ <td>
67
+ <span class="lead-name">{lead.name}</span>
68
+ {#if lead.organizationName}
69
+ <span class="secondary">{lead.organizationName}</span>
70
+ {/if}
71
+ {#if merged && lead.mergedIntoId}
72
+ <span class="merged-note">
73
+ merged into <code>{lead.mergedIntoId.slice(0, 8)}</code>
74
+ </span>
75
+ {/if}
76
+ </td>
77
+ <td>
78
+ {#if lead.contactName}
79
+ <span class="secondary">{lead.contactName}</span>
80
+ {/if}
81
+ {#if lead.email}
82
+ <span class="secondary">{lead.email}</span>
83
+ {/if}
84
+ {#if lead.phone}
85
+ <span class="secondary">{lead.phone}</span>
86
+ {/if}
87
+ </td>
88
+ <td>{lead.sourceLabel ?? '—'}</td>
89
+ <td>
90
+ {#if onAssign && !merged}
91
+ <Select
92
+ value={lead.ownerRepId ?? ''}
93
+ disabled={busy}
94
+ aria-label={`Assign owner for ${lead.name}`}
95
+ onchange={(event) => handleAssign(lead.id, event)}
96
+ >
97
+ <option value="" disabled>Unassigned</option>
98
+ {#each reps as rep (rep.id)}
99
+ <option value={rep.id}>{rep.name}</option>
100
+ {/each}
101
+ </Select>
102
+ {:else}
103
+ {lead.ownerName ?? '—'}
104
+ {/if}
105
+ </td>
106
+ <td>
107
+ <Badge variant={leadStatusBadgeVariant(lead.status)} size="sm">
108
+ {lead.status}
109
+ </Badge>
110
+ </td>
111
+ <td>
112
+ {#if lead.nextAction}
113
+ <span class="next-action" class:overdue={isOverdue(lead.nextAction.dueAt)}>
114
+ {lead.nextAction.summary}
115
+ </span>
116
+ {#if lead.nextAction.dueAt}
117
+ <span class="secondary">
118
+ due {formatDate(lead.nextAction.dueAt, locale)}
119
+ </span>
120
+ {/if}
121
+ {:else}
122
+
123
+ {/if}
124
+ </td>
125
+ <td class="actions">
126
+ {#if onQualify && canQualifyLead(lead.status)}
127
+ <Button
128
+ variant="secondary"
129
+ size="sm"
130
+ disabled={busy}
131
+ onclick={() => onQualify?.(lead.id)}
132
+ >
133
+ Qualify
134
+ </Button>
135
+ {/if}
136
+ </td>
137
+ </tr>
138
+ {/each}
139
+ </tbody>
140
+ </table>
141
+ {/if}
142
+ </div>
143
+
144
+ <style>
145
+ .sales-lead-list {
146
+ width: 100%;
147
+ overflow-x: auto;
148
+ }
149
+
150
+ .sales-lead-list__empty {
151
+ margin: 0;
152
+ color: var(--smrt-color-on-surface-variant, #64748b);
153
+ font-style: italic;
154
+ }
155
+
156
+ table {
157
+ width: 100%;
158
+ border-collapse: collapse;
159
+ font-size: var(--smrt-typography-body-medium-size, 0.875rem);
160
+ }
161
+
162
+ th {
163
+ padding: var(--smrt-spacing-2, 0.5rem) var(--smrt-spacing-3, 0.75rem);
164
+ text-align: left;
165
+ font-weight: var(--smrt-typography-weight-semibold, 600);
166
+ background: var(--smrt-color-surface-container, #f3f4f6);
167
+ border-bottom: 1px solid var(--smrt-color-outline-variant, #d8dde6);
168
+ white-space: nowrap;
169
+ }
170
+
171
+ td {
172
+ padding: var(--smrt-spacing-2, 0.5rem) var(--smrt-spacing-3, 0.75rem);
173
+ border-bottom: 1px solid var(--smrt-color-outline-variant, #d8dde6);
174
+ vertical-align: top;
175
+ }
176
+
177
+ tr.merged td {
178
+ opacity: 0.65;
179
+ }
180
+
181
+ .lead-name {
182
+ display: block;
183
+ font-weight: var(--smrt-typography-weight-medium, 500);
184
+ }
185
+
186
+ .secondary {
187
+ display: block;
188
+ color: var(--smrt-color-on-surface-variant, #64748b);
189
+ font-size: var(--smrt-typography-body-small-size, 0.75rem);
190
+ }
191
+
192
+ .merged-note {
193
+ display: block;
194
+ color: var(--smrt-color-on-surface-variant, #64748b);
195
+ font-size: var(--smrt-typography-body-small-size, 0.75rem);
196
+ }
197
+
198
+ .merged-note code {
199
+ font-family: var(--smrt-font-family-mono, ui-monospace, monospace);
200
+ }
201
+
202
+ .next-action {
203
+ display: block;
204
+ }
205
+
206
+ .next-action.overdue {
207
+ color: var(--smrt-color-error, #dc2626);
208
+ font-weight: var(--smrt-typography-weight-medium, 500);
209
+ }
210
+
211
+ .actions {
212
+ white-space: nowrap;
213
+ text-align: right;
214
+ }
215
+
216
+ .visually-hidden {
217
+ position: absolute;
218
+ width: 1px;
219
+ height: 1px;
220
+ overflow: hidden;
221
+ clip: rect(0 0 0 0);
222
+ white-space: nowrap;
223
+ }
224
+ </style>
@@ -0,0 +1,19 @@
1
+ import type { LeadListItemView, SalesRepOptionView } from '../types.js';
2
+ export interface Props {
3
+ /** Leads to display. */
4
+ leads?: LeadListItemView[];
5
+ /** Assignable sales representatives for the owner picker. */
6
+ reps?: SalesRepOptionView[];
7
+ /** Disable actions while a mutation is in flight. */
8
+ busy?: boolean;
9
+ /** BCP 47 locale for date formatting. */
10
+ locale?: string;
11
+ /** Assign (or reassign) a lead to a representative. */
12
+ onAssign?: (leadId: string, repId: string) => void;
13
+ /** Qualify a lead into an opportunity. */
14
+ onQualify?: (leadId: string) => void;
15
+ }
16
+ declare const LeadList: import("svelte").Component<Props, {}, "">;
17
+ type LeadList = ReturnType<typeof LeadList>;
18
+ export default LeadList;
19
+ //# sourceMappingURL=LeadList.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LeadList.svelte.d.ts","sourceRoot":"","sources":["../../../src/svelte/components/LeadList.svelte.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAIxE,MAAM,WAAW,KAAK;IACpB,wBAAwB;IACxB,KAAK,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC3B,6DAA6D;IAC7D,IAAI,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAC5B,qDAAqD;IACrD,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,yCAAyC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,uDAAuD;IACvD,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnD,0CAA0C;IAC1C,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACtC;AAmHD,QAAA,MAAM,QAAQ,2CAAwC,CAAC;AACvD,KAAK,QAAQ,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC;AAC5C,eAAe,QAAQ,CAAC"}