@contractspec/example.crm-pipeline 1.57.0 → 1.59.0

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 (259) hide show
  1. package/.turbo/turbo-build.log +148 -164
  2. package/.turbo/turbo-prebuild.log +1 -0
  3. package/CHANGELOG.md +39 -0
  4. package/dist/browser/crm-pipeline.feature.js +75 -0
  5. package/dist/browser/deal/deal.enum.js +18 -0
  6. package/dist/browser/deal/deal.operation.js +396 -0
  7. package/dist/browser/deal/deal.schema.js +141 -0
  8. package/dist/browser/deal/deal.test-spec.js +58 -0
  9. package/dist/browser/deal/index.js +408 -0
  10. package/dist/browser/docs/crm-pipeline.docblock.js +113 -0
  11. package/dist/browser/docs/index.js +113 -0
  12. package/dist/browser/entities/company.entity.js +52 -0
  13. package/dist/browser/entities/contact.entity.js +66 -0
  14. package/dist/browser/entities/deal.entity.js +107 -0
  15. package/dist/browser/entities/index.js +343 -0
  16. package/dist/browser/entities/task.entity.js +99 -0
  17. package/dist/browser/events/contact.event.js +31 -0
  18. package/dist/browser/events/deal.event.js +101 -0
  19. package/dist/browser/events/index.js +158 -0
  20. package/dist/browser/events/task.event.js +28 -0
  21. package/dist/browser/example.js +39 -0
  22. package/dist/browser/handlers/crm.handlers.js +160 -0
  23. package/dist/browser/handlers/deal.handlers.js +293 -0
  24. package/dist/browser/handlers/index.js +456 -0
  25. package/dist/browser/handlers/mock-data.js +165 -0
  26. package/dist/browser/index.js +3279 -0
  27. package/dist/browser/operations/index.js +407 -0
  28. package/dist/browser/presentations/dashboard.presentation.js +52 -0
  29. package/dist/browser/presentations/index.js +284 -0
  30. package/dist/browser/presentations/pipeline.presentation.js +233 -0
  31. package/dist/browser/seeders/index.js +22 -0
  32. package/dist/browser/shared/overlay-types.js +0 -0
  33. package/dist/browser/ui/CrmDashboard.js +1325 -0
  34. package/dist/browser/ui/CrmDealCard.js +50 -0
  35. package/dist/browser/ui/CrmPipelineBoard.js +160 -0
  36. package/dist/browser/ui/hooks/index.js +186 -0
  37. package/dist/browser/ui/hooks/useDealList.js +84 -0
  38. package/dist/browser/ui/hooks/useDealMutations.js +100 -0
  39. package/dist/browser/ui/index.js +1972 -0
  40. package/dist/browser/ui/modals/CreateDealModal.js +211 -0
  41. package/dist/browser/ui/modals/DealActionsModal.js +428 -0
  42. package/dist/browser/ui/modals/index.js +638 -0
  43. package/dist/browser/ui/overlays/demo-overlays.js +55 -0
  44. package/dist/browser/ui/overlays/index.js +55 -0
  45. package/dist/browser/ui/renderers/index.js +827 -0
  46. package/dist/browser/ui/renderers/pipeline.markdown.js +564 -0
  47. package/dist/browser/ui/renderers/pipeline.renderer.js +264 -0
  48. package/dist/crm-pipeline.feature.d.ts +1 -6
  49. package/dist/crm-pipeline.feature.d.ts.map +1 -1
  50. package/dist/crm-pipeline.feature.js +74 -164
  51. package/dist/deal/deal.enum.d.ts +2 -7
  52. package/dist/deal/deal.enum.d.ts.map +1 -1
  53. package/dist/deal/deal.enum.js +16 -22
  54. package/dist/deal/deal.operation.d.ts +444 -450
  55. package/dist/deal/deal.operation.d.ts.map +1 -1
  56. package/dist/deal/deal.operation.js +390 -263
  57. package/dist/deal/deal.schema.d.ts +251 -256
  58. package/dist/deal/deal.schema.d.ts.map +1 -1
  59. package/dist/deal/deal.schema.js +131 -275
  60. package/dist/deal/deal.test-spec.d.ts +2 -7
  61. package/dist/deal/deal.test-spec.d.ts.map +1 -1
  62. package/dist/deal/deal.test-spec.js +56 -62
  63. package/dist/deal/index.d.ts +7 -4
  64. package/dist/deal/index.d.ts.map +1 -0
  65. package/dist/deal/index.js +408 -4
  66. package/dist/docs/crm-pipeline.docblock.d.ts +2 -1
  67. package/dist/docs/crm-pipeline.docblock.d.ts.map +1 -0
  68. package/dist/docs/crm-pipeline.docblock.js +45 -51
  69. package/dist/docs/index.d.ts +2 -1
  70. package/dist/docs/index.d.ts.map +1 -0
  71. package/dist/docs/index.js +114 -1
  72. package/dist/entities/company.entity.d.ts +27 -32
  73. package/dist/entities/company.entity.d.ts.map +1 -1
  74. package/dist/entities/company.entity.js +51 -61
  75. package/dist/entities/contact.entity.d.ts +31 -36
  76. package/dist/entities/contact.entity.d.ts.map +1 -1
  77. package/dist/entities/contact.entity.js +65 -76
  78. package/dist/entities/deal.entity.d.ts +52 -57
  79. package/dist/entities/deal.entity.d.ts.map +1 -1
  80. package/dist/entities/deal.entity.js +104 -116
  81. package/dist/entities/index.d.ts +6 -10
  82. package/dist/entities/index.d.ts.map +1 -1
  83. package/dist/entities/index.js +342 -31
  84. package/dist/entities/task.entity.d.ts +42 -47
  85. package/dist/entities/task.entity.d.ts.map +1 -1
  86. package/dist/entities/task.entity.js +95 -124
  87. package/dist/events/contact.event.d.ts +21 -27
  88. package/dist/events/contact.event.d.ts.map +1 -1
  89. package/dist/events/contact.event.js +29 -42
  90. package/dist/events/deal.event.d.ts +100 -106
  91. package/dist/events/deal.event.d.ts.map +1 -1
  92. package/dist/events/deal.event.js +93 -163
  93. package/dist/events/index.d.ts +4 -4
  94. package/dist/events/index.d.ts.map +1 -0
  95. package/dist/events/index.js +158 -4
  96. package/dist/events/task.event.d.ts +21 -27
  97. package/dist/events/task.event.d.ts.map +1 -1
  98. package/dist/events/task.event.js +26 -42
  99. package/dist/example.d.ts +2 -6
  100. package/dist/example.d.ts.map +1 -1
  101. package/dist/example.js +38 -50
  102. package/dist/handlers/crm.handlers.d.ts +80 -78
  103. package/dist/handlers/crm.handlers.d.ts.map +1 -1
  104. package/dist/handlers/crm.handlers.js +155 -166
  105. package/dist/handlers/deal.handlers.d.ts +58 -63
  106. package/dist/handlers/deal.handlers.d.ts.map +1 -1
  107. package/dist/handlers/deal.handlers.js +279 -105
  108. package/dist/handlers/index.d.ts +10 -4
  109. package/dist/handlers/index.d.ts.map +1 -0
  110. package/dist/handlers/index.js +456 -4
  111. package/dist/handlers/mock-data.d.ts +38 -41
  112. package/dist/handlers/mock-data.d.ts.map +1 -1
  113. package/dist/handlers/mock-data.js +162 -184
  114. package/dist/index.d.ts +13 -42
  115. package/dist/index.d.ts.map +1 -1
  116. package/dist/index.js +3277 -53
  117. package/dist/node/crm-pipeline.feature.js +75 -0
  118. package/dist/node/deal/deal.enum.js +18 -0
  119. package/dist/node/deal/deal.operation.js +396 -0
  120. package/dist/node/deal/deal.schema.js +141 -0
  121. package/dist/node/deal/deal.test-spec.js +58 -0
  122. package/dist/node/deal/index.js +408 -0
  123. package/dist/node/docs/crm-pipeline.docblock.js +113 -0
  124. package/dist/node/docs/index.js +113 -0
  125. package/dist/node/entities/company.entity.js +52 -0
  126. package/dist/node/entities/contact.entity.js +66 -0
  127. package/dist/node/entities/deal.entity.js +107 -0
  128. package/dist/node/entities/index.js +343 -0
  129. package/dist/node/entities/task.entity.js +99 -0
  130. package/dist/node/events/contact.event.js +31 -0
  131. package/dist/node/events/deal.event.js +101 -0
  132. package/dist/node/events/index.js +158 -0
  133. package/dist/node/events/task.event.js +28 -0
  134. package/dist/node/example.js +39 -0
  135. package/dist/node/handlers/crm.handlers.js +160 -0
  136. package/dist/node/handlers/deal.handlers.js +293 -0
  137. package/dist/node/handlers/index.js +456 -0
  138. package/dist/node/handlers/mock-data.js +165 -0
  139. package/dist/node/index.js +3279 -0
  140. package/dist/node/operations/index.js +407 -0
  141. package/dist/node/presentations/dashboard.presentation.js +52 -0
  142. package/dist/node/presentations/index.js +284 -0
  143. package/dist/node/presentations/pipeline.presentation.js +233 -0
  144. package/dist/node/seeders/index.js +22 -0
  145. package/dist/node/shared/overlay-types.js +0 -0
  146. package/dist/node/ui/CrmDashboard.js +1325 -0
  147. package/dist/node/ui/CrmDealCard.js +50 -0
  148. package/dist/node/ui/CrmPipelineBoard.js +160 -0
  149. package/dist/node/ui/hooks/index.js +186 -0
  150. package/dist/node/ui/hooks/useDealList.js +84 -0
  151. package/dist/node/ui/hooks/useDealMutations.js +100 -0
  152. package/dist/node/ui/index.js +1972 -0
  153. package/dist/node/ui/modals/CreateDealModal.js +211 -0
  154. package/dist/node/ui/modals/DealActionsModal.js +428 -0
  155. package/dist/node/ui/modals/index.js +638 -0
  156. package/dist/node/ui/overlays/demo-overlays.js +55 -0
  157. package/dist/node/ui/overlays/index.js +55 -0
  158. package/dist/node/ui/renderers/index.js +827 -0
  159. package/dist/node/ui/renderers/pipeline.markdown.js +564 -0
  160. package/dist/node/ui/renderers/pipeline.renderer.js +264 -0
  161. package/dist/operations/index.d.ts +2 -5
  162. package/dist/operations/index.d.ts.map +1 -0
  163. package/dist/operations/index.js +407 -5
  164. package/dist/presentations/dashboard.presentation.d.ts +2 -7
  165. package/dist/presentations/dashboard.presentation.d.ts.map +1 -1
  166. package/dist/presentations/dashboard.presentation.js +51 -60
  167. package/dist/presentations/index.d.ts +3 -3
  168. package/dist/presentations/index.d.ts.map +1 -0
  169. package/dist/presentations/index.js +284 -3
  170. package/dist/presentations/pipeline.presentation.d.ts +4 -9
  171. package/dist/presentations/pipeline.presentation.d.ts.map +1 -1
  172. package/dist/presentations/pipeline.presentation.js +228 -116
  173. package/dist/seeders/index.d.ts +4 -8
  174. package/dist/seeders/index.d.ts.map +1 -1
  175. package/dist/seeders/index.js +21 -45
  176. package/dist/shared/overlay-types.d.ts +25 -28
  177. package/dist/shared/overlay-types.d.ts.map +1 -1
  178. package/dist/shared/overlay-types.js +1 -0
  179. package/dist/ui/CrmDashboard.d.ts +1 -6
  180. package/dist/ui/CrmDashboard.d.ts.map +1 -1
  181. package/dist/ui/CrmDashboard.js +1318 -296
  182. package/dist/ui/CrmDealCard.d.ts +8 -12
  183. package/dist/ui/CrmDealCard.d.ts.map +1 -1
  184. package/dist/ui/CrmDealCard.js +47 -45
  185. package/dist/ui/CrmPipelineBoard.d.ts +11 -20
  186. package/dist/ui/CrmPipelineBoard.d.ts.map +1 -1
  187. package/dist/ui/CrmPipelineBoard.js +157 -94
  188. package/dist/ui/hooks/index.d.ts +3 -3
  189. package/dist/ui/hooks/index.d.ts.map +1 -0
  190. package/dist/ui/hooks/index.js +185 -4
  191. package/dist/ui/hooks/useDealList.d.ts +28 -32
  192. package/dist/ui/hooks/useDealList.d.ts.map +1 -1
  193. package/dist/ui/hooks/useDealList.js +81 -90
  194. package/dist/ui/hooks/useDealMutations.d.ts +18 -22
  195. package/dist/ui/hooks/useDealMutations.d.ts.map +1 -1
  196. package/dist/ui/hooks/useDealMutations.js +97 -155
  197. package/dist/ui/index.d.ts +8 -14
  198. package/dist/ui/index.d.ts.map +1 -0
  199. package/dist/ui/index.js +1973 -15
  200. package/dist/ui/modals/CreateDealModal.d.ts +19 -29
  201. package/dist/ui/modals/CreateDealModal.d.ts.map +1 -1
  202. package/dist/ui/modals/CreateDealModal.js +209 -180
  203. package/dist/ui/modals/DealActionsModal.d.ts +31 -44
  204. package/dist/ui/modals/DealActionsModal.d.ts.map +1 -1
  205. package/dist/ui/modals/DealActionsModal.js +424 -367
  206. package/dist/ui/modals/index.d.ts +3 -3
  207. package/dist/ui/modals/index.d.ts.map +1 -0
  208. package/dist/ui/modals/index.js +638 -3
  209. package/dist/ui/overlays/demo-overlays.d.ts +10 -8
  210. package/dist/ui/overlays/demo-overlays.d.ts.map +1 -1
  211. package/dist/ui/overlays/demo-overlays.js +54 -66
  212. package/dist/ui/overlays/index.d.ts +2 -2
  213. package/dist/ui/overlays/index.d.ts.map +1 -0
  214. package/dist/ui/overlays/index.js +56 -3
  215. package/dist/ui/renderers/index.d.ts +3 -3
  216. package/dist/ui/renderers/index.d.ts.map +1 -0
  217. package/dist/ui/renderers/index.js +827 -3
  218. package/dist/ui/renderers/pipeline.markdown.d.ts +12 -11
  219. package/dist/ui/renderers/pipeline.markdown.d.ts.map +1 -1
  220. package/dist/ui/renderers/pipeline.markdown.js +560 -114
  221. package/dist/ui/renderers/pipeline.renderer.d.ts +9 -7
  222. package/dist/ui/renderers/pipeline.renderer.d.ts.map +1 -1
  223. package/dist/ui/renderers/pipeline.renderer.js +261 -24
  224. package/package.json +476 -90
  225. package/tsdown.config.js +1 -2
  226. package/.turbo/turbo-build$colon$bundle.log +0 -164
  227. package/dist/crm-pipeline.feature.js.map +0 -1
  228. package/dist/deal/deal.enum.js.map +0 -1
  229. package/dist/deal/deal.operation.js.map +0 -1
  230. package/dist/deal/deal.schema.js.map +0 -1
  231. package/dist/deal/deal.test-spec.js.map +0 -1
  232. package/dist/docs/crm-pipeline.docblock.js.map +0 -1
  233. package/dist/entities/company.entity.js.map +0 -1
  234. package/dist/entities/contact.entity.js.map +0 -1
  235. package/dist/entities/deal.entity.js.map +0 -1
  236. package/dist/entities/index.js.map +0 -1
  237. package/dist/entities/task.entity.js.map +0 -1
  238. package/dist/events/contact.event.js.map +0 -1
  239. package/dist/events/deal.event.js.map +0 -1
  240. package/dist/events/task.event.js.map +0 -1
  241. package/dist/example.js.map +0 -1
  242. package/dist/handlers/crm.handlers.js.map +0 -1
  243. package/dist/handlers/deal.handlers.js.map +0 -1
  244. package/dist/handlers/mock-data.js.map +0 -1
  245. package/dist/index.js.map +0 -1
  246. package/dist/presentations/dashboard.presentation.js.map +0 -1
  247. package/dist/presentations/pipeline.presentation.js.map +0 -1
  248. package/dist/seeders/index.js.map +0 -1
  249. package/dist/ui/CrmDashboard.js.map +0 -1
  250. package/dist/ui/CrmDealCard.js.map +0 -1
  251. package/dist/ui/CrmPipelineBoard.js.map +0 -1
  252. package/dist/ui/hooks/useDealList.js.map +0 -1
  253. package/dist/ui/hooks/useDealMutations.js.map +0 -1
  254. package/dist/ui/modals/CreateDealModal.js.map +0 -1
  255. package/dist/ui/modals/DealActionsModal.js.map +0 -1
  256. package/dist/ui/overlays/demo-overlays.js.map +0 -1
  257. package/dist/ui/renderers/pipeline.markdown.js.map +0 -1
  258. package/dist/ui/renderers/pipeline.renderer.js.map +0 -1
  259. package/tsconfig.tsbuildinfo +0 -1
