@burdenoff/microfe-proserviceworld 2026.706.3 → 2026.709.1

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 (91) hide show
  1. package/dist/dev/main.d.ts +2 -0
  2. package/dist/dev/main.d.ts.map +1 -0
  3. package/dist/generated/global-operations.d.ts +2 -0
  4. package/dist/generated/global-operations.d.ts.map +1 -0
  5. package/dist/generated/global-types.d.ts +18199 -0
  6. package/dist/generated/global-types.d.ts.map +1 -0
  7. package/dist/generated/wspace-operations.d.ts +2 -0
  8. package/dist/generated/wspace-operations.d.ts.map +1 -0
  9. package/dist/generated/wspace-types.d.ts +43046 -0
  10. package/dist/generated/wspace-types.d.ts.map +1 -0
  11. package/dist/index.d.ts +2 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +2 -1
  14. package/dist/proserviceworld/ProServiceWorldRoot.d.ts +5 -0
  15. package/dist/proserviceworld/ProServiceWorldRoot.d.ts.map +1 -0
  16. package/dist/proserviceworld/ProServiceWorldRoutes.d.ts +2 -0
  17. package/dist/proserviceworld/ProServiceWorldRoutes.d.ts.map +1 -0
  18. package/dist/proserviceworld/components/DiscussionThread.d.ts +12 -0
  19. package/dist/proserviceworld/components/DiscussionThread.d.ts.map +1 -0
  20. package/dist/proserviceworld/components/ui.d.ts +82 -0
  21. package/dist/proserviceworld/components/ui.d.ts.map +1 -0
  22. package/dist/proserviceworld/hooks/useAnalytics.d.ts +18 -0
  23. package/dist/proserviceworld/hooks/useAnalytics.d.ts.map +1 -0
  24. package/dist/proserviceworld/hooks/useAnalytics.js +21 -0
  25. package/dist/proserviceworld/hooks/useAnalytics.js.map +1 -0
  26. package/dist/proserviceworld/hooks/useEntityComments.d.ts +27 -0
  27. package/dist/proserviceworld/hooks/useEntityComments.d.ts.map +1 -0
  28. package/dist/proserviceworld/hooks/useFiles.d.ts +23 -0
  29. package/dist/proserviceworld/hooks/useFiles.d.ts.map +1 -0
  30. package/dist/proserviceworld/hooks/useProServiceWorldApi.d.ts +351 -0
  31. package/dist/proserviceworld/hooks/useProServiceWorldApi.d.ts.map +1 -0
  32. package/dist/proserviceworld/index.d.ts +5 -0
  33. package/dist/proserviceworld/index.d.ts.map +1 -0
  34. package/dist/proserviceworld/index.js +1 -0
  35. package/dist/proserviceworld/pages/AnalyticsPage.d.ts +4 -0
  36. package/dist/proserviceworld/pages/AnalyticsPage.d.ts.map +1 -0
  37. package/dist/proserviceworld/pages/ClientDetailPage.d.ts +4 -0
  38. package/dist/proserviceworld/pages/ClientDetailPage.d.ts.map +1 -0
  39. package/dist/proserviceworld/pages/ClientsPage.d.ts +9 -0
  40. package/dist/proserviceworld/pages/ClientsPage.d.ts.map +1 -0
  41. package/dist/proserviceworld/pages/ClientsPage.js +157 -146
  42. package/dist/proserviceworld/pages/ClientsPage.js.map +1 -1
  43. package/dist/proserviceworld/pages/CompliancePage.d.ts +4 -0
  44. package/dist/proserviceworld/pages/CompliancePage.d.ts.map +1 -0
  45. package/dist/proserviceworld/pages/ConflictsPage.d.ts +4 -0
  46. package/dist/proserviceworld/pages/ConflictsPage.d.ts.map +1 -0
  47. package/dist/proserviceworld/pages/DashboardPage.d.ts +4 -0
  48. package/dist/proserviceworld/pages/DashboardPage.d.ts.map +1 -0
  49. package/dist/proserviceworld/pages/DocumentsPage.d.ts +4 -0
  50. package/dist/proserviceworld/pages/DocumentsPage.d.ts.map +1 -0
  51. package/dist/proserviceworld/pages/EngagementDetailPage.d.ts +4 -0
  52. package/dist/proserviceworld/pages/EngagementDetailPage.d.ts.map +1 -0
  53. package/dist/proserviceworld/pages/EngagementDetailPage.js +162 -156
  54. package/dist/proserviceworld/pages/EngagementDetailPage.js.map +1 -1
  55. package/dist/proserviceworld/pages/EngagementsPage.d.ts +4 -0
  56. package/dist/proserviceworld/pages/EngagementsPage.d.ts.map +1 -0
  57. package/dist/proserviceworld/pages/EngagementsPage.js +141 -128
  58. package/dist/proserviceworld/pages/EngagementsPage.js.map +1 -1
  59. package/dist/proserviceworld/pages/InvoicesPage.d.ts +4 -0
  60. package/dist/proserviceworld/pages/InvoicesPage.d.ts.map +1 -0
  61. package/dist/proserviceworld/pages/MattersPage.d.ts +4 -0
  62. package/dist/proserviceworld/pages/MattersPage.d.ts.map +1 -0
  63. package/dist/proserviceworld/pages/MattersPage.js +165 -150
  64. package/dist/proserviceworld/pages/MattersPage.js.map +1 -1
  65. package/dist/proserviceworld/pages/PracticeAreasPage.d.ts +4 -0
  66. package/dist/proserviceworld/pages/PracticeAreasPage.d.ts.map +1 -0
  67. package/dist/proserviceworld/pages/TimePage.d.ts +4 -0
  68. package/dist/proserviceworld/pages/TimePage.d.ts.map +1 -0
  69. package/dist/proserviceworld/providers/ProServiceWorldProvider.d.ts +6 -0
  70. package/dist/proserviceworld/providers/ProServiceWorldProvider.d.ts.map +1 -0
  71. package/dist/proserviceworld/services/assistantApi.d.ts +74 -0
  72. package/dist/proserviceworld/services/assistantApi.d.ts.map +1 -0
  73. package/dist/proserviceworld/services/assistantApi.js +203 -0
  74. package/dist/proserviceworld/services/assistantApi.js.map +1 -0
  75. package/dist/proserviceworld/services/createSandboxAssistantTransport.d.ts +28 -0
  76. package/dist/proserviceworld/services/createSandboxAssistantTransport.d.ts.map +1 -0
  77. package/dist/proserviceworld/services/createSandboxAssistantTransport.js +120 -0
  78. package/dist/proserviceworld/services/createSandboxAssistantTransport.js.map +1 -0
  79. package/dist/proserviceworld/types/index.d.ts +57 -0
  80. package/dist/proserviceworld/types/index.d.ts.map +1 -0
  81. package/dist/proserviceworld/utils/cn.d.ts +4 -0
  82. package/dist/proserviceworld/utils/cn.d.ts.map +1 -0
  83. package/dist/proserviceworld/utils/nav.d.ts +6 -0
  84. package/dist/proserviceworld/utils/nav.d.ts.map +1 -0
  85. package/dist/proserviceworld/utils/navigation.d.ts +2 -0
  86. package/dist/proserviceworld/utils/navigation.d.ts.map +1 -0
  87. package/dist/proserviceworld/utils/pageContext.d.ts +12 -0
  88. package/dist/proserviceworld/utils/pageContext.d.ts.map +1 -0
  89. package/dist/proserviceworld/utils/pageContext.js +74 -0
  90. package/dist/proserviceworld/utils/pageContext.js.map +1 -0
  91. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AnalyticsPage.d.ts","sourceRoot":"","sources":["../../../src/proserviceworld/pages/AnalyticsPage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAehC,eAAO,MAAM,aAAa,EAAE,EA6G3B,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { FC } from 'react';
