@burdenoff/microfe-proserviceworld 2026.801.1 → 2026.830.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 (37) hide show
  1. package/dist/index.js +4 -4
  2. package/dist/proserviceworld/hooks/useActorNames.d.ts +16 -0
  3. package/dist/proserviceworld/hooks/useActorNames.d.ts.map +1 -0
  4. package/dist/proserviceworld/hooks/useActorNames.js +18 -0
  5. package/dist/proserviceworld/hooks/useActorNames.js.map +1 -0
  6. package/dist/proserviceworld/hooks/useProServiceWorldApi.d.ts +53 -0
  7. package/dist/proserviceworld/hooks/useProServiceWorldApi.d.ts.map +1 -1
  8. package/dist/proserviceworld/hooks/useProServiceWorldApi.js +289 -227
  9. package/dist/proserviceworld/hooks/useProServiceWorldApi.js.map +1 -1
  10. package/dist/proserviceworld/hooks/useTr.d.ts +19 -0
  11. package/dist/proserviceworld/hooks/useTr.d.ts.map +1 -0
  12. package/dist/proserviceworld/hooks/useTr.js +33 -0
  13. package/dist/proserviceworld/hooks/useTr.js.map +1 -0
  14. package/dist/proserviceworld/i18n/index.d.ts +1 -1
  15. package/dist/proserviceworld/i18n/index.d.ts.map +1 -1
  16. package/dist/proserviceworld/i18n/index.js +723 -18
  17. package/dist/proserviceworld/i18n/index.js.map +1 -1
  18. package/dist/proserviceworld/index.js +4 -4
  19. package/dist/proserviceworld/pages/ClientDetailPage.d.ts.map +1 -1
  20. package/dist/proserviceworld/pages/ClientDetailPage.js +268 -144
  21. package/dist/proserviceworld/pages/ClientDetailPage.js.map +1 -1
  22. package/dist/proserviceworld/pages/ClientsPage.d.ts.map +1 -1
  23. package/dist/proserviceworld/pages/ClientsPage.js +324 -241
  24. package/dist/proserviceworld/pages/ClientsPage.js.map +1 -1
  25. package/dist/proserviceworld/pages/DashboardPage.d.ts.map +1 -1
  26. package/dist/proserviceworld/pages/DashboardPage.js +152 -142
  27. package/dist/proserviceworld/pages/DashboardPage.js.map +1 -1
  28. package/dist/proserviceworld/pages/EngagementDetailPage.d.ts.map +1 -1
  29. package/dist/proserviceworld/pages/EngagementDetailPage.js +420 -186
  30. package/dist/proserviceworld/pages/EngagementDetailPage.js.map +1 -1
  31. package/dist/proserviceworld/pages/EngagementsPage.d.ts.map +1 -1
  32. package/dist/proserviceworld/pages/EngagementsPage.js +135 -135
  33. package/dist/proserviceworld/pages/EngagementsPage.js.map +1 -1
  34. package/dist/proserviceworld/pages/MattersPage.d.ts.map +1 -1
  35. package/dist/proserviceworld/pages/MattersPage.js +204 -197
  36. package/dist/proserviceworld/pages/MattersPage.js.map +1 -1
  37. package/package.json +2 -2
@@ -1,27 +1,27 @@
1
1
  import { useArchiveClient as e, useClients as t, useCreateClient as n, useUpdateClient as r } from "../hooks/useProServiceWorldApi.js";
2
2
  import { useNav as i } from "../utils/nav.js";
3
3
  import { cn as a } from "../utils/cn.js";
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 { t as C } from "../i18n/index.js";
4
+ import { useTr as o } from "../hooks/useTr.js";
5
+ import { Banner as s, Empty as c, ErrorState as l, Field as u, LoadingBlock as d, Modal as f, NativeSelect as p, PageHeader as m, SectionCard as h, StatusPill as g, TableWrap as _, Td as v, TextArea as y, TextInput as b, Th as x, enumOptions as S, fmtDate as C } from "../components/ui.js";
6
6
  import { useAnalytics as w } from "../hooks/useAnalytics.js";
7
7
  import { impactFeedback as T } from "../utils/native.js";
8
8
  import { TagPicker as E } from "../components/TagPicker.js";
9
- import { LoadMore as D } from "../components/LoadMore.js";
10
- import { useMemo as O, useState as k } from "react";
11
- import { Archive as A, Building2 as ee, ChevronRight as te, Pencil as ne, Plus as j, Search as M, User as N, Users as P } from "lucide-react";
12
- import { Fragment as F, jsx as I, jsxs as L } from "react/jsx-runtime";
13
- import { Button as R } from "@burdenoff/fe-libs/ui";
9
+ import { LoadMore as ee } from "../components/LoadMore.js";
10
+ import { useMemo as D, useState as O } from "react";
11
+ import { Archive as k, Building2 as te, ChevronRight as A, Pencil as j, Plus as M, Search as ne, User as re, Users as N } from "lucide-react";
12
+ import { Fragment as P, jsx as F, jsxs as I } from "react/jsx-runtime";
13
+ import { Button as L } from "@burdenoff/fe-libs/ui";
14
14
  //#region src/proserviceworld/pages/ClientsPage.tsx