@@ -1,15 +1,11 @@
1
- import { Deal } from "./hooks/useDealList.js";
2
- import * as react_jsx_runtime0 from "react/jsx-runtime";
3
-
4
- //#region src/ui/CrmDealCard.d.ts
1
+ /**
2
+ * CRM Deal Card - Individual deal card for kanban board
3
+ */
4
+ import type { Deal } from './hooks/useDealList';
5
5
  interface CrmDealCardProps {
6
- deal: Deal;
7
- onClick?: () => void;
6
+ deal: Deal;
7
+ onClick?: () => void;
8
8
  }
9
- declare function CrmDealCard({
10
- deal,
11
- onClick
12
- }: CrmDealCardProps): react_jsx_runtime0.JSX.Element;
13
- //#endregion
14
- export { CrmDealCard };
9
+ export declare function CrmDealCard({ deal, onClick }: CrmDealCardProps): import("react/jsx-runtime").JSX.Element;
10
+ export {};
15
11
  //# sourceMappingURL=CrmDealCard.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CrmDealCard.d.ts","names":[],"sources":["../../src/ui/CrmDealCard.tsx"],"mappings":";;;;UAOU,gBAAA;EACR,IAAA,EAAM,IAAA;EACN,OAAA;AAAA;AAAA,iBAYc,WAAA,CAAA;EAAc,IAAA;EAAM;AAAA,GAAW,gBAAA,GAAgB,kBAAA,CAAA,GAAA,CAAA,OAAA"}