2
+
3
+ export declare const ClientDetailPage: FC;
4
+ //# sourceMappingURL=ClientDetailPage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClientDetailPage.d.ts","sourceRoot":"","sources":["../../../src/proserviceworld/pages/ClientDetailPage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAsDhC,eAAO,MAAM,gBAAgB,EAAE,EA2P9B,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { FC } from 'react';
2
+
3
+ /** Tinted initials avatar (semantic tokens only). */
4
+ export declare const Avatar: FC<{
5
+ name: string;
6
+ className?: string;
7
+ }>;
8
+ export declare const ClientsPage: FC;
9
+ //# sourceMappingURL=ClientsPage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClientsPage.d.ts","sourceRoot":"","sources":["../../../src/proserviceworld/pages/ClientsPage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AA8ChC,qDAAqD;AACrD,eAAO,MAAM,MAAM,EAAE,EAAE,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAU3D,CAAC;AAuBF,eAAO,MAAM,WAAW,EAAE,EAoLzB,CAAC"}
@@ -2,21 +2,22 @@ import { useArchiveClient as e, useClients as t, useCreateClient as n, useUpdate
2
2
  import { useNav as i } from "../utils/nav.js";
3
3
  import { cn as a } from "../utils/cn.js";
4
4
  import { Banner as o, Empty as s, ErrorState as c, Field as l, LoadingBlock as u, Modal as d, NativeSelect as f, PageHeader as p, SectionCard as m, StatusPill as h, TableWrap as g, Td as _, TextArea as v, TextInput as y, Th as b, enumOptions as x, fmtDate as S } from "../components/ui.js";
5
- import { useMemo as C, useState as w } from "react";
6
- import { Archive as T, Building2 as E, ChevronRight as D, Pencil as O, Plus as k, Search as A, User as j, Users as M } from "lucide-react";
7
- import { Fragment as N, jsx as P, jsxs as F } from "react/jsx-runtime";
8
- import { Button as I } from "@burdenoff/fe-libs/ui";
5
+ import { useAnalytics as C } from "../hooks/useAnalytics.js";
6
+ import { useMemo as w, useState as T } from "react";
7
+ import { Archive as E, Building2 as D, ChevronRight as O, Pencil as k, Plus as A, Search as j, User as M, Users as N } from "lucide-react";
8
+ import { Fragment as P, jsx as F, jsxs as I } from "react/jsx-runtime";
9
+ import { Button as L } from "@burdenoff/fe-libs/ui";
9
10
  //#region src/proserviceworld/pages/ClientsPage.tsx
10
- var L = ["ORGANIZATION", "INDIVIDUAL"], R = [
11
+ var R = ["ORGANIZATION", "INDIVIDUAL"], z = [
11
12
  "PROSPECT",
12
13
  "ACTIVE",
13
14
  "INACTIVE",
14
15
  "ARCHIVED"
15
- ], z = (e) => e.split(/\s+/).filter(Boolean).slice(0, 2).map((e) => e[0]?.toUpperCase() ?? "").join("") || "?", B = ({ name: e, className: t }) => /* @__PURE__ */ P("span", {
16
+ ], B = (e) => e.split(/\s+/).filter(Boolean).slice(0, 2).map((e) => e[0]?.toUpperCase() ?? "").join("") || "?", V = ({ name: e, className: t }) => /* @__PURE__ */ F("span", {
16
17
  className: a("flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-accent/10 text-xs font-semibold text-accent ring-1 ring-inset ring-accent/15", t),
17
18
  "aria-hidden": !0,
18
- children: z(e)
19
- }), V = {
19
+ children: B(e)
20
+ }), H = {
20
21
  name: "",
21
22
  type: "ORGANIZATION",
22
23
  status: "PROSPECT",
@@ -25,116 +26,124 @@ var L = ["ORGANIZATION", "INDIVIDUAL"], R = [
25
26
  contactEmail: "",
26
27
  contactPhone: "",
27
28
  notes: ""
28
- }, H = () => {
29
- let e = i(), [n, r] = w(""), [a, l] = w(""), [d, v] = w(null), [C, T] = w(!1), [N, L] = w(null), { data: z, isLoading: V, error: H, refetch: G } = t({
30
- search: n.trim() || void 0,
31
- status: a || void 0
29
+ }, U = () => {
30
+ let e = i(), { emitIntent: n, emitFact: r } = C(), [a, l] = T(""), [d, v] = T(""), [w, E] = T(null), [P, R] = T(!1), [B, H] = T(null), { data: U, isLoading: K, error: q, refetch: J } = t({
31
+ search: a.trim() || void 0,
32
+ status: d || void 0
32
33
  });
33
- return /* @__PURE__ */ F("div", {
34
+ return /* @__PURE__ */ I("div", {
34
35
  className: "space-y-6",
35
36
  children: [
36
- /* @__PURE__ */ P(p, {
37
+ /* @__PURE__ */ F(p, {
37
38
  title: "Clients",
38
39
  subtitle: "Every person or organization your firm serves — the record engagements, matters, documents and invoices hang off.",
39
- icon: /* @__PURE__ */ P(M, { className: "h-6 w-6" }),
40
- actions: /* @__PURE__ */ F(I, {
41
- onClick: () => T(!0),
42
- children: [/* @__PURE__ */ P(k, { className: "mr-1.5 h-4 w-4" }), " New client"]
40
+ icon: /* @__PURE__ */ F(N, { className: "h-6 w-6" }),
41
+ actions: /* @__PURE__ */ I(L, {
42
+ onClick: () => {
43
+ n("psw.client.create_clicked"), R(!0);
44
+ },
45
+ children: [/* @__PURE__ */ F(A, { className: "mr-1.5 h-4 w-4" }), " New client"]
43
46
  })
44
47
  }),
45
- N && /* @__PURE__ */ P(o, {
46
- tone: N.tone,
47
- onClose: () => L(null),
48
- children: N.text
48
+ B && /* @__PURE__ */ F(o, {
49
+ tone: B.tone,
50
+ onClose: () => H(null),
51
+ children: B.text
49
52
  }),
50
- /* @__PURE__ */ F("div", {
53
+ /* @__PURE__ */ I("div", {
51
54
  className: "flex flex-col gap-2 sm:flex-row sm:items-center",
52
- children: [/* @__PURE__ */ F("div", {
55
+ children: [/* @__PURE__ */ I("div", {
53
56
  className: "relative flex-1",
54
- children: [/* @__PURE__ */ P(A, { className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-tertiary" }), /* @__PURE__ */ P(y, {
57
+ children: [/* @__PURE__ */ F(j, { className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-tertiary" }), /* @__PURE__ */ F(y, {
55
58
  placeholder: "Search clients…",
56
- value: n,
57
- onChange: (e) => r(e.target.value),
59
+ value: a,
60
+ onChange: (e) => l(e.target.value),
61
+ onKeyDown: (e) => {
62
+ e.key === "Enter" && a.trim() && r("psw.search.performed", {
63
+ entityType: "client",
64
+ queryLength: a.trim().length
65
+ });
66
+ },
58
67
  className: "pl-9"
59
68
  })]
60
- }), /* @__PURE__ */ F(f, {
61
- value: a,
62
- onChange: (e) => l(e.target.value),
69
+ }), /* @__PURE__ */ I(f, {
70
+ value: d,
71
+ onChange: (e) => v(e.target.value),
63
72
  className: "sm:w-48",
64
- children: [/* @__PURE__ */ P("option", {
73
+ children: [/* @__PURE__ */ F("option", {
65
74
  value: "",
66
75
  children: "All statuses"
67
- }), x(R)]
76
+ }), x(z)]
68
77
  })]
69
78
  }),
70
- V ? /* @__PURE__ */ P(u, {}) : H ? /* @__PURE__ */ P(c, {
71
- error: H,
72
- onRetry: () => void G()
73
- }) : !z || z.items.length === 0 ? /* @__PURE__ */ P(s, {
79
+ K ? /* @__PURE__ */ F(u, {}) : q ? /* @__PURE__ */ F(c, {
80
+ error: q,
81
+ onRetry: () => void J()
82
+ }) : !U || U.items.length === 0 ? /* @__PURE__ */ F(s, {
74
83
  title: "No clients yet",
75
84
  description: "Add your first client to start scoping engagements and matters.",
76
- icon: /* @__PURE__ */ P(M, { className: "h-8 w-8" }),
77
- action: /* @__PURE__ */ F(I, {
78
- onClick: () => T(!0),
79
- children: [/* @__PURE__ */ P(k, { className: "mr-1.5 h-4 w-4" }), " New client"]
85
+ icon: /* @__PURE__ */ F(N, { className: "h-8 w-8" }),
86
+ action: /* @__PURE__ */ I(L, {
87
+ onClick: () => R(!0),
88
+ children: [/* @__PURE__ */ F(A, { className: "mr-1.5 h-4 w-4" }), " New client"]
80
89
  })
81
- }) : /* @__PURE__ */ P(m, {
82
- title: `${z.totalCount} client${z.totalCount === 1 ? "" : "s"}`,
83
- children: /* @__PURE__ */ F(g, { children: [/* @__PURE__ */ P("thead", { children: /* @__PURE__ */ F("tr", { children: [
84
- /* @__PURE__ */ P(b, { children: "Name" }),
85
- /* @__PURE__ */ P(b, { children: "Type" }),
86
- /* @__PURE__ */ P(b, { children: "Industry" }),
87
- /* @__PURE__ */ P(b, { children: "Status" }),
88
- /* @__PURE__ */ P(b, { children: "Added" }),
89
- /* @__PURE__ */ P(b, {
90
+ }) : /* @__PURE__ */ F(m, {
91
+ title: `${U.totalCount} client${U.totalCount === 1 ? "" : "s"}`,
92
+ children: /* @__PURE__ */ I(g, { children: [/* @__PURE__ */ F("thead", { children: /* @__PURE__ */ I("tr", { children: [
93
+ /* @__PURE__ */ F(b, { children: "Name" }),
94
+ /* @__PURE__ */ F(b, { children: "Type" }),
95
+ /* @__PURE__ */ F(b, { children: "Industry" }),
96
+ /* @__PURE__ */ F(b, { children: "Status" }),
97
+ /* @__PURE__ */ F(b, { children: "Added" }),
98
+ /* @__PURE__ */ F(b, {
90
99
  className: "text-right",
91
100
  children: "Actions"
92
101
  })
93
- ] }) }), /* @__PURE__ */ P("tbody", { children: z.items.map((t) => /* @__PURE__ */ F("tr", {
102
+ ] }) }), /* @__PURE__ */ F("tbody", { children: U.items.map((t) => /* @__PURE__ */ I("tr", {
94
103
  className: "group cursor-pointer transition-colors hover:bg-bg-sunken/60",
95
104
  onClick: () => e(`clients/${t.id}`),
96
105
  children: [
97
- /* @__PURE__ */ P(_, { children: /* @__PURE__ */ F("div", {
106
+ /* @__PURE__ */ F(_, { children: /* @__PURE__ */ I("div", {
98
107
  className: "flex items-center gap-3",
99
- children: [/* @__PURE__ */ P(B, { name: t.name }), /* @__PURE__ */ F("div", {
108
+ children: [/* @__PURE__ */ F(V, { name: t.name }), /* @__PURE__ */ I("div", {
100
109
  className: "min-w-0",
101
- children: [/* @__PURE__ */ F("div", {
110
+ children: [/* @__PURE__ */ I("div", {
102
111
  className: "flex items-center gap-1 font-medium text-text-primary transition-colors group-hover:text-accent",
103
- children: [/* @__PURE__ */ P("span", {
112
+ children: [/* @__PURE__ */ F("span", {
104
113
  className: "truncate",
105
114
  children: t.name
106
- }), /* @__PURE__ */ P(D, { className: "h-3.5 w-3.5 shrink-0 text-text-tertiary opacity-0 transition-opacity group-hover:opacity-100" })]
107
- }), t.contactName ? /* @__PURE__ */ P("div", {
115
+ }), /* @__PURE__ */ F(O, { className: "h-3.5 w-3.5 shrink-0 text-text-tertiary opacity-0 transition-opacity group-hover:opacity-100" })]
116
+ }), t.contactName ? /* @__PURE__ */ F("div", {
108
117
  className: "truncate text-xs text-text-tertiary",
109
118
  children: t.contactName
110
119
  }) : null]
111
120
  })]
112
121
  }) }),
113
- /* @__PURE__ */ P(_, { children: /* @__PURE__ */ F("span", {
122
+ /* @__PURE__ */ F(_, { children: /* @__PURE__ */ I("span", {
114
123
  className: "inline-flex items-center gap-1.5 text-text-secondary",
115
- children: [t.type === "ORGANIZATION" ? /* @__PURE__ */ P(E, { className: "h-3.5 w-3.5 text-text-tertiary" }) : /* @__PURE__ */ P(j, { className: "h-3.5 w-3.5 text-text-tertiary" }), t.type === "ORGANIZATION" ? "Organization" : "Individual"]
124
+ children: [t.type === "ORGANIZATION" ? /* @__PURE__ */ F(D, { className: "h-3.5 w-3.5 text-text-tertiary" }) : /* @__PURE__ */ F(M, { className: "h-3.5 w-3.5 text-text-tertiary" }), t.type === "ORGANIZATION" ? "Organization" : "Individual"]
116
125
  }) }),
117
- /* @__PURE__ */ P(_, { children: t.industry || "—" }),
118
- /* @__PURE__ */ P(_, { children: /* @__PURE__ */ P(h, { status: t.status }) }),
119
- /* @__PURE__ */ P(_, {
126
+ /* @__PURE__ */ F(_, { children: t.industry || "—" }),
127
+ /* @__PURE__ */ F(_, { children: /* @__PURE__ */ F(h, { status: t.status }) }),
128
+ /* @__PURE__ */ F(_, {
120
129
  className: "whitespace-nowrap",
121
130
  children: S(t.createdAt)
122
131
  }),
123
- /* @__PURE__ */ P(_, {
132
+ /* @__PURE__ */ F(_, {
124
133
  className: "text-right",
125
- children: /* @__PURE__ */ F("div", {
134
+ children: /* @__PURE__ */ I("div", {
126
135
  className: "flex justify-end gap-1",
127
136
  onClick: (e) => e.stopPropagation(),
128
137
  role: "presentation",
129
- children: [/* @__PURE__ */ P(I, {
138
+ children: [/* @__PURE__ */ F(L, {
130
139
  variant: "ghost",
131
140
  size: "sm",
132
- onClick: () => v(t),
141
+ onClick: () => E(t),
133
142
  "aria-label": "Edit",
134
- children: /* @__PURE__ */ P(O, { className: "h-4 w-4" })
135
- }), t.status !== "ARCHIVED" && /* @__PURE__ */ P(U, {
143
+ children: /* @__PURE__ */ F(k, { className: "h-4 w-4" })
144
+ }), t.status !== "ARCHIVED" && /* @__PURE__ */ F(W, {
136
145
  id: t.id,
137
- onDone: (e) => L(e ? {
146
+ onDone: (e) => H(e ? {
138
147
  tone: "success",
139
148
  text: `${t.name} archived.`
140
149
  } : {
@@ -147,40 +156,42 @@ var L = ["ORGANIZATION", "INDIVIDUAL"], R = [
147
156
  ]
148
157
  }, t.id)) })] })
149
158
  }),
150
- C && /* @__PURE__ */ P(W, {
151
- onClose: () => T(!1),
152
- onSaved: (e) => L({
159
+ P && /* @__PURE__ */ F(G, {
160
+ onClose: () => R(!1),
161
+ onSaved: (e) => H({
153
162
  tone: "success",
154
163
  text: `${e} created.`
155
164
  })
156
165
  }),
157
- d && /* @__PURE__ */ P(W, {
158
- client: d,
159
- onClose: () => v(null),
160
- onSaved: (e) => L({
166
+ w && /* @__PURE__ */ F(G, {
167
+ client: w,
168
+ onClose: () => E(null),
169
+ onSaved: (e) => H({
161
170
  tone: "success",
162
171
  text: `${e} updated.`
163
172
  })
164
173
  })
165
174
  ]
166
175
  });
167
- }, U = ({ id: t, onDone: n }) => {
168
- let r = e();
169
- return /* @__PURE__ */ P(I, {
176
+ }, W = ({ id: t, onDone: n }) => {
177
+ let r = e(), { emitFact: i } = C();
178
+ return /* @__PURE__ */ F(L, {
170
179
  variant: "ghost",
171
180
  size: "sm",
172
181
  "aria-label": "Archive",
173
182
  disabled: r.isPending,
174
183
  onClick: () => {
175
184
  window.confirm("Archive this client? Their engagements and matters remain.") && r.mutate(t, {
176
- onSuccess: (e) => n(!!e),
185
+ onSuccess: (e) => {
186
+ i("psw.client.archived", { clientId: t }), n(!!e);
187
+ },
177
188
  onError: () => n(!1)
178
189
  });
179
190
  },
180
- children: /* @__PURE__ */ P(T, { className: "h-4 w-4" })
191
+ children: /* @__PURE__ */ F(E, { className: "h-4 w-4" })
181
192
  });
182
- }, W = ({ client: e, onClose: t, onSaved: i }) => {
183
- let a = n(), s = r(), [c, u] = w(e ? {
193
+ }, G = ({ client: e, onClose: t, onSaved: i }) => {
194
+ let a = n(), s = r(), { emitFact: c } = C(), [u, p] = T(e ? {
184
195
  name: e.name,
185
196
  type: e.type,
186
197
  status: e.status,
@@ -189,121 +200,121 @@ var L = ["ORGANIZATION", "INDIVIDUAL"], R = [
189
200
  contactEmail: e.contactEmail ?? "",
190
201
  contactPhone: e.contactPhone ?? "",
191
202
  notes: e.notes ?? ""
192
- } : V), [p, m] = w(null), h = (e) => (t) => u((n) => ({
203
+ } : H), [m, h] = T(null), g = (e) => (t) => p((n) => ({
193
204
  ...n,
194
205
  [e]: t.target.value
195
- })), g = a.isPending || s.isPending, _ = C(() => ({
196
- name: c.name.trim(),
197
- type: c.type,
198
- status: c.status,
199
- industry: c.industry.trim() || null,
200
- contactName: c.contactName.trim() || null,
201
- contactEmail: c.contactEmail.trim() || null,
202
- contactPhone: c.contactPhone.trim() || null,
203
- notes: c.notes.trim() || null
204
- }), [c]);
205
- return /* @__PURE__ */ P(d, {
206
+ })), _ = a.isPending || s.isPending, b = w(() => ({
207
+ name: u.name.trim(),
208
+ type: u.type,
209
+ status: u.status,
210
+ industry: u.industry.trim() || null,
211
+ contactName: u.contactName.trim() || null,
212
+ contactEmail: u.contactEmail.trim() || null,
213
+ contactPhone: u.contactPhone.trim() || null,
214
+ notes: u.notes.trim() || null
215
+ }), [u]);
216
+ return /* @__PURE__ */ F(d, {
206
217
  open: !0,
207
218
  onClose: t,
208
219
  title: e ? "Edit client" : "New client",
209
- footer: /* @__PURE__ */ F(N, { children: [/* @__PURE__ */ P(I, {
220
+ footer: /* @__PURE__ */ I(P, { children: [/* @__PURE__ */ F(L, {
210
221
  variant: "outline",
211
222
  onClick: t,
212
- disabled: g,
223
+ disabled: _,
213
224
  children: "Cancel"
214
- }), /* @__PURE__ */ P(I, {
225
+ }), /* @__PURE__ */ F(L, {
215
226
  onClick: () => {
216
- if (m(null), !_.name) return m("Client name is required.");
217
- let n = (e) => m(e instanceof Error ? e.message : "Save failed.");
227
+ if (h(null), !b.name) return h("Client name is required.");
228
+ let n = (e) => h(e instanceof Error ? e.message : "Save failed.");
218
229
  e ? s.mutate({
219
230
  id: e.id,
220
- input: _
231
+ input: b
221
232
  }, {
222
233
  onSuccess: () => {
223
- i(_.name), t();
234
+ c("psw.client.updated", { clientId: e.id }), i(b.name), t();
224
235
  },
225
236
  onError: n
226
- }) : a.mutate(_, {
227
- onSuccess: () => {
228
- i(_.name), t();
237
+ }) : a.mutate(b, {
238
+ onSuccess: (e) => {
239
+ c("psw.client.created", { clientId: e.pswCreateClient.id }), i(b.name), t();
229
240
  },
230
241
  onError: n
231
242
  });
232
243
  },
233
- disabled: g,
234
- children: g ? "Saving…" : e ? "Save changes" : "Create client"
244
+ disabled: _,
245
+ children: _ ? "Saving…" : e ? "Save changes" : "Create client"
235
246
  })] }),
236
- children: /* @__PURE__ */ F("div", {
247
+ children: /* @__PURE__ */ I("div", {
237
248
  className: "space-y-3",
238
249
  children: [
239
- p && /* @__PURE__ */ P(o, {
250
+ m && /* @__PURE__ */ F(o, {
240
251
  tone: "danger",
241
- children: p
252
+ children: m
242
253
  }),
243
- /* @__PURE__ */ P(l, {
254
+ /* @__PURE__ */ F(l, {
244
255
  label: "Name",
245
256
  required: !0,
246
- children: /* @__PURE__ */ P(y, {
247
- value: c.name,
248
- onChange: h("name"),
257
+ children: /* @__PURE__ */ F(y, {
258
+ value: u.name,
259
+ onChange: g("name"),
249
260
  placeholder: "Acme Holdings Ltd."
250
261
  })
251
262
  }),
252
- /* @__PURE__ */ F("div", {
263
+ /* @__PURE__ */ I("div", {
253
264
  className: "grid grid-cols-2 gap-3",
254
- children: [/* @__PURE__ */ P(l, {
265
+ children: [/* @__PURE__ */ F(l, {
255
266
  label: "Type",
256
- children: /* @__PURE__ */ P(f, {
257
- value: c.type,
258
- onChange: h("type"),
259
- children: x(L)
267
+ children: /* @__PURE__ */ F(f, {
268
+ value: u.type,
269
+ onChange: g("type"),
270
+ children: x(R)
260
271
  })
261
- }), /* @__PURE__ */ P(l, {
272
+ }), /* @__PURE__ */ F(l, {
262
273
  label: "Status",
263
- children: /* @__PURE__ */ P(f, {
264
- value: c.status,
265
- onChange: h("status"),
266
- children: x(R)
274
+ children: /* @__PURE__ */ F(f, {
275
+ value: u.status,
276
+ onChange: g("status"),
277
+ children: x(z)
267
278
  })
268
279
  })]
269
280
  }),
270
- /* @__PURE__ */ P(l, {
281
+ /* @__PURE__ */ F(l, {
271
282
  label: "Industry",
272
- children: /* @__PURE__ */ P(y, {
273
- value: c.industry,
274
- onChange: h("industry"),
283
+ children: /* @__PURE__ */ F(y, {
284
+ value: u.industry,
285
+ onChange: g("industry"),
275
286
  placeholder: "Financial services"
276
287
  })
277
288
  }),
278
- /* @__PURE__ */ F("div", {
289
+ /* @__PURE__ */ I("div", {
279
290
  className: "grid grid-cols-1 gap-3 sm:grid-cols-2",
280
- children: [/* @__PURE__ */ P(l, {
291
+ children: [/* @__PURE__ */ F(l, {
281
292
  label: "Contact name",
282
- children: /* @__PURE__ */ P(y, {
283
- value: c.contactName,
284
- onChange: h("contactName")
293
+ children: /* @__PURE__ */ F(y, {
294
+ value: u.contactName,
295
+ onChange: g("contactName")
285
296
  })
286
- }), /* @__PURE__ */ P(l, {
297
+ }), /* @__PURE__ */ F(l, {
287
298
  label: "Contact email",
288
- children: /* @__PURE__ */ P(y, {
299
+ children: /* @__PURE__ */ F(y, {
289
300
  type: "email",
290
- value: c.contactEmail,
291
- onChange: h("contactEmail")
301
+ value: u.contactEmail,
302
+ onChange: g("contactEmail")
292
303
  })
293
304
  })]
294
305
  }),
295
- /* @__PURE__ */ P(l, {
306
+ /* @__PURE__ */ F(l, {
296
307
  label: "Contact phone",
297
- children: /* @__PURE__ */ P(y, {
298
- value: c.contactPhone,
299
- onChange: h("contactPhone")
308
+ children: /* @__PURE__ */ F(y, {
309
+ value: u.contactPhone,
310
+ onChange: g("contactPhone")
300
311
  })
301
312
  }),
302
- /* @__PURE__ */ P(l, {
313
+ /* @__PURE__ */ F(l, {
303
314
  label: "Notes",
304
- children: /* @__PURE__ */ P(v, {
305
- value: c.notes,
306
- onChange: h("notes")
315
+ children: /* @__PURE__ */ F(v, {
316
+ value: u.notes,
317
+ onChange: g("notes")
307
318
  })
308
319
  })
309
320
  ]
@@ -311,6 +322,6 @@ var L = ["ORGANIZATION", "INDIVIDUAL"], R = [
311
322
  });
312
323
  };
313
324
  //#endregion
314
- export { H as ClientsPage };
325
+ export { U as ClientsPage };
315
326
 
316
327
  //# sourceMappingURL=ClientsPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ClientsPage.js","names":[],"sources":["../../../src/proserviceworld/pages/ClientsPage.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useMemo, useState } from 'react';\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport { Plus, Search, Users, Pencil, Archive, Building2, User, ChevronRight } from 'lucide-react';\nimport {\n useClients,\n useCreateClient,\n useUpdateClient,\n useArchiveClient,\n type PswClient,\n type PswClientStatus,\n} from '../hooks/useProServiceWorldApi';\nimport { useNav } from '../utils/nav';\nimport { cn } from '../utils/cn';\nimport {\n PageHeader,\n SectionCard,\n LoadingBlock,\n ErrorState,\n Empty,\n StatusPill,\n Modal,\n Field,\n TextInput,\n TextArea,\n NativeSelect,\n Banner,\n TableWrap,\n Th,\n Td,\n enumOptions,\n fmtDate,\n} from '../components/ui';\n\nconst CLIENT_TYPES = ['ORGANIZATION', 'INDIVIDUAL'] as const;\nconst CLIENT_STATUSES: PswClientStatus[] = ['PROSPECT', 'ACTIVE', 'INACTIVE', 'ARCHIVED'];\n\nconst initials = (name: string): string =>\n name\n .split(/\\s+/)\n .filter(Boolean)\n .slice(0, 2)\n .map((w) => w[0]?.toUpperCase() ?? '')\n .join('') || '?';\n\n/** Tinted initials avatar (semantic tokens only). */\nexport const Avatar: FC<{ name: string; className?: string }> = ({ name, className }) => (\n <span\n className={cn(\n 'flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-accent/10 text-xs font-semibold text-accent ring-1 ring-inset ring-accent/15',\n className\n )}\n aria-hidden\n >\n {initials(name)}\n </span>\n);\n\ninterface FormState {\n name: string;\n type: string;\n status: string;\n industry: string;\n contactName: string;\n contactEmail: string;\n contactPhone: string;\n notes: string;\n}\nconst emptyForm: FormState = {\n name: '',\n type: 'ORGANIZATION',\n status: 'PROSPECT',\n industry: '',\n contactName: '',\n contactEmail: '',\n contactPhone: '',\n notes: '',\n};\n\nexport const ClientsPage: FC = () => {\n const nav = useNav();\n const [search, setSearch] = useState('');\n const [statusFilter, setStatusFilter] = useState<PswClientStatus | ''>('');\n const [editing, setEditing] = useState<PswClient | null>(null);\n const [creating, setCreating] = useState(false);\n const [banner, setBanner] = useState<{ tone: 'success' | 'danger'; text: string } | null>(null);\n\n const { data, isLoading, error, refetch } = useClients({\n search: search.trim() || undefined,\n status: statusFilter || undefined,\n });\n\n return (\n <div className=\"space-y-6\">\n <PageHeader\n title=\"Clients\"\n subtitle=\"Every person or organization your firm serves — the record engagements, matters, documents and invoices hang off.\"\n icon={<Users className=\"h-6 w-6\" />}\n actions={\n <Button onClick={() => setCreating(true)}>\n <Plus className=\"mr-1.5 h-4 w-4\" /> New client\n </Button>\n }\n />\n\n {banner && (\n <Banner tone={banner.tone} onClose={() => setBanner(null)}>\n {banner.text}\n </Banner>\n )}\n\n <div className=\"flex flex-col gap-2 sm:flex-row sm:items-center\">\n <div className=\"relative flex-1\">\n <Search className=\"pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-tertiary\" />\n <TextInput\n placeholder=\"Search clients…\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n className=\"pl-9\"\n />\n </div>\n <NativeSelect\n value={statusFilter}\n onChange={(e) => setStatusFilter(e.target.value as PswClientStatus | '')}\n className=\"sm:w-48\"\n >\n <option value=\"\">All statuses</option>\n {enumOptions(CLIENT_STATUSES)}\n </NativeSelect>\n </div>\n\n {isLoading ? (\n <LoadingBlock />\n ) : error ? (\n <ErrorState error={error} onRetry={() => void refetch()} />\n ) : !data || data.items.length === 0 ? (\n <Empty\n title=\"No clients yet\"\n description=\"Add your first client to start scoping engagements and matters.\"\n icon={<Users className=\"h-8 w-8\" />}\n action={\n <Button onClick={() => setCreating(true)}>\n <Plus className=\"mr-1.5 h-4 w-4\" /> New client\n </Button>\n }\n />\n ) : (\n <SectionCard title={`${data.totalCount} client${data.totalCount === 1 ? '' : 's'}`}>\n <TableWrap>\n <thead>\n <tr>\n <Th>Name</Th>\n <Th>Type</Th>\n <Th>Industry</Th>\n <Th>Status</Th>\n <Th>Added</Th>\n <Th className=\"text-right\">Actions</Th>\n </tr>\n </thead>\n <tbody>\n {data.items.map((c) => (\n <tr\n key={c.id}\n className=\"group cursor-pointer transition-colors hover:bg-bg-sunken/60\"\n onClick={() => nav(`clients/${c.id}`)}\n >\n <Td>\n <div className=\"flex items-center gap-3\">\n <Avatar name={c.name} />\n <div className=\"min-w-0\">\n <div className=\"flex items-center gap-1 font-medium text-text-primary transition-colors group-hover:text-accent\">\n <span className=\"truncate\">{c.name}</span>\n <ChevronRight className=\"h-3.5 w-3.5 shrink-0 text-text-tertiary opacity-0 transition-opacity group-hover:opacity-100\" />\n </div>\n {c.contactName ? (\n <div className=\"truncate text-xs text-text-tertiary\">{c.contactName}</div>\n ) : null}\n </div>\n </div>\n </Td>\n <Td>\n <span className=\"inline-flex items-center gap-1.5 text-text-secondary\">\n {c.type === 'ORGANIZATION' ? (\n <Building2 className=\"h-3.5 w-3.5 text-text-tertiary\" />\n ) : (\n <User className=\"h-3.5 w-3.5 text-text-tertiary\" />\n )}\n {c.type === 'ORGANIZATION' ? 'Organization' : 'Individual'}\n </span>\n </Td>\n <Td>{c.industry || '—'}</Td>\n <Td>\n <StatusPill status={c.status} />\n </Td>\n <Td className=\"whitespace-nowrap\">{fmtDate(c.createdAt)}</Td>\n <Td className=\"text-right\">\n <div\n className=\"flex justify-end gap-1\"\n onClick={(ev) => ev.stopPropagation()}\n role=\"presentation\"\n >\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => setEditing(c)}\n aria-label=\"Edit\"\n >\n <Pencil className=\"h-4 w-4\" />\n </Button>\n {c.status !== 'ARCHIVED' && (\n <ArchiveButton\n id={c.id}\n onDone={(ok) =>\n setBanner(\n ok\n ? { tone: 'success', text: `${c.name} archived.` }\n : { tone: 'danger', text: 'Could not archive client.' }\n )\n }\n />\n )}\n </div>\n </Td>\n </tr>\n ))}\n </tbody>\n </TableWrap>\n </SectionCard>\n )}\n\n {creating && (\n <ClientModal\n onClose={() => setCreating(false)}\n onSaved={(name) => setBanner({ tone: 'success', text: `${name} created.` })}\n />\n )}\n {editing && (\n <ClientModal\n client={editing}\n onClose={() => setEditing(null)}\n onSaved={(name) => setBanner({ tone: 'success', text: `${name} updated.` })}\n />\n )}\n </div>\n );\n};\n\nconst ArchiveButton: FC<{ id: string; onDone: (ok: boolean) => void }> = ({ id, onDone }) => {\n const archive = useArchiveClient();\n return (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n aria-label=\"Archive\"\n disabled={archive.isPending}\n onClick={() => {\n if (!window.confirm('Archive this client? Their engagements and matters remain.')) return;\n archive.mutate(id, { onSuccess: (r) => onDone(Boolean(r)), onError: () => onDone(false) });\n }}\n >\n <Archive className=\"h-4 w-4\" />\n </Button>\n );\n};\n\nconst ClientModal: FC<{\n client?: PswClient;\n onClose: () => void;\n onSaved: (name: string) => void;\n}> = ({ client, onClose, onSaved }) => {\n const create = useCreateClient();\n const update = useUpdateClient();\n const [form, setForm] = useState<FormState>(\n client\n ? {\n name: client.name,\n type: client.type,\n status: client.status,\n industry: client.industry ?? '',\n contactName: client.contactName ?? '',\n contactEmail: client.contactEmail ?? '',\n contactPhone: client.contactPhone ?? '',\n notes: client.notes ?? '',\n }\n : emptyForm\n );\n const [err, setErr] = useState<string | null>(null);\n const set = (k: keyof FormState) => (e: { target: { value: string } }) =>\n setForm((f) => ({ ...f, [k]: e.target.value }));\n const pending = create.isPending || update.isPending;\n\n const payload = useMemo(\n () => ({\n name: form.name.trim(),\n type: form.type,\n status: form.status,\n industry: form.industry.trim() || null,\n contactName: form.contactName.trim() || null,\n contactEmail: form.contactEmail.trim() || null,\n contactPhone: form.contactPhone.trim() || null,\n notes: form.notes.trim() || null,\n }),\n [form]\n );\n\n const submit = () => {\n setErr(null);\n if (!payload.name) return setErr('Client name is required.');\n const onError = (e: unknown) => setErr(e instanceof Error ? e.message : 'Save failed.');\n if (client) {\n update.mutate(\n { id: client.id, input: payload },\n {\n onSuccess: () => {\n onSaved(payload.name);\n onClose();\n },\n onError,\n }\n );\n } else {\n create.mutate(payload, {\n onSuccess: () => {\n onSaved(payload.name);\n onClose();\n },\n onError,\n });\n }\n };\n\n return (\n <Modal\n open\n onClose={onClose}\n title={client ? 'Edit client' : 'New client'}\n footer={\n <>\n <Button variant=\"outline\" onClick={onClose} disabled={pending}>\n Cancel\n </Button>\n <Button onClick={submit} disabled={pending}>\n {pending ? 'Saving…' : client ? 'Save changes' : 'Create client'}\n </Button>\n </>\n }\n >\n <div className=\"space-y-3\">\n {err && <Banner tone=\"danger\">{err}</Banner>}\n <Field label=\"Name\" required>\n <TextInput value={form.name} onChange={set('name')} placeholder=\"Acme Holdings Ltd.\" />\n </Field>\n <div className=\"grid grid-cols-2 gap-3\">\n <Field label=\"Type\">\n <NativeSelect value={form.type} onChange={set('type')}>\n {enumOptions(CLIENT_TYPES)}\n </NativeSelect>\n </Field>\n <Field label=\"Status\">\n <NativeSelect value={form.status} onChange={set('status')}>\n {enumOptions(CLIENT_STATUSES)}\n </NativeSelect>\n </Field>\n </div>\n <Field label=\"Industry\">\n <TextInput\n value={form.industry}\n onChange={set('industry')}\n placeholder=\"Financial services\"\n />\n </Field>\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n <Field label=\"Contact name\">\n <TextInput value={form.contactName} onChange={set('contactName')} />\n </Field>\n <Field label=\"Contact email\">\n <TextInput type=\"email\" value={form.contactEmail} onChange={set('contactEmail')} />\n </Field>\n </div>\n <Field label=\"Contact phone\">\n <TextInput value={form.contactPhone} onChange={set('contactPhone')} />\n </Field>\n <Field label=\"Notes\">\n <TextArea value={form.notes} onChange={set('notes')} />\n </Field>\n </div>\n </Modal>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"ClientsPage.js","names":[],"sources":["../../../src/proserviceworld/pages/ClientsPage.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useMemo, useState } from 'react';\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport { Plus, Search, Users, Pencil, Archive, Building2, User, ChevronRight } from 'lucide-react';\nimport {\n useClients,\n useCreateClient,\n useUpdateClient,\n useArchiveClient,\n type PswClient,\n type PswClientStatus,\n} from '../hooks/useProServiceWorldApi';\nimport { useNav } from '../utils/nav';\nimport { cn } from '../utils/cn';\nimport { useAnalytics } from '../hooks/useAnalytics';\nimport {\n PageHeader,\n SectionCard,\n LoadingBlock,\n ErrorState,\n Empty,\n StatusPill,\n Modal,\n Field,\n TextInput,\n TextArea,\n NativeSelect,\n Banner,\n TableWrap,\n Th,\n Td,\n enumOptions,\n fmtDate,\n} from '../components/ui';\n\nconst CLIENT_TYPES = ['ORGANIZATION', 'INDIVIDUAL'] as const;\nconst CLIENT_STATUSES: PswClientStatus[] = ['PROSPECT', 'ACTIVE', 'INACTIVE', 'ARCHIVED'];\n\nconst initials = (name: string): string =>\n name\n .split(/\\s+/)\n .filter(Boolean)\n .slice(0, 2)\n .map((w) => w[0]?.toUpperCase() ?? '')\n .join('') || '?';\n\n/** Tinted initials avatar (semantic tokens only). */\nexport const Avatar: FC<{ name: string; className?: string }> = ({ name, className }) => (\n <span\n className={cn(\n 'flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-accent/10 text-xs font-semibold text-accent ring-1 ring-inset ring-accent/15',\n className\n )}\n aria-hidden\n >\n {initials(name)}\n </span>\n);\n\ninterface FormState {\n name: string;\n type: string;\n status: string;\n industry: string;\n contactName: string;\n contactEmail: string;\n contactPhone: string;\n notes: string;\n}\nconst emptyForm: FormState = {\n name: '',\n type: 'ORGANIZATION',\n status: 'PROSPECT',\n industry: '',\n contactName: '',\n contactEmail: '',\n contactPhone: '',\n notes: '',\n};\n\nexport const ClientsPage: FC = () => {\n const nav = useNav();\n const { emitIntent, emitFact } = useAnalytics();\n const [search, setSearch] = useState('');\n const [statusFilter, setStatusFilter] = useState<PswClientStatus | ''>('');\n const [editing, setEditing] = useState<PswClient | null>(null);\n const [creating, setCreating] = useState(false);\n const [banner, setBanner] = useState<{ tone: 'success' | 'danger'; text: string } | null>(null);\n\n const { data, isLoading, error, refetch } = useClients({\n search: search.trim() || undefined,\n status: statusFilter || undefined,\n });\n\n return (\n <div className=\"space-y-6\">\n <PageHeader\n title=\"Clients\"\n subtitle=\"Every person or organization your firm serves — the record engagements, matters, documents and invoices hang off.\"\n icon={<Users className=\"h-6 w-6\" />}\n actions={\n <Button\n onClick={() => {\n emitIntent('psw.client.create_clicked');\n setCreating(true);\n }}\n >\n <Plus className=\"mr-1.5 h-4 w-4\" /> New client\n </Button>\n }\n />\n\n {banner && (\n <Banner tone={banner.tone} onClose={() => setBanner(null)}>\n {banner.text}\n </Banner>\n )}\n\n <div className=\"flex flex-col gap-2 sm:flex-row sm:items-center\">\n <div className=\"relative flex-1\">\n <Search className=\"pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-tertiary\" />\n <TextInput\n placeholder=\"Search clients…\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' && search.trim()) {\n emitFact('psw.search.performed', {\n entityType: 'client',\n queryLength: search.trim().length,\n });\n }\n }}\n className=\"pl-9\"\n />\n </div>\n <NativeSelect\n value={statusFilter}\n onChange={(e) => setStatusFilter(e.target.value as PswClientStatus | '')}\n className=\"sm:w-48\"\n >\n <option value=\"\">All statuses</option>\n {enumOptions(CLIENT_STATUSES)}\n </NativeSelect>\n </div>\n\n {isLoading ? (\n <LoadingBlock />\n ) : error ? (\n <ErrorState error={error} onRetry={() => void refetch()} />\n ) : !data || data.items.length === 0 ? (\n <Empty\n title=\"No clients yet\"\n description=\"Add your first client to start scoping engagements and matters.\"\n icon={<Users className=\"h-8 w-8\" />}\n action={\n <Button onClick={() => setCreating(true)}>\n <Plus className=\"mr-1.5 h-4 w-4\" /> New client\n </Button>\n }\n />\n ) : (\n <SectionCard title={`${data.totalCount} client${data.totalCount === 1 ? '' : 's'}`}>\n <TableWrap>\n <thead>\n <tr>\n <Th>Name</Th>\n <Th>Type</Th>\n <Th>Industry</Th>\n <Th>Status</Th>\n <Th>Added</Th>\n <Th className=\"text-right\">Actions</Th>\n </tr>\n </thead>\n <tbody>\n {data.items.map((c) => (\n <tr\n key={c.id}\n className=\"group cursor-pointer transition-colors hover:bg-bg-sunken/60\"\n onClick={() => nav(`clients/${c.id}`)}\n >\n <Td>\n <div className=\"flex items-center gap-3\">\n <Avatar name={c.name} />\n <div className=\"min-w-0\">\n <div className=\"flex items-center gap-1 font-medium text-text-primary transition-colors group-hover:text-accent\">\n <span className=\"truncate\">{c.name}</span>\n <ChevronRight className=\"h-3.5 w-3.5 shrink-0 text-text-tertiary opacity-0 transition-opacity group-hover:opacity-100\" />\n </div>\n {c.contactName ? (\n <div className=\"truncate text-xs text-text-tertiary\">{c.contactName}</div>\n ) : null}\n </div>\n </div>\n </Td>\n <Td>\n <span className=\"inline-flex items-center gap-1.5 text-text-secondary\">\n {c.type === 'ORGANIZATION' ? (\n <Building2 className=\"h-3.5 w-3.5 text-text-tertiary\" />\n ) : (\n <User className=\"h-3.5 w-3.5 text-text-tertiary\" />\n )}\n {c.type === 'ORGANIZATION' ? 'Organization' : 'Individual'}\n </span>\n </Td>\n <Td>{c.industry || '—'}</Td>\n <Td>\n <StatusPill status={c.status} />\n </Td>\n <Td className=\"whitespace-nowrap\">{fmtDate(c.createdAt)}</Td>\n <Td className=\"text-right\">\n <div\n className=\"flex justify-end gap-1\"\n onClick={(ev) => ev.stopPropagation()}\n role=\"presentation\"\n >\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => setEditing(c)}\n aria-label=\"Edit\"\n >\n <Pencil className=\"h-4 w-4\" />\n </Button>\n {c.status !== 'ARCHIVED' && (\n <ArchiveButton\n id={c.id}\n onDone={(ok) =>\n setBanner(\n ok\n ? { tone: 'success', text: `${c.name} archived.` }\n : { tone: 'danger', text: 'Could not archive client.' }\n )\n }\n />\n )}\n </div>\n </Td>\n </tr>\n ))}\n </tbody>\n </TableWrap>\n </SectionCard>\n )}\n\n {creating && (\n <ClientModal\n onClose={() => setCreating(false)}\n onSaved={(name) => setBanner({ tone: 'success', text: `${name} created.` })}\n />\n )}\n {editing && (\n <ClientModal\n client={editing}\n onClose={() => setEditing(null)}\n onSaved={(name) => setBanner({ tone: 'success', text: `${name} updated.` })}\n />\n )}\n </div>\n );\n};\n\nconst ArchiveButton: FC<{ id: string; onDone: (ok: boolean) => void }> = ({ id, onDone }) => {\n const archive = useArchiveClient();\n const { emitFact } = useAnalytics();\n return (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n aria-label=\"Archive\"\n disabled={archive.isPending}\n onClick={() => {\n if (!window.confirm('Archive this client? Their engagements and matters remain.')) return;\n archive.mutate(id, {\n onSuccess: (r) => {\n emitFact('psw.client.archived', { clientId: id });\n onDone(Boolean(r));\n },\n onError: () => onDone(false),\n });\n }}\n >\n <Archive className=\"h-4 w-4\" />\n </Button>\n );\n};\n\nconst ClientModal: FC<{\n client?: PswClient;\n onClose: () => void;\n onSaved: (name: string) => void;\n}> = ({ client, onClose, onSaved }) => {\n const create = useCreateClient();\n const update = useUpdateClient();\n const { emitFact } = useAnalytics();\n const [form, setForm] = useState<FormState>(\n client\n ? {\n name: client.name,\n type: client.type,\n status: client.status,\n industry: client.industry ?? '',\n contactName: client.contactName ?? '',\n contactEmail: client.contactEmail ?? '',\n contactPhone: client.contactPhone ?? '',\n notes: client.notes ?? '',\n }\n : emptyForm\n );\n const [err, setErr] = useState<string | null>(null);\n const set = (k: keyof FormState) => (e: { target: { value: string } }) =>\n setForm((f) => ({ ...f, [k]: e.target.value }));\n const pending = create.isPending || update.isPending;\n\n const payload = useMemo(\n () => ({\n name: form.name.trim(),\n type: form.type,\n status: form.status,\n industry: form.industry.trim() || null,\n contactName: form.contactName.trim() || null,\n contactEmail: form.contactEmail.trim() || null,\n contactPhone: form.contactPhone.trim() || null,\n notes: form.notes.trim() || null,\n }),\n [form]\n );\n\n const submit = () => {\n setErr(null);\n if (!payload.name) return setErr('Client name is required.');\n const onError = (e: unknown) => setErr(e instanceof Error ? e.message : 'Save failed.');\n if (client) {\n update.mutate(\n { id: client.id, input: payload },\n {\n onSuccess: () => {\n emitFact('psw.client.updated', { clientId: client.id });\n onSaved(payload.name);\n onClose();\n },\n onError,\n }\n );\n } else {\n create.mutate(payload, {\n onSuccess: (created) => {\n emitFact('psw.client.created', { clientId: created.pswCreateClient.id });\n onSaved(payload.name);\n onClose();\n },\n onError,\n });\n }\n };\n\n return (\n <Modal\n open\n onClose={onClose}\n title={client ? 'Edit client' : 'New client'}\n footer={\n <>\n <Button variant=\"outline\" onClick={onClose} disabled={pending}>\n Cancel\n </Button>\n <Button onClick={submit} disabled={pending}>\n {pending ? 'Saving…' : client ? 'Save changes' : 'Create client'}\n </Button>\n </>\n }\n >\n <div className=\"space-y-3\">\n {err && <Banner tone=\"danger\">{err}</Banner>}\n <Field label=\"Name\" required>\n <TextInput value={form.name} onChange={set('name')} placeholder=\"Acme Holdings Ltd.\" />\n </Field>\n <div className=\"grid grid-cols-2 gap-3\">\n <Field label=\"Type\">\n <NativeSelect value={form.type} onChange={set('type')}>\n {enumOptions(CLIENT_TYPES)}\n </NativeSelect>\n </Field>\n <Field label=\"Status\">\n <NativeSelect value={form.status} onChange={set('status')}>\n {enumOptions(CLIENT_STATUSES)}\n </NativeSelect>\n </Field>\n </div>\n <Field label=\"Industry\">\n <TextInput\n value={form.industry}\n onChange={set('industry')}\n placeholder=\"Financial services\"\n />\n </Field>\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n <Field label=\"Contact name\">\n <TextInput value={form.contactName} onChange={set('contactName')} />\n </Field>\n <Field label=\"Contact email\">\n <TextInput type=\"email\" value={form.contactEmail} onChange={set('contactEmail')} />\n </Field>\n </div>\n <Field label=\"Contact phone\">\n <TextInput value={form.contactPhone} onChange={set('contactPhone')} />\n </Field>\n <Field label=\"Notes\">\n <TextArea value={form.notes} onChange={set('notes')} />\n </Field>\n </div>\n </Modal>\n );\n};\n"],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { FC } from 'react';
2
+
3
+ export declare const CompliancePage: FC;
4
+ //# sourceMappingURL=CompliancePage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CompliancePage.d.ts","sourceRoot":"","sources":["../../../src/proserviceworld/pages/CompliancePage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAa,MAAM,OAAO,CAAC;AAoE3C,eAAO,MAAM,cAAc,EAAE,EAsK5B,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { FC } from 'react';
2
+
3
+ export declare const ConflictsPage: FC;
4
+ //# sourceMappingURL=ConflictsPage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConflictsPage.d.ts","sourceRoot":"","sources":["../../../src/proserviceworld/pages/ConflictsPage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAsChC,eAAO,MAAM,aAAa,EAAE,EA+G3B,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { FC } from 'react';
2
+
3
+ export declare const DashboardPage: FC;
4
+ //# sourceMappingURL=DashboardPage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DashboardPage.d.ts","sourceRoot":"","sources":["../../../src/proserviceworld/pages/DashboardPage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAa,MAAM,OAAO,CAAC;AA0C3C,eAAO,MAAM,aAAa,EAAE,EA0G3B,CAAC"}