@contractspec/example.crm-pipeline 1.57.0 → 1.58.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 +20 -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,3 +1,3 @@
1
- import { CreateDealModal } from "./CreateDealModal.js";
2
- import { DealActionsModal } from "./DealActionsModal.js";
3
- export { CreateDealModal, DealActionsModal };
1
+ export { CreateDealModal } from './CreateDealModal';
2
+ export { DealActionsModal } from './DealActionsModal';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui/modals/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC"}
@@ -1,4 +1,639 @@
1
- import { CreateDealModal } from "./CreateDealModal.js";
2
- import { DealActionsModal } from "./DealActionsModal.js";
1
+ // @bun
2
+ // src/ui/modals/CreateDealModal.tsx
3
+ import { useState } from "react";
4
+ import { Button, Input } from "@contractspec/lib.design-system";
5
+ import { jsxDEV } from "react/jsx-dev-runtime";
6
+ "use client";
7
+ var CURRENCIES = ["USD", "EUR", "GBP", "CAD"];
8
+ var DEFAULT_PIPELINE_ID = "pipeline-1";
9
+ function CreateDealModal({
10
+ isOpen,
11
+ onClose,
12
+ onSubmit,
13
+ stages,
14
+ isLoading = false
15
+ }) {
16
+ const [name, setName] = useState("");
17
+ const [value, setValue] = useState("");
18
+ const [currency, setCurrency] = useState("USD");
19
+ const [stageId, setStageId] = useState(stages[0]?.id ?? "");
20
+ const [expectedCloseDate, setExpectedCloseDate] = useState("");
21
+ const [error, setError] = useState(null);
22
+ const handleSubmit = async (e) => {
23
+ e.preventDefault();
24
+ setError(null);
25
+ if (!name.trim()) {
26
+ setError("Deal name is required");
27
+ return;
28
+ }
29
+ const numericValue = parseFloat(value);
30
+ if (isNaN(numericValue) || numericValue <= 0) {
31
+ setError("Value must be a positive number");
32
+ return;
33
+ }
34
+ if (!stageId) {
35
+ setError("Please select a pipeline stage");
36
+ return;
37
+ }
38
+ try {
39
+ await onSubmit({
40
+ name: name.trim(),
41
+ value: numericValue,
42
+ currency,
43
+ pipelineId: DEFAULT_PIPELINE_ID,
44
+ stageId,
45
+ expectedCloseDate: expectedCloseDate ? new Date(expectedCloseDate) : undefined
46
+ });
47
+ setName("");
48
+ setValue("");
49
+ setCurrency("USD");
50
+ setStageId(stages[0]?.id ?? "");
51
+ setExpectedCloseDate("");
52
+ onClose();
53
+ } catch (err) {
54
+ setError(err instanceof Error ? err.message : "Failed to create deal");
55
+ }
56
+ };
57
+ if (!isOpen)
58
+ return null;
59
+ return /* @__PURE__ */ jsxDEV("div", {
60
+ className: "fixed inset-0 z-50 flex items-center justify-center",
61
+ children: [
62
+ /* @__PURE__ */ jsxDEV("div", {
63
+ className: "bg-background/80 absolute inset-0 backdrop-blur-sm",
64
+ onClick: onClose,
65
+ role: "button",
66
+ tabIndex: 0,
67
+ onKeyDown: (e) => {
68
+ if (e.key === "Enter" || e.key === " ")
69
+ onClose();
70
+ },
71
+ "aria-label": "Close modal"
72
+ }, undefined, false, undefined, this),
73
+ /* @__PURE__ */ jsxDEV("div", {
74
+ className: "bg-card border-border relative z-10 w-full max-w-md rounded-xl border p-6 shadow-xl",
75
+ children: [
76
+ /* @__PURE__ */ jsxDEV("h2", {
77
+ className: "mb-4 text-xl font-semibold",
78
+ children: "Create New Deal"
79
+ }, undefined, false, undefined, this),
80
+ /* @__PURE__ */ jsxDEV("form", {
81
+ onSubmit: handleSubmit,
82
+ className: "space-y-4",
83
+ children: [
84
+ /* @__PURE__ */ jsxDEV("div", {
85
+ children: [
86
+ /* @__PURE__ */ jsxDEV("label", {
87
+ htmlFor: "deal-name",
88
+ className: "text-muted-foreground mb-1 block text-sm font-medium",
89
+ children: "Deal Name *"
90
+ }, undefined, false, undefined, this),
91
+ /* @__PURE__ */ jsxDEV(Input, {
92
+ id: "deal-name",
93
+ value: name,
94
+ onChange: (e) => setName(e.target.value),
95
+ placeholder: "e.g., Enterprise License - Acme Corp",
96
+ disabled: isLoading
97
+ }, undefined, false, undefined, this)
98
+ ]
99
+ }, undefined, true, undefined, this),
100
+ /* @__PURE__ */ jsxDEV("div", {
101
+ className: "flex gap-3",
102
+ children: [
103
+ /* @__PURE__ */ jsxDEV("div", {
104
+ className: "flex-1",
105
+ children: [
106
+ /* @__PURE__ */ jsxDEV("label", {
107
+ htmlFor: "deal-value",
108
+ className: "text-muted-foreground mb-1 block text-sm font-medium",
109
+ children: "Value *"
110
+ }, undefined, false, undefined, this),
111
+ /* @__PURE__ */ jsxDEV(Input, {
112
+ id: "deal-value",
113
+ type: "number",
114
+ min: "0",
115
+ step: "0.01",
116
+ value,
117
+ onChange: (e) => setValue(e.target.value),
118
+ placeholder: "50000",
119
+ disabled: isLoading
120
+ }, undefined, false, undefined, this)
121
+ ]
122
+ }, undefined, true, undefined, this),
123
+ /* @__PURE__ */ jsxDEV("div", {
124
+ className: "w-24",
125
+ children: [
126
+ /* @__PURE__ */ jsxDEV("label", {
127
+ htmlFor: "deal-currency",
128
+ className: "text-muted-foreground mb-1 block text-sm font-medium",
129
+ children: "Currency"
130
+ }, undefined, false, undefined, this),
131
+ /* @__PURE__ */ jsxDEV("select", {
132
+ id: "deal-currency",
133
+ value: currency,
134
+ onChange: (e) => setCurrency(e.target.value),
135
+ disabled: isLoading,
136
+ className: "border-input bg-background focus:ring-ring h-10 w-full rounded-md border px-3 py-2 text-sm focus:ring-2 focus:outline-none disabled:opacity-50",
137
+ children: CURRENCIES.map((c) => /* @__PURE__ */ jsxDEV("option", {
138
+ value: c,
139
+ children: c
140
+ }, c, false, undefined, this))
141
+ }, undefined, false, undefined, this)
142
+ ]
143
+ }, undefined, true, undefined, this)
144
+ ]
145
+ }, undefined, true, undefined, this),
146
+ /* @__PURE__ */ jsxDEV("div", {
147
+ children: [
148
+ /* @__PURE__ */ jsxDEV("label", {
149
+ htmlFor: "deal-stage",
150
+ className: "text-muted-foreground mb-1 block text-sm font-medium",
151
+ children: "Pipeline Stage *"
152
+ }, undefined, false, undefined, this),
153
+ /* @__PURE__ */ jsxDEV("select", {
154
+ id: "deal-stage",
155
+ value: stageId,
156
+ onChange: (e) => setStageId(e.target.value),
157
+ disabled: isLoading,
158
+ className: "border-input bg-background focus:ring-ring h-10 w-full rounded-md border px-3 py-2 text-sm focus:ring-2 focus:outline-none disabled:opacity-50",
159
+ children: stages.map((stage) => /* @__PURE__ */ jsxDEV("option", {
160
+ value: stage.id,
161
+ children: stage.name
162
+ }, stage.id, false, undefined, this))
163
+ }, undefined, false, undefined, this)
164
+ ]
165
+ }, undefined, true, undefined, this),
166
+ /* @__PURE__ */ jsxDEV("div", {
167
+ children: [
168
+ /* @__PURE__ */ jsxDEV("label", {
169
+ htmlFor: "deal-close-date",
170
+ className: "text-muted-foreground mb-1 block text-sm font-medium",
171
+ children: "Expected Close Date"
172
+ }, undefined, false, undefined, this),
173
+ /* @__PURE__ */ jsxDEV(Input, {
174
+ id: "deal-close-date",
175
+ type: "date",
176
+ value: expectedCloseDate,
177
+ onChange: (e) => setExpectedCloseDate(e.target.value),
178
+ disabled: isLoading
179
+ }, undefined, false, undefined, this)
180
+ ]
181
+ }, undefined, true, undefined, this),
182
+ error && /* @__PURE__ */ jsxDEV("div", {
183
+ className: "bg-destructive/10 text-destructive rounded-md p-3 text-sm",
184
+ children: error
185
+ }, undefined, false, undefined, this),
186
+ /* @__PURE__ */ jsxDEV("div", {
187
+ className: "flex justify-end gap-3 pt-2",
188
+ children: [
189
+ /* @__PURE__ */ jsxDEV(Button, {
190
+ type: "button",
191
+ variant: "ghost",
192
+ onPress: onClose,
193
+ disabled: isLoading,
194
+ children: "Cancel"
195
+ }, undefined, false, undefined, this),
196
+ /* @__PURE__ */ jsxDEV(Button, {
197
+ type: "submit",
198
+ disabled: isLoading,
199
+ children: isLoading ? "Creating..." : "Create Deal"
200
+ }, undefined, false, undefined, this)
201
+ ]
202
+ }, undefined, true, undefined, this)
203
+ ]
204
+ }, undefined, true, undefined, this)
205
+ ]
206
+ }, undefined, true, undefined, this)
207
+ ]
208
+ }, undefined, true, undefined, this);
209
+ }
3
210
 