1
+ {"version":3,"file":"CrmDealCard.d.ts","sourceRoot":"","sources":["../../src/ui/CrmDealCard.tsx"],"names":[],"mappings":"AAEA;;GAEG;AACH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAEhD,UAAU,gBAAgB;IACxB,IAAI,EAAE,IAAI,CAAC;IACX,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAWD,wBAAgB,WAAW,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,gBAAgB,2CA6D9D"}
@@ -1,49 +1,51 @@
1
- 'use client';
2
-
3
- import { jsx, jsxs } from "react/jsx-runtime";
4
-
5
- //#region src/ui/CrmDealCard.tsx
1
+ // @bun
2
+ // src/ui/CrmDealCard.tsx
3
+ import { jsxDEV } from "react/jsx-dev-runtime";
4
+ "use client";
6
5
  function formatCurrency(value, currency) {
7
- return new Intl.NumberFormat("en-US", {
8
- style: "currency",
9
- currency,
10
- minimumFractionDigits: 0,
11
- maximumFractionDigits: 0
12
- }).format(value);
6
+ return new Intl.NumberFormat("en-US", {
7
+ style: "currency",
8
+ currency,
9
+ minimumFractionDigits: 0,
10
+ maximumFractionDigits: 0
11
+ }).format(value);
13
12
  }
