@contractspec/example.crm-pipeline 3.7.7 → 3.7.10

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