@burdenoff/microfe-proserviceworld 2026.706.2 → 2026.706.3
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.
- package/dist/proserviceworld/components/DiscussionThread.js +1 -1
- package/dist/proserviceworld/components/DiscussionThread.js.map +1 -1
- package/dist/proserviceworld/components/ui.js +18 -18
- package/dist/proserviceworld/components/ui.js.map +1 -1
- package/dist/proserviceworld/hooks/useEntityComments.js.map +1 -1
- package/dist/proserviceworld/pages/AnalyticsPage.js +277 -111
- package/dist/proserviceworld/pages/AnalyticsPage.js.map +1 -1
- package/dist/proserviceworld/pages/ClientDetailPage.js +219 -151
- package/dist/proserviceworld/pages/ClientDetailPage.js.map +1 -1
- package/dist/proserviceworld/pages/ClientsPage.js +148 -127
- package/dist/proserviceworld/pages/ClientsPage.js.map +1 -1
- package/dist/proserviceworld/pages/CompliancePage.js +140 -96
- package/dist/proserviceworld/pages/CompliancePage.js.map +1 -1
- package/dist/proserviceworld/pages/DashboardPage.js +221 -104
- package/dist/proserviceworld/pages/DashboardPage.js.map +1 -1
- package/dist/proserviceworld/pages/EngagementDetailPage.js +211 -181
- package/dist/proserviceworld/pages/EngagementDetailPage.js.map +1 -1
- package/dist/proserviceworld/pages/EngagementsPage.js +144 -106
- package/dist/proserviceworld/pages/EngagementsPage.js.map +1 -1
- package/dist/proserviceworld/pages/InvoicesPage.js +144 -129
- package/dist/proserviceworld/pages/InvoicesPage.js.map +1 -1
- package/dist/proserviceworld/pages/MattersPage.js +163 -122
- package/dist/proserviceworld/pages/MattersPage.js.map +1 -1
- package/dist/proserviceworld/pages/TimePage.js +112 -92
- package/dist/proserviceworld/pages/TimePage.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,135 +1,173 @@
|
|
|
1
1
|
import { useClients as e, useCloseMatter as t, useCreateMatter as n, useMatters as r, usePracticeAreas as i } from "../hooks/useProServiceWorldApi.js";
|
|
2
|
-
import { Banner as a, Empty as o, ErrorState as s, Field as c, LoadingBlock as l,
|
|
3
|
-
import { useState as
|
|
4
|
-
import { CheckCircle2 as
|
|
5
|
-
import { Fragment as
|
|
6
|
-
import { Button as
|
|
2
|
+
import { Banner as a, Empty as o, ErrorState as s, Field as c, LoadingBlock as l, MetricCard 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";
|
|
3
|
+
import { useState as C } from "react";
|
|
4
|
+
import { AlertTriangle as w, CheckCircle2 as T, CircleDot as E, FolderKanban as D, Lock as O, Plus as k, Search as A } from "lucide-react";
|
|
5
|
+
import { Fragment as j, jsx as M, jsxs as N } from "react/jsx-runtime";
|
|
6
|
+
import { Button as P } from "@burdenoff/fe-libs/ui";
|
|
7
7
|
//#region src/proserviceworld/pages/MattersPage.tsx
|
|
8
|
-
var
|
|
8
|
+
var F = [
|
|
9
9
|
"OPEN",
|
|
10
10
|
"ON_HOLD",
|
|
11
11
|
"CLOSED",
|
|
12
12
|
"ARCHIVED"
|
|
13
|
-
],
|
|
13
|
+
], I = [
|
|
14
14
|
"LOW",
|
|
15
15
|
"MEDIUM",
|
|
16
16
|
"HIGH",
|
|
17
17
|
"CRITICAL"
|
|
18
|
-
],
|
|
19
|
-
|
|
18
|
+
], L = () => /* @__PURE__ */ M("span", {
|
|
19
|
+
className: "inline-flex h-5 w-5 shrink-0 items-center justify-center rounded-md bg-status-warning-bg-subtle text-status-warning-text",
|
|
20
|
+
title: "Privileged / confidential",
|
|
21
|
+
"aria-label": "Privileged",
|
|
22
|
+
children: /* @__PURE__ */ M(O, { className: "h-3 w-3" })
|
|
23
|
+
}), R = () => {
|
|
24
|
+
let [e, n] = C(""), [i, c] = C(""), [d, v] = C(!1), [I, R] = C(null), { data: B, isLoading: V, error: H, refetch: U } = r({
|
|
20
25
|
search: e.trim() || void 0,
|
|
21
26
|
status: i || void 0
|
|
22
|
-
}),
|
|
23
|
-
return /* @__PURE__ */
|
|
27
|
+
}), W = t(), G = B?.items ?? [], K = G.filter((e) => e.status === "OPEN").length, q = G.filter((e) => e.isPrivileged).length, J = G.filter((e) => e.priority === "HIGH" || e.priority === "CRITICAL").length;
|
|
28
|
+
return /* @__PURE__ */ N("div", {
|
|
24
29
|
className: "space-y-6",
|
|
25
30
|
children: [
|
|
26
|
-
/* @__PURE__ */
|
|
31
|
+
/* @__PURE__ */ M(p, {
|
|
27
32
|
title: "Matters",
|
|
28
33
|
subtitle: "The regulated threads of work — legal matters, audits, filings — with their own deadlines and sensitive-document handling.",
|
|
29
|
-
icon: /* @__PURE__ */
|
|
30
|
-
actions: /* @__PURE__ */
|
|
31
|
-
onClick: () =>
|
|
32
|
-
children: [/* @__PURE__ */ k
|
|
34
|
+
icon: /* @__PURE__ */ M(D, { className: "h-6 w-6" }),
|
|
35
|
+
actions: /* @__PURE__ */ N(P, {
|
|
36
|
+
onClick: () => v(!0),
|
|
37
|
+
children: [/* @__PURE__ */ M(k, { className: "mr-1.5 h-4 w-4" }), "New matter"]
|
|
33
38
|
})
|
|
34
39
|
}),
|
|
35
|
-
|
|
36
|
-
tone:
|
|
37
|
-
onClose: () =>
|
|
38
|
-
children:
|
|
40
|
+
I && /* @__PURE__ */ M(a, {
|
|
41
|
+
tone: I.tone,
|
|
42
|
+
onClose: () => R(null),
|
|
43
|
+
children: I.text
|
|
39
44
|
}),
|
|
40
|
-
/* @__PURE__ */
|
|
45
|
+
/* @__PURE__ */ N("div", {
|
|
41
46
|
className: "flex flex-col gap-2 sm:flex-row sm:items-center",
|
|
42
|
-
children: [/* @__PURE__ */
|
|
47
|
+
children: [/* @__PURE__ */ N("div", {
|
|
43
48
|
className: "relative flex-1",
|
|
44
|
-
children: [/* @__PURE__ */
|
|
49
|
+
children: [/* @__PURE__ */ M(A, { className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-tertiary" }), /* @__PURE__ */ M(y, {
|
|
45
50
|
placeholder: "Search matters…",
|
|
46
51
|
value: e,
|
|
47
52
|
onChange: (e) => n(e.target.value),
|
|
48
53
|
className: "pl-9"
|
|
49
54
|
})]
|
|
50
|
-
}), /* @__PURE__ */
|
|
55
|
+
}), /* @__PURE__ */ N(f, {
|
|
51
56
|
value: i,
|
|
52
57
|
onChange: (e) => c(e.target.value),
|
|
53
58
|
className: "sm:w-48",
|
|
54
|
-
children: [/* @__PURE__ */
|
|
59
|
+
children: [/* @__PURE__ */ M("option", {
|
|
55
60
|
value: "",
|
|
56
61
|
children: "All statuses"
|
|
57
|
-
}),
|
|
62
|
+
}), x(F)]
|
|
58
63
|
})]
|
|
59
64
|
}),
|
|
60
|
-
|
|
61
|
-
error:
|
|
62
|
-
onRetry: () => void
|
|
63
|
-
}) : !
|
|
65
|
+
V ? /* @__PURE__ */ M(l, {}) : H ? /* @__PURE__ */ M(s, {
|
|
66
|
+
error: H,
|
|
67
|
+
onRetry: () => void U()
|
|
68
|
+
}) : !B || B.items.length === 0 ? /* @__PURE__ */ M(o, {
|
|
64
69
|
title: "No matters yet",
|
|
65
70
|
description: "Open a matter to track a regulated thread of work for a client.",
|
|
66
|
-
icon: /* @__PURE__ */
|
|
67
|
-
action: /* @__PURE__ */
|
|
68
|
-
onClick: () =>
|
|
69
|
-
children: [/* @__PURE__ */ k
|
|
71
|
+
icon: /* @__PURE__ */ M(D, { className: "h-8 w-8" }),
|
|
72
|
+
action: /* @__PURE__ */ N(P, {
|
|
73
|
+
onClick: () => v(!0),
|
|
74
|
+
children: [/* @__PURE__ */ M(k, { className: "mr-1.5 h-4 w-4" }), "New matter"]
|
|
70
75
|
})
|
|
71
|
-
}) : /* @__PURE__ */
|
|
72
|
-
|
|
73
|
-
children:
|
|
74
|
-
/* @__PURE__ */
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
/* @__PURE__ */
|
|
76
|
+
}) : /* @__PURE__ */ N(j, { children: [/* @__PURE__ */ N("div", {
|
|
77
|
+
className: "grid grid-cols-2 gap-3 lg:grid-cols-4",
|
|
78
|
+
children: [
|
|
79
|
+
/* @__PURE__ */ M(u, {
|
|
80
|
+
label: "Matters",
|
|
81
|
+
value: B.totalCount,
|
|
82
|
+
icon: /* @__PURE__ */ M(D, { className: "h-4 w-4" })
|
|
83
|
+
}),
|
|
84
|
+
/* @__PURE__ */ M(u, {
|
|
85
|
+
label: "Open",
|
|
86
|
+
value: K,
|
|
87
|
+
icon: /* @__PURE__ */ M(E, { className: "h-4 w-4" }),
|
|
88
|
+
tone: "accent"
|
|
89
|
+
}),
|
|
90
|
+
/* @__PURE__ */ M(u, {
|
|
91
|
+
label: "Privileged",
|
|
92
|
+
value: q,
|
|
93
|
+
icon: /* @__PURE__ */ M(O, { className: "h-4 w-4" }),
|
|
94
|
+
tone: "warning"
|
|
95
|
+
}),
|
|
96
|
+
/* @__PURE__ */ M(u, {
|
|
97
|
+
label: "High priority",
|
|
98
|
+
value: J,
|
|
99
|
+
icon: /* @__PURE__ */ M(w, { className: "h-4 w-4" }),
|
|
100
|
+
tone: J ? "danger" : "neutral"
|
|
101
|
+
})
|
|
102
|
+
]
|
|
103
|
+
}), /* @__PURE__ */ M(m, {
|
|
104
|
+
title: `${B.totalCount} matter${B.totalCount === 1 ? "" : "s"}`,
|
|
105
|
+
children: /* @__PURE__ */ N(g, { children: [/* @__PURE__ */ M("thead", { children: /* @__PURE__ */ N("tr", { children: [
|
|
106
|
+
/* @__PURE__ */ M(b, { children: "Matter" }),
|
|
107
|
+
/* @__PURE__ */ M(b, { children: "Client" }),
|
|
108
|
+
/* @__PURE__ */ M(b, { children: "Priority" }),
|
|
109
|
+
/* @__PURE__ */ M(b, { children: "Status" }),
|
|
110
|
+
/* @__PURE__ */ M(b, { children: "Due" }),
|
|
111
|
+
/* @__PURE__ */ M(b, {
|
|
80
112
|
className: "text-right",
|
|
81
113
|
children: "Actions"
|
|
82
114
|
})
|
|
83
|
-
] }) }), /* @__PURE__ */
|
|
84
|
-
className: "hover:bg-bg-sunken/
|
|
115
|
+
] }) }), /* @__PURE__ */ M("tbody", { children: B.items.map((e) => /* @__PURE__ */ N("tr", {
|
|
116
|
+
className: "transition-colors hover:bg-bg-sunken/60",
|
|
85
117
|
children: [
|
|
86
|
-
/* @__PURE__ */
|
|
87
|
-
className: "flex items-center gap-
|
|
88
|
-
children: [e.isPrivileged && /* @__PURE__ */
|
|
89
|
-
className: "
|
|
90
|
-
|
|
91
|
-
})
|
|
92
|
-
}), e.reference ? /* @__PURE__ */
|
|
93
|
-
className: "text-xs text-text-tertiary",
|
|
94
|
-
children: e.reference
|
|
118
|
+
/* @__PURE__ */ N(_, { children: [/* @__PURE__ */ N("span", {
|
|
119
|
+
className: "flex items-center gap-2 font-medium text-text-primary",
|
|
120
|
+
children: [e.isPrivileged && /* @__PURE__ */ M(L, {}), /* @__PURE__ */ M("span", {
|
|
121
|
+
className: "truncate",
|
|
122
|
+
children: e.title
|
|
123
|
+
})]
|
|
124
|
+
}), e.reference ? /* @__PURE__ */ N("div", {
|
|
125
|
+
className: "mt-0.5 pl-0 text-xs text-text-tertiary",
|
|
126
|
+
children: ["Ref: ", e.reference]
|
|
95
127
|
}) : null] }),
|
|
96
|
-
/* @__PURE__ */
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
/* @__PURE__ */
|
|
128
|
+
/* @__PURE__ */ M(_, {
|
|
129
|
+
className: "text-text-primary",
|
|
130
|
+
children: e.client?.name ?? "—"
|
|
131
|
+
}),
|
|
132
|
+
/* @__PURE__ */ M(_, { children: /* @__PURE__ */ M(h, { status: e.priority }) }),
|
|
133
|
+
/* @__PURE__ */ M(_, { children: /* @__PURE__ */ M(h, { status: e.status }) }),
|
|
134
|
+
/* @__PURE__ */ M(_, { children: S(e.dueDate) }),
|
|
135
|
+
/* @__PURE__ */ M(_, {
|
|
101
136
|
className: "text-right",
|
|
102
|
-
children: e.status !== "CLOSED" && e.status !== "ARCHIVED"
|
|
137
|
+
children: e.status !== "CLOSED" && e.status !== "ARCHIVED" ? /* @__PURE__ */ N(P, {
|
|
103
138
|
variant: "ghost",
|
|
104
139
|
size: "sm",
|
|
105
|
-
disabled:
|
|
106
|
-
onClick: () =>
|
|
107
|
-
onSuccess: () =>
|
|
140
|
+
disabled: W.isPending,
|
|
141
|
+
onClick: () => W.mutate(e.id, {
|
|
142
|
+
onSuccess: () => R({
|
|
108
143
|
tone: "success",
|
|
109
144
|
text: `${e.title} closed.`
|
|
110
145
|
}),
|
|
111
|
-
onError: (e) =>
|
|
146
|
+
onError: (e) => R({
|
|
112
147
|
tone: "danger",
|
|
113
148
|
text: e instanceof Error ? e.message : "Failed."
|
|
114
149
|
})
|
|
115
150
|
}),
|
|
116
|
-
children: [/* @__PURE__ */
|
|
151
|
+
children: [/* @__PURE__ */ M(T, { className: "mr-1 h-4 w-4" }), " Close"]
|
|
152
|
+
}) : /* @__PURE__ */ M("span", {
|
|
153
|
+
className: "text-xs text-text-tertiary",
|
|
154
|
+
children: e.closedAt ? `Closed ${S(e.closedAt)}` : "—"
|
|
117
155
|
})
|
|
118
156
|
})
|
|
119
157
|
]
|
|
120
158
|
}, e.id)) })] })
|
|
121
|
-
}),
|
|
122
|
-
|
|
123
|
-
onClose: () =>
|
|
124
|
-
onSaved: (e) =>
|
|
159
|
+
})] }),
|
|
160
|
+
d && /* @__PURE__ */ M(z, {
|
|
161
|
+
onClose: () => v(!1),
|
|
162
|
+
onSaved: (e) => R({
|
|
125
163
|
tone: "success",
|
|
126
164
|
text: `${e} opened.`
|
|
127
165
|
})
|
|
128
166
|
})
|
|
129
167
|
]
|
|
130
168
|
});
|
|
131
|
-
},
|
|
132
|
-
let o = n(), s = e({ pagination: { limit: 100 } }), l = i(), [
|
|
169
|
+
}, z = ({ onClose: t, onSaved: r }) => {
|
|
170
|
+
let o = n(), s = e({ pagination: { limit: 100 } }), l = i(), [u, p] = C({
|
|
133
171
|
clientId: "",
|
|
134
172
|
practiceAreaId: "",
|
|
135
173
|
title: "",
|
|
@@ -138,35 +176,35 @@ var M = [
|
|
|
138
176
|
priority: "MEDIUM",
|
|
139
177
|
dueDate: "",
|
|
140
178
|
isPrivileged: !1
|
|
141
|
-
}), [m, h] =
|
|
179
|
+
}), [m, h] = C(null), g = (e) => (t) => p((n) => ({
|
|
142
180
|
...n,
|
|
143
181
|
[e]: t.target.value
|
|
144
182
|
}));
|
|
145
|
-
return /* @__PURE__ */
|
|
183
|
+
return /* @__PURE__ */ M(d, {
|
|
146
184
|
open: !0,
|
|
147
185
|
onClose: t,
|
|
148
186
|
title: "New matter",
|
|
149
|
-
footer: /* @__PURE__ */
|
|
187
|
+
footer: /* @__PURE__ */ N(j, { children: [/* @__PURE__ */ M(P, {
|
|
150
188
|
variant: "outline",
|
|
151
189
|
onClick: t,
|
|
152
190
|
disabled: o.isPending,
|
|
153
191
|
children: "Cancel"
|
|
154
|
-
}), /* @__PURE__ */
|
|
192
|
+
}), /* @__PURE__ */ M(P, {
|
|
155
193
|
onClick: () => {
|
|
156
|
-
if (h(null), !
|
|
157
|
-
if (!
|
|
194
|
+
if (h(null), !u.clientId) return h("Select a client.");
|
|
195
|
+
if (!u.title.trim()) return h("Matter title is required.");
|
|
158
196
|
o.mutate({
|
|
159
|
-
clientId:
|
|
160
|
-
practiceAreaId:
|
|
161
|
-
title:
|
|
162
|
-
reference:
|
|
163
|
-
description:
|
|
164
|
-
priority:
|
|
165
|
-
isPrivileged:
|
|
166
|
-
dueDate:
|
|
197
|
+
clientId: u.clientId,
|
|
198
|
+
practiceAreaId: u.practiceAreaId || null,
|
|
199
|
+
title: u.title.trim(),
|
|
200
|
+
reference: u.reference.trim() || null,
|
|
201
|
+
description: u.description.trim() || null,
|
|
202
|
+
priority: u.priority,
|
|
203
|
+
isPrivileged: u.isPrivileged,
|
|
204
|
+
dueDate: u.dueDate ? new Date(u.dueDate).toISOString() : null
|
|
167
205
|
}, {
|
|
168
206
|
onSuccess: () => {
|
|
169
|
-
r(
|
|
207
|
+
r(u.title.trim()), t();
|
|
170
208
|
},
|
|
171
209
|
onError: (e) => h(e instanceof Error ? e.message : "Failed.")
|
|
172
210
|
});
|
|
@@ -174,102 +212,105 @@ var M = [
|
|
|
174
212
|
disabled: o.isPending,
|
|
175
213
|
children: o.isPending ? "Opening…" : "Open matter"
|
|
176
214
|
})] }),
|
|
177
|
-
children: /* @__PURE__ */
|
|
215
|
+
children: /* @__PURE__ */ N("div", {
|
|
178
216
|
className: "space-y-3",
|
|
179
217
|
children: [
|
|
180
|
-
m && /* @__PURE__ */
|
|
218
|
+
m && /* @__PURE__ */ M(a, {
|
|
181
219
|
tone: "danger",
|
|
182
220
|
children: m
|
|
183
221
|
}),
|
|
184
|
-
/* @__PURE__ */
|
|
222
|
+
/* @__PURE__ */ M(c, {
|
|
185
223
|
label: "Client",
|
|
186
224
|
required: !0,
|
|
187
|
-
children: /* @__PURE__ */
|
|
188
|
-
value:
|
|
225
|
+
children: /* @__PURE__ */ N(f, {
|
|
226
|
+
value: u.clientId,
|
|
189
227
|
onChange: g("clientId"),
|
|
190
|
-
children: [/* @__PURE__ */
|
|
228
|
+
children: [/* @__PURE__ */ M("option", {
|
|
191
229
|
value: "",
|
|
192
230
|
children: "Select a client…"
|
|
193
|
-
}), s.data?.items.map((e) => /* @__PURE__ */
|
|
231
|
+
}), s.data?.items.map((e) => /* @__PURE__ */ M("option", {
|
|
194
232
|
value: e.id,
|
|
195
233
|
children: e.name
|
|
196
234
|
}, e.id))]
|
|
197
235
|
})
|
|
198
236
|
}),
|
|
199
|
-
/* @__PURE__ */
|
|
237
|
+
/* @__PURE__ */ M(c, {
|
|
200
238
|
label: "Title",
|
|
201
239
|
required: !0,
|
|
202
|
-
children: /* @__PURE__ */
|
|
203
|
-
value:
|
|
240
|
+
children: /* @__PURE__ */ M(y, {
|
|
241
|
+
value: u.title,
|
|
204
242
|
onChange: g("title"),
|
|
205
243
|
placeholder: "Regulatory investigation — SEC inquiry"
|
|
206
244
|
})
|
|
207
245
|
}),
|
|
208
|
-
/* @__PURE__ */
|
|
246
|
+
/* @__PURE__ */ N("div", {
|
|
209
247
|
className: "grid grid-cols-2 gap-3",
|
|
210
|
-
children: [/* @__PURE__ */
|
|
248
|
+
children: [/* @__PURE__ */ M(c, {
|
|
211
249
|
label: "Reference",
|
|
212
|
-
children: /* @__PURE__ */
|
|
213
|
-
value:
|
|
250
|
+
children: /* @__PURE__ */ M(y, {
|
|
251
|
+
value: u.reference,
|
|
214
252
|
onChange: g("reference"),
|
|
215
253
|
placeholder: "MAT-2026-014"
|
|
216
254
|
})
|
|
217
|
-
}), /* @__PURE__ */
|
|
255
|
+
}), /* @__PURE__ */ M(c, {
|
|
218
256
|
label: "Priority",
|
|
219
|
-
children: /* @__PURE__ */
|
|
220
|
-
value:
|
|
257
|
+
children: /* @__PURE__ */ M(f, {
|
|
258
|
+
value: u.priority,
|
|
221
259
|
onChange: g("priority"),
|
|
222
|
-
children:
|
|
260
|
+
children: x(I)
|
|
223
261
|
})
|
|
224
262
|
})]
|
|
225
263
|
}),
|
|
226
|
-
/* @__PURE__ */
|
|
264
|
+
/* @__PURE__ */ N("div", {
|
|
227
265
|
className: "grid grid-cols-2 gap-3",
|
|
228
|
-
children: [/* @__PURE__ */
|
|
266
|
+
children: [/* @__PURE__ */ M(c, {
|
|
229
267
|
label: "Practice area",
|
|
230
|
-
children: /* @__PURE__ */
|
|
231
|
-
value:
|
|
268
|
+
children: /* @__PURE__ */ N(f, {
|
|
269
|
+
value: u.practiceAreaId,
|
|
232
270
|
onChange: g("practiceAreaId"),
|
|
233
|
-
children: [/* @__PURE__ */
|
|
271
|
+
children: [/* @__PURE__ */ M("option", {
|
|
234
272
|
value: "",
|
|
235
273
|
children: "Unassigned"
|
|
236
|
-
}), l.data?.map((e) => /* @__PURE__ */
|
|
274
|
+
}), l.data?.map((e) => /* @__PURE__ */ M("option", {
|
|
237
275
|
value: e.id,
|
|
238
276
|
children: e.name
|
|
239
277
|
}, e.id))]
|
|
240
278
|
})
|
|
241
|
-
}), /* @__PURE__ */
|
|
279
|
+
}), /* @__PURE__ */ M(c, {
|
|
242
280
|
label: "Due date",
|
|
243
|
-
children: /* @__PURE__ */
|
|
281
|
+
children: /* @__PURE__ */ M(y, {
|
|
244
282
|
type: "date",
|
|
245
|
-
value:
|
|
283
|
+
value: u.dueDate,
|
|
246
284
|
onChange: g("dueDate")
|
|
247
285
|
})
|
|
248
286
|
})]
|
|
249
287
|
}),
|
|
250
|
-
/* @__PURE__ */
|
|
288
|
+
/* @__PURE__ */ M(c, {
|
|
251
289
|
label: "Description",
|
|
252
|
-
children: /* @__PURE__ */
|
|
253
|
-
value:
|
|
290
|
+
children: /* @__PURE__ */ M(v, {
|
|
291
|
+
value: u.description,
|
|
254
292
|
onChange: g("description")
|
|
255
293
|
})
|
|
256
294
|
}),
|
|
257
|
-
/* @__PURE__ */
|
|
258
|
-
className: "flex items-center gap-2 text-sm text-text-secondary",
|
|
259
|
-
children: [/* @__PURE__ */
|
|
295
|
+
/* @__PURE__ */ N("label", {
|
|
296
|
+
className: "flex items-center gap-2.5 rounded-lg border border-border-seam bg-bg-canvas px-3 py-2.5 text-sm text-text-secondary",
|
|
297
|
+
children: [/* @__PURE__ */ M("input", {
|
|
260
298
|
type: "checkbox",
|
|
261
|
-
checked:
|
|
299
|
+
checked: u.isPrivileged,
|
|
262
300
|
onChange: (e) => p((t) => ({
|
|
263
301
|
...t,
|
|
264
302
|
isPrivileged: e.target.checked
|
|
265
303
|
}))
|
|
266
|
-
}),
|
|
304
|
+
}), /* @__PURE__ */ N("span", {
|
|
305
|
+
className: "flex items-center gap-1.5",
|
|
306
|
+
children: [/* @__PURE__ */ M(O, { className: "h-3.5 w-3.5 text-status-warning-text" }), "Privileged / confidential matter"]
|
|
307
|
+
})]
|
|
267
308
|
})
|
|
268
309
|
]
|
|
269
310
|
})
|
|
270
311
|
});
|
|
271
312
|
};
|
|
272
313
|
//#endregion
|
|
273
|
-
export {
|
|
314
|
+
export { R as MattersPage };
|
|
274
315
|
|
|
275
316
|
//# sourceMappingURL=MattersPage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MattersPage.js","names":[],"sources":["../../../src/proserviceworld/pages/MattersPage.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useState } from 'react';\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport { Plus, Search, FolderKanban, Lock, CheckCircle2 } from 'lucide-react';\nimport {\n useMatters,\n useCreateMatter,\n useCloseMatter,\n useClients,\n usePracticeAreas,\n type PswMatterStatus,\n} from '../hooks/useProServiceWorldApi';\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 STATUSES: PswMatterStatus[] = ['OPEN', 'ON_HOLD', 'CLOSED', 'ARCHIVED'];\nconst PRIORITIES = ['LOW', 'MEDIUM', 'HIGH', 'CRITICAL'] as const;\n\nexport const MattersPage: FC = () => {\n const [search, setSearch] = useState('');\n const [statusFilter, setStatusFilter] = useState<PswMatterStatus | ''>('');\n const [creating, setCreating] = useState(false);\n const [banner, setBanner] = useState<{ tone: 'success' | 'danger'; text: string } | null>(null);\n const { data, isLoading, error, refetch } = useMatters({\n search: search.trim() || undefined,\n status: statusFilter || undefined,\n });\n const close = useCloseMatter();\n\n return (\n <div className=\"space-y-6\">\n <PageHeader\n title=\"Matters\"\n subtitle=\"The regulated threads of work — legal matters, audits, filings — with their own deadlines and sensitive-document handling.\"\n icon={<FolderKanban className=\"h-6 w-6\" />}\n actions={\n <Button onClick={() => setCreating(true)}>\n <Plus className=\"mr-1.5 h-4 w-4\" />\n New matter\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 matters…\"\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 PswMatterStatus | '')}\n className=\"sm:w-48\"\n >\n <option value=\"\">All statuses</option>\n {enumOptions(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 matters yet\"\n description=\"Open a matter to track a regulated thread of work for a client.\"\n icon={<FolderKanban className=\"h-8 w-8\" />}\n action={\n <Button onClick={() => setCreating(true)}>\n <Plus className=\"mr-1.5 h-4 w-4\" />\n New matter\n </Button>\n }\n />\n ) : (\n <SectionCard title={`${data.totalCount} matter${data.totalCount === 1 ? '' : 's'}`}>\n <TableWrap>\n <thead>\n <tr>\n <Th>Matter</Th>\n <Th>Client</Th>\n <Th>Priority</Th>\n <Th>Status</Th>\n <Th>Due</Th>\n <Th className=\"text-right\">Actions</Th>\n </tr>\n </thead>\n <tbody>\n {data.items.map((m) => (\n <tr key={m.id} className=\"hover:bg-bg-sunken/50\">\n <Td>\n <span className=\"flex items-center gap-1.5 font-medium text-text-primary\">\n {m.isPrivileged && (\n <Lock\n className=\"h-3.5 w-3.5 text-status-warning-text\"\n aria-label=\"Privileged\"\n />\n )}\n {m.title}\n </span>\n {m.reference ? (\n <div className=\"text-xs text-text-tertiary\">{m.reference}</div>\n ) : null}\n </Td>\n <Td>{m.client?.name ?? '—'}</Td>\n <Td>\n <StatusPill status={m.priority} />\n </Td>\n <Td>\n <StatusPill status={m.status} />\n </Td>\n <Td>{fmtDate(m.dueDate)}</Td>\n <Td className=\"text-right\">\n {m.status !== 'CLOSED' && m.status !== 'ARCHIVED' && (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n disabled={close.isPending}\n onClick={() =>\n close.mutate(m.id, {\n onSuccess: () =>\n setBanner({ tone: 'success', text: `${m.title} closed.` }),\n onError: (e) =>\n setBanner({\n tone: 'danger',\n text: e instanceof Error ? e.message : 'Failed.',\n }),\n })\n }\n >\n <CheckCircle2 className=\"mr-1 h-4 w-4\" /> Close\n </Button>\n )}\n </Td>\n </tr>\n ))}\n </tbody>\n </TableWrap>\n </SectionCard>\n )}\n\n {creating && (\n <MatterModal\n onClose={() => setCreating(false)}\n onSaved={(t) => setBanner({ tone: 'success', text: `${t} opened.` })}\n />\n )}\n </div>\n );\n};\n\nconst MatterModal: FC<{ onClose: () => void; onSaved: (title: string) => void }> = ({\n onClose,\n onSaved,\n}) => {\n const create = useCreateMatter();\n const clients = useClients({ pagination: { limit: 100 } });\n const practiceAreas = usePracticeAreas();\n const [form, setForm] = useState({\n clientId: '',\n practiceAreaId: '',\n title: '',\n reference: '',\n description: '',\n priority: 'MEDIUM',\n dueDate: '',\n isPrivileged: false,\n });\n const [err, setErr] = useState<string | null>(null);\n const set = (k: keyof typeof form) => (e: { target: { value: string } }) =>\n setForm((f) => ({ ...f, [k]: e.target.value }));\n\n const submit = () => {\n setErr(null);\n if (!form.clientId) return setErr('Select a client.');\n if (!form.title.trim()) return setErr('Matter title is required.');\n create.mutate(\n {\n clientId: form.clientId,\n practiceAreaId: form.practiceAreaId || null,\n title: form.title.trim(),\n reference: form.reference.trim() || null,\n description: form.description.trim() || null,\n priority: form.priority,\n isPrivileged: form.isPrivileged,\n dueDate: form.dueDate ? new Date(form.dueDate).toISOString() : null,\n },\n {\n onSuccess: () => {\n onSaved(form.title.trim());\n onClose();\n },\n onError: (e) => setErr(e instanceof Error ? e.message : 'Failed.'),\n }\n );\n };\n\n return (\n <Modal\n open\n onClose={onClose}\n title=\"New matter\"\n footer={\n <>\n <Button variant=\"outline\" onClick={onClose} disabled={create.isPending}>\n Cancel\n </Button>\n <Button onClick={submit} disabled={create.isPending}>\n {create.isPending ? 'Opening…' : 'Open matter'}\n </Button>\n </>\n }\n >\n <div className=\"space-y-3\">\n {err && <Banner tone=\"danger\">{err}</Banner>}\n <Field label=\"Client\" required>\n <NativeSelect value={form.clientId} onChange={set('clientId')}>\n <option value=\"\">Select a client…</option>\n {clients.data?.items.map((c) => (\n <option key={c.id} value={c.id}>\n {c.name}\n </option>\n ))}\n </NativeSelect>\n </Field>\n <Field label=\"Title\" required>\n <TextInput\n value={form.title}\n onChange={set('title')}\n placeholder=\"Regulatory investigation — SEC inquiry\"\n />\n </Field>\n <div className=\"grid grid-cols-2 gap-3\">\n <Field label=\"Reference\">\n <TextInput\n value={form.reference}\n onChange={set('reference')}\n placeholder=\"MAT-2026-014\"\n />\n </Field>\n <Field label=\"Priority\">\n <NativeSelect value={form.priority} onChange={set('priority')}>\n {enumOptions(PRIORITIES)}\n </NativeSelect>\n </Field>\n </div>\n <div className=\"grid grid-cols-2 gap-3\">\n <Field label=\"Practice area\">\n <NativeSelect value={form.practiceAreaId} onChange={set('practiceAreaId')}>\n <option value=\"\">Unassigned</option>\n {practiceAreas.data?.map((p) => (\n <option key={p.id} value={p.id}>\n {p.name}\n </option>\n ))}\n </NativeSelect>\n </Field>\n <Field label=\"Due date\">\n <TextInput type=\"date\" value={form.dueDate} onChange={set('dueDate')} />\n </Field>\n </div>\n <Field label=\"Description\">\n <TextArea value={form.description} onChange={set('description')} />\n </Field>\n <label className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <input\n type=\"checkbox\"\n checked={form.isPrivileged}\n onChange={(e) => setForm((f) => ({ ...f, isPrivileged: e.target.checked }))}\n />\n Privileged / confidential matter\n </label>\n </div>\n </Modal>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"MattersPage.js","names":[],"sources":["../../../src/proserviceworld/pages/MattersPage.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useState } from 'react';\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport {\n Plus,\n Search,\n FolderKanban,\n Lock,\n CheckCircle2,\n CircleDot,\n AlertTriangle,\n} from 'lucide-react';\nimport {\n useMatters,\n useCreateMatter,\n useCloseMatter,\n useClients,\n usePracticeAreas,\n type PswMatterStatus,\n} from '../hooks/useProServiceWorldApi';\nimport {\n PageHeader,\n SectionCard,\n MetricCard,\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 STATUSES: PswMatterStatus[] = ['OPEN', 'ON_HOLD', 'CLOSED', 'ARCHIVED'];\nconst PRIORITIES = ['LOW', 'MEDIUM', 'HIGH', 'CRITICAL'] as const;\n\n/** Amber padlock chip that flags privileged / confidential matters. */\nconst PrivilegeLock: FC = () => (\n <span\n className=\"inline-flex h-5 w-5 shrink-0 items-center justify-center rounded-md bg-status-warning-bg-subtle text-status-warning-text\"\n title=\"Privileged / confidential\"\n aria-label=\"Privileged\"\n >\n <Lock className=\"h-3 w-3\" />\n </span>\n);\n\nexport const MattersPage: FC = () => {\n const [search, setSearch] = useState('');\n const [statusFilter, setStatusFilter] = useState<PswMatterStatus | ''>('');\n const [creating, setCreating] = useState(false);\n const [banner, setBanner] = useState<{ tone: 'success' | 'danger'; text: string } | null>(null);\n const { data, isLoading, error, refetch } = useMatters({\n search: search.trim() || undefined,\n status: statusFilter || undefined,\n });\n const close = useCloseMatter();\n\n const items = data?.items ?? [];\n const openCount = items.filter((m) => m.status === 'OPEN').length;\n const privilegedCount = items.filter((m) => m.isPrivileged).length;\n const highCount = items.filter((m) => m.priority === 'HIGH' || m.priority === 'CRITICAL').length;\n\n return (\n <div className=\"space-y-6\">\n <PageHeader\n title=\"Matters\"\n subtitle=\"The regulated threads of work — legal matters, audits, filings — with their own deadlines and sensitive-document handling.\"\n icon={<FolderKanban className=\"h-6 w-6\" />}\n actions={\n <Button onClick={() => setCreating(true)}>\n <Plus className=\"mr-1.5 h-4 w-4\" />\n New matter\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 matters…\"\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 PswMatterStatus | '')}\n className=\"sm:w-48\"\n >\n <option value=\"\">All statuses</option>\n {enumOptions(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 matters yet\"\n description=\"Open a matter to track a regulated thread of work for a client.\"\n icon={<FolderKanban className=\"h-8 w-8\" />}\n action={\n <Button onClick={() => setCreating(true)}>\n <Plus className=\"mr-1.5 h-4 w-4\" />\n New matter\n </Button>\n }\n />\n ) : (\n <>\n <div className=\"grid grid-cols-2 gap-3 lg:grid-cols-4\">\n <MetricCard\n label=\"Matters\"\n value={data.totalCount}\n icon={<FolderKanban className=\"h-4 w-4\" />}\n />\n <MetricCard\n label=\"Open\"\n value={openCount}\n icon={<CircleDot className=\"h-4 w-4\" />}\n tone=\"accent\"\n />\n <MetricCard\n label=\"Privileged\"\n value={privilegedCount}\n icon={<Lock className=\"h-4 w-4\" />}\n tone=\"warning\"\n />\n <MetricCard\n label=\"High priority\"\n value={highCount}\n icon={<AlertTriangle className=\"h-4 w-4\" />}\n tone={highCount ? 'danger' : 'neutral'}\n />\n </div>\n\n <SectionCard title={`${data.totalCount} matter${data.totalCount === 1 ? '' : 's'}`}>\n <TableWrap>\n <thead>\n <tr>\n <Th>Matter</Th>\n <Th>Client</Th>\n <Th>Priority</Th>\n <Th>Status</Th>\n <Th>Due</Th>\n <Th className=\"text-right\">Actions</Th>\n </tr>\n </thead>\n <tbody>\n {data.items.map((m) => (\n <tr key={m.id} className=\"transition-colors hover:bg-bg-sunken/60\">\n <Td>\n <span className=\"flex items-center gap-2 font-medium text-text-primary\">\n {m.isPrivileged && <PrivilegeLock />}\n <span className=\"truncate\">{m.title}</span>\n </span>\n {m.reference ? (\n <div className=\"mt-0.5 pl-0 text-xs text-text-tertiary\">\n Ref: {m.reference}\n </div>\n ) : null}\n </Td>\n <Td className=\"text-text-primary\">{m.client?.name ?? '—'}</Td>\n <Td>\n <StatusPill status={m.priority} />\n </Td>\n <Td>\n <StatusPill status={m.status} />\n </Td>\n <Td>{fmtDate(m.dueDate)}</Td>\n <Td className=\"text-right\">\n {m.status !== 'CLOSED' && m.status !== 'ARCHIVED' ? (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n disabled={close.isPending}\n onClick={() =>\n close.mutate(m.id, {\n onSuccess: () =>\n setBanner({ tone: 'success', text: `${m.title} closed.` }),\n onError: (e) =>\n setBanner({\n tone: 'danger',\n text: e instanceof Error ? e.message : 'Failed.',\n }),\n })\n }\n >\n <CheckCircle2 className=\"mr-1 h-4 w-4\" /> Close\n </Button>\n ) : (\n <span className=\"text-xs text-text-tertiary\">\n {m.closedAt ? `Closed ${fmtDate(m.closedAt)}` : '—'}\n </span>\n )}\n </Td>\n </tr>\n ))}\n </tbody>\n </TableWrap>\n </SectionCard>\n </>\n )}\n\n {creating && (\n <MatterModal\n onClose={() => setCreating(false)}\n onSaved={(t) => setBanner({ tone: 'success', text: `${t} opened.` })}\n />\n )}\n </div>\n );\n};\n\nconst MatterModal: FC<{ onClose: () => void; onSaved: (title: string) => void }> = ({\n onClose,\n onSaved,\n}) => {\n const create = useCreateMatter();\n const clients = useClients({ pagination: { limit: 100 } });\n const practiceAreas = usePracticeAreas();\n const [form, setForm] = useState({\n clientId: '',\n practiceAreaId: '',\n title: '',\n reference: '',\n description: '',\n priority: 'MEDIUM',\n dueDate: '',\n isPrivileged: false,\n });\n const [err, setErr] = useState<string | null>(null);\n const set = (k: keyof typeof form) => (e: { target: { value: string } }) =>\n setForm((f) => ({ ...f, [k]: e.target.value }));\n\n const submit = () => {\n setErr(null);\n if (!form.clientId) return setErr('Select a client.');\n if (!form.title.trim()) return setErr('Matter title is required.');\n create.mutate(\n {\n clientId: form.clientId,\n practiceAreaId: form.practiceAreaId || null,\n title: form.title.trim(),\n reference: form.reference.trim() || null,\n description: form.description.trim() || null,\n priority: form.priority,\n isPrivileged: form.isPrivileged,\n dueDate: form.dueDate ? new Date(form.dueDate).toISOString() : null,\n },\n {\n onSuccess: () => {\n onSaved(form.title.trim());\n onClose();\n },\n onError: (e) => setErr(e instanceof Error ? e.message : 'Failed.'),\n }\n );\n };\n\n return (\n <Modal\n open\n onClose={onClose}\n title=\"New matter\"\n footer={\n <>\n <Button variant=\"outline\" onClick={onClose} disabled={create.isPending}>\n Cancel\n </Button>\n <Button onClick={submit} disabled={create.isPending}>\n {create.isPending ? 'Opening…' : 'Open matter'}\n </Button>\n </>\n }\n >\n <div className=\"space-y-3\">\n {err && <Banner tone=\"danger\">{err}</Banner>}\n <Field label=\"Client\" required>\n <NativeSelect value={form.clientId} onChange={set('clientId')}>\n <option value=\"\">Select a client…</option>\n {clients.data?.items.map((c) => (\n <option key={c.id} value={c.id}>\n {c.name}\n </option>\n ))}\n </NativeSelect>\n </Field>\n <Field label=\"Title\" required>\n <TextInput\n value={form.title}\n onChange={set('title')}\n placeholder=\"Regulatory investigation — SEC inquiry\"\n />\n </Field>\n <div className=\"grid grid-cols-2 gap-3\">\n <Field label=\"Reference\">\n <TextInput\n value={form.reference}\n onChange={set('reference')}\n placeholder=\"MAT-2026-014\"\n />\n </Field>\n <Field label=\"Priority\">\n <NativeSelect value={form.priority} onChange={set('priority')}>\n {enumOptions(PRIORITIES)}\n </NativeSelect>\n </Field>\n </div>\n <div className=\"grid grid-cols-2 gap-3\">\n <Field label=\"Practice area\">\n <NativeSelect value={form.practiceAreaId} onChange={set('practiceAreaId')}>\n <option value=\"\">Unassigned</option>\n {practiceAreas.data?.map((p) => (\n <option key={p.id} value={p.id}>\n {p.name}\n </option>\n ))}\n </NativeSelect>\n </Field>\n <Field label=\"Due date\">\n <TextInput type=\"date\" value={form.dueDate} onChange={set('dueDate')} />\n </Field>\n </div>\n <Field label=\"Description\">\n <TextArea value={form.description} onChange={set('description')} />\n </Field>\n <label className=\"flex items-center gap-2.5 rounded-lg border border-border-seam bg-bg-canvas px-3 py-2.5 text-sm text-text-secondary\">\n <input\n type=\"checkbox\"\n checked={form.isPrivileged}\n onChange={(e) => setForm((f) => ({ ...f, isPrivileged: e.target.checked }))}\n />\n <span className=\"flex items-center gap-1.5\">\n <Lock className=\"h-3.5 w-3.5 text-status-warning-text\" />\n Privileged / confidential matter\n </span>\n </label>\n </div>\n </Modal>\n );\n};\n"],"mappings":"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"}
|