14
13
  function CrmDealCard({ deal, onClick }) {
15
- const daysUntilClose = deal.expectedCloseDate ? Math.ceil((deal.expectedCloseDate.getTime() - Date.now()) / (1e3 * 60 * 60 * 24)) : null;
16
- return /* @__PURE__ */ jsxs("div", {
17
- onClick,
18
- className: "border-border bg-card cursor-pointer rounded-lg border p-3 shadow-sm transition-shadow hover:shadow-md",
19
- role: "button",
20
- tabIndex: 0,
21
- onKeyDown: (e) => {
22
- if (e.key === "Enter" || e.key === " ") onClick?.();
23
- },
24
- children: [
25
- /* @__PURE__ */ jsx("h4", {
26
- className: "leading-snug font-medium",
27
- children: deal.name
28
- }),
29
- /* @__PURE__ */ jsx("div", {
30
- className: "text-primary mt-2 text-lg font-semibold",
31
- children: formatCurrency(deal.value, deal.currency)
32
- }),
33
- /* @__PURE__ */ jsxs("div", {
34
- className: "text-muted-foreground mt-3 flex items-center justify-between text-xs",
35
- children: [daysUntilClose !== null && /* @__PURE__ */ jsx("span", {
36
- className: daysUntilClose < 0 ? "text-red-500" : daysUntilClose <= 7 ? "text-yellow-600 dark:text-yellow-500" : "",
37
- children: daysUntilClose < 0 ? `${Math.abs(daysUntilClose)}d overdue` : daysUntilClose === 0 ? "Due today" : `${daysUntilClose}d left`
38
- }), /* @__PURE__ */ jsx("span", {
39
- className: `rounded px-1.5 py-0.5 text-xs font-medium ${deal.status === "WON" ? "bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400" : deal.status === "LOST" ? "bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400" : "bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400"}`,
40
- children: deal.status
41
- })]
42
- })
43
- ]
44
- });
14
+ const daysUntilClose = deal.expectedCloseDate ? Math.ceil((deal.expectedCloseDate.getTime() - Date.now()) / (1000 * 60 * 60 * 24)) : null;
15
+ return /* @__PURE__ */ jsxDEV("div", {
16
+ onClick,
17
+ className: "border-border bg-card cursor-pointer rounded-lg border p-3 shadow-sm transition-shadow hover:shadow-md",
18
+ role: "button",
19
+ tabIndex: 0,
20
+ onKeyDown: (e) => {
21
+ if (e.key === "Enter" || e.key === " ")
22
+ onClick?.();
23
+ },
24
+ children: [
25
+ /* @__PURE__ */ jsxDEV("h4", {
26
+ className: "leading-snug font-medium",
27
+ children: deal.name
28
+ }, undefined, false, undefined, this),
29
+ /* @__PURE__ */ jsxDEV("div", {
30
+ className: "text-primary mt-2 text-lg font-semibold",
31
+ children: formatCurrency(deal.value, deal.currency)
32
+ }, undefined, false, undefined, this),
33
+ /* @__PURE__ */ jsxDEV("div", {
34
+ className: "text-muted-foreground mt-3 flex items-center justify-between text-xs",
35
+ children: [
36
+ daysUntilClose !== null && /* @__PURE__ */ jsxDEV("span", {
37
+ className: daysUntilClose < 0 ? "text-red-500" : daysUntilClose <= 7 ? "text-yellow-600 dark:text-yellow-500" : "",
38
+ children: daysUntilClose < 0 ? `${Math.abs(daysUntilClose)}d overdue` : daysUntilClose === 0 ? "Due today" : `${daysUntilClose}d left`
39
+ }, undefined, false, undefined, this),
40
+ /* @__PURE__ */ jsxDEV("span", {
41
+ className: `rounded px-1.5 py-0.5 text-xs font-medium ${deal.status === "WON" ? "bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400" : deal.status === "LOST" ? "bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400" : "bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400"}`,
42
+ children: deal.status
43
+ }, undefined, false, undefined, this)
44
+ ]
45
+ }, undefined, true, undefined, this)
46
+ ]
47
+ }, undefined, true, undefined, this);
45
48
  }