15
- var z = ["ORGANIZATION", "INDIVIDUAL"], B = [
15
+ var R = ["ORGANIZATION", "INDIVIDUAL"], z = [
16
16
  "PROSPECT",
17
17
  "ACTIVE",
18
18
  "INACTIVE",
19
19
  "ARCHIVED"
20
- ], V = (e) => e.split(/\s+/).filter(Boolean).slice(0, 2).map((e) => e[0]?.toUpperCase() ?? "").join("") || "?", H = ({ name: e, className: t }) => /* @__PURE__ */ I("span", {
20
+ ], B = (e) => e.split(/\s+/).filter(Boolean).slice(0, 2).map((e) => e[0]?.toUpperCase() ?? "").join("") || "?", V = ({ name: e, className: t }) => /* @__PURE__ */ F("span", {
21
21
  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),
22
22
  "aria-hidden": !0,
23
- children: V(e)
24
- }), U = {
23
+ children: B(e)
24
+ }), H = {
25
25
  name: "",
26
26
  type: "ORGANIZATION",
27
27
  status: "PROSPECT",
@@ -30,220 +30,303 @@ var z = ["ORGANIZATION", "INDIVIDUAL"], B = [
30
30
  contactEmail: "",
31
31
  contactPhone: "",
32
32
  notes: ""
33
- }, W = 25, G = () => {
34
- let e = i(), { emitIntent: n, emitFact: a } = w(), [l, d] = k(""), [v, A] = k(""), [F, z] = k(null), [V, U] = k(!1), [G, q] = k(null), [ie, J] = k({
35
- limit: W,
33
+ }, U = 25, W = () => {
34
+ let e = i(), n = o(), { emitIntent: a, emitFact: u } = w(), [f, y] = O(""), [k, P] = O(""), [R, B] = O(null), [H, W] = O(!1), [q, J] = O(null), [ie, Y] = O({
35
+ limit: U,
36
36
  offset: 0
37
- }), { data: Y, isLoading: X, error: Z, refetch: Q } = t({
38
- search: l.trim() || void 0,
39
- status: v || void 0,
37
+ }), { data: X, isLoading: Z, error: Q, refetch: $ } = t({
38
+ search: f.trim() || void 0,
39
+ status: k || void 0,
40
40
  pagination: ie
41
- }), ae = r(), $ = O(() => Y?.items ?? [], [Y]);
42
- return /* @__PURE__ */ L("div", {
41
+ }), ae = r(), oe = D(() => X?.items ?? [], [X]);
42
+ return /* @__PURE__ */ I("div", {
43
43
  className: "space-y-6",
44
44
  children: [
45
- /* @__PURE__ */ I(p, {
46
- title: C("psw.clients.title"),
47
- subtitle: C("psw.clients.subtitle"),
48
- icon: /* @__PURE__ */ I(P, { className: "h-6 w-6" }),
49
- actions: /* @__PURE__ */ L(R, {
45
+ /* @__PURE__ */ F(m, {
46
+ title: n("psw.clients.title", "Clients"),
47
+ subtitle: n("psw.clients.subtitle", "Every person or organization your firm serves."),
48
+ icon: /* @__PURE__ */ F(N, { className: "h-6 w-6" }),
49
+ actions: /* @__PURE__ */ I(L, {
50
50
  onClick: () => {
51
- T("light"), n("psw.client.create_clicked"), U(!0);
51
+ T("light"), a("psw.client.create_clicked"), W(!0);
52
52
  },
53
53
  children: [
54
- /* @__PURE__ */ I(j, { className: "mr-1.5 h-4 w-4" }),
54
+ /* @__PURE__ */ F(M, { className: "mr-1.5 h-4 w-4" }),
55
55
  " ",
56
- C("psw.clients.new")
56
+ n("psw.clients.new", "New client")
57
57
  ]
58
58
  })
59
59
  }),
60
- G && /* @__PURE__ */ I(o, {
61
- tone: G.tone,
62
- onClose: () => q(null),
63
- children: G.text
60
+ q && /* @__PURE__ */ F(s, {
61
+ tone: q.tone,
62
+ onClose: () => J(null),
63
+ children: q.text
64
64
  }),
65
- /* @__PURE__ */ L("div", {
65
+ /* @__PURE__ */ I("div", {
66
66
  className: "flex flex-col gap-2 sm:flex-row sm:items-center",
67
- children: [/* @__PURE__ */ L("div", {
67
+ children: [/* @__PURE__ */ I("div", {
68
68
  className: "relative flex-1",
69
- children: [/* @__PURE__ */ I(M, { className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-tertiary" }), /* @__PURE__ */ I(y, {
70
- placeholder: C("psw.clients.searchPlaceholder"),
71
- value: l,
69
+ children: [/* @__PURE__ */ F(ne, { className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-tertiary" }), /* @__PURE__ */ F(b, {
70
+ placeholder: n("psw.clients.searchPlaceholder", "Search clients…"),
71
+ value: f,
72
72
  onChange: (e) => {
73
- d(e.target.value), J({
74
- limit: W,
73
+ y(e.target.value), Y({
74
+ limit: U,
75
75
  offset: 0
76
76
  });
77
77
  },
78
78
  onKeyDown: (e) => {
79
- e.key === "Enter" && l.trim() && a("psw.search.performed", {
79
+ e.key === "Enter" && f.trim() && u("psw.search.performed", {
80
80
  entityType: "client",
81
- queryLength: l.trim().length
81
+ queryLength: f.trim().length
82
82
  });
83
83
  },
84
84
  className: "pl-9"
85
85
  })]
86
- }), /* @__PURE__ */ L(f, {
87
- value: v,
86
+ }), /* @__PURE__ */ I(p, {
87
+ value: k,
88
88
  onChange: (e) => {
89
- A(e.target.value), J({
90
- limit: W,
89
+ P(e.target.value), Y({
90
+ limit: U,
91
91
  offset: 0
92
92
  });
93
93
  },
94
94
  className: "sm:w-48",
95
- children: [/* @__PURE__ */ I("option", {
95
+ children: [/* @__PURE__ */ F("option", {
96
96
  value: "",
97
- children: C("psw.clients.allStatuses")
98
- }), x(B)]
97
+ children: n("psw.clients.allStatuses", "All statuses")
98
+ }), S(z)]
99
99
  })]
100
100
  }),
101
- X ? /* @__PURE__ */ I(u, {}) : Z ? /* @__PURE__ */ I(c, {
102
- error: Z,
103
- onRetry: () => void Q()
104
- }) : !Y || Y.items.length === 0 ? /* @__PURE__ */ I(s, {
105
- title: C("psw.clients.emptyTitle"),
106
- description: C("psw.clients.emptyDescription"),
107
- icon: /* @__PURE__ */ I(P, { className: "h-8 w-8" }),
108
- action: /* @__PURE__ */ L(R, {
109
- onClick: () => U(!0),
101
+ Z ? /* @__PURE__ */ F(d, {}) : Q ? /* @__PURE__ */ F(l, {
102
+ error: Q,
103
+ onRetry: () => void $()
104
+ }) : !X || X.items.length === 0 ? /* @__PURE__ */ F(c, {
105
+ title: n("psw.clients.emptyTitle", "No clients yet"),
106
+ description: n("psw.clients.emptyDescription", "Add your first client to start scoping engagements and matters."),
107
+ icon: /* @__PURE__ */ F(N, { className: "h-8 w-8" }),
108
+ action: /* @__PURE__ */ I(L, {
109
+ onClick: () => W(!0),
110
110
  children: [
111
- /* @__PURE__ */ I(j, { className: "mr-1.5 h-4 w-4" }),
111
+ /* @__PURE__ */ F(M, { className: "mr-1.5 h-4 w-4" }),
112
112
  " ",
113
- C("psw.clients.new")
113
+ n("psw.clients.new", "New client")
114
114
  ]
115
115
  })
116
- }) : /* @__PURE__ */ L(m, {
117
- title: `${Y.totalCount} client${Y.totalCount === 1 ? "" : "s"}`,
118
- children: [/* @__PURE__ */ L(g, { children: [/* @__PURE__ */ I("thead", { children: /* @__PURE__ */ L("tr", { children: [
119
- /* @__PURE__ */ I(b, { children: C("psw.common.name") }),
120
- /* @__PURE__ */ I(b, { children: C("psw.common.type") }),
121
- /* @__PURE__ */ I(b, { children: "Industry" }),
122
- /* @__PURE__ */ I(b, { children: C("psw.common.status") }),
123
- /* @__PURE__ */ I(b, { children: C("psw.common.added") }),
124
- /* @__PURE__ */ I(b, { children: "Tags" }),
125
- /* @__PURE__ */ I(b, {
126
- className: "text-right",
127
- children: C("psw.common.actions")
128
- })
129
- ] }) }), /* @__PURE__ */ I("tbody", { children: Y.items.map((t) => /* @__PURE__ */ L("tr", {
130
- className: "group cursor-pointer transition-colors hover:bg-bg-sunken/60",
131
- onClick: () => e(`clients/${t.id}`),
132
- children: [
133
- /* @__PURE__ */ I(_, { children: /* @__PURE__ */ L("div", {
134
- className: "flex items-center gap-3",
135
- children: [/* @__PURE__ */ I(H, { name: t.name }), /* @__PURE__ */ L("div", {
136
- className: "min-w-0",
137
- children: [/* @__PURE__ */ L("div", {
138
- className: "flex items-center gap-1 font-medium text-text-primary transition-colors group-hover:text-accent",
139
- children: [/* @__PURE__ */ I("span", {
140
- className: "truncate",
141
- children: t.name
142
- }), /* @__PURE__ */ I(te, { className: "h-3.5 w-3.5 shrink-0 text-text-tertiary opacity-0 transition-opacity group-hover:opacity-100" })]
143
- }), t.contactName ? /* @__PURE__ */ I("div", {
144
- className: "truncate text-xs text-text-tertiary",
145
- children: t.contactName
146
- }) : null]
147
- })]
148
- }) }),
149
- /* @__PURE__ */ I(_, { children: /* @__PURE__ */ L("span", {
150
- className: "inline-flex items-center gap-1.5 text-text-secondary",
151
- children: [t.type === "ORGANIZATION" ? /* @__PURE__ */ I(ee, { className: "h-3.5 w-3.5 text-text-tertiary" }) : /* @__PURE__ */ I(N, { className: "h-3.5 w-3.5 text-text-tertiary" }), t.type === "ORGANIZATION" ? "Organization" : "Individual"]
152
- }) }),
153
- /* @__PURE__ */ I(_, { children: t.industry || "—" }),
154
- /* @__PURE__ */ I(_, { children: /* @__PURE__ */ I(h, { status: t.status }) }),
155
- /* @__PURE__ */ I(_, {
156
- className: "whitespace-nowrap",
157
- children: S(t.createdAt)
158
- }),
159
- /* @__PURE__ */ I(_, { children: /* @__PURE__ */ I("div", {
160
- onClick: (e) => e.stopPropagation(),
161
- role: "presentation",
162
- children: /* @__PURE__ */ I(E, {
163
- entityType: "PswClient",
164
- entityId: t.id,
165
- tags: t.tags ?? [],
166
- onChange: async (e) => {
167
- await ae.mutateAsync({
168
- id: t.id,
169
- input: { tags: e }
170
- }), Q();
116
+ }) : /* @__PURE__ */ I(h, {
117
+ title: X.totalCount === 1 ? n("psw.clients.count", "{{count}} client", { count: X.totalCount }) : n("psw.clients.countPlural", "{{count}} clients", { count: X.totalCount }),
118
+ children: [
119
+ /* @__PURE__ */ F("ul", {
120
+ className: "space-y-2.5 sm:hidden",
121
+ children: X.items.map((t) => /* @__PURE__ */ I("li", {
122
+ className: "overflow-hidden rounded-xl border border-border-seam bg-bg-canvas",
123
+ children: [/* @__PURE__ */ I("button", {
124
+ type: "button",
125
+ onClick: () => {
126
+ T("light"), e(`clients/${t.id}`);
171
127
  },
172
- maxTags: 5
173
- })
174
- }) }),
175
- /* @__PURE__ */ I(_, {
176
- className: "text-right",
177
- children: /* @__PURE__ */ L("div", {
178
- className: "flex justify-end gap-1",
179
- onClick: (e) => e.stopPropagation(),
180
- role: "presentation",
181
- children: [/* @__PURE__ */ I(R, {
182
- variant: "ghost",
183
- size: "sm",
184
- onClick: () => z(t),
185
- "aria-label": "Edit",
186
- children: /* @__PURE__ */ I(ne, { className: "h-4 w-4" })
187
- }), t.status !== "ARCHIVED" && /* @__PURE__ */ I(re, {
188
- id: t.id,
189
- onDone: (e) => q(e ? {
190
- tone: "success",
191
- text: `${t.name} archived.`
192
- } : {
193
- tone: "danger",
194
- text: "Could not archive client."
128
+ className: "flex w-full items-center gap-3 p-3.5 text-left transition-colors active:bg-bg-sunken/60",
129
+ children: [
130
+ /* @__PURE__ */ F(V, {
131
+ name: t.name,
132
+ className: "h-11 w-11 text-sm"
133
+ }),
134
+ /* @__PURE__ */ I("span", {
135
+ className: "min-w-0 flex-1",
136
+ children: [
137
+ /* @__PURE__ */ F("span", {
138
+ className: "block truncate text-sm font-semibold text-text-primary",
139
+ children: t.name
140
+ }),
141
+ /* @__PURE__ */ F("span", {
142
+ className: "mt-0.5 block truncate text-sm text-text-secondary",
143
+ children: t.contactName || (t.type === "ORGANIZATION" ? n("psw.clients.typeOrganization", "Organization") : n("psw.clients.typeIndividual", "Individual"))
144
+ }),
145
+ /* @__PURE__ */ I("span", {
146
+ className: "mt-1.5 flex items-center gap-2",
147
+ children: [/* @__PURE__ */ F("span", {
148
+ className: "truncate text-xs text-text-tertiary",
149
+ children: t.industry || C(t.createdAt)
150
+ }), /* @__PURE__ */ F(g, { status: t.status })]
151
+ })
152
+ ]
153
+ }),
154
+ /* @__PURE__ */ F(A, { className: "h-4 w-4 shrink-0 text-text-tertiary" })
155
+ ]
156
+ }), /* @__PURE__ */ I("div", {
157
+ className: "flex items-center justify-between gap-2 border-t border-border-seam px-3.5 py-2",
158
+ children: [/* @__PURE__ */ F("div", {
159
+ className: "min-w-0 flex-1",
160
+ children: /* @__PURE__ */ F(E, {
161
+ entityType: "PswClient",
162
+ entityId: t.id,
163
+ tags: t.tags ?? [],
164
+ onChange: async (e) => {
165
+ await ae.mutateAsync({
166
+ id: t.id,
167
+ input: { tags: e }
168
+ }), $();
169
+ },
170
+ maxTags: 5
195
171
  })
172
+ }), /* @__PURE__ */ I("div", {
173
+ className: "flex shrink-0 gap-1",
174
+ children: [/* @__PURE__ */ F(L, {
175
+ variant: "ghost",
176
+ size: "sm",
177
+ onClick: () => B(t),
178
+ "aria-label": n("psw.common.edit", "Edit"),
179
+ children: /* @__PURE__ */ F(j, { className: "h-4 w-4" })
180
+ }), t.status !== "ARCHIVED" && /* @__PURE__ */ F(G, {
181
+ id: t.id,
182
+ name: t.name,
183
+ onDone: (e) => J(e ? {
184
+ tone: "success",
185
+ text: n("psw.clients.archived", "{{name}} archived.", { name: t.name })
186
+ } : {
187
+ tone: "danger",
188
+ text: n("psw.clients.archiveFailed", "Could not archive client.")
189
+ })
190
+ })]
196
191
  })]
192
+ })]
193
+ }, t.id))
194
+ }),
195
+ /* @__PURE__ */ F("div", {
196
+ className: "hidden sm:block",
197
+ children: /* @__PURE__ */ I(_, { children: [/* @__PURE__ */ F("thead", { children: /* @__PURE__ */ I("tr", { children: [
198
+ /* @__PURE__ */ F(x, { children: n("psw.common.name", "Name") }),
199
+ /* @__PURE__ */ F(x, { children: n("psw.common.type", "Type") }),
200
+ /* @__PURE__ */ F(x, { children: n("psw.clients.tableIndustry", "Industry") }),
201
+ /* @__PURE__ */ F(x, { children: n("psw.common.status", "Status") }),
202
+ /* @__PURE__ */ F(x, { children: n("psw.common.added", "Added") }),
203
+ /* @__PURE__ */ F(x, { children: n("psw.clients.tableTags", "Tags") }),
204
+ /* @__PURE__ */ F(x, {
205
+ className: "text-right",
206
+ children: n("psw.common.actions", "Actions")
197
207
  })
198
- })
199
- ]
200
- }, t.id)) })] }), /* @__PURE__ */ I(D, {
201
- hasMore: Y?.pageInfo?.hasMore ?? !1,
202
- loading: X,
203
- loadedCount: $.length,
204
- totalCount: Y?.totalCount ?? $.length,
205
- onLoadMore: () => J((e) => ({
206
- limit: W,
207
- offset: e.offset + W
208
- }))
209
- })]
208
+ ] }) }), /* @__PURE__ */ F("tbody", { children: X.items.map((t) => /* @__PURE__ */ I("tr", {
209
+ className: "group cursor-pointer transition-colors hover:bg-bg-sunken/60",
210
+ onClick: () => e(`clients/${t.id}`),
211
+ children: [
212
+ /* @__PURE__ */ F(v, { children: /* @__PURE__ */ I("div", {
213
+ className: "flex items-center gap-3",
214
+ children: [/* @__PURE__ */ F(V, { name: t.name }), /* @__PURE__ */ I("div", {
215
+ className: "min-w-0",
216
+ children: [/* @__PURE__ */ I("div", {
217
+ className: "flex items-center gap-1 font-medium text-text-primary transition-colors group-hover:text-accent",
218
+ children: [/* @__PURE__ */ F("span", {
219
+ className: "truncate",
220
+ children: t.name
221
+ }), /* @__PURE__ */ F(A, { className: "h-3.5 w-3.5 shrink-0 text-text-tertiary opacity-0 transition-opacity group-hover:opacity-100" })]
222
+ }), t.contactName ? /* @__PURE__ */ F("div", {
223
+ className: "truncate text-xs text-text-tertiary",
224
+ children: t.contactName
225
+ }) : null]
226
+ })]
227
+ }) }),
228
+ /* @__PURE__ */ F(v, { children: /* @__PURE__ */ I("span", {
229
+ className: "inline-flex items-center gap-1.5 text-text-secondary",
230
+ children: [t.type === "ORGANIZATION" ? /* @__PURE__ */ F(te, { className: "h-3.5 w-3.5 text-text-tertiary" }) : /* @__PURE__ */ F(re, { className: "h-3.5 w-3.5 text-text-tertiary" }), t.type === "ORGANIZATION" ? n("psw.clients.typeOrganization", "Organization") : n("psw.clients.typeIndividual", "Individual")]
231
+ }) }),
232
+ /* @__PURE__ */ F(v, { children: t.industry || n("psw.common.dash", "—") }),
233
+ /* @__PURE__ */ F(v, { children: /* @__PURE__ */ F(g, { status: t.status }) }),
234
+ /* @__PURE__ */ F(v, {
235
+ className: "whitespace-nowrap",
236
+ children: C(t.createdAt)
237
+ }),
238
+ /* @__PURE__ */ F(v, { children: /* @__PURE__ */ F("div", {
239
+ onClick: (e) => e.stopPropagation(),
240
+ role: "presentation",
241
+ children: /* @__PURE__ */ F(E, {
242
+ entityType: "PswClient",
243
+ entityId: t.id,
244
+ tags: t.tags ?? [],
245
+ onChange: async (e) => {
246
+ await ae.mutateAsync({
247
+ id: t.id,
248
+ input: { tags: e }
249
+ }), $();
250
+ },
251
+ maxTags: 5
252
+ })
253
+ }) }),
254
+ /* @__PURE__ */ F(v, {
255
+ className: "text-right",
256
+ children: /* @__PURE__ */ I("div", {
257
+ className: "flex justify-end gap-1",
258
+ onClick: (e) => e.stopPropagation(),
259
+ role: "presentation",
260
+ children: [/* @__PURE__ */ F(L, {
261
+ variant: "ghost",
262
+ size: "sm",
263
+ onClick: () => B(t),
264
+ "aria-label": n("psw.common.edit", "Edit"),
265
+ children: /* @__PURE__ */ F(j, { className: "h-4 w-4" })
266
+ }), t.status !== "ARCHIVED" && /* @__PURE__ */ F(G, {
267
+ id: t.id,
268
+ name: t.name,
269
+ onDone: (e) => J(e ? {
270
+ tone: "success",
271
+ text: n("psw.clients.archived", "{{name}} archived.", { name: t.name })
272
+ } : {
273
+ tone: "danger",
274
+ text: n("psw.clients.archiveFailed", "Could not archive client.")
275
+ })
276
+ })]
277
+ })
278
+ })
279
+ ]
280
+ }, t.id)) })] })
281
+ }),
282
+ /* @__PURE__ */ F(ee, {
283
+ hasMore: X?.pageInfo?.hasMore ?? !1,
284
+ loading: Z,
285
+ loadedCount: oe.length,
286
+ totalCount: X?.totalCount ?? oe.length,
287
+ onLoadMore: () => Y((e) => ({
288
+ limit: U,
289
+ offset: e.offset + U
290
+ }))
291
+ })
292
+ ]
210
293
  }),
211
- V && /* @__PURE__ */ I(K, {
212
- onClose: () => U(!1),
213
- onSaved: (e) => q({
294
+ H && /* @__PURE__ */ F(K, {
295
+ onClose: () => W(!1),
296
+ onSaved: (e) => J({
214
297
  tone: "success",
215
- text: `${e} created.`
298
+ text: n("psw.clients.created", "{{name}} created.", { name: e })
216
299
  })
217
300
  }),
218
- F && /* @__PURE__ */ I(K, {
219
- client: F,
220
- onClose: () => z(null),
221
- onSaved: (e) => q({
301
+ R && /* @__PURE__ */ F(K, {
302
+ client: R,
303
+ onClose: () => B(null),
304
+ onSaved: (e) => J({
222
305
  tone: "success",
223
- text: `${e} updated.`
306
+ text: n("psw.clients.updated", "{{name}} updated.", { name: e })
224
307
  })
225
308
  })
226
309
  ]
227
310
  });
228
- }, re = ({ id: t, onDone: n }) => {
229
- let r = e(), { emitFact: i } = w();
230
- return /* @__PURE__ */ I(R, {
311
+ }, G = ({ id: t, name: n, onDone: r }) => {
312
+ let i = e(), a = o(), { emitFact: s } = w();
313
+ return /* @__PURE__ */ F(L, {
231
314
  variant: "ghost",
232
315
  size: "sm",
233
- "aria-label": "Archive",
234
- disabled: r.isPending,
316
+ "aria-label": a("psw.common.archive", "Archive"),
317
+ disabled: i.isPending,
235
318
  onClick: () => {
236
- window.confirm("Archive this client? Their engagements and matters remain.") && r.mutate(t, {
319
+ window.confirm(a("psw.clients.archiveConfirm", "Archive this client? Their engagements and matters remain.")) && i.mutate(t, {
237
320
  onSuccess: (e) => {
238
- i("psw.client.archived", { clientId: t }), n(!!e);
321
+ s("psw.client.archived", { clientId: t }), r(!!e);
239
322
  },
240
- onError: () => n(!1)
323
+ onError: () => r(!1)
241
324
  });
242
325
  },
243
- children: /* @__PURE__ */ I(A, { className: "h-4 w-4" })
326
+ children: /* @__PURE__ */ F(k, { className: "h-4 w-4" })
244
327
  });
245
328
  }, K = ({ client: e, onClose: t, onSaved: i }) => {
246
- let a = n(), s = r(), { emitFact: c } = w(), [u, p] = k(e ? {
329
+ let a = o(), c = n(), l = r(), { emitFact: d } = w(), [m, h] = O(e ? {
247
330
  name: e.name,
248
331
  type: e.type,
249
332
  status: e.status,
@@ -252,121 +335,121 @@ var z = ["ORGANIZATION", "INDIVIDUAL"], B = [
252
335
  contactEmail: e.contactEmail ?? "",
253
336
  contactPhone: e.contactPhone ?? "",
254
337
  notes: e.notes ?? ""
255
- } : U), [m, h] = k(null), g = (e) => (t) => p((n) => ({
338
+ } : H), [g, _] = O(null), v = (e) => (t) => h((n) => ({
256
339
  ...n,
257
340
  [e]: t.target.value
258
- })), _ = a.isPending || s.isPending, b = O(() => ({
259
- name: u.name.trim(),
260
- type: u.type,
261
- status: u.status,
262
- industry: u.industry.trim() || null,
263
- contactName: u.contactName.trim() || null,
264
- contactEmail: u.contactEmail.trim() || null,
265
- contactPhone: u.contactPhone.trim() || null,
266
- notes: u.notes.trim() || null
267
- }), [u]);
268
- return /* @__PURE__ */ I(d, {
341
+ })), x = c.isPending || l.isPending, C = D(() => ({
342
+ name: m.name.trim(),
343
+ type: m.type,
344
+ status: m.status,
345
+ industry: m.industry.trim() || null,
346
+ contactName: m.contactName.trim() || null,
347
+ contactEmail: m.contactEmail.trim() || null,
348
+ contactPhone: m.contactPhone.trim() || null,
349
+ notes: m.notes.trim() || null
350
+ }), [m]);
351
+ return /* @__PURE__ */ F(f, {
269
352
  open: !0,
270
353
  onClose: t,
271
- title: e ? "Edit client" : "New client",
272
- footer: /* @__PURE__ */ L(F, { children: [/* @__PURE__ */ I(R, {
354
+ title: e ? a("psw.clients.edit", "Edit client") : a("psw.clients.newTitle", "New client"),
355
+ footer: /* @__PURE__ */ I(P, { children: [/* @__PURE__ */ F(L, {
273
356
  variant: "outline",
274
357
  onClick: t,
275
- disabled: _,
276
- children: "Cancel"
277
- }), /* @__PURE__ */ I(R, {
358
+ disabled: x,
359
+ children: a("psw.common.cancel", "Cancel")
360
+ }), /* @__PURE__ */ F(L, {
278
361
  onClick: () => {
279
- if (h(null), !b.name) return h("Client name is required.");
280
- let n = (e) => h(e instanceof Error ? e.message : "Save failed.");
281
- e ? s.mutate({
362
+ if (_(null), !C.name) return _(a("psw.clients.nameRequired", "Client name is required."));
363
+ let n = (e) => _(e instanceof Error ? e.message : a("psw.clients.saveFailed", "Save failed."));
364
+ e ? l.mutate({
282
365
  id: e.id,
283
- input: b
366
+ input: C
284
367
  }, {
285
368
  onSuccess: () => {
286
- c("psw.client.updated", { clientId: e.id }), i(b.name), t();
369
+ d("psw.client.updated", { clientId: e.id }), i(C.name), t();
287
370
  },
288
371
  onError: n
289
- }) : a.mutate(b, {
372
+ }) : c.mutate(C, {
290
373
  onSuccess: (e) => {
291
- c("psw.client.created", { clientId: e.pswCreateClient.id }), i(b.name), t();
374
+ d("psw.client.created", { clientId: e.pswCreateClient.id }), i(C.name), t();
292
375
  },
293
376
  onError: n
294
377
  });
295
378
  },
296
- disabled: _,
297
- children: _ ? "Saving…" : e ? "Save changes" : "Create client"
379
+ disabled: x,
380
+ children: x ? a("psw.common.saving", "Saving…") : e ? a("psw.common.save", "Save changes") : a("psw.common.create", "Create client")
298
381
  })] }),
299
- children: /* @__PURE__ */ L("div", {
382
+ children: /* @__PURE__ */ I("div", {
300
383
  className: "space-y-3",
301
384
  children: [
302
- m && /* @__PURE__ */ I(o, {
385
+ g && /* @__PURE__ */ F(s, {
303
386
  tone: "danger",
304
- children: m
387
+ children: g
305
388
  }),
306
- /* @__PURE__ */ I(l, {
307
- label: "Name",
389
+ /* @__PURE__ */ F(u, {
390
+ label: a("psw.common.name", "Name"),
308
391
  required: !0,
309
- children: /* @__PURE__ */ I(y, {
310
- value: u.name,
311
- onChange: g("name"),
392
+ children: /* @__PURE__ */ F(b, {
393
+ value: m.name,
394
+ onChange: v("name"),
312
395
  placeholder: "Acme Holdings Ltd."
313
396
  })
314
397
  }),
315
- /* @__PURE__ */ L("div", {
398
+ /* @__PURE__ */ I("div", {
316
399
  className: "grid grid-cols-2 gap-3",
317
- children: [/* @__PURE__ */ I(l, {
318
- label: "Type",
319
- children: /* @__PURE__ */ I(f, {
320
- value: u.type,
321
- onChange: g("type"),
322
- children: x(z)
400
+ children: [/* @__PURE__ */ F(u, {
401
+ label: a("psw.common.type", "Type"),
402
+ children: /* @__PURE__ */ F(p, {
403
+ value: m.type,
404
+ onChange: v("type"),
405
+ children: S(R)
323
406
  })
324
- }), /* @__PURE__ */ I(l, {
325
- label: "Status",
326
- children: /* @__PURE__ */ I(f, {
327
- value: u.status,
328
- onChange: g("status"),
329
- children: x(B)
407
+ }), /* @__PURE__ */ F(u, {
408
+ label: a("psw.common.status", "Status"),
409
+ children: /* @__PURE__ */ F(p, {
410
+ value: m.status,
411
+ onChange: v("status"),
412
+ children: S(z)
330
413
  })
331
414
  })]
332
415
  }),
333
- /* @__PURE__ */ I(l, {
334
- label: "Industry",
335
- children: /* @__PURE__ */ I(y, {
336
- value: u.industry,
337
- onChange: g("industry"),
416
+ /* @__PURE__ */ F(u, {
417
+ label: a("psw.clients.industry", "Industry"),
418
+ children: /* @__PURE__ */ F(b, {
419
+ value: m.industry,
420
+ onChange: v("industry"),
338
421
  placeholder: "Financial services"
339
422
  })
340
423
  }),
341
- /* @__PURE__ */ L("div", {
424
+ /* @__PURE__ */ I("div", {
342
425
  className: "grid grid-cols-1 gap-3 sm:grid-cols-2",
343
- children: [/* @__PURE__ */ I(l, {
344
- label: "Contact name",
345
- children: /* @__PURE__ */ I(y, {
346
- value: u.contactName,
347
- onChange: g("contactName")
426
+ children: [/* @__PURE__ */ F(u, {
427
+ label: a("psw.clients.contactName", "Contact name"),
428
+ children: /* @__PURE__ */ F(b, {
429
+ value: m.contactName,
430
+ onChange: v("contactName")
348
431
  })
349
- }), /* @__PURE__ */ I(l, {
350
- label: "Contact email",
351
- children: /* @__PURE__ */ I(y, {
432
+ }), /* @__PURE__ */ F(u, {
433
+ label: a("psw.clients.contactEmail", "Contact email"),
434
+ children: /* @__PURE__ */ F(b, {
352
435
  type: "email",
353
- value: u.contactEmail,
354
- onChange: g("contactEmail")
436
+ value: m.contactEmail,
437
+ onChange: v("contactEmail")
355
438
  })
356
439
  })]
357
440
  }),
358
- /* @__PURE__ */ I(l, {
359
- label: "Contact phone",
360
- children: /* @__PURE__ */ I(y, {
361
- value: u.contactPhone,
362
- onChange: g("contactPhone")
441
+ /* @__PURE__ */ F(u, {
442
+ label: a("psw.clients.contactPhone", "Contact phone"),
443
+ children: /* @__PURE__ */ F(b, {
444
+ value: m.contactPhone,
445
+ onChange: v("contactPhone")
363
446
  })
364
447
  }),
365
- /* @__PURE__ */ I(l, {
366
- label: "Notes",
367
- children: /* @__PURE__ */ I(v, {
368
- value: u.notes,
369
- onChange: g("notes")
448
+ /* @__PURE__ */ F(u, {
449
+ label: a("psw.clients.notes", "Notes"),
450
+ children: /* @__PURE__ */ F(y, {
451
+ value: m.notes,
452
+ onChange: v("notes")
370
453
  })
371
454
  })
372
455
  ]
@@ -374,6 +457,6 @@ var z = ["ORGANIZATION", "INDIVIDUAL"], B = [
374
457
  });
375
458
  };
376
459
  //#endregion
377
- export { H as Avatar, G as ClientsPage };
460
+ export { V as Avatar, W as ClientsPage };
378
461
 
379
462
  //# sourceMappingURL=ClientsPage.js.map