4
- export { CreateDealModal, DealActionsModal };
211
+ // src/ui/modals/DealActionsModal.tsx
212
+ import { useState as useState2 } from "react";
213
+ import { Button as Button2 } from "@contractspec/lib.design-system";
214
+ import { jsxDEV as jsxDEV2, Fragment } from "react/jsx-dev-runtime";
215
+ "use client";
216
+ function formatCurrency(value, currency) {
217
+ return new Intl.NumberFormat("en-US", {
218
+ style: "currency",
219
+ currency,
220
+ minimumFractionDigits: 0,
221
+ maximumFractionDigits: 0
222
+ }).format(value);
223
+ }
224
+ function DealActionsModal({
225
+ isOpen,
226
+ deal,
227
+ stages,
228
+ onClose,
229
+ onWin,
230
+ onLose,
231
+ onMove,
232
+ isLoading = false
233
+ }) {
234
+ const [mode, setMode] = useState2("menu");
235
+ const [wonSource, setWonSource] = useState2("");
236
+ const [lostReason, setLostReason] = useState2("");
237
+ const [notes, setNotes] = useState2("");
238
+ const [selectedStageId, setSelectedStageId] = useState2("");
239
+ const [error, setError] = useState2(null);
240
+ const resetForm = () => {
241
+ setMode("menu");
242
+ setWonSource("");
243
+ setLostReason("");
244
+ setNotes("");
245
+ setSelectedStageId("");
246
+ setError(null);
247
+ };
248
+ const handleClose = () => {
249
+ resetForm();
250
+ onClose();
251
+ };
252
+ const handleWin = async () => {
253
+ if (!deal)
254
+ return;
255
+ setError(null);
256
+ try {
257
+ await onWin({
258
+ dealId: deal.id,
259
+ wonSource: wonSource.trim() || undefined,
260
+ notes: notes.trim() || undefined
261
+ });
262
+ handleClose();
263
+ } catch (err) {
264
+ setError(err instanceof Error ? err.message : "Failed to mark deal as won");
265
+ }
266
+ };
267
+ const handleLose = async () => {
268
+ if (!deal)
269
+ return;
270
+ setError(null);
271
+ if (!lostReason.trim()) {
272
+ setError("Please provide a reason for losing the deal");
273
+ return;
274
+ }
275
+ try {
276
+ await onLose({
277
+ dealId: deal.id,
278
+ lostReason: lostReason.trim(),
279
+ notes: notes.trim() || undefined
280
+ });
281
+ handleClose();
282
+ } catch (err) {
283
+ setError(err instanceof Error ? err.message : "Failed to mark deal as lost");
284
+ }
285
+ };
286
+ const handleMove = async () => {
287
+ if (!deal)
288
+ return;
289
+ setError(null);
290
+ if (!selectedStageId) {
291
+ setError("Please select a stage");
292
+ return;
293
+ }
294
+ if (selectedStageId === deal.stageId) {
295
+ setError("Deal is already in this stage");
296
+ return;
297
+ }
298
+ try {
299
+ await onMove({
300
+ dealId: deal.id,
301
+ stageId: selectedStageId
302
+ });
303
+ handleClose();
304
+ } catch (err) {
305
+ setError(err instanceof Error ? err.message : "Failed to move deal");
306
+ }
307
+ };
308
+ if (!isOpen || !deal)
309
+ return null;
310
+ return /* @__PURE__ */ jsxDEV2("div", {
311
+ className: "fixed inset-0 z-50 flex items-center justify-center",
312
+ children: [
313
+ /* @__PURE__ */ jsxDEV2("div", {
314
+ className: "bg-background/80 absolute inset-0 backdrop-blur-sm",
315
+ onClick: handleClose,
316
+ role: "button",
317
+ tabIndex: 0,
318
+ onKeyDown: (e) => {
319
+ if (e.key === "Enter" || e.key === " ")
320
+ handleClose();
321
+ },
322
+ "aria-label": "Close modal"
323
+ }, undefined, false, undefined, this),
324
+ /* @__PURE__ */ jsxDEV2("div", {
325
+ className: "bg-card border-border relative z-10 w-full max-w-md rounded-xl border p-6 shadow-xl",
326
+ children: [
327
+ /* @__PURE__ */ jsxDEV2("div", {
328
+ className: "border-border mb-4 border-b pb-4",
329
+ children: [
330
+ /* @__PURE__ */ jsxDEV2("h2", {
331
+ className: "text-xl font-semibold",
332
+ children: deal.name
333
+ }, undefined, false, undefined, this),
334
+ /* @__PURE__ */ jsxDEV2("p", {
335
+ className: "text-primary text-lg font-medium",
336
+ children: formatCurrency(deal.value, deal.currency)
337
+ }, undefined, false, undefined, this),
338
+ /* @__PURE__ */ jsxDEV2("span", {
339
+ className: `mt-2 inline-flex rounded-full px-2 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"}`,
340
+ children: deal.status
341
+ }, undefined, false, undefined, this)
342
+ ]
343
+ }, undefined, true, undefined, this),
344
+ mode === "menu" && /* @__PURE__ */ jsxDEV2("div", {
345
+ className: "space-y-3",
346
+ children: [
347
+ deal.status === "OPEN" && /* @__PURE__ */ jsxDEV2(Fragment, {
348
+ children: [
349
+ /* @__PURE__ */ jsxDEV2(Button2, {
350
+ className: "w-full justify-start",
351
+ variant: "ghost",
352
+ onPress: () => setMode("win"),
353
+ children: [
354
+ /* @__PURE__ */ jsxDEV2("span", {
355
+ className: "mr-2",
356
+ children: "\uD83C\uDFC6"
357
+ }, undefined, false, undefined, this),
358
+ " Mark as Won"
359
+ ]
360
+ }, undefined, true, undefined, this),
361
+ /* @__PURE__ */ jsxDEV2(Button2, {
362
+ className: "w-full justify-start",
363
+ variant: "ghost",
364
+ onPress: () => setMode("lose"),
365
+ children: [
366
+ /* @__PURE__ */ jsxDEV2("span", {
367
+ className: "mr-2",
368
+ children: "\u274C"
369
+ }, undefined, false, undefined, this),
370
+ " Mark as Lost"
371
+ ]
372
+ }, undefined, true, undefined, this),
373
+ /* @__PURE__ */ jsxDEV2(Button2, {
374
+ className: "w-full justify-start",
375
+ variant: "ghost",
376
+ onPress: () => {
377
+ setSelectedStageId(deal.stageId);
378
+ setMode("move");
379
+ },
380
+ children: [
381
+ /* @__PURE__ */ jsxDEV2("span", {
382
+ className: "mr-2",
383
+ children: "\u27A1\uFE0F"
384
+ }, undefined, false, undefined, this),
385
+ " Move to Stage"
386
+ ]
387
+ }, undefined, true, undefined, this)
388
+ ]
389
+ }, undefined, true, undefined, this),
390
+ deal.status !== "OPEN" && /* @__PURE__ */ jsxDEV2("p", {
391
+ className: "text-muted-foreground py-4 text-center",
392
+ children: [
393
+ "This deal is already ",
394
+ deal.status.toLowerCase(),
395
+ ". No actions available."
396
+ ]
397
+ }, undefined, true, undefined, this),
398
+ /* @__PURE__ */ jsxDEV2("div", {
399
+ className: "border-border border-t pt-3",
400
+ children: /* @__PURE__ */ jsxDEV2(Button2, {
401
+ className: "w-full",
402
+ variant: "outline",
403
+ onPress: handleClose,
404
+ children: "Close"
405
+ }, undefined, false, undefined, this)
406
+ }, undefined, false, undefined, this)
407
+ ]
408
+ }, undefined, true, undefined, this),
409
+ mode === "win" && /* @__PURE__ */ jsxDEV2("div", {
410
+ className: "space-y-4",
411
+ children: [
412
+ /* @__PURE__ */ jsxDEV2("div", {
413
+ children: [
414
+ /* @__PURE__ */ jsxDEV2("label", {
415
+ htmlFor: "won-source",
416
+ className: "text-muted-foreground mb-1 block text-sm font-medium",
417
+ children: "How did you win this deal?"
418
+ }, undefined, false, undefined, this),
419
+ /* @__PURE__ */ jsxDEV2("select", {
420
+ id: "won-source",
421
+ value: wonSource,
422
+ onChange: (e) => setWonSource(e.target.value),
423
+ className: "border-input bg-background focus:ring-ring h-10 w-full rounded-md border px-3 py-2 text-sm focus:ring-2 focus:outline-none",
424
+ children: [
425
+ /* @__PURE__ */ jsxDEV2("option", {
426
+ value: "",
427
+ children: "Select a source..."
428
+ }, undefined, false, undefined, this),
429
+ /* @__PURE__ */ jsxDEV2("option", {
430
+ value: "referral",
431
+ children: "Referral"
432
+ }, undefined, false, undefined, this),
433
+ /* @__PURE__ */ jsxDEV2("option", {
434
+ value: "cold_outreach",
435
+ children: "Cold Outreach"
436
+ }, undefined, false, undefined, this),
437
+ /* @__PURE__ */ jsxDEV2("option", {
438
+ value: "inbound",
439
+ children: "Inbound Lead"
440
+ }, undefined, false, undefined, this),
441
+ /* @__PURE__ */ jsxDEV2("option", {
442
+ value: "upsell",
443
+ children: "Upsell"
444
+ }, undefined, false, undefined, this),
445
+ /* @__PURE__ */ jsxDEV2("option", {
446
+ value: "other",
447
+ children: "Other"
448
+ }, undefined, false, undefined, this)
449
+ ]
450
+ }, undefined, true, undefined, this)
451
+ ]
452
+ }, undefined, true, undefined, this),
453
+ /* @__PURE__ */ jsxDEV2("div", {
454
+ children: [
455
+ /* @__PURE__ */ jsxDEV2("label", {
456
+ htmlFor: "win-notes",
457
+ className: "text-muted-foreground mb-1 block text-sm font-medium",
458
+ children: "Notes (optional)"
459
+ }, undefined, false, undefined, this),
460
+ /* @__PURE__ */ jsxDEV2("textarea", {
461
+ id: "win-notes",
462
+ value: notes,
463
+ onChange: (e) => setNotes(e.target.value),
464
+ placeholder: "Any additional notes about the win...",
465
+ rows: 3,
466
+ className: "border-input bg-background focus:ring-ring w-full rounded-md border px-3 py-2 text-sm focus:ring-2 focus:outline-none"
467
+ }, undefined, false, undefined, this)
468
+ ]
469
+ }, undefined, true, undefined, this),
470
+ error && /* @__PURE__ */ jsxDEV2("div", {
471
+ className: "bg-destructive/10 text-destructive rounded-md p-3 text-sm",
472
+ children: error
473
+ }, undefined, false, undefined, this),
474
+ /* @__PURE__ */ jsxDEV2("div", {
475
+ className: "flex justify-end gap-3 pt-2",
476
+ children: [
477
+ /* @__PURE__ */ jsxDEV2(Button2, {
478
+ variant: "ghost",
479
+ onPress: () => setMode("menu"),
480
+ disabled: isLoading,
481
+ children: "Back"
482
+ }, undefined, false, undefined, this),
483
+ /* @__PURE__ */ jsxDEV2(Button2, {
484
+ onPress: handleWin,
485
+ disabled: isLoading,
486
+ children: isLoading ? "Processing..." : "\uD83C\uDFC6 Confirm Win"
487
+ }, undefined, false, undefined, this)
488
+ ]
489
+ }, undefined, true, undefined, this)
490
+ ]
491
+ }, undefined, true, undefined, this),
492
+ mode === "lose" && /* @__PURE__ */ jsxDEV2("div", {
493
+ className: "space-y-4",
494
+ children: [
495
+ /* @__PURE__ */ jsxDEV2("div", {
496
+ children: [
497
+ /* @__PURE__ */ jsxDEV2("label", {
498
+ htmlFor: "lost-reason",
499
+ className: "text-muted-foreground mb-1 block text-sm font-medium",
500
+ children: "Why was this deal lost? *"
501
+ }, undefined, false, undefined, this),
502
+ /* @__PURE__ */ jsxDEV2("select", {
503
+ id: "lost-reason",
504
+ value: lostReason,
505
+ onChange: (e) => setLostReason(e.target.value),
506
+ className: "border-input bg-background focus:ring-ring h-10 w-full rounded-md border px-3 py-2 text-sm focus:ring-2 focus:outline-none",
507
+ children: [
508
+ /* @__PURE__ */ jsxDEV2("option", {
509
+ value: "",
510
+ children: "Select a reason..."
511
+ }, undefined, false, undefined, this),
512
+ /* @__PURE__ */ jsxDEV2("option", {
513
+ value: "price",
514
+ children: "Price too high"
515
+ }, undefined, false, undefined, this),
516
+ /* @__PURE__ */ jsxDEV2("option", {
517
+ value: "competitor",
518
+ children: "Lost to competitor"
519
+ }, undefined, false, undefined, this),
520
+ /* @__PURE__ */ jsxDEV2("option", {
521
+ value: "no_budget",
522
+ children: "No budget"
523
+ }, undefined, false, undefined, this),
524
+ /* @__PURE__ */ jsxDEV2("option", {
525
+ value: "no_decision",
526
+ children: "No decision made"
527
+ }, undefined, false, undefined, this),
528
+ /* @__PURE__ */ jsxDEV2("option", {
529
+ value: "timing",
530
+ children: "Bad timing"
531
+ }, undefined, false, undefined, this),
532
+ /* @__PURE__ */ jsxDEV2("option", {
533
+ value: "product_fit",
534
+ children: "Product not a fit"
535
+ }, undefined, false, undefined, this),
536
+ /* @__PURE__ */ jsxDEV2("option", {
537
+ value: "other",
538
+ children: "Other"
539
+ }, undefined, false, undefined, this)
540
+ ]
541
+ }, undefined, true, undefined, this)
542
+ ]
543
+ }, undefined, true, undefined, this),
544
+ /* @__PURE__ */ jsxDEV2("div", {
545
+ children: [
546
+ /* @__PURE__ */ jsxDEV2("label", {
547
+ htmlFor: "lose-notes",
548
+ className: "text-muted-foreground mb-1 block text-sm font-medium",
549
+ children: "Notes (optional)"
550
+ }, undefined, false, undefined, this),
551
+ /* @__PURE__ */ jsxDEV2("textarea", {
552
+ id: "lose-notes",
553
+ value: notes,
554
+ onChange: (e) => setNotes(e.target.value),
555
+ placeholder: "Any additional details...",
556
+ rows: 3,
557
+ className: "border-input bg-background focus:ring-ring w-full rounded-md border px-3 py-2 text-sm focus:ring-2 focus:outline-none"
558
+ }, undefined, false, undefined, this)
559
+ ]
560
+ }, undefined, true, undefined, this),
561
+ error && /* @__PURE__ */ jsxDEV2("div", {
562
+ className: "bg-destructive/10 text-destructive rounded-md p-3 text-sm",
563
+ children: error
564
+ }, undefined, false, undefined, this),
565
+ /* @__PURE__ */ jsxDEV2("div", {
566
+ className: "flex justify-end gap-3 pt-2",
567
+ children: [
568
+ /* @__PURE__ */ jsxDEV2(Button2, {
569
+ variant: "ghost",
570
+ onPress: () => setMode("menu"),
571
+ disabled: isLoading,
572
+ children: "Back"
573
+ }, undefined, false, undefined, this),
574
+ /* @__PURE__ */ jsxDEV2(Button2, {
575
+ variant: "destructive",
576
+ onPress: handleLose,
577
+ disabled: isLoading,
578
+ children: isLoading ? "Processing..." : "\u274C Confirm Loss"
579
+ }, undefined, false, undefined, this)
580
+ ]
581
+ }, undefined, true, undefined, this)
582
+ ]
583
+ }, undefined, true, undefined, this),
584
+ mode === "move" && /* @__PURE__ */ jsxDEV2("div", {
585
+ className: "space-y-4",
586
+ children: [
587
+ /* @__PURE__ */ jsxDEV2("div", {
588
+ children: [
589
+ /* @__PURE__ */ jsxDEV2("label", {
590
+ htmlFor: "move-stage",
591
+ className: "text-muted-foreground mb-1 block text-sm font-medium",
592
+ children: "Move to Stage"
593
+ }, undefined, false, undefined, this),
594
+ /* @__PURE__ */ jsxDEV2("select", {
595
+ id: "move-stage",
596
+ value: selectedStageId,
597
+ onChange: (e) => setSelectedStageId(e.target.value),
598
+ className: "border-input bg-background focus:ring-ring h-10 w-full rounded-md border px-3 py-2 text-sm focus:ring-2 focus:outline-none",
599
+ children: stages.map((stage) => /* @__PURE__ */ jsxDEV2("option", {
600
+ value: stage.id,
601
+ children: [
602
+ stage.name,
603
+ stage.id === deal.stageId ? " (current)" : ""
604
+ ]
605
+ }, stage.id, true, undefined, this))
606
+ }, undefined, false, undefined, this)
607
+ ]
608
+ }, undefined, true, undefined, this),
609
+ error && /* @__PURE__ */ jsxDEV2("div", {
610
+ className: "bg-destructive/10 text-destructive rounded-md p-3 text-sm",
611
+ children: error
612
+ }, undefined, false, undefined, this),
613
+ /* @__PURE__ */ jsxDEV2("div", {
614
+ className: "flex justify-end gap-3 pt-2",
615
+ children: [
616
+ /* @__PURE__ */ jsxDEV2(Button2, {
617
+ variant: "ghost",
618
+ onPress: () => setMode("menu"),
619
+ disabled: isLoading,
620
+ children: "Back"
621
+ }, undefined, false, undefined, this),
622
+ /* @__PURE__ */ jsxDEV2(Button2, {
623
+ onPress: handleMove,
624
+ disabled: isLoading,
625
+ children: isLoading ? "Moving..." : "\u27A1\uFE0F Move Deal"
626
+ }, undefined, false, undefined, this)
627
+ ]
628
+ }, undefined, true, undefined, this)
629
+ ]
630
+ }, undefined, true, undefined, this)
631
+ ]
632
+ }, undefined, true, undefined, this)
633
+ ]
634
+ }, undefined, true, undefined, this);
635
+ }
636
+ export {
637
+ DealActionsModal,
638
+ CreateDealModal
639
+ };
@@ -1,18 +1,20 @@
1
- import { OverlayDefinition } from "../../shared/overlay-types.js";
2
-
3
- //#region src/ui/overlays/demo-overlays.d.ts
1
+ /**
2
+ * Demo Overlay Definitions for CRM Pipeline
3
+ *
4
+ * These overlays customize the presentation for different contexts
5
+ * (e.g., demo users, different roles).
6
+ */
7
+ import type { OverlayDefinition } from '../../shared/overlay-types';
4
8
  /**
5
9
  * Demo user overlay - sample data mode
6
10
  */
7
- declare const crmDemoOverlay: OverlayDefinition;
11
+ export declare const crmDemoOverlay: OverlayDefinition;
8
12
  /**
9
13
  * Sales rep overlay - focused view for sales
10
14
  */
11
- declare const crmSalesRepOverlay: OverlayDefinition;
15
+ export declare const crmSalesRepOverlay: OverlayDefinition;
12
16
  /**
13
17
  * All overlays for crm-pipeline
14
18
  */
15
- declare const crmOverlays: OverlayDefinition[];
16
- //#endregion
17
- export { crmDemoOverlay, crmOverlays, crmSalesRepOverlay };
19
+ export declare const crmOverlays: OverlayDefinition[];
18
20
  //# sourceMappingURL=demo-overlays.d.ts.map