46
-
47
- //#endregion
48
- export { CrmDealCard };
49
- //# sourceMappingURL=CrmDealCard.js.map
49
+ export {
50
+ CrmDealCard
51
+ };
@@ -1,23 +1,14 @@
1
- import { Deal } from "./hooks/useDealList.js";
2
- import * as react_jsx_runtime0 from "react/jsx-runtime";
3
-
4
- //#region src/ui/CrmPipelineBoard.d.ts
1
+ import type { Deal } from './hooks/useDealList';
5
2
  interface CrmPipelineBoardProps {
6
- dealsByStage: Record<string, Deal[]>;
7
- stages: {
8
- id: string;
9
- name: string;
10
- position: number;
11
- }[];
12
- onDealClick?: (dealId: string) => void;
13
- onDealMove?: (dealId: string, toStageId: string) => void;
3
+ dealsByStage: Record<string, Deal[]>;
4
+ stages: {
5
+ id: string;
6
+ name: string;
7
+ position: number;
8
+ }[];
9
+ onDealClick?: (dealId: string) => void;
10
+ onDealMove?: (dealId: string, toStageId: string) => void;
14
11
  }
15
- declare function CrmPipelineBoard({
16
- dealsByStage,
17
- stages,
18
- onDealClick,
19
- onDealMove
20
- }: CrmPipelineBoardProps): react_jsx_runtime0.JSX.Element;
21
- //#endregion
22
- export { CrmPipelineBoard };
12
+ export declare function CrmPipelineBoard({ dealsByStage, stages, onDealClick, onDealMove, }: CrmPipelineBoardProps): import("react/jsx-runtime").JSX.Element;
13
+ export {};
23
14
  //# sourceMappingURL=CrmPipelineBoard.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CrmPipelineBoard.d.ts","names":[],"sources":["../../src/ui/CrmPipelineBoard.tsx"],"mappings":";;;;UAgBU,qBAAA;EACR,YAAA,EAAc,MAAA,SAAe,IAAA;EAC7B,MAAA;IAAU,EAAA;IAAY,IAAA;IAAc,QAAA;EAAA;EACpC,WAAA,IAAe,MAAA;EACf,UAAA,IAAc,MAAA,UAAgB,SAAA;AAAA;AAAA,iBAShB,gBAAA,CAAA;EACd,YAAA;EACA,MAAA;EACA,WAAA;EACA;AAAA,GACC,qBAAA,GAAqB,kBAAA,CAAA,GAAA,CAAA,OAAA"}
