@burdenoff/microfe-proserviceworld 2026.626.2 → 2026.706.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.
- package/dist/index.js +2 -3
- package/dist/node_modules/clsx/dist/clsx.js +18 -0
- package/dist/node_modules/clsx/dist/clsx.js.map +1 -0
- package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js +1716 -0
- package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js.map +1 -0
- package/dist/proserviceworld/ProServiceWorldRoot.js +92 -136
- package/dist/proserviceworld/ProServiceWorldRoot.js.map +1 -1
- package/dist/proserviceworld/ProServiceWorldRoutes.js +18 -26
- package/dist/proserviceworld/ProServiceWorldRoutes.js.map +1 -1
- package/dist/proserviceworld/components/ui.js +273 -0
- package/dist/proserviceworld/components/ui.js.map +1 -0
- package/dist/proserviceworld/hooks/useFiles.js +45 -0
- package/dist/proserviceworld/hooks/useFiles.js.map +1 -0
- package/dist/proserviceworld/hooks/useProServiceWorldApi.js +416 -0
- package/dist/proserviceworld/hooks/useProServiceWorldApi.js.map +1 -0
- package/dist/proserviceworld/index.js +0 -1
- package/dist/proserviceworld/pages/AnalyticsPage.js +163 -475
- package/dist/proserviceworld/pages/AnalyticsPage.js.map +1 -1
- package/dist/proserviceworld/pages/ClientDetailPage.js +238 -0
- package/dist/proserviceworld/pages/ClientDetailPage.js.map +1 -0
- package/dist/proserviceworld/pages/ClientsPage.js +295 -0
- package/dist/proserviceworld/pages/ClientsPage.js.map +1 -0
- package/dist/proserviceworld/pages/CompliancePage.js +307 -0
- package/dist/proserviceworld/pages/CompliancePage.js.map +1 -0
- package/dist/proserviceworld/pages/ConflictsPage.js +234 -0
- package/dist/proserviceworld/pages/ConflictsPage.js.map +1 -0
- package/dist/proserviceworld/pages/DashboardPage.js +179 -632
- package/dist/proserviceworld/pages/DashboardPage.js.map +1 -1
- package/dist/proserviceworld/pages/DocumentsPage.js +235 -539
- package/dist/proserviceworld/pages/DocumentsPage.js.map +1 -1
- package/dist/proserviceworld/pages/EngagementDetailPage.js +444 -0
- package/dist/proserviceworld/pages/EngagementDetailPage.js.map +1 -0
- package/dist/proserviceworld/pages/EngagementsPage.js +256 -0
- package/dist/proserviceworld/pages/EngagementsPage.js.map +1 -0
- package/dist/proserviceworld/pages/InvoicesPage.js +303 -0
- package/dist/proserviceworld/pages/InvoicesPage.js.map +1 -0
- package/dist/proserviceworld/pages/MattersPage.js +275 -0
- package/dist/proserviceworld/pages/MattersPage.js.map +1 -0
- package/dist/proserviceworld/pages/PracticeAreasPage.js +176 -0
- package/dist/proserviceworld/pages/PracticeAreasPage.js.map +1 -0
- package/dist/proserviceworld/pages/TimePage.js +310 -0
- package/dist/proserviceworld/pages/TimePage.js.map +1 -0
- package/dist/proserviceworld/utils/cn.js +10 -0
- package/dist/proserviceworld/utils/cn.js.map +1 -0
- package/dist/proserviceworld/utils/nav.js +11 -0
- package/dist/proserviceworld/utils/nav.js.map +1 -0
- package/package.json +3 -2
- package/dist/proserviceworld/pages/AdminReportsPage.js +0 -579
- package/dist/proserviceworld/pages/AdminReportsPage.js.map +0 -1
- package/dist/proserviceworld/pages/AdminUsersPage.js +0 -468
- package/dist/proserviceworld/pages/AdminUsersPage.js.map +0 -1
- package/dist/proserviceworld/pages/BookingsPage.js +0 -446
- package/dist/proserviceworld/pages/BookingsPage.js.map +0 -1
- package/dist/proserviceworld/pages/MessagesPage.js +0 -238
- package/dist/proserviceworld/pages/MessagesPage.js.map +0 -1
- package/dist/proserviceworld/pages/PaymentsPage.js +0 -537
- package/dist/proserviceworld/pages/PaymentsPage.js.map +0 -1
- package/dist/proserviceworld/pages/ProjectsPage.js +0 -627
- package/dist/proserviceworld/pages/ProjectsPage.js.map +0 -1
- package/dist/proserviceworld/pages/ProviderDetailPage.js +0 -538
- package/dist/proserviceworld/pages/ProviderDetailPage.js.map +0 -1
- package/dist/proserviceworld/pages/ProvidersPage.js +0 -347
- package/dist/proserviceworld/pages/ProvidersPage.js.map +0 -1
- package/dist/proserviceworld/pages/ReviewsPage.js +0 -356
- package/dist/proserviceworld/pages/ReviewsPage.js.map +0 -1
- package/dist/proserviceworld/pages/ServiceDetailsPage.js +0 -631
- package/dist/proserviceworld/pages/ServiceDetailsPage.js.map +0 -1
- package/dist/proserviceworld/pages/ServicesPage.js +0 -344
- package/dist/proserviceworld/pages/ServicesPage.js.map +0 -1
- package/dist/proserviceworld/pages/VerificationPage.js +0 -370
- package/dist/proserviceworld/pages/VerificationPage.js.map +0 -1
- package/dist/proserviceworld/store/proserviceworldStore.js +0 -2490
- package/dist/proserviceworld/store/proserviceworldStore.js.map +0 -1
- package/dist/proserviceworld/utils/i18n.js +0 -15
- package/dist/proserviceworld/utils/i18n.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CompliancePage.js","names":[],"sources":["../../../src/proserviceworld/pages/CompliancePage.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useState } from 'react';\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport { Plus, ShieldCheck } from 'lucide-react';\nimport {\n useComplianceChecks,\n useCreateComplianceCheck,\n useResolveComplianceCheck,\n useClients,\n useEngagements,\n useMatters,\n type PswComplianceStatus,\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 humanize,\n} from '../components/ui';\n\nconst TYPES = [\n 'ENGAGEMENT_ACCEPTANCE',\n 'INDEPENDENCE',\n 'LICENSING',\n 'CONTINUING_EDUCATION',\n 'DATA_RETENTION',\n 'LEGAL_HOLD',\n] as const;\nconst RESOLVE_STATUSES: PswComplianceStatus[] = ['IN_REVIEW', 'PASSED', 'FAILED', 'WAIVED'];\nconst SUBJECT_TYPES = ['CLIENT', 'ENGAGEMENT', 'MATTER'] as const;\n\nexport const CompliancePage: FC = () => {\n const [statusFilter, setStatusFilter] = useState<PswComplianceStatus | ''>('');\n const [creating, setCreating] = useState(false);\n const [resolving, setResolving] = useState<{ id: string; title: string } | null>(null);\n const [banner, setBanner] = useState<string | null>(null);\n const { data, isLoading, error, refetch } = useComplianceChecks({\n status: statusFilter || undefined,\n });\n\n return (\n <div className=\"space-y-6\">\n <PageHeader\n title=\"Compliance\"\n subtitle=\"The duties that travel with the work — acceptance, independence, licensing, CE, retention and legal hold — as gates, not afterthoughts.\"\n icon={<ShieldCheck className=\"h-6 w-6\" />}\n actions={\n <Button onClick={() => setCreating(true)}>\n <Plus className=\"mr-1.5 h-4 w-4\" />\n New check\n </Button>\n }\n />\n\n {banner && (\n <Banner tone=\"success\" onClose={() => setBanner(null)}>\n {banner}\n </Banner>\n )}\n\n <div className=\"flex justify-end\">\n <NativeSelect\n value={statusFilter}\n onChange={(e) => setStatusFilter(e.target.value as PswComplianceStatus | '')}\n className=\"sm:w-52\"\n >\n <option value=\"\">All statuses</option>\n {enumOptions(['PENDING', 'IN_REVIEW', 'PASSED', 'FAILED', 'WAIVED'])}\n </NativeSelect>\n </div>\n\n {isLoading ? (\n <LoadingBlock />\n ) : error ? (\n <ErrorState error={error} onRetry={() => void refetch()} />\n ) : !data || data.length === 0 ? (\n <Empty\n title=\"No compliance checks\"\n description=\"Raise a check to gate acceptance or track a professional obligation.\"\n icon={<ShieldCheck className=\"h-8 w-8\" />}\n action={\n <Button onClick={() => setCreating(true)}>\n <Plus className=\"mr-1.5 h-4 w-4\" />\n New check\n </Button>\n }\n />\n ) : (\n <SectionCard title={`${data.length} check${data.length === 1 ? '' : 's'}`}>\n <TableWrap>\n <thead>\n <tr>\n <Th>Title</Th>\n <Th>Type</Th>\n <Th>Subject</Th>\n <Th>Due</Th>\n <Th>Status</Th>\n <Th className=\"text-right\">Actions</Th>\n </tr>\n </thead>\n <tbody>\n {data.map((c) => (\n <tr key={c.id} className=\"hover:bg-bg-sunken/50\">\n <Td>\n <span className=\"font-medium text-text-primary\">{c.title}</span>\n </Td>\n <Td>{humanize(c.type)}</Td>\n <Td>{humanize(c.subjectType)}</Td>\n <Td>{fmtDate(c.dueDate)}</Td>\n <Td>\n <StatusPill status={c.status} />\n </Td>\n <Td className=\"text-right\">\n {c.status === 'PENDING' || c.status === 'IN_REVIEW' ? (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => setResolving({ id: c.id, title: c.title })}\n >\n Resolve\n </Button>\n ) : (\n <span className=\"text-xs text-text-tertiary\">\n {c.resolvedAt ? fmtDate(c.resolvedAt) : ''}\n </span>\n )}\n </Td>\n </tr>\n ))}\n </tbody>\n </TableWrap>\n </SectionCard>\n )}\n\n {creating && (\n <ComplianceModal\n onClose={() => setCreating(false)}\n onDone={() => {\n void refetch();\n setBanner('Compliance check created.');\n }}\n />\n )}\n {resolving && (\n <ResolveModal\n check={resolving}\n onClose={() => setResolving(null)}\n onDone={() => {\n void refetch();\n setBanner('Compliance check resolved.');\n }}\n />\n )}\n </div>\n );\n};\n\nconst ComplianceModal: FC<{ onClose: () => void; onDone: () => void }> = ({ onClose, onDone }) => {\n const create = useCreateComplianceCheck();\n const [form, setForm] = useState({\n type: 'ENGAGEMENT_ACCEPTANCE',\n subjectType: 'ENGAGEMENT',\n subjectId: '',\n title: '',\n dueDate: '',\n details: '',\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 clients = useClients({ pagination: { limit: 100 } });\n const engagements = useEngagements({ pagination: { limit: 100 } });\n const matters = useMatters({ pagination: { limit: 100 } });\n const subjects =\n form.subjectType === 'CLIENT'\n ? (clients.data?.items ?? []).map((c) => ({ id: c.id, label: c.name }))\n : form.subjectType === 'ENGAGEMENT'\n ? (engagements.data?.items ?? []).map((e) => ({ id: e.id, label: e.name }))\n : (matters.data?.items ?? []).map((m) => ({ id: m.id, label: m.title }));\n\n const submit = () => {\n setErr(null);\n if (!form.title.trim()) return setErr('Title is required.');\n if (!form.subjectId) return setErr('Select a subject.');\n create.mutate(\n {\n type: form.type,\n subjectType: form.subjectType,\n subjectId: form.subjectId,\n title: form.title.trim(),\n dueDate: form.dueDate ? new Date(form.dueDate).toISOString() : null,\n details: form.details.trim() || null,\n },\n {\n onSuccess: () => {\n onDone();\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 compliance check\"\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 ? 'Creating…' : 'Create check'}\n </Button>\n </>\n }\n >\n <div className=\"space-y-3\">\n {err && <Banner tone=\"danger\">{err}</Banner>}\n <Field label=\"Title\" required>\n <TextInput\n value={form.title}\n onChange={set('title')}\n placeholder=\"Independence confirmation — FY26 audit\"\n />\n </Field>\n <Field label=\"Type\">\n <NativeSelect value={form.type} onChange={set('type')}>\n {enumOptions(TYPES)}\n </NativeSelect>\n </Field>\n <div className=\"grid grid-cols-2 gap-3\">\n <Field label=\"Subject type\">\n <NativeSelect\n value={form.subjectType}\n onChange={(e) =>\n setForm((f) => ({ ...f, subjectType: e.target.value, subjectId: '' }))\n }\n >\n {enumOptions(SUBJECT_TYPES)}\n </NativeSelect>\n </Field>\n <Field label=\"Subject\" required>\n <NativeSelect value={form.subjectId} onChange={set('subjectId')}>\n <option value=\"\">Select…</option>\n {subjects.map((s) => (\n <option key={s.id} value={s.id}>\n {s.label}\n </option>\n ))}\n </NativeSelect>\n </Field>\n </div>\n <Field label=\"Due date\">\n <TextInput type=\"date\" value={form.dueDate} onChange={set('dueDate')} />\n </Field>\n <Field label=\"Details\">\n <TextArea value={form.details} onChange={set('details')} />\n </Field>\n </div>\n </Modal>\n );\n};\n\nconst ResolveModal: FC<{\n check: { id: string; title: string };\n onClose: () => void;\n onDone: () => void;\n}> = ({ check, onClose, onDone }) => {\n const resolve = useResolveComplianceCheck();\n const [status, setStatus] = useState<PswComplianceStatus>('PASSED');\n const [details, setDetails] = useState('');\n const [err, setErr] = useState<string | null>(null);\n const submit = () =>\n resolve.mutate(\n { id: check.id, status, details: details.trim() || undefined },\n {\n onSuccess: () => {\n onDone();\n onClose();\n },\n onError: (e) => setErr(e instanceof Error ? e.message : 'Failed.'),\n }\n );\n return (\n <Modal\n open\n onClose={onClose}\n title={`Resolve: ${check.title}`}\n footer={\n <>\n <Button variant=\"outline\" onClick={onClose} disabled={resolve.isPending}>\n Cancel\n </Button>\n <Button onClick={submit} disabled={resolve.isPending}>\n {resolve.isPending ? 'Saving…' : 'Resolve'}\n </Button>\n </>\n }\n >\n <div className=\"space-y-3\">\n {err && <Banner tone=\"danger\">{err}</Banner>}\n <Field label=\"Outcome\">\n <NativeSelect\n value={status}\n onChange={(e) => setStatus(e.target.value as PswComplianceStatus)}\n >\n {RESOLVE_STATUSES.map((s) => (\n <option key={s} value={s}>\n {humanize(s)}\n </option>\n ))}\n </NativeSelect>\n </Field>\n <Field label=\"Notes\">\n <TextArea value={details} onChange={(e) => setDetails(e.target.value)} />\n </Field>\n </div>\n </Modal>\n );\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import { useClients as e, useConflictChecks as t, useCreateConflictCheck as n, useResolveConflictCheck as r } from "../hooks/useProServiceWorldApi.js";
|
|
2
|
+
import { Banner as i, Empty as a, ErrorState as o, Field as s, LoadingBlock as c, Modal as l, NativeSelect as u, PageHeader as d, SectionCard as f, StatusPill as p, TableWrap as m, Td as h, TextArea as g, TextInput as _, Th as v, fmtDate as y, humanize as b } from "../components/ui.js";
|
|
3
|
+
import { useMemo as x, useState as S } from "react";
|
|
4
|
+
import { GitBranch as C, Plus as w } from "lucide-react";
|
|
5
|
+
import { Fragment as T, jsx as E, jsxs as D } from "react/jsx-runtime";
|
|
6
|
+
import { Button as O } from "@burdenoff/fe-libs/ui";
|
|
7
|
+
//#region src/proserviceworld/pages/ConflictsPage.tsx
|
|
8
|
+
var k = [
|
|
9
|
+
"CLEAR",
|
|
10
|
+
"POTENTIAL_CONFLICT",
|
|
11
|
+
"CONFLICT",
|
|
12
|
+
"WAIVED"
|
|
13
|
+
], A = () => {
|
|
14
|
+
let [n, r] = S(!1), [s, l] = S(null), [u, g] = S(null), { data: _, isLoading: b, error: T, refetch: k } = t(), A = e({ pagination: { limit: 100 } }), N = x(() => new Map((A.data?.items ?? []).map((e) => [e.id, e.name])), [A.data]);
|
|
15
|
+
return /* @__PURE__ */ D("div", {
|
|
16
|
+
className: "space-y-6",
|
|
17
|
+
children: [
|
|
18
|
+
/* @__PURE__ */ E(d, {
|
|
19
|
+
title: "Conflict checks",
|
|
20
|
+
subtitle: "Run before accepting a client or opening a matter — searched against existing clients, matters and counterparties, with a documented result and waiver.",
|
|
21
|
+
icon: /* @__PURE__ */ E(C, { className: "h-6 w-6" }),
|
|
22
|
+
actions: /* @__PURE__ */ D(O, {
|
|
23
|
+
onClick: () => r(!0),
|
|
24
|
+
children: [/* @__PURE__ */ E(w, { className: "mr-1.5 h-4 w-4" }), "Run check"]
|
|
25
|
+
})
|
|
26
|
+
}),
|
|
27
|
+
u && /* @__PURE__ */ E(i, {
|
|
28
|
+
tone: "success",
|
|
29
|
+
onClose: () => g(null),
|
|
30
|
+
children: u
|
|
31
|
+
}),
|
|
32
|
+
b ? /* @__PURE__ */ E(c, {}) : T ? /* @__PURE__ */ E(o, {
|
|
33
|
+
error: T,
|
|
34
|
+
onRetry: () => void k()
|
|
35
|
+
}) : !_ || _.length === 0 ? /* @__PURE__ */ E(a, {
|
|
36
|
+
title: "No conflict checks",
|
|
37
|
+
description: "Run a conflict check before taking on new work.",
|
|
38
|
+
icon: /* @__PURE__ */ E(C, { className: "h-8 w-8" }),
|
|
39
|
+
action: /* @__PURE__ */ D(O, {
|
|
40
|
+
onClick: () => r(!0),
|
|
41
|
+
children: [/* @__PURE__ */ E(w, { className: "mr-1.5 h-4 w-4" }), "Run check"]
|
|
42
|
+
})
|
|
43
|
+
}) : /* @__PURE__ */ E(f, {
|
|
44
|
+
title: `${_.length} check${_.length === 1 ? "" : "s"}`,
|
|
45
|
+
children: /* @__PURE__ */ D(m, { children: [/* @__PURE__ */ E("thead", { children: /* @__PURE__ */ D("tr", { children: [
|
|
46
|
+
/* @__PURE__ */ E(v, { children: "Client" }),
|
|
47
|
+
/* @__PURE__ */ E(v, { children: "Parties searched" }),
|
|
48
|
+
/* @__PURE__ */ E(v, { children: "Run" }),
|
|
49
|
+
/* @__PURE__ */ E(v, { children: "Status" }),
|
|
50
|
+
/* @__PURE__ */ E(v, {
|
|
51
|
+
className: "text-right",
|
|
52
|
+
children: "Actions"
|
|
53
|
+
})
|
|
54
|
+
] }) }), /* @__PURE__ */ E("tbody", { children: _.map((e) => /* @__PURE__ */ D("tr", {
|
|
55
|
+
className: "hover:bg-bg-sunken/50",
|
|
56
|
+
children: [
|
|
57
|
+
/* @__PURE__ */ E(h, { children: /* @__PURE__ */ E("span", {
|
|
58
|
+
className: "font-medium text-text-primary",
|
|
59
|
+
children: N.get(e.clientId) ?? "—"
|
|
60
|
+
}) }),
|
|
61
|
+
/* @__PURE__ */ E(h, {
|
|
62
|
+
className: "max-w-xs truncate",
|
|
63
|
+
children: e.searchedParties.join(", ") || "—"
|
|
64
|
+
}),
|
|
65
|
+
/* @__PURE__ */ E(h, { children: y(e.createdAt) }),
|
|
66
|
+
/* @__PURE__ */ E(h, { children: /* @__PURE__ */ E(p, { status: e.status }) }),
|
|
67
|
+
/* @__PURE__ */ E(h, {
|
|
68
|
+
className: "text-right",
|
|
69
|
+
children: e.status === "PENDING" || e.status === "POTENTIAL_CONFLICT" ? /* @__PURE__ */ E(O, {
|
|
70
|
+
variant: "ghost",
|
|
71
|
+
size: "sm",
|
|
72
|
+
onClick: () => l({ id: e.id }),
|
|
73
|
+
children: "Resolve"
|
|
74
|
+
}) : /* @__PURE__ */ E("span", {
|
|
75
|
+
className: "text-xs text-text-tertiary",
|
|
76
|
+
children: e.resolvedAt ? y(e.resolvedAt) : ""
|
|
77
|
+
})
|
|
78
|
+
})
|
|
79
|
+
]
|
|
80
|
+
}, e.id)) })] })
|
|
81
|
+
}),
|
|
82
|
+
n && /* @__PURE__ */ E(j, {
|
|
83
|
+
onClose: () => r(!1),
|
|
84
|
+
onDone: () => {
|
|
85
|
+
k(), g("Conflict check recorded.");
|
|
86
|
+
}
|
|
87
|
+
}),
|
|
88
|
+
s && /* @__PURE__ */ E(M, {
|
|
89
|
+
id: s.id,
|
|
90
|
+
onClose: () => l(null),
|
|
91
|
+
onDone: () => {
|
|
92
|
+
k(), g("Conflict check resolved.");
|
|
93
|
+
}
|
|
94
|
+
})
|
|
95
|
+
]
|
|
96
|
+
});
|
|
97
|
+
}, j = ({ onClose: t, onDone: r }) => {
|
|
98
|
+
let a = n(), o = e({ pagination: { limit: 100 } }), [c, d] = S(""), [f, p] = S(""), [m, h] = S(""), [v, y] = S(null);
|
|
99
|
+
return /* @__PURE__ */ E(l, {
|
|
100
|
+
open: !0,
|
|
101
|
+
onClose: t,
|
|
102
|
+
title: "Run conflict check",
|
|
103
|
+
footer: /* @__PURE__ */ D(T, { children: [/* @__PURE__ */ E(O, {
|
|
104
|
+
variant: "outline",
|
|
105
|
+
onClick: t,
|
|
106
|
+
disabled: a.isPending,
|
|
107
|
+
children: "Cancel"
|
|
108
|
+
}), /* @__PURE__ */ E(O, {
|
|
109
|
+
onClick: () => {
|
|
110
|
+
if (y(null), !c) return y("Select a client.");
|
|
111
|
+
let e = f.split(",").map((e) => e.trim()).filter(Boolean);
|
|
112
|
+
if (e.length === 0) return y("Add at least one party.");
|
|
113
|
+
a.mutate({
|
|
114
|
+
clientId: c,
|
|
115
|
+
searchedParties: e,
|
|
116
|
+
findings: m.trim() || null
|
|
117
|
+
}, {
|
|
118
|
+
onSuccess: () => {
|
|
119
|
+
r(), t();
|
|
120
|
+
},
|
|
121
|
+
onError: (e) => y(e instanceof Error ? e.message : "Failed.")
|
|
122
|
+
});
|
|
123
|
+
},
|
|
124
|
+
disabled: a.isPending,
|
|
125
|
+
children: a.isPending ? "Running…" : "Record check"
|
|
126
|
+
})] }),
|
|
127
|
+
children: /* @__PURE__ */ D("div", {
|
|
128
|
+
className: "space-y-3",
|
|
129
|
+
children: [
|
|
130
|
+
v && /* @__PURE__ */ E(i, {
|
|
131
|
+
tone: "danger",
|
|
132
|
+
children: v
|
|
133
|
+
}),
|
|
134
|
+
/* @__PURE__ */ E(s, {
|
|
135
|
+
label: "Client",
|
|
136
|
+
required: !0,
|
|
137
|
+
children: /* @__PURE__ */ D(u, {
|
|
138
|
+
value: c,
|
|
139
|
+
onChange: (e) => d(e.target.value),
|
|
140
|
+
children: [/* @__PURE__ */ E("option", {
|
|
141
|
+
value: "",
|
|
142
|
+
children: "Select…"
|
|
143
|
+
}), o.data?.items.map((e) => /* @__PURE__ */ E("option", {
|
|
144
|
+
value: e.id,
|
|
145
|
+
children: e.name
|
|
146
|
+
}, e.id))]
|
|
147
|
+
})
|
|
148
|
+
}),
|
|
149
|
+
/* @__PURE__ */ E(s, {
|
|
150
|
+
label: "Parties searched",
|
|
151
|
+
required: !0,
|
|
152
|
+
hint: "Comma-separated.",
|
|
153
|
+
children: /* @__PURE__ */ E(_, {
|
|
154
|
+
value: f,
|
|
155
|
+
onChange: (e) => p(e.target.value),
|
|
156
|
+
placeholder: "Beta Corp, John Roe"
|
|
157
|
+
})
|
|
158
|
+
}),
|
|
159
|
+
/* @__PURE__ */ E(s, {
|
|
160
|
+
label: "Findings",
|
|
161
|
+
children: /* @__PURE__ */ E(g, {
|
|
162
|
+
value: m,
|
|
163
|
+
onChange: (e) => h(e.target.value)
|
|
164
|
+
})
|
|
165
|
+
})
|
|
166
|
+
]
|
|
167
|
+
})
|
|
168
|
+
});
|
|
169
|
+
}, M = ({ id: e, onClose: t, onDone: n }) => {
|
|
170
|
+
let a = r(), [o, c] = S("CLEAR"), [d, f] = S(""), [p, m] = S(""), [h, _] = S(null);
|
|
171
|
+
return /* @__PURE__ */ E(l, {
|
|
172
|
+
open: !0,
|
|
173
|
+
onClose: t,
|
|
174
|
+
title: "Resolve conflict check",
|
|
175
|
+
footer: /* @__PURE__ */ D(T, { children: [/* @__PURE__ */ E(O, {
|
|
176
|
+
variant: "outline",
|
|
177
|
+
onClick: t,
|
|
178
|
+
disabled: a.isPending,
|
|
179
|
+
children: "Cancel"
|
|
180
|
+
}), /* @__PURE__ */ E(O, {
|
|
181
|
+
onClick: () => a.mutate({
|
|
182
|
+
id: e,
|
|
183
|
+
status: o,
|
|
184
|
+
findings: d.trim() || void 0,
|
|
185
|
+
waiverReason: o === "WAIVED" && p.trim() || void 0
|
|
186
|
+
}, {
|
|
187
|
+
onSuccess: () => {
|
|
188
|
+
n(), t();
|
|
189
|
+
},
|
|
190
|
+
onError: (e) => _(e instanceof Error ? e.message : "Failed.")
|
|
191
|
+
}),
|
|
192
|
+
disabled: a.isPending,
|
|
193
|
+
children: a.isPending ? "Saving…" : "Resolve"
|
|
194
|
+
})] }),
|
|
195
|
+
children: /* @__PURE__ */ D("div", {
|
|
196
|
+
className: "space-y-3",
|
|
197
|
+
children: [
|
|
198
|
+
h && /* @__PURE__ */ E(i, {
|
|
199
|
+
tone: "danger",
|
|
200
|
+
children: h
|
|
201
|
+
}),
|
|
202
|
+
/* @__PURE__ */ E(s, {
|
|
203
|
+
label: "Outcome",
|
|
204
|
+
children: /* @__PURE__ */ E(u, {
|
|
205
|
+
value: o,
|
|
206
|
+
onChange: (e) => c(e.target.value),
|
|
207
|
+
children: k.map((e) => /* @__PURE__ */ E("option", {
|
|
208
|
+
value: e,
|
|
209
|
+
children: b(e)
|
|
210
|
+
}, e))
|
|
211
|
+
})
|
|
212
|
+
}),
|
|
213
|
+
/* @__PURE__ */ E(s, {
|
|
214
|
+
label: "Findings",
|
|
215
|
+
children: /* @__PURE__ */ E(g, {
|
|
216
|
+
value: d,
|
|
217
|
+
onChange: (e) => f(e.target.value)
|
|
218
|
+
})
|
|
219
|
+
}),
|
|
220
|
+
o === "WAIVED" && /* @__PURE__ */ E(s, {
|
|
221
|
+
label: "Waiver reason",
|
|
222
|
+
children: /* @__PURE__ */ E(g, {
|
|
223
|
+
value: p,
|
|
224
|
+
onChange: (e) => m(e.target.value)
|
|
225
|
+
})
|
|
226
|
+
})
|
|
227
|
+
]
|
|
228
|
+
})
|
|
229
|
+
});
|
|
230
|
+
};
|
|
231
|
+
//#endregion
|
|
232
|
+
export { A as ConflictsPage };
|
|
233
|
+
|
|
234
|
+
//# sourceMappingURL=ConflictsPage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConflictsPage.js","names":[],"sources":["../../../src/proserviceworld/pages/ConflictsPage.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useMemo, useState } from 'react';\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport { Plus, GitBranch } from 'lucide-react';\nimport {\n useConflictChecks,\n useCreateConflictCheck,\n useResolveConflictCheck,\n useClients,\n type PswConflictCheckStatus,\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 humanize,\n fmtDate,\n} from '../components/ui';\n\nconst RESOLVE_STATUSES: PswConflictCheckStatus[] = [\n 'CLEAR',\n 'POTENTIAL_CONFLICT',\n 'CONFLICT',\n 'WAIVED',\n];\n\nexport const ConflictsPage: FC = () => {\n const [creating, setCreating] = useState(false);\n const [resolving, setResolving] = useState<{ id: string } | null>(null);\n const [banner, setBanner] = useState<string | null>(null);\n const { data, isLoading, error, refetch } = useConflictChecks();\n const clients = useClients({ pagination: { limit: 100 } });\n const clientName = useMemo(\n () => new Map((clients.data?.items ?? []).map((c) => [c.id, c.name])),\n [clients.data]\n );\n\n return (\n <div className=\"space-y-6\">\n <PageHeader\n title=\"Conflict checks\"\n subtitle=\"Run before accepting a client or opening a matter — searched against existing clients, matters and counterparties, with a documented result and waiver.\"\n icon={<GitBranch className=\"h-6 w-6\" />}\n actions={\n <Button onClick={() => setCreating(true)}>\n <Plus className=\"mr-1.5 h-4 w-4\" />\n Run check\n </Button>\n }\n />\n\n {banner && (\n <Banner tone=\"success\" onClose={() => setBanner(null)}>\n {banner}\n </Banner>\n )}\n\n {isLoading ? (\n <LoadingBlock />\n ) : error ? (\n <ErrorState error={error} onRetry={() => void refetch()} />\n ) : !data || data.length === 0 ? (\n <Empty\n title=\"No conflict checks\"\n description=\"Run a conflict check before taking on new work.\"\n icon={<GitBranch className=\"h-8 w-8\" />}\n action={\n <Button onClick={() => setCreating(true)}>\n <Plus className=\"mr-1.5 h-4 w-4\" />\n Run check\n </Button>\n }\n />\n ) : (\n <SectionCard title={`${data.length} check${data.length === 1 ? '' : 's'}`}>\n <TableWrap>\n <thead>\n <tr>\n <Th>Client</Th>\n <Th>Parties searched</Th>\n <Th>Run</Th>\n <Th>Status</Th>\n <Th className=\"text-right\">Actions</Th>\n </tr>\n </thead>\n <tbody>\n {data.map((c) => (\n <tr key={c.id} className=\"hover:bg-bg-sunken/50\">\n <Td>\n <span className=\"font-medium text-text-primary\">\n {clientName.get(c.clientId) ?? '—'}\n </span>\n </Td>\n <Td className=\"max-w-xs truncate\">{c.searchedParties.join(', ') || '—'}</Td>\n <Td>{fmtDate(c.createdAt)}</Td>\n <Td>\n <StatusPill status={c.status} />\n </Td>\n <Td className=\"text-right\">\n {c.status === 'PENDING' || c.status === 'POTENTIAL_CONFLICT' ? (\n <Button variant=\"ghost\" size=\"sm\" onClick={() => setResolving({ id: c.id })}>\n Resolve\n </Button>\n ) : (\n <span className=\"text-xs text-text-tertiary\">\n {c.resolvedAt ? fmtDate(c.resolvedAt) : ''}\n </span>\n )}\n </Td>\n </tr>\n ))}\n </tbody>\n </TableWrap>\n </SectionCard>\n )}\n\n {creating && (\n <ConflictModal\n onClose={() => setCreating(false)}\n onDone={() => {\n void refetch();\n setBanner('Conflict check recorded.');\n }}\n />\n )}\n {resolving && (\n <ResolveModal\n id={resolving.id}\n onClose={() => setResolving(null)}\n onDone={() => {\n void refetch();\n setBanner('Conflict check resolved.');\n }}\n />\n )}\n </div>\n );\n};\n\nconst ConflictModal: FC<{ onClose: () => void; onDone: () => void }> = ({ onClose, onDone }) => {\n const create = useCreateConflictCheck();\n const clients = useClients({ pagination: { limit: 100 } });\n const [clientId, setClientId] = useState('');\n const [parties, setParties] = useState('');\n const [findings, setFindings] = useState('');\n const [err, setErr] = useState<string | null>(null);\n const submit = () => {\n setErr(null);\n if (!clientId) return setErr('Select a client.');\n const searchedParties = parties\n .split(',')\n .map((p) => p.trim())\n .filter(Boolean);\n if (searchedParties.length === 0) return setErr('Add at least one party.');\n create.mutate(\n { clientId, searchedParties, findings: findings.trim() || null },\n {\n onSuccess: () => {\n onDone();\n onClose();\n },\n onError: (e) => setErr(e instanceof Error ? e.message : 'Failed.'),\n }\n );\n };\n return (\n <Modal\n open\n onClose={onClose}\n title=\"Run conflict check\"\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 ? 'Running…' : 'Record check'}\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={clientId} onChange={(e) => setClientId(e.target.value)}>\n <option value=\"\">Select…</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=\"Parties searched\" required hint=\"Comma-separated.\">\n <TextInput\n value={parties}\n onChange={(e) => setParties(e.target.value)}\n placeholder=\"Beta Corp, John Roe\"\n />\n </Field>\n <Field label=\"Findings\">\n <TextArea value={findings} onChange={(e) => setFindings(e.target.value)} />\n </Field>\n </div>\n </Modal>\n );\n};\n\nconst ResolveModal: FC<{ id: string; onClose: () => void; onDone: () => void }> = ({\n id,\n onClose,\n onDone,\n}) => {\n const resolve = useResolveConflictCheck();\n const [status, setStatus] = useState<PswConflictCheckStatus>('CLEAR');\n const [findings, setFindings] = useState('');\n const [waiverReason, setWaiverReason] = useState('');\n const [err, setErr] = useState<string | null>(null);\n const submit = () =>\n resolve.mutate(\n {\n id,\n status,\n findings: findings.trim() || undefined,\n waiverReason: status === 'WAIVED' ? waiverReason.trim() || undefined : undefined,\n },\n {\n onSuccess: () => {\n onDone();\n onClose();\n },\n onError: (e) => setErr(e instanceof Error ? e.message : 'Failed.'),\n }\n );\n return (\n <Modal\n open\n onClose={onClose}\n title=\"Resolve conflict check\"\n footer={\n <>\n <Button variant=\"outline\" onClick={onClose} disabled={resolve.isPending}>\n Cancel\n </Button>\n <Button onClick={submit} disabled={resolve.isPending}>\n {resolve.isPending ? 'Saving…' : 'Resolve'}\n </Button>\n </>\n }\n >\n <div className=\"space-y-3\">\n {err && <Banner tone=\"danger\">{err}</Banner>}\n <Field label=\"Outcome\">\n <NativeSelect\n value={status}\n onChange={(e) => setStatus(e.target.value as PswConflictCheckStatus)}\n >\n {RESOLVE_STATUSES.map((s) => (\n <option key={s} value={s}>\n {humanize(s)}\n </option>\n ))}\n </NativeSelect>\n </Field>\n <Field label=\"Findings\">\n <TextArea value={findings} onChange={(e) => setFindings(e.target.value)} />\n </Field>\n {status === 'WAIVED' && (\n <Field label=\"Waiver reason\">\n <TextArea value={waiverReason} onChange={(e) => setWaiverReason(e.target.value)} />\n </Field>\n )}\n </div>\n </Modal>\n );\n};\n"],"mappings":"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"}
|