@contractspec/example.crm-pipeline 3.7.7 → 3.7.12

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 (57) hide show
  1. package/.turbo/turbo-build.log +45 -42
  2. package/CHANGELOG.md +72 -0
  3. package/README.md +2 -1
  4. package/dist/browser/docs/crm-pipeline.docblock.js +1 -1
  5. package/dist/browser/docs/index.js +1 -1
  6. package/dist/browser/handlers/crm.handlers.js +13 -2
  7. package/dist/browser/handlers/index.js +13 -2
  8. package/dist/browser/index.js +392 -159
  9. package/dist/browser/ui/CrmDashboard.js +366 -144
  10. package/dist/browser/ui/hooks/index.js +19 -8
  11. package/dist/browser/ui/hooks/useDealList.js +19 -8
  12. package/dist/browser/ui/index.js +391 -158
  13. package/dist/browser/ui/renderers/index.js +32 -10
  14. package/dist/browser/ui/renderers/pipeline.markdown.js +13 -2
  15. package/dist/browser/ui/renderers/pipeline.renderer.js +19 -8
  16. package/dist/browser/ui/tables/DealListTab.js +390 -0
  17. package/dist/docs/crm-pipeline.docblock.js +1 -1
  18. package/dist/docs/index.js +1 -1
  19. package/dist/handlers/crm.handlers.d.ts +2 -0
  20. package/dist/handlers/crm.handlers.js +13 -2
  21. package/dist/handlers/index.js +13 -2
  22. package/dist/index.js +392 -159
  23. package/dist/node/docs/crm-pipeline.docblock.js +1 -1
  24. package/dist/node/docs/index.js +1 -1
  25. package/dist/node/handlers/crm.handlers.js +13 -2
  26. package/dist/node/handlers/index.js +13 -2
  27. package/dist/node/index.js +392 -159
  28. package/dist/node/ui/CrmDashboard.js +366 -144
  29. package/dist/node/ui/hooks/index.js +19 -8
  30. package/dist/node/ui/hooks/useDealList.js +19 -8
  31. package/dist/node/ui/index.js +391 -158
  32. package/dist/node/ui/renderers/index.js +32 -10
  33. package/dist/node/ui/renderers/pipeline.markdown.js +13 -2
  34. package/dist/node/ui/renderers/pipeline.renderer.js +19 -8
  35. package/dist/node/ui/tables/DealListTab.js +390 -0
  36. package/dist/ui/CrmDashboard.js +366 -144
  37. package/dist/ui/hooks/index.js +19 -8
  38. package/dist/ui/hooks/useDealList.d.ts +8 -2
  39. package/dist/ui/hooks/useDealList.js +19 -8
  40. package/dist/ui/index.js +391 -158
  41. package/dist/ui/renderers/index.js +32 -10
  42. package/dist/ui/renderers/pipeline.markdown.d.ts +1 -1
  43. package/dist/ui/renderers/pipeline.markdown.js +13 -2
  44. package/dist/ui/renderers/pipeline.renderer.d.ts +1 -1
  45. package/dist/ui/renderers/pipeline.renderer.js +19 -8
  46. package/dist/ui/tables/DealListTab.d.ts +20 -0
  47. package/dist/ui/tables/DealListTab.js +391 -0
  48. package/dist/ui/tables/DealListTab.smoke.test.d.ts +1 -0
  49. package/package.json +29 -13
  50. package/src/docs/crm-pipeline.docblock.ts +1 -1
  51. package/src/handlers/crm.handlers.ts +18 -1
  52. package/src/ui/CrmDashboard.tsx +2 -71
  53. package/src/ui/hooks/useDealList.ts +36 -8
  54. package/src/ui/renderers/pipeline.markdown.ts +1 -1
  55. package/src/ui/renderers/pipeline.renderer.tsx +1 -1
  56. package/src/ui/tables/DealListTab.smoke.test.tsx +149 -0
  57. package/src/ui/tables/DealListTab.tsx +276 -0