1
+ {"version":3,"file":"CrmPipelineBoard.d.ts","sourceRoot":"","sources":["../../src/ui/CrmPipelineBoard.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAGhD,UAAU,qBAAqB;IAC7B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IACrC,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACzD,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CAC1D;AAQD,wBAAgB,gBAAgB,CAAC,EAC/B,YAAY,EACZ,MAAM,EACN,WAAW,EACX,UAAU,GACX,EAAE,qBAAqB,2CAqGvB"}
@@ -1,98 +1,161 @@
1
- 'use client';
1
+ // @bun
2
+ // src/ui/CrmDealCard.tsx
3
+ import { jsxDEV } from "react/jsx-dev-runtime";
4
+ "use client";
5
+ function formatCurrency(value, currency) {
6
+ return new Intl.NumberFormat("en-US", {
7
+ style: "currency",
8
+ currency,
9
+ minimumFractionDigits: 0,
10
+ maximumFractionDigits: 0
11
+ }).format(value);
12
+ }
13
+ function CrmDealCard({ deal, onClick }) {
14
+ const daysUntilClose = deal.expectedCloseDate ? Math.ceil((deal.expectedCloseDate.getTime() - Date.now()) / (1000 * 60 * 60 * 24)) : null;
15
+ return /* @__PURE__ */ jsxDEV("div", {
16
+ onClick,
17
+ className: "border-border bg-card cursor-pointer rounded-lg border p-3 shadow-sm transition-shadow hover:shadow-md",
18
+ role: "button",
19
+ tabIndex: 0,
20
+ onKeyDown: (e) => {
21
+ if (e.key === "Enter" || e.key === " ")
22
+ onClick?.();
23
+ },
24
+ children: [
25
+ /* @__PURE__ */ jsxDEV("h4", {
26
+ className: "leading-snug font-medium",
27
+ children: deal.name
28
+ }, undefined, false, undefined, this),
29
+ /* @__PURE__ */ jsxDEV("div", {
30
+ className: "text-primary mt-2 text-lg font-semibold",
31
+ children: formatCurrency(deal.value, deal.currency)
32
+ }, undefined, false, undefined, this),
33
+ /* @__PURE__ */ jsxDEV("div", {
34
+ className: "text-muted-foreground mt-3 flex items-center justify-between text-xs",
35
+ children: [
36
+ daysUntilClose !== null && /* @__PURE__ */ jsxDEV("span", {
37
+ className: daysUntilClose < 0 ? "text-red-500" : daysUntilClose <= 7 ? "text-yellow-600 dark:text-yellow-500" : "",
38
+ children: daysUntilClose < 0 ? `${Math.abs(daysUntilClose)}d overdue` : daysUntilClose === 0 ? "Due today" : `${daysUntilClose}d left`
39
+ }, undefined, false, undefined, this),
40
+ /* @__PURE__ */ jsxDEV("span", {
41
+ className: `rounded px-1.5 py-0.5 text-xs font-medium ${deal.status === "WON" ? "bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400" : deal.status === "LOST" ? "bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400" : "bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400"}`,
42
+ children: deal.status
43
+ }, undefined, false, undefined, this)
44
+ ]
45
+ }, undefined, true, undefined, this)
46
+ ]
47
+ }, undefined, true, undefined, this);
48
+ }
2
49
 
3
- import { CrmDealCard } from "./CrmDealCard.js";
50
+ // src/ui/CrmPipelineBoard.tsx
4
51
  import { useState } from "react";
5
- import { jsx, jsxs } from "react/jsx-runtime";
6
-
7
- //#region src/ui/CrmPipelineBoard.tsx
8
- /**
9
- * CRM Pipeline Board - Kanban-style deal board
10
- *
11
- * Features:
12
- * - Visual pipeline stages
13
- * - Deal cards with click actions
14
- * - Quick move dropdown per card
15
- * - Drag-and-drop ready (UI only, no lib dependency)
16
- */
17
- function formatCurrency(value) {
18
- if (value >= 1e6) return `$${(value / 1e6).toFixed(1)}M`;
19
- if (value >= 1e3) return `$${(value / 1e3).toFixed(0)}K`;
20
- return `$${value}`;
52
+ import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
53
+ "use client";
54
+ function formatCurrency2(value) {
55
+ if (value >= 1e6)
56
+ return `$${(value / 1e6).toFixed(1)}M`;
57
+ if (value >= 1000)
58
+ return `$${(value / 1000).toFixed(0)}K`;
59
+ return `$${value}`;
21
60
  }
22
- function CrmPipelineBoard({ dealsByStage, stages, onDealClick, onDealMove }) {
23
- const [quickMoveOpen, setQuickMoveOpen] = useState(null);
24
- const sortedStages = [...stages].sort((a, b) => a.position - b.position);
25
- const handleQuickMove = (dealId, toStageId) => {
26
- onDealMove?.(dealId, toStageId);
27
- setQuickMoveOpen(null);
28
- };
29
- return /* @__PURE__ */ jsx("div", {
30
- className: "flex gap-4 overflow-x-auto pb-4",
31
- children: sortedStages.map((stage) => {
32
- const deals = dealsByStage[stage.id] ?? [];
33
- const stageValue = deals.reduce((sum, d) => sum + d.value, 0);
34
- return /* @__PURE__ */ jsxs("div", {
35
- className: "bg-muted/30 flex w-72 flex-shrink-0 flex-col rounded-lg",
36
- children: [/* @__PURE__ */ jsxs("div", {
37
- className: "border-border flex items-center justify-between border-b px-3 py-2",
38
- children: [/* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("h3", {
39
- className: "font-medium",
40
- children: stage.name
41
- }), /* @__PURE__ */ jsxs("p", {
42
- className: "text-muted-foreground text-xs",
43
- children: [
44
- deals.length,
45
- " deals · ",
46
- formatCurrency(stageValue)
47
- ]
48
- })] }), /* @__PURE__ */ jsx("span", {
49
- className: "bg-muted flex h-6 w-6 items-center justify-center rounded-full text-xs font-medium",
50
- children: deals.length
51
- })]
52
- }), /* @__PURE__ */ jsx("div", {
53
- className: "flex flex-1 flex-col gap-2 p-2",
54
- children: deals.length === 0 ? /* @__PURE__ */ jsx("div", {
55
- className: "border-muted-foreground/20 text-muted-foreground flex h-24 items-center justify-center rounded-md border-2 border-dashed text-xs",
56
- children: "No deals"
57
- }) : deals.map((deal) => /* @__PURE__ */ jsxs("div", {
58
- className: "group relative",
59
- children: [/* @__PURE__ */ jsx(CrmDealCard, {
60
- deal,
61
- onClick: () => onDealClick?.(deal.id)
62
- }), deal.status === "OPEN" && onDealMove && /* @__PURE__ */ jsxs("div", {
63
- className: "absolute top-1 right-1 opacity-0 transition-opacity group-hover:opacity-100",
64
- children: [/* @__PURE__ */ jsx("button", {
65
- type: "button",
66
- onClick: (e) => {
67
- e.stopPropagation();
68
- setQuickMoveOpen(quickMoveOpen === deal.id ? null : deal.id);
69
- },
70
- className: "bg-background border-border hover:bg-muted flex h-6 w-6 items-center justify-center rounded border text-xs shadow-sm",
71
- title: "Quick move",
72
- children: "➡️"
73
- }), quickMoveOpen === deal.id && /* @__PURE__ */ jsxs("div", {
74
- className: "bg-card border-border absolute top-7 right-0 z-20 min-w-[140px] rounded-lg border py-1 shadow-lg",
75
- children: [/* @__PURE__ */ jsx("p", {
76
- className: "text-muted-foreground px-3 py-1 text-xs font-medium",
77
- children: "Move to:"
78
- }), sortedStages.filter((s) => s.id !== deal.stageId).map((s) => /* @__PURE__ */ jsx("button", {
79
- type: "button",
80
- onClick: (e) => {
81
- e.stopPropagation();
82
- handleQuickMove(deal.id, s.id);
83
- },
84
- className: "hover:bg-muted w-full px-3 py-1.5 text-left text-sm",
85
- children: s.name
86
- }, s.id))]
87
- })]
88
- })]
89
- }, deal.id))
90
- })]
91
- }, stage.id);
92
- })
93
- });
61
+ function CrmPipelineBoard({
62
+ dealsByStage,
63
+ stages,
64
+ onDealClick,
65
+ onDealMove
66
+ }) {
67
+ const [quickMoveOpen, setQuickMoveOpen] = useState(null);
68
+ const sortedStages = [...stages].sort((a, b) => a.position - b.position);
69
+ const handleQuickMove = (dealId, toStageId) => {
70
+ onDealMove?.(dealId, toStageId);
71
+ setQuickMoveOpen(null);
72
+ };
73
+ return /* @__PURE__ */ jsxDEV2("div", {
74
+ className: "flex gap-4 overflow-x-auto pb-4",
75
+ children: sortedStages.map((stage) => {
76
+ const deals = dealsByStage[stage.id] ?? [];
77
+ const stageValue = deals.reduce((sum, d) => sum + d.value, 0);
78
+ return /* @__PURE__ */ jsxDEV2("div", {
79
+ className: "bg-muted/30 flex w-72 flex-shrink-0 flex-col rounded-lg",
80
+ children: [
81
+ /* @__PURE__ */ jsxDEV2("div", {
82
+ className: "border-border flex items-center justify-between border-b px-3 py-2",
83
+ children: [
84
+ /* @__PURE__ */ jsxDEV2("div", {
85
+ children: [
86
+ /* @__PURE__ */ jsxDEV2("h3", {
87
+ className: "font-medium",
88
+ children: stage.name
89
+ }, undefined, false, undefined, this),
90
+ /* @__PURE__ */ jsxDEV2("p", {
91
+ className: "text-muted-foreground text-xs",
92
+ children: [
93
+ deals.length,
94
+ " deals \xB7 ",
95
+ formatCurrency2(stageValue)
96
+ ]
97
+ }, undefined, true, undefined, this)
98
+ ]
99
+ }, undefined, true, undefined, this),
100
+ /* @__PURE__ */ jsxDEV2("span", {
101
+ className: "bg-muted flex h-6 w-6 items-center justify-center rounded-full text-xs font-medium",
102
+ children: deals.length
103
+ }, undefined, false, undefined, this)
104
+ ]
105
+ }, undefined, true, undefined, this),
106
+ /* @__PURE__ */ jsxDEV2("div", {
107
+ className: "flex flex-1 flex-col gap-2 p-2",
108
+ children: deals.length === 0 ? /* @__PURE__ */ jsxDEV2("div", {
109
+ className: "border-muted-foreground/20 text-muted-foreground flex h-24 items-center justify-center rounded-md border-2 border-dashed text-xs",
110
+ children: "No deals"
111
+ }, undefined, false, undefined, this) : deals.map((deal) => /* @__PURE__ */ jsxDEV2("div", {
112
+ className: "group relative",
113
+ children: [
114
+ /* @__PURE__ */ jsxDEV2(CrmDealCard, {
115
+ deal,
116
+ onClick: () => onDealClick?.(deal.id)
117
+ }, undefined, false, undefined, this),
118
+ deal.status === "OPEN" && onDealMove && /* @__PURE__ */ jsxDEV2("div", {
119
+ className: "absolute top-1 right-1 opacity-0 transition-opacity group-hover:opacity-100",
120
+ children: [
121
+ /* @__PURE__ */ jsxDEV2("button", {
122
+ type: "button",
123
+ onClick: (e) => {
124
+ e.stopPropagation();
125
+ setQuickMoveOpen(quickMoveOpen === deal.id ? null : deal.id);
126
+ },
127
+ className: "bg-background border-border hover:bg-muted flex h-6 w-6 items-center justify-center rounded border text-xs shadow-sm",
128
+ title: "Quick move",
129
+ children: "\u27A1\uFE0F"
130
+ }, undefined, false, undefined, this),
131
+ quickMoveOpen === deal.id && /* @__PURE__ */ jsxDEV2("div", {
132
+ className: "bg-card border-border absolute top-7 right-0 z-20 min-w-[140px] rounded-lg border py-1 shadow-lg",
133
+ children: [
134
+ /* @__PURE__ */ jsxDEV2("p", {
135
+ className: "text-muted-foreground px-3 py-1 text-xs font-medium",
136
+ children: "Move to:"
137
+ }, undefined, false, undefined, this),
138
+ sortedStages.filter((s) => s.id !== deal.stageId).map((s) => /* @__PURE__ */ jsxDEV2("button", {
139
+ type: "button",
140
+ onClick: (e) => {
141
+ e.stopPropagation();
142
+ handleQuickMove(deal.id, s.id);
143
+ },
144
+ className: "hover:bg-muted w-full px-3 py-1.5 text-left text-sm",
145
+ children: s.name
146
+ }, s.id, false, undefined, this))
147
+ ]
148
+ }, undefined, true, undefined, this)
149
+ ]
150
+ }, undefined, true, undefined, this)
151
+ ]
152
+ }, deal.id, true, undefined, this))
153
+ }, undefined, false, undefined, this)
154
+ ]
155
+ }, stage.id, true, undefined, this);
156
+ })
157
+ }, undefined, false, undefined, this);
94
158
  }
95
-
96
- //#endregion
97
- export { CrmPipelineBoard };
98
- //# sourceMappingURL=CrmPipelineBoard.js.map
159
+ export {
160
+ CrmPipelineBoard
161
+ };
@@ -1,3 +1,3 @@
1
- import { UseDealListOptions, useDealList } from "./useDealList.js";
2
- import { UseDealMutationsOptions, useDealMutations } from "./useDealMutations.js";
3
- export { type UseDealListOptions, type UseDealMutationsOptions, useDealList, useDealMutations };
1
+ export { useDealList, type UseDealListOptions } from './useDealList';
2
+ export { useDealMutations, type UseDealMutationsOptions, } from './useDealMutations';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui/hooks/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,KAAK,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACrE,OAAO,EACL,gBAAgB,EAChB,KAAK,uBAAuB,GAC7B,MAAM,oBAAoB,CAAC"}
@@ -1,6 +1,187 @@
1
- 'use client';
1
+ // @bun
2
+ // src/ui/hooks/useDealList.ts
3
+ import { useCallback, useEffect, useMemo, useState } from "react";
4
+ import { useTemplateRuntime } from "@contractspec/lib.example-shared-ui";
5
+ "use client";
6
+ function useDealList(options = {}) {
7
+ const { handlers, projectId } = useTemplateRuntime();
8
+ const { crm } = handlers;
9
+ const [data, setData] = useState(null);
10
+ const [dealsByStage, setDealsByStage] = useState({});
11
+ const [stages, setStages] = useState([]);
12
+ const [loading, setLoading] = useState(true);
13
+ const [error, setError] = useState(null);
14
+ const [page, setPage] = useState(1);
15
+ const pipelineId = options.pipelineId ?? "pipeline-1";
16
+ const fetchData = useCallback(async () => {
17
+ setLoading(true);
18
+ setError(null);
19
+ try {
20
+ const [dealsResult, stageDealsResult, stagesResult] = await Promise.all([
21
+ crm.listDeals({
22
+ projectId,
23
+ pipelineId,
24
+ stageId: options.stageId,
25
+ status: options.status === "all" ? undefined : options.status,
26
+ search: options.search,
27
+ limit: options.limit ?? 50,
28
+ offset: (page - 1) * (options.limit ?? 50)
29
+ }),
30
+ crm.getDealsByStage({ projectId, pipelineId }),
31
+ crm.getPipelineStages({ pipelineId })
32
+ ]);
33
+ setData(dealsResult);
34
+ setDealsByStage(stageDealsResult);
35
+ setStages(stagesResult);
36
+ } catch (err) {
37
+ setError(err instanceof Error ? err : new Error("Unknown error"));
38
+ } finally {
39
+ setLoading(false);
40
+ }
41
+ }, [
42
+ crm,
43
+ projectId,
44
+ pipelineId,
45
+ options.stageId,
46
+ options.status,
47
+ options.search,
48
+ options.limit,
49
+ page
50
+ ]);
51
+ useEffect(() => {
52
+ fetchData();
53
+ }, [fetchData]);
54
+ const stats = useMemo(() => {
55
+ if (!data)
56
+ return null;
57
+ const open = data.deals.filter((d) => d.status === "OPEN");
58
+ const won = data.deals.filter((d) => d.status === "WON");
59
+ const lost = data.deals.filter((d) => d.status === "LOST");
60
+ return {
61
+ total: data.total,
62
+ totalValue: data.totalValue,
63
+ openCount: open.length,
64
+ openValue: open.reduce((sum, d) => sum + d.value, 0),
65
+ wonCount: won.length,
66
+ wonValue: won.reduce((sum, d) => sum + d.value, 0),
67
+ lostCount: lost.length
68
+ };
69
+ }, [data]);
70
+ return {
71
+ data,
72
+ dealsByStage,
73
+ stages,
74
+ loading,
75
+ error,
76
+ stats,
77
+ page,
78
+ refetch: fetchData,
79
+ nextPage: () => setPage((p) => p + 1),
80
+ prevPage: () => page > 1 && setPage((p) => p - 1)
81
+ };
82
+ }
2
83
 