@@ -169,8 +169,13 @@ function useDealList(options = {}) {
169
169
  const [stages, setStages] = useState2([]);
170
170
  const [loading, setLoading] = useState2(true);
171
171
  const [error, setError] = useState2(null);
172
- const [page, setPage] = useState2(1);
172
+ const [internalPage, setInternalPage] = useState2(0);
173
173
  const pipelineId = options.pipelineId ?? "pipeline-1";
174
+ const pageIndex = options.pageIndex ?? internalPage;
175
+ const pageSize = options.pageSize ?? options.limit ?? 50;
176
+ const [sort] = options.sorting ?? [];
177
+ const sortBy = sort?.id;
178
+ const sortDirection = sort ? sort.desc ? "desc" : "asc" : undefined;
174
179
  const fetchData = useCallback(async () => {
175
180
  setLoading(true);
176
181
  setError(null);
@@ -182,8 +187,10 @@ function useDealList(options = {}) {
182
187
  stageId: options.stageId,
183
188
  status: options.status === "all" ? undefined : options.status,
184
189
  search: options.search,
185
- limit: options.limit ?? 50,
186
- offset: (page - 1) * (options.limit ?? 50)
190
+ limit: pageSize,
191
+ offset: pageIndex * pageSize,
192
+ sortBy: sortBy === "name" || sortBy === "value" || sortBy === "status" || sortBy === "expectedCloseDate" || sortBy === "updatedAt" ? sortBy : undefined,
193
+ sortDirection
187
194
  }),
188
195
  crm.getDealsByStage({ projectId, pipelineId }),
189
196
  crm.getPipelineStages({ pipelineId })
@@ -203,8 +210,10 @@ function useDealList(options = {}) {
203
210
  options.stageId,
204
211
  options.status,
205
212
  options.search,
206
- options.limit,
207
- page
213
+ pageIndex,
214
+ pageSize,
215
+ sortBy,
216
+ sortDirection
208
217
  ]);
209
218
  useEffect(() => {
210
219
  fetchData();
@@ -232,10 +241,12 @@ function useDealList(options = {}) {
232
241
  loading,
233
242
  error,
234
243
  stats,
235
- page,
244
+ page: pageIndex + 1,
245
+ pageIndex,
246
+ pageSize,
236
247
  refetch: fetchData,
237
- nextPage: () => setPage((p) => p + 1),
238
- prevPage: () => page > 1 && setPage((p) => p - 1)
248
+ nextPage: options.pageIndex === undefined ? () => setInternalPage((page) => page + 1) : undefined,
249
+ prevPage: options.pageIndex === undefined ? () => pageIndex > 0 && setInternalPage((page) => page - 1) : undefined
239
250
  };
240
251
  }
241
252
 
@@ -972,11 +983,305 @@ function DealActionsModal({
972
983
  }, undefined, true, undefined, this);
973
984
  }
974
985
 
975
- // src/ui/CrmDashboard.tsx
986
+ // src/ui/tables/DealListTab.tsx
976
987
  import {
977
988
  Button as Button3,
989
+ DataTable,
990
+ LoaderBlock
991
+ } from "@contractspec/lib.design-system";
992
+ import { useContractTable } from "@contractspec/lib.presentation-runtime-react";
993
+ import { Badge } from "@contractspec/lib.ui-kit-web/ui/badge";
994
+ import { HStack, VStack } from "@contractspec/lib.ui-kit-web/ui/stack";
995
+ import { Text } from "@contractspec/lib.ui-kit-web/ui/text";
996
+ import * as React from "react";
997
+ import { jsxDEV as jsxDEV5 } from "react/jsx-dev-runtime";
998
+ "use client";
999
+ function formatCurrency4(value, currency = "USD") {
1000
+ return new Intl.NumberFormat("en-US", {
1001
+ style: "currency",
1002
+ currency,
1003
+ minimumFractionDigits: 0,
1004
+ maximumFractionDigits: 0
1005
+ }).format(value);
1006
+ }
1007
+ function statusVariant(status) {
1008
+ switch (status) {
1009
+ case "WON":
1010
+ return "default";
1011
+ case "LOST":
1012
+ return "destructive";
1013
+ case "STALE":
1014
+ return "outline";
1015
+ default:
1016
+ return "secondary";
1017
+ }
1018
+ }
1019
+ function DealListDataTable({
1020
+ deals,
1021
+ totalItems,
1022
+ pageIndex,
1023
+ pageSize,
1024
+ sorting,
1025
+ loading,
1026
+ onSortingChange,
1027
+ onPaginationChange,
1028
+ onDealClick
1029
+ }) {
1030
+ const controller = useContractTable({
1031
+ data: deals,
1032
+ columns: [
1033
+ {
1034
+ id: "deal",
1035
+ header: "Deal",
1036
+ label: "Deal",
1037
+ accessor: (deal) => deal.name,
1038
+ cell: ({ item }) => /* @__PURE__ */ jsxDEV5(VStack, {
1039
+ gap: "xs",
1040
+ children: [
1041
+ /* @__PURE__ */ jsxDEV5(Text, {
1042
+ className: "font-medium text-sm",
1043
+ children: item.name
1044
+ }, undefined, false, undefined, this),
1045
+ /* @__PURE__ */ jsxDEV5(Text, {
1046
+ className: "text-muted-foreground text-xs",
1047
+ children: item.companyId ?? "Unassigned company"
1048
+ }, undefined, false, undefined, this)
1049
+ ]
1050
+ }, undefined, true, undefined, this),
1051
+ size: 240,
1052
+ minSize: 180,
1053
+ canSort: true,
1054
+ canPin: true,
1055
+ canResize: true
1056
+ },
1057
+ {
1058
+ id: "value",
1059
+ header: "Value",
1060
+ label: "Value",
1061
+ accessorKey: "value",
1062
+ cell: ({ item }) => formatCurrency4(item.value, item.currency),
1063
+ align: "right",
1064
+ size: 140,
1065
+ canSort: true,
1066
+ canResize: true
1067
+ },
1068
+ {
1069
+ id: "status",
1070
+ header: "Status",
1071
+ label: "Status",
1072
+ accessorKey: "status",
1073
+ cell: ({ value }) => /* @__PURE__ */ jsxDEV5(Badge, {
1074
+ variant: statusVariant(value),
1075
+ children: String(value)
1076
+ }, undefined, false, undefined, this),
1077
+ size: 130,
1078
+ canSort: true,
1079
+ canHide: true,
1080
+ canPin: true,
1081
+ canResize: true
1082
+ },
1083
+ {
1084
+ id: "expectedCloseDate",
1085
+ header: "Expected Close",
1086
+ label: "Expected Close",
1087
+ accessor: (deal) => deal.expectedCloseDate?.toISOString() ?? "",
1088
+ cell: ({ item }) => item.expectedCloseDate?.toLocaleDateString() ?? "Not scheduled",
1089
+ size: 170,
1090
+ canSort: true,
1091
+ canHide: true,
1092
+ canResize: true
1093
+ },
1094
+ {
1095
+ id: "updatedAt",
1096
+ header: "Updated",
1097
+ label: "Updated",
1098
+ accessor: (deal) => deal.updatedAt.toISOString(),
1099
+ cell: ({ item }) => item.updatedAt.toLocaleDateString(),
1100
+ size: 140,
1101
+ canSort: true,
1102
+ canHide: true,
1103
+ canResize: true
1104
+ },
1105
+ {
1106
+ id: "actions",
1107
+ header: "Actions",
1108
+ label: "Actions",
1109
+ accessor: (deal) => deal.id,
1110
+ cell: ({ item }) => /* @__PURE__ */ jsxDEV5(Button3, {
1111
+ variant: "ghost",
1112
+ size: "sm",
1113
+ onPress: () => onDealClick?.(item.id),
1114
+ children: "Actions"
1115
+ }, undefined, false, undefined, this),
1116
+ size: 120,
1117
+ canSort: false,
1118
+ canHide: false,
1119
+ canPin: false,
1120
+ canResize: false
1121
+ }
1122
+ ],
1123
+ executionMode: "server",
1124
+ selectionMode: "multiple",
1125
+ totalItems,
1126
+ state: {
1127
+ sorting,
1128
+ pagination: {
1129
+ pageIndex,
1130
+ pageSize
1131
+ }
1132
+ },
1133
+ onSortingChange,
1134
+ onPaginationChange,
1135
+ initialState: {
1136
+ columnVisibility: { updatedAt: false },
1137
+ columnPinning: { left: ["deal", "status"], right: [] }
1138
+ },
1139
+ renderExpandedContent: (deal) => /* @__PURE__ */ jsxDEV5(VStack, {
1140
+ gap: "sm",
1141
+ className: "py-2",
1142
+ children: [
1143
+ /* @__PURE__ */ jsxDEV5(HStack, {
1144
+ justify: "between",
1145
+ children: [
1146
+ /* @__PURE__ */ jsxDEV5(Text, {
1147
+ className: "font-medium text-sm",
1148
+ children: "Owner"
1149
+ }, undefined, false, undefined, this),
1150
+ /* @__PURE__ */ jsxDEV5(Text, {
1151
+ className: "text-muted-foreground text-sm",
1152
+ children: deal.ownerId
1153
+ }, undefined, false, undefined, this)
1154
+ ]
1155
+ }, undefined, true, undefined, this),
1156
+ /* @__PURE__ */ jsxDEV5(HStack, {
1157
+ justify: "between",
1158
+ children: [
1159
+ /* @__PURE__ */ jsxDEV5(Text, {
1160
+ className: "font-medium text-sm",
1161
+ children: "Contact"
1162
+ }, undefined, false, undefined, this),
1163
+ /* @__PURE__ */ jsxDEV5(Text, {
1164
+ className: "text-muted-foreground text-sm",
1165
+ children: deal.contactId ?? "No linked contact"
1166
+ }, undefined, false, undefined, this)
1167
+ ]
1168
+ }, undefined, true, undefined, this),
1169
+ deal.wonSource ? /* @__PURE__ */ jsxDEV5(HStack, {
1170
+ justify: "between",
1171
+ children: [
1172
+ /* @__PURE__ */ jsxDEV5(Text, {
1173
+ className: "font-medium text-sm",
1174
+ children: "Won Source"
1175
+ }, undefined, false, undefined, this),
1176
+ /* @__PURE__ */ jsxDEV5(Text, {
1177
+ className: "text-muted-foreground text-sm",
1178
+ children: deal.wonSource
1179
+ }, undefined, false, undefined, this)
1180
+ ]
1181
+ }, undefined, true, undefined, this) : null,
1182
+ deal.lostReason ? /* @__PURE__ */ jsxDEV5(HStack, {
1183
+ justify: "between",
1184
+ children: [
1185
+ /* @__PURE__ */ jsxDEV5(Text, {
1186
+ className: "font-medium text-sm",
1187
+ children: "Lost Reason"
1188
+ }, undefined, false, undefined, this),
1189
+ /* @__PURE__ */ jsxDEV5(Text, {
1190
+ className: "text-muted-foreground text-sm",
1191
+ children: deal.lostReason
1192
+ }, undefined, false, undefined, this)
1193
+ ]
1194
+ }, undefined, true, undefined, this) : null,
1195
+ deal.notes ? /* @__PURE__ */ jsxDEV5(VStack, {
1196
+ gap: "xs",
1197
+ children: [
1198
+ /* @__PURE__ */ jsxDEV5(Text, {
1199
+ className: "font-medium text-sm",
1200
+ children: "Notes"
1201
+ }, undefined, false, undefined, this),
1202
+ /* @__PURE__ */ jsxDEV5(Text, {
1203
+ className: "text-muted-foreground text-sm",
1204
+ children: deal.notes
1205
+ }, undefined, false, undefined, this)
1206
+ ]
1207
+ }, undefined, true, undefined, this) : null
1208
+ ]
1209
+ }, undefined, true, undefined, this),
1210
+ getCanExpand: () => true
1211
+ });
1212
+ return /* @__PURE__ */ jsxDEV5(DataTable, {
1213
+ controller,
1214
+ title: "All Deals",
1215
+ description: "Server-mode table using the shared ContractSpec controller.",
1216
+ loading,
1217
+ toolbar: /* @__PURE__ */ jsxDEV5(HStack, {
1218
+ gap: "sm",
1219
+ className: "flex-wrap",
1220
+ children: [
1221
+ /* @__PURE__ */ jsxDEV5(Text, {
1222
+ className: "text-muted-foreground text-sm",
1223
+ children: [
1224
+ "Selected ",
1225
+ controller.selectedRowIds.length
1226
+ ]
1227
+ }, undefined, true, undefined, this),
1228
+ /* @__PURE__ */ jsxDEV5(Text, {
1229
+ className: "text-muted-foreground text-sm",
1230
+ children: [
1231
+ totalItems,
1232
+ " total deals"
1233
+ ]
1234
+ }, undefined, true, undefined, this)
1235
+ ]
1236
+ }, undefined, true, undefined, this),
1237
+ footer: `Page ${controller.pageIndex + 1} of ${controller.pageCount}`,
1238
+ emptyState: /* @__PURE__ */ jsxDEV5("div", {
1239
+ className: "rounded-md border border-dashed p-8 text-center text-muted-foreground text-sm",
1240
+ children: "No deals found"
1241
+ }, undefined, false, undefined, this)
1242
+ }, undefined, false, undefined, this);
1243
+ }
1244
+ function DealListTab({
1245
+ onDealClick
1246
+ }) {
1247
+ const [sorting, setSorting] = React.useState([
1248
+ { id: "value", desc: true }
1249
+ ]);
1250
+ const [pagination, setPagination] = React.useState({
1251
+ pageIndex: 0,
1252
+ pageSize: 3
1253
+ });
1254
+ const { data, loading } = useDealList({
1255
+ pageIndex: pagination.pageIndex,
1256
+ pageSize: pagination.pageSize,
1257
+ sorting
1258
+ });
1259
+ if (loading && !data) {
1260
+ return /* @__PURE__ */ jsxDEV5(LoaderBlock, {
1261
+ label: "Loading deals..."
1262
+ }, undefined, false, undefined, this);
1263
+ }
1264
+ return /* @__PURE__ */ jsxDEV5(DealListDataTable, {
1265
+ deals: data?.deals ?? [],
1266
+ totalItems: data?.total ?? 0,
1267
+ pageIndex: pagination.pageIndex,
1268
+ pageSize: pagination.pageSize,
1269
+ sorting,
1270
+ loading,
1271
+ onSortingChange: (nextSorting) => {
1272
+ setSorting(nextSorting);
1273
+ setPagination((current) => ({ ...current, pageIndex: 0 }));
1274
+ },
1275
+ onPaginationChange: setPagination,
1276
+ onDealClick
1277
+ }, undefined, false, undefined, this);
1278
+ }
1279
+
1280
+ // src/ui/CrmDashboard.tsx
1281
+ import {
1282
+ Button as Button4,
978
1283
  ErrorState,
979
- LoaderBlock,
1284
+ LoaderBlock as LoaderBlock2,
980
1285
  StatCard,
981
1286
  StatCardGroup
982
1287
  } from "@contractspec/lib.design-system";
@@ -986,10 +1291,10 @@ import {
986
1291
  TabsList,
987
1292
  TabsTrigger
988
1293
  } from "@contractspec/lib.ui-kit-web/ui/tabs";
989
- import { useCallback as useCallback3, useState as useState6 } from "react";
990
- import { jsxDEV as jsxDEV5 } from "react/jsx-dev-runtime";
1294
+ import { useCallback as useCallback3, useState as useState7 } from "react";
1295
+ import { jsxDEV as jsxDEV6 } from "react/jsx-dev-runtime";
991
1296
  "use client";
992
- function formatCurrency4(value, currency = "USD") {
1297
+ function formatCurrency5(value, currency = "USD") {
993
1298
  return new Intl.NumberFormat("en-US", {
994
1299
  style: "currency",
995
1300
  currency,
@@ -998,9 +1303,9 @@ function formatCurrency4(value, currency = "USD") {
998
1303
  }).format(value);
999
1304
  }
1000
1305
  function CrmDashboard() {
1001
- const [isCreateModalOpen, setIsCreateModalOpen] = useState6(false);
1002
- const [selectedDeal, setSelectedDeal] = useState6(null);
1003
- const [isDealActionsOpen, setIsDealActionsOpen] = useState6(false);
1306
+ const [isCreateModalOpen, setIsCreateModalOpen] = useState7(false);
1307
+ const [selectedDeal, setSelectedDeal] = useState7(null);
1308
+ const [isDealActionsOpen, setIsDealActionsOpen] = useState7(false);
1004
1309
  const { data, dealsByStage, stages, loading, error, stats, refetch } = useDealList();
1005
1310
  const mutations = useDealMutations({
1006
1311
  onSuccess: () => {
@@ -1018,32 +1323,32 @@ function CrmDashboard() {
1018
1323
  await mutations.moveDeal({ dealId, stageId: toStageId });
1019
1324
  }, [mutations]);
1020
1325
  if (loading && !data) {
1021
- return /* @__PURE__ */ jsxDEV5(LoaderBlock, {
1326
+ return /* @__PURE__ */ jsxDEV6(LoaderBlock2, {
1022
1327
  label: "Loading CRM..."
1023
1328
  }, undefined, false, undefined, this);
1024
1329
  }
1025
1330
  if (error) {
1026
- return /* @__PURE__ */ jsxDEV5(ErrorState, {
1331
+ return /* @__PURE__ */ jsxDEV6(ErrorState, {
1027
1332
  title: "Failed to load CRM",
1028
1333
  description: error.message,
1029
1334
  onRetry: refetch,
1030
1335
  retryLabel: "Retry"
1031
1336
  }, undefined, false, undefined, this);
1032
1337
  }
1033
- return /* @__PURE__ */ jsxDEV5("div", {
1338
+ return /* @__PURE__ */ jsxDEV6("div", {
1034
1339
  className: "space-y-6",
1035
1340
  children: [
1036
- /* @__PURE__ */ jsxDEV5("div", {
1341
+ /* @__PURE__ */ jsxDEV6("div", {
1037
1342
  className: "flex items-center justify-between",
1038
1343
  children: [
1039
- /* @__PURE__ */ jsxDEV5("h2", {
1344
+ /* @__PURE__ */ jsxDEV6("h2", {
1040
1345
  className: "font-bold text-2xl",
1041
1346
  children: "CRM Pipeline"
1042
1347
  }, undefined, false, undefined, this),
1043
- /* @__PURE__ */ jsxDEV5(Button3, {
1348
+ /* @__PURE__ */ jsxDEV6(Button4, {
1044
1349
  onClick: () => setIsCreateModalOpen(true),
1045
1350
  children: [
1046
- /* @__PURE__ */ jsxDEV5("span", {
1351
+ /* @__PURE__ */ jsxDEV6("span", {
1047
1352
  className: "mr-2",
1048
1353
  children: "+"
1049
1354
  }, undefined, false, undefined, this),
@@ -1052,60 +1357,60 @@ function CrmDashboard() {
1052
1357
  }, undefined, true, undefined, this)
1053
1358
  ]
1054
1359
  }, undefined, true, undefined, this),
1055
- stats && /* @__PURE__ */ jsxDEV5(StatCardGroup, {
1360
+ stats && /* @__PURE__ */ jsxDEV6(StatCardGroup, {
1056
1361
  children: [
1057
- /* @__PURE__ */ jsxDEV5(StatCard, {
1362
+ /* @__PURE__ */ jsxDEV6(StatCard, {
1058
1363
  label: "Total Pipeline",
1059
- value: formatCurrency4(stats.totalValue),
1364
+ value: formatCurrency5(stats.totalValue),
1060
1365
  hint: `${stats.total} deals`
1061
1366
  }, undefined, false, undefined, this),
1062
- /* @__PURE__ */ jsxDEV5(StatCard, {
1367
+ /* @__PURE__ */ jsxDEV6(StatCard, {
1063
1368
  label: "Open Deals",
1064
- value: formatCurrency4(stats.openValue),
1369
+ value: formatCurrency5(stats.openValue),
1065
1370
  hint: `${stats.openCount} active`
1066
1371
  }, undefined, false, undefined, this),
1067
- /* @__PURE__ */ jsxDEV5(StatCard, {
1372
+ /* @__PURE__ */ jsxDEV6(StatCard, {
1068
1373
  label: "Won",
1069
- value: formatCurrency4(stats.wonValue),
1374
+ value: formatCurrency5(stats.wonValue),
1070
1375
  hint: `${stats.wonCount} closed`
1071
1376
  }, undefined, false, undefined, this),
1072
- /* @__PURE__ */ jsxDEV5(StatCard, {
1377
+ /* @__PURE__ */ jsxDEV6(StatCard, {
1073
1378
  label: "Lost",
1074
1379
  value: stats.lostCount,
1075
1380
  hint: "deals lost"
1076
1381
  }, undefined, false, undefined, this)
1077
1382
  ]
1078
1383
  }, undefined, true, undefined, this),
1079
- /* @__PURE__ */ jsxDEV5(Tabs, {
1384
+ /* @__PURE__ */ jsxDEV6(Tabs, {
1080
1385
  defaultValue: "pipeline",
1081
1386
  className: "w-full",
1082
1387
  children: [
1083
- /* @__PURE__ */ jsxDEV5(TabsList, {
1388
+ /* @__PURE__ */ jsxDEV6(TabsList, {
1084
1389
  children: [
1085
- /* @__PURE__ */ jsxDEV5(TabsTrigger, {
1390
+ /* @__PURE__ */ jsxDEV6(TabsTrigger, {
1086
1391
  value: "pipeline",
1087
1392
  children: [
1088
- /* @__PURE__ */ jsxDEV5("span", {
1393
+ /* @__PURE__ */ jsxDEV6("span", {
1089
1394
  className: "mr-2",
1090
1395
  children: "\uD83D\uDCCA"
1091
1396
  }, undefined, false, undefined, this),
1092
1397
  "Pipeline"
1093
1398
  ]
1094
1399
  }, undefined, true, undefined, this),
1095
- /* @__PURE__ */ jsxDEV5(TabsTrigger, {
1400
+ /* @__PURE__ */ jsxDEV6(TabsTrigger, {
1096
1401
  value: "list",
1097
1402
  children: [
1098
- /* @__PURE__ */ jsxDEV5("span", {
1403
+ /* @__PURE__ */ jsxDEV6("span", {
1099
1404
  className: "mr-2",
1100
1405
  children: "\uD83D\uDCCB"
1101
1406
  }, undefined, false, undefined, this),
1102
1407
  "All Deals"
1103
1408
  ]
1104
1409
  }, undefined, true, undefined, this),
1105
- /* @__PURE__ */ jsxDEV5(TabsTrigger, {
1410
+ /* @__PURE__ */ jsxDEV6(TabsTrigger, {
1106
1411
  value: "metrics",
1107
1412
  children: [
1108
- /* @__PURE__ */ jsxDEV5("span", {
1413
+ /* @__PURE__ */ jsxDEV6("span", {
1109
1414
  className: "mr-2",
1110
1415
  children: "\uD83D\uDCC8"
1111
1416
  }, undefined, false, undefined, this),
@@ -1114,34 +1419,33 @@ function CrmDashboard() {
1114
1419
  }, undefined, true, undefined, this)
1115
1420
  ]
1116
1421
  }, undefined, true, undefined, this),
1117
- /* @__PURE__ */ jsxDEV5(TabsContent, {
1422
+ /* @__PURE__ */ jsxDEV6(TabsContent, {
1118
1423
  value: "pipeline",
1119
1424
  className: "min-h-[400px]",
1120
- children: /* @__PURE__ */ jsxDEV5(CrmPipelineBoard, {
1425
+ children: /* @__PURE__ */ jsxDEV6(CrmPipelineBoard, {
1121
1426
  dealsByStage,
1122
1427
  stages,
1123
1428
  onDealClick: handleDealClick,
1124
1429
  onDealMove: handleDealMove
1125
1430
  }, undefined, false, undefined, this)
1126
1431
  }, undefined, false, undefined, this),
1127
- /* @__PURE__ */ jsxDEV5(TabsContent, {
1432
+ /* @__PURE__ */ jsxDEV6(TabsContent, {
1128
1433
  value: "list",
1129
1434
  className: "min-h-[400px]",
1130
- children: /* @__PURE__ */ jsxDEV5(DealListTab, {
1131
- data,
1435
+ children: /* @__PURE__ */ jsxDEV6(DealListTab, {
1132
1436
  onDealClick: handleDealClick
1133
1437
  }, undefined, false, undefined, this)
1134
1438
  }, undefined, false, undefined, this),
1135
- /* @__PURE__ */ jsxDEV5(TabsContent, {
1439
+ /* @__PURE__ */ jsxDEV6(TabsContent, {
1136
1440
  value: "metrics",
1137
1441
  className: "min-h-[400px]",
1138
- children: /* @__PURE__ */ jsxDEV5(MetricsTab, {
1442
+ children: /* @__PURE__ */ jsxDEV6(MetricsTab, {
1139
1443
  stats
1140
1444
  }, undefined, false, undefined, this)
1141
1445
  }, undefined, false, undefined, this)
1142
1446
  ]
1143
1447
  }, undefined, true, undefined, this),
1144
- /* @__PURE__ */ jsxDEV5(CreateDealModal, {
1448
+ /* @__PURE__ */ jsxDEV6(CreateDealModal, {
1145
1449
  isOpen: isCreateModalOpen,
1146
1450
  onClose: () => setIsCreateModalOpen(false),
1147
1451
  onSubmit: async (input) => {
@@ -1150,7 +1454,7 @@ function CrmDashboard() {
1150
1454
  stages,
1151
1455
  isLoading: mutations.createState.loading
1152
1456
  }, undefined, false, undefined, this),
1153
- /* @__PURE__ */ jsxDEV5(DealActionsModal, {
1457
+ /* @__PURE__ */ jsxDEV6(DealActionsModal, {
1154
1458
  isOpen: isDealActionsOpen,
1155
1459
  deal: selectedDeal,
1156
1460
  stages,
@@ -1173,112 +1477,30 @@ function CrmDashboard() {
1173
1477
  ]
1174
1478
  }, undefined, true, undefined, this);
1175
1479
  }
1176
- function DealListTab({ data, onDealClick }) {
1177
- if (!data?.deals.length) {
1178
- return /* @__PURE__ */ jsxDEV5("div", {
1179
- className: "flex h-64 items-center justify-center text-muted-foreground",
1180
- children: "No deals found"
1181
- }, undefined, false, undefined, this);
1182
- }
1183
- return /* @__PURE__ */ jsxDEV5("div", {
1184
- className: "rounded-lg border border-border",
1185
- children: /* @__PURE__ */ jsxDEV5("table", {
1186
- className: "w-full",
1187
- children: [
1188
- /* @__PURE__ */ jsxDEV5("thead", {
1189
- className: "border-border border-b bg-muted/30",
1190
- children: /* @__PURE__ */ jsxDEV5("tr", {
1191
- children: [
1192
- /* @__PURE__ */ jsxDEV5("th", {
1193
- className: "px-4 py-3 text-left font-medium text-sm",
1194
- children: "Deal"
1195
- }, undefined, false, undefined, this),
1196
- /* @__PURE__ */ jsxDEV5("th", {
1197
- className: "px-4 py-3 text-left font-medium text-sm",
1198
- children: "Value"
1199
- }, undefined, false, undefined, this),
1200
- /* @__PURE__ */ jsxDEV5("th", {
1201
- className: "px-4 py-3 text-left font-medium text-sm",
1202
- children: "Status"
1203
- }, undefined, false, undefined, this),
1204
- /* @__PURE__ */ jsxDEV5("th", {
1205
- className: "px-4 py-3 text-left font-medium text-sm",
1206
- children: "Expected Close"
1207
- }, undefined, false, undefined, this),
1208
- /* @__PURE__ */ jsxDEV5("th", {
1209
- className: "px-4 py-3 text-left font-medium text-sm",
1210
- children: "Actions"
1211
- }, undefined, false, undefined, this)
1212
- ]
1213
- }, undefined, true, undefined, this)
1214
- }, undefined, false, undefined, this),
1215
- /* @__PURE__ */ jsxDEV5("tbody", {
1216
- className: "divide-y divide-border",
1217
- children: data.deals.map((deal) => /* @__PURE__ */ jsxDEV5("tr", {
1218
- className: "hover:bg-muted/50",
1219
- children: [
1220
- /* @__PURE__ */ jsxDEV5("td", {
1221
- className: "px-4 py-3",
1222
- children: /* @__PURE__ */ jsxDEV5("div", {
1223
- className: "font-medium",
1224
- children: deal.name
1225
- }, undefined, false, undefined, this)
1226
- }, undefined, false, undefined, this),
1227
- /* @__PURE__ */ jsxDEV5("td", {
1228
- className: "px-4 py-3 font-mono",
1229
- children: formatCurrency4(deal.value, deal.currency)
1230
- }, undefined, false, undefined, this),
1231
- /* @__PURE__ */ jsxDEV5("td", {
1232
- className: "px-4 py-3",
1233
- children: /* @__PURE__ */ jsxDEV5("span", {
1234
- className: `inline-flex rounded-full px-2 py-0.5 font-medium text-xs ${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"}`,
1235
- children: deal.status
1236
- }, undefined, false, undefined, this)
1237
- }, undefined, false, undefined, this),
1238
- /* @__PURE__ */ jsxDEV5("td", {
1239
- className: "px-4 py-3 text-muted-foreground",
1240
- children: deal.expectedCloseDate?.toLocaleDateString() ?? "-"
1241
- }, undefined, false, undefined, this),
1242
- /* @__PURE__ */ jsxDEV5("td", {
1243
- className: "px-4 py-3",
1244
- children: /* @__PURE__ */ jsxDEV5(Button3, {
1245
- variant: "ghost",
1246
- size: "sm",
1247
- onPress: () => onDealClick?.(deal.id),
1248
- children: "Actions"
1249
- }, undefined, false, undefined, this)
1250
- }, undefined, false, undefined, this)
1251
- ]
1252
- }, deal.id, true, undefined, this))
1253
- }, undefined, false, undefined, this)
1254
- ]
1255
- }, undefined, true, undefined, this)
1256
- }, undefined, false, undefined, this);
1257
- }
1258
1480
  function MetricsTab({
1259
1481
  stats
1260
1482
  }) {
1261
1483
  if (!stats)
1262
1484
  return null;
1263
- return /* @__PURE__ */ jsxDEV5("div", {
1485
+ return /* @__PURE__ */ jsxDEV6("div", {
1264
1486
  className: "space-y-6",
1265
- children: /* @__PURE__ */ jsxDEV5("div", {
1487
+ children: /* @__PURE__ */ jsxDEV6("div", {
1266
1488
  className: "rounded-xl border border-border bg-card p-6",
1267
1489
  children: [
1268
- /* @__PURE__ */ jsxDEV5("h3", {
1490
+ /* @__PURE__ */ jsxDEV6("h3", {
1269
1491
  className: "mb-4 font-semibold text-lg",
1270
1492
  children: "Pipeline Overview"
1271
1493
  }, undefined, false, undefined, this),
1272
- /* @__PURE__ */ jsxDEV5("dl", {
1494
+ /* @__PURE__ */ jsxDEV6("dl", {
1273
1495
  className: "grid gap-4 sm:grid-cols-3",
1274
1496
  children: [
1275
- /* @__PURE__ */ jsxDEV5("div", {
1497
+ /* @__PURE__ */ jsxDEV6("div", {
1276
1498
  children: [
1277
- /* @__PURE__ */ jsxDEV5("dt", {
1499
+ /* @__PURE__ */ jsxDEV6("dt", {
1278
1500
  className: "text-muted-foreground text-sm",
1279
1501
  children: "Win Rate"
1280
1502
  }, undefined, false, undefined, this),
1281
- /* @__PURE__ */ jsxDEV5("dd", {
1503
+ /* @__PURE__ */ jsxDEV6("dd", {
1282
1504
  className: "font-semibold text-2xl",
1283
1505
  children: [
1284
1506
  stats.total > 0 ? (stats.wonCount / stats.total * 100).toFixed(0) : 0,
@@ -1287,25 +1509,25 @@ function MetricsTab({
1287
1509
  }, undefined, true, undefined, this)
1288
1510
  ]
1289
1511
  }, undefined, true, undefined, this),
1290
- /* @__PURE__ */ jsxDEV5("div", {
1512
+ /* @__PURE__ */ jsxDEV6("div", {
1291
1513
  children: [
1292
- /* @__PURE__ */ jsxDEV5("dt", {
1514
+ /* @__PURE__ */ jsxDEV6("dt", {
1293
1515
  className: "text-muted-foreground text-sm",
1294
1516
  children: "Avg Deal Size"
1295
1517
  }, undefined, false, undefined, this),
1296
- /* @__PURE__ */ jsxDEV5("dd", {
1518
+ /* @__PURE__ */ jsxDEV6("dd", {
1297
1519
  className: "font-semibold text-2xl",
1298
- children: formatCurrency4(stats.total > 0 ? stats.totalValue / stats.total : 0)
1520
+ children: formatCurrency5(stats.total > 0 ? stats.totalValue / stats.total : 0)
1299
1521
  }, undefined, false, undefined, this)
1300
1522
  ]
1301
1523
  }, undefined, true, undefined, this),
1302
- /* @__PURE__ */ jsxDEV5("div", {
1524
+ /* @__PURE__ */ jsxDEV6("div", {
1303
1525
  children: [
1304
- /* @__PURE__ */ jsxDEV5("dt", {
1526
+ /* @__PURE__ */ jsxDEV6("dt", {
1305
1527
  className: "text-muted-foreground text-sm",
1306
1528
  children: "Conversion"
1307
1529
  }, undefined, false, undefined, this),
1308
- /* @__PURE__ */ jsxDEV5("dd", {
1530
+ /* @__PURE__ */ jsxDEV6("dd", {
1309
1531
  className: "font-semibold text-2xl",
1310
1532
  children: [
1311
1533
  stats.wonCount,