3
- import { useDealList } from "./useDealList.js";
4
- import { useDealMutations } from "./useDealMutations.js";
84
+ // src/ui/hooks/useDealMutations.ts
85
+ import { useCallback as useCallback2, useState as useState2 } from "react";
86
+ import { useTemplateRuntime as useTemplateRuntime2 } from "@contractspec/lib.example-shared-ui";
87
+ function useDealMutations(options = {}) {
88
+ const { handlers, projectId } = useTemplateRuntime2();
89
+ const { crm } = handlers;
90
+ const [createState, setCreateState] = useState2({
91
+ loading: false,
92
+ error: null,
93
+ data: null
94
+ });
95
+ const [moveState, setMoveState] = useState2({
96
+ loading: false,
97
+ error: null,
98
+ data: null
99
+ });
100
+ const [winState, setWinState] = useState2({
101
+ loading: false,
102
+ error: null,
103
+ data: null
104
+ });
105
+ const [loseState, setLoseState] = useState2({
106
+ loading: false,
107
+ error: null,
108
+ data: null
109
+ });
110
+ const createDeal = useCallback2(async (input) => {
111
+ setCreateState({ loading: true, error: null, data: null });
112
+ try {
113
+ const result = await crm.createDeal(input, {
114
+ projectId,
115
+ ownerId: "user-1"
116
+ });
117
+ setCreateState({ loading: false, error: null, data: result });
118
+ options.onSuccess?.();
119
+ return result;
120
+ } catch (err) {
121
+ const error = err instanceof Error ? err : new Error("Failed to create deal");
122
+ setCreateState({ loading: false, error, data: null });
123
+ options.onError?.(error);
124
+ return null;
125
+ }
126
+ }, [crm, projectId, options]);
127
+ const moveDeal = useCallback2(async (input) => {
128
+ setMoveState({ loading: true, error: null, data: null });
129
+ try {
130
+ const result = await crm.moveDeal(input);
131
+ setMoveState({ loading: false, error: null, data: result });
132
+ options.onSuccess?.();
133
+ return result;
134
+ } catch (err) {
135
+ const error = err instanceof Error ? err : new Error("Failed to move deal");
136
+ setMoveState({ loading: false, error, data: null });
137
+ options.onError?.(error);
138
+ return null;
139
+ }
140
+ }, [crm, options]);
141
+ const winDeal = useCallback2(async (input) => {
142
+ setWinState({ loading: true, error: null, data: null });
143
+ try {
144
+ const result = await crm.winDeal(input);
145
+ setWinState({ loading: false, error: null, data: result });
146
+ options.onSuccess?.();
147
+ return result;
148
+ } catch (err) {
149
+ const error = err instanceof Error ? err : new Error("Failed to mark deal as won");
150
+ setWinState({ loading: false, error, data: null });
151
+ options.onError?.(error);
152
+ return null;
153
+ }
154
+ }, [crm, options]);
155
+ const loseDeal = useCallback2(async (input) => {
156
+ setLoseState({ loading: true, error: null, data: null });
157
+ try {
158
+ const result = await crm.loseDeal(input);
159
+ setLoseState({ loading: false, error: null, data: result });
160
+ options.onSuccess?.();
161
+ return result;
162
+ } catch (err) {
163
+ const error = err instanceof Error ? err : new Error("Failed to mark deal as lost");
164
+ setLoseState({ loading: false, error, data: null });
165
+ options.onError?.(error);
166
+ return null;
167
+ }
168
+ }, [crm, options]);
169
+ return {
170
+ createDeal,
171
+ moveDeal,
172
+ winDeal,
173
+ loseDeal,
174
+ createState,
175
+ moveState,
176
+ winState,
177
+ loseState,
178
+ isLoading: createState.loading || moveState.loading || winState.loading || loseState.loading
179
+ };
180
+ }
5
181
 
6
- export { useDealList, useDealMutations };
182
+ // src/ui/hooks/index.ts
183
+ "use client";
184
+ export {
185
+ useDealMutations,
186
+ useDealList
187
+ };