@burdenoff/microfe-proserviceworld 2026.709.2 → 2026.709.4

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 (51) hide show
  1. package/dist/node_modules/clsx/dist/clsx.js +1 -1
  2. package/dist/node_modules/clsx/dist/clsx.js.map +1 -1
  3. package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js +130 -130
  4. package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js.map +1 -1
  5. package/dist/proserviceworld/ProServiceWorldRoot.js +4 -2
  6. package/dist/proserviceworld/ProServiceWorldRoot.js.map +1 -1
  7. package/dist/proserviceworld/ProServiceWorldRoutes.js.map +1 -1
  8. package/dist/proserviceworld/components/DiscussionThread.js.map +1 -1
  9. package/dist/proserviceworld/components/FeatureFlaggedPage.js.map +1 -1
  10. package/dist/proserviceworld/components/LoadMore.js.map +1 -1
  11. package/dist/proserviceworld/components/TagPicker.js.map +1 -1
  12. package/dist/proserviceworld/components/ui.js.map +1 -1
  13. package/dist/proserviceworld/hooks/useAnalytics.js.map +1 -1
  14. package/dist/proserviceworld/hooks/useEntityComments.js.map +1 -1
  15. package/dist/proserviceworld/hooks/useFiles.js.map +1 -1
  16. package/dist/proserviceworld/hooks/usePageViewAnalytics.js.map +1 -1
  17. package/dist/proserviceworld/hooks/useProServiceWorldApi.js.map +1 -1
  18. package/dist/proserviceworld/i18n/index.d.ts.map +1 -1
  19. package/dist/proserviceworld/i18n/index.js +30 -1
  20. package/dist/proserviceworld/i18n/index.js.map +1 -1
  21. package/dist/proserviceworld/index.js +5 -4
  22. package/dist/proserviceworld/pages/AnalyticsPage.js.map +1 -1
  23. package/dist/proserviceworld/pages/ClientDetailPage.js.map +1 -1
  24. package/dist/proserviceworld/pages/ClientsPage.d.ts.map +1 -1
  25. package/dist/proserviceworld/pages/ClientsPage.js +1 -1
  26. package/dist/proserviceworld/pages/ClientsPage.js.map +1 -1
  27. package/dist/proserviceworld/pages/CompliancePage.js.map +1 -1
  28. package/dist/proserviceworld/pages/ConflictsPage.js.map +1 -1
  29. package/dist/proserviceworld/pages/DashboardPage.js.map +1 -1
  30. package/dist/proserviceworld/pages/DocumentsPage.js.map +1 -1
  31. package/dist/proserviceworld/pages/EngagementDetailPage.js.map +1 -1
  32. package/dist/proserviceworld/pages/EngagementsPage.d.ts.map +1 -1
  33. package/dist/proserviceworld/pages/EngagementsPage.js +123 -122
  34. package/dist/proserviceworld/pages/EngagementsPage.js.map +1 -1
  35. package/dist/proserviceworld/pages/InvoicesPage.js.map +1 -1
  36. package/dist/proserviceworld/pages/MattersPage.d.ts.map +1 -1
  37. package/dist/proserviceworld/pages/MattersPage.js +124 -123
  38. package/dist/proserviceworld/pages/MattersPage.js.map +1 -1
  39. package/dist/proserviceworld/pages/PracticeAreasPage.js.map +1 -1
  40. package/dist/proserviceworld/pages/TimePage.js.map +1 -1
  41. package/dist/proserviceworld/providers/ProServiceWorldProvider.js.map +1 -1
  42. package/dist/proserviceworld/services/assistantApi.js.map +1 -1
  43. package/dist/proserviceworld/services/createSandboxAssistantTransport.js.map +1 -1
  44. package/dist/proserviceworld/utils/cn.js +1 -1
  45. package/dist/proserviceworld/utils/cn.js.map +1 -1
  46. package/dist/proserviceworld/utils/native.js.map +1 -1
  47. package/dist/proserviceworld/utils/nav.js.map +1 -1
  48. package/dist/proserviceworld/utils/navigation.js.map +1 -1
  49. package/dist/proserviceworld/utils/pageContext.js +14 -16
  50. package/dist/proserviceworld/utils/pageContext.js.map +1 -1
  51. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"InvoicesPage.js","names":[],"sources":["../../../src/proserviceworld/pages/InvoicesPage.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useMemo, useState } from 'react';\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport { Plus, Receipt, CheckCircle2, AlertCircle, Wallet } from 'lucide-react';\nimport {\n useInvoices,\n useCreateInvoice,\n useMarkInvoicePaid,\n useClients,\n useEngagements,\n type PswInvoiceStatus,\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 MetricCard,\n TableWrap,\n Th,\n Td,\n enumOptions,\n fmtDate,\n fmtMoney,\n} from '../components/ui';\nimport { cn } from '../utils/cn';\n\nconst STATUSES: PswInvoiceStatus[] = ['DRAFT', 'SENT', 'PAID', 'OVERDUE', 'CANCELLED'];\n\nexport const InvoicesPage: FC = () => {\n const [statusFilter, setStatusFilter] = useState<PswInvoiceStatus | ''>('');\n const [creating, setCreating] = useState(false);\n const [banner, setBanner] = useState<{ tone: 'success' | 'danger'; text: string } | null>(null);\n const { data, isLoading, error, refetch } = useInvoices({ status: statusFilter || undefined });\n const markPaid = useMarkInvoicePaid();\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 const outstandingInvoices = (data?.items ?? []).filter(\n (i) => i.status === 'SENT' || i.status === 'OVERDUE'\n );\n const paidInvoices = (data?.items ?? []).filter((i) => i.status === 'PAID');\n const outstanding = outstandingInvoices.reduce((s, i) => s + i.total, 0);\n const collected = paidInvoices.reduce((s, i) => s + i.total, 0);\n\n return (\n <div className=\"space-y-6\">\n <PageHeader\n title=\"Invoices\"\n subtitle=\"Assemble invoices from time, milestones and fixed-fee schedules — and track what's outstanding.\"\n icon={<Receipt className=\"h-6 w-6\" />}\n actions={\n <Button onClick={() => setCreating(true)}>\n <Plus className=\"mr-1.5 h-4 w-4\" />\n New invoice\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=\"grid grid-cols-1 gap-3 sm:grid-cols-3\">\n <MetricCard\n label=\"Invoices\"\n value={data?.totalCount ?? 0}\n icon={<Receipt className=\"h-4 w-4\" />}\n />\n <MetricCard\n label=\"Outstanding\"\n value={fmtMoney(outstanding)}\n hint={`${outstandingInvoices.length} sent + overdue`}\n icon={<AlertCircle className=\"h-4 w-4\" />}\n tone=\"warning\"\n />\n <MetricCard\n label=\"Collected\"\n value={fmtMoney(collected)}\n hint={`${paidInvoices.length} paid`}\n icon={<Wallet className=\"h-4 w-4\" />}\n tone=\"success\"\n />\n </div>\n\n <div className=\"flex justify-end\">\n <NativeSelect\n value={statusFilter}\n onChange={(e) => setStatusFilter(e.target.value as PswInvoiceStatus | '')}\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 invoices yet\"\n description=\"Raise an invoice for a client to start tracking receivables.\"\n icon={<Receipt className=\"h-8 w-8\" />}\n action={\n <Button onClick={() => setCreating(true)}>\n <Plus className=\"mr-1.5 h-4 w-4\" />\n New invoice\n </Button>\n }\n />\n ) : (\n <SectionCard title=\"Invoices\">\n <TableWrap>\n <thead>\n <tr>\n <Th>Number</Th>\n <Th>Client</Th>\n <Th>Total</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((i) => (\n <tr key={i.id} className=\"transition-colors hover:bg-bg-sunken/60\">\n <Td>\n <span className=\"font-medium text-text-primary\">{i.number}</span>\n </Td>\n <Td className=\"text-text-primary\">{clientName.get(i.clientId) ?? '—'}</Td>\n <Td className=\"whitespace-nowrap font-semibold text-text-primary\">\n {fmtMoney(i.total, i.currency)}\n </Td>\n <Td>\n <StatusPill status={i.status} />\n </Td>\n <Td\n className={cn(\n 'whitespace-nowrap',\n i.status === 'OVERDUE' && 'font-medium text-status-error-text'\n )}\n >\n {fmtDate(i.dueDate)}\n </Td>\n <Td className=\"text-right\">\n {i.status !== 'PAID' && i.status !== 'CANCELLED' && (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n disabled={markPaid.isPending}\n onClick={() =>\n markPaid.mutate(i.id, {\n onSuccess: () =>\n setBanner({ tone: 'success', text: `${i.number} marked paid.` }),\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\" />\n Mark paid\n </Button>\n )}\n </Td>\n </tr>\n ))}\n </tbody>\n </TableWrap>\n </SectionCard>\n )}\n\n {creating && (\n <InvoiceModal\n onClose={() => setCreating(false)}\n onSaved={(n) => setBanner({ tone: 'success', text: `${n} created.` })}\n />\n )}\n </div>\n );\n};\n\nconst InvoiceModal: FC<{ onClose: () => void; onSaved: (number: string) => void }> = ({\n onClose,\n onSaved,\n}) => {\n const create = useCreateInvoice();\n const clients = useClients({ pagination: { limit: 100 } });\n const [form, setForm] = useState({\n clientId: '',\n engagementId: '',\n number: '',\n currency: 'USD',\n subtotal: '',\n taxAmount: '',\n issueDate: new Date().toISOString().slice(0, 10),\n dueDate: '',\n notes: '',\n });\n const [err, setErr] = useState<string | null>(null);\n const engagements = useEngagements({\n clientId: form.clientId || undefined,\n pagination: { limit: 100 },\n });\n const set = (k: keyof typeof form) => (e: { target: { value: string } }) =>\n setForm((f) => ({ ...f, [k]: e.target.value }));\n const total = (Number(form.subtotal) || 0) + (Number(form.taxAmount) || 0);\n\n const submit = () => {\n setErr(null);\n if (!form.clientId) return setErr('Select a client.');\n if (!form.number.trim()) return setErr('Invoice number is required.');\n create.mutate(\n {\n clientId: form.clientId,\n engagementId: form.engagementId || null,\n number: form.number.trim(),\n currency: form.currency || 'USD',\n subtotal: Number(form.subtotal) || 0,\n taxAmount: Number(form.taxAmount) || 0,\n total,\n issueDate: form.issueDate ? new Date(form.issueDate).toISOString() : null,\n dueDate: form.dueDate ? new Date(form.dueDate).toISOString() : null,\n notes: form.notes.trim() || null,\n },\n {\n onSuccess: () => {\n onSaved(form.number.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 invoice\"\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 invoice'}\n </Button>\n </>\n }\n >\n <div className=\"space-y-3\">\n {err && <Banner tone=\"danger\">{err}</Banner>}\n <div className=\"grid grid-cols-2 gap-3\">\n <Field label=\"Client\" required>\n <NativeSelect value={form.clientId} onChange={set('clientId')}>\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=\"Number\" required>\n <TextInput value={form.number} onChange={set('number')} placeholder=\"INV-2026-014\" />\n </Field>\n </div>\n <Field label=\"Engagement (optional)\">\n <NativeSelect\n value={form.engagementId}\n onChange={set('engagementId')}\n disabled={!form.clientId}\n >\n <option value=\"\">None</option>\n {engagements.data?.items.map((e) => (\n <option key={e.id} value={e.id}>\n {e.name}\n </option>\n ))}\n </NativeSelect>\n </Field>\n <div className=\"grid grid-cols-3 gap-3\">\n <Field label=\"Subtotal\">\n <TextInput type=\"number\" min=\"0\" value={form.subtotal} onChange={set('subtotal')} />\n </Field>\n <Field label=\"Tax\">\n <TextInput type=\"number\" min=\"0\" value={form.taxAmount} onChange={set('taxAmount')} />\n </Field>\n <Field label=\"Currency\">\n <TextInput value={form.currency} onChange={set('currency')} maxLength={3} />\n </Field>\n </div>\n <div className=\"rounded-lg bg-bg-sunken px-3 py-2 text-sm text-text-secondary\">\n Total:{' '}\n <span className=\"font-semibold text-text-primary\">{fmtMoney(total, form.currency)}</span>\n </div>\n <div className=\"grid grid-cols-2 gap-3\">\n <Field label=\"Issue date\">\n <TextInput type=\"date\" value={form.issueDate} onChange={set('issueDate')} />\n </Field>\n <Field label=\"Due date\">\n <TextInput type=\"date\" value={form.dueDate} onChange={set('dueDate')} />\n </Field>\n </div>\n <Field label=\"Notes\">\n <TextArea value={form.notes} onChange={set('notes')} />\n </Field>\n </div>\n </Modal>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"InvoicesPage.js","names":[],"sources":["../../../src/proserviceworld/pages/InvoicesPage.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useMemo, useState } from 'react';\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport { Plus, Receipt, CheckCircle2, AlertCircle, Wallet } from 'lucide-react';\nimport {\n useInvoices,\n useCreateInvoice,\n useMarkInvoicePaid,\n useClients,\n useEngagements,\n type PswInvoiceStatus,\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 MetricCard,\n TableWrap,\n Th,\n Td,\n enumOptions,\n fmtDate,\n fmtMoney,\n} from '../components/ui';\nimport { cn } from '../utils/cn';\n\nconst STATUSES: PswInvoiceStatus[] = ['DRAFT', 'SENT', 'PAID', 'OVERDUE', 'CANCELLED'];\n\nexport const InvoicesPage: FC = () => {\n const [statusFilter, setStatusFilter] = useState<PswInvoiceStatus | ''>('');\n const [creating, setCreating] = useState(false);\n const [banner, setBanner] = useState<{ tone: 'success' | 'danger'; text: string } | null>(null);\n const { data, isLoading, error, refetch } = useInvoices({ status: statusFilter || undefined });\n const markPaid = useMarkInvoicePaid();\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 const outstandingInvoices = (data?.items ?? []).filter(\n (i) => i.status === 'SENT' || i.status === 'OVERDUE'\n );\n const paidInvoices = (data?.items ?? []).filter((i) => i.status === 'PAID');\n const outstanding = outstandingInvoices.reduce((s, i) => s + i.total, 0);\n const collected = paidInvoices.reduce((s, i) => s + i.total, 0);\n\n return (\n <div className=\"space-y-6\">\n <PageHeader\n title=\"Invoices\"\n subtitle=\"Assemble invoices from time, milestones and fixed-fee schedules — and track what's outstanding.\"\n icon={<Receipt className=\"h-6 w-6\" />}\n actions={\n <Button onClick={() => setCreating(true)}>\n <Plus className=\"mr-1.5 h-4 w-4\" />\n New invoice\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=\"grid grid-cols-1 gap-3 sm:grid-cols-3\">\n <MetricCard\n label=\"Invoices\"\n value={data?.totalCount ?? 0}\n icon={<Receipt className=\"h-4 w-4\" />}\n />\n <MetricCard\n label=\"Outstanding\"\n value={fmtMoney(outstanding)}\n hint={`${outstandingInvoices.length} sent + overdue`}\n icon={<AlertCircle className=\"h-4 w-4\" />}\n tone=\"warning\"\n />\n <MetricCard\n label=\"Collected\"\n value={fmtMoney(collected)}\n hint={`${paidInvoices.length} paid`}\n icon={<Wallet className=\"h-4 w-4\" />}\n tone=\"success\"\n />\n </div>\n\n <div className=\"flex justify-end\">\n <NativeSelect\n value={statusFilter}\n onChange={(e) => setStatusFilter(e.target.value as PswInvoiceStatus | '')}\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 invoices yet\"\n description=\"Raise an invoice for a client to start tracking receivables.\"\n icon={<Receipt className=\"h-8 w-8\" />}\n action={\n <Button onClick={() => setCreating(true)}>\n <Plus className=\"mr-1.5 h-4 w-4\" />\n New invoice\n </Button>\n }\n />\n ) : (\n <SectionCard title=\"Invoices\">\n <TableWrap>\n <thead>\n <tr>\n <Th>Number</Th>\n <Th>Client</Th>\n <Th>Total</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((i) => (\n <tr key={i.id} className=\"transition-colors hover:bg-bg-sunken/60\">\n <Td>\n <span className=\"font-medium text-text-primary\">{i.number}</span>\n </Td>\n <Td className=\"text-text-primary\">{clientName.get(i.clientId) ?? '—'}</Td>\n <Td className=\"whitespace-nowrap font-semibold text-text-primary\">\n {fmtMoney(i.total, i.currency)}\n </Td>\n <Td>\n <StatusPill status={i.status} />\n </Td>\n <Td\n className={cn(\n 'whitespace-nowrap',\n i.status === 'OVERDUE' && 'font-medium text-status-error-text'\n )}\n >\n {fmtDate(i.dueDate)}\n </Td>\n <Td className=\"text-right\">\n {i.status !== 'PAID' && i.status !== 'CANCELLED' && (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n disabled={markPaid.isPending}\n onClick={() =>\n markPaid.mutate(i.id, {\n onSuccess: () =>\n setBanner({ tone: 'success', text: `${i.number} marked paid.` }),\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\" />\n Mark paid\n </Button>\n )}\n </Td>\n </tr>\n ))}\n </tbody>\n </TableWrap>\n </SectionCard>\n )}\n\n {creating && (\n <InvoiceModal\n onClose={() => setCreating(false)}\n onSaved={(n) => setBanner({ tone: 'success', text: `${n} created.` })}\n />\n )}\n </div>\n );\n};\n\nconst InvoiceModal: FC<{ onClose: () => void; onSaved: (number: string) => void }> = ({\n onClose,\n onSaved,\n}) => {\n const create = useCreateInvoice();\n const clients = useClients({ pagination: { limit: 100 } });\n const [form, setForm] = useState({\n clientId: '',\n engagementId: '',\n number: '',\n currency: 'USD',\n subtotal: '',\n taxAmount: '',\n issueDate: new Date().toISOString().slice(0, 10),\n dueDate: '',\n notes: '',\n });\n const [err, setErr] = useState<string | null>(null);\n const engagements = useEngagements({\n clientId: form.clientId || undefined,\n pagination: { limit: 100 },\n });\n const set = (k: keyof typeof form) => (e: { target: { value: string } }) =>\n setForm((f) => ({ ...f, [k]: e.target.value }));\n const total = (Number(form.subtotal) || 0) + (Number(form.taxAmount) || 0);\n\n const submit = () => {\n setErr(null);\n if (!form.clientId) return setErr('Select a client.');\n if (!form.number.trim()) return setErr('Invoice number is required.');\n create.mutate(\n {\n clientId: form.clientId,\n engagementId: form.engagementId || null,\n number: form.number.trim(),\n currency: form.currency || 'USD',\n subtotal: Number(form.subtotal) || 0,\n taxAmount: Number(form.taxAmount) || 0,\n total,\n issueDate: form.issueDate ? new Date(form.issueDate).toISOString() : null,\n dueDate: form.dueDate ? new Date(form.dueDate).toISOString() : null,\n notes: form.notes.trim() || null,\n },\n {\n onSuccess: () => {\n onSaved(form.number.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 invoice\"\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 invoice'}\n </Button>\n </>\n }\n >\n <div className=\"space-y-3\">\n {err && <Banner tone=\"danger\">{err}</Banner>}\n <div className=\"grid grid-cols-2 gap-3\">\n <Field label=\"Client\" required>\n <NativeSelect value={form.clientId} onChange={set('clientId')}>\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=\"Number\" required>\n <TextInput value={form.number} onChange={set('number')} placeholder=\"INV-2026-014\" />\n </Field>\n </div>\n <Field label=\"Engagement (optional)\">\n <NativeSelect\n value={form.engagementId}\n onChange={set('engagementId')}\n disabled={!form.clientId}\n >\n <option value=\"\">None</option>\n {engagements.data?.items.map((e) => (\n <option key={e.id} value={e.id}>\n {e.name}\n </option>\n ))}\n </NativeSelect>\n </Field>\n <div className=\"grid grid-cols-3 gap-3\">\n <Field label=\"Subtotal\">\n <TextInput type=\"number\" min=\"0\" value={form.subtotal} onChange={set('subtotal')} />\n </Field>\n <Field label=\"Tax\">\n <TextInput type=\"number\" min=\"0\" value={form.taxAmount} onChange={set('taxAmount')} />\n </Field>\n <Field label=\"Currency\">\n <TextInput value={form.currency} onChange={set('currency')} maxLength={3} />\n </Field>\n </div>\n <div className=\"rounded-lg bg-bg-sunken px-3 py-2 text-sm text-text-secondary\">\n Total:{' '}\n <span className=\"font-semibold text-text-primary\">{fmtMoney(total, form.currency)}</span>\n </div>\n <div className=\"grid grid-cols-2 gap-3\">\n <Field label=\"Issue date\">\n <TextInput type=\"date\" value={form.issueDate} onChange={set('issueDate')} />\n </Field>\n <Field label=\"Due date\">\n <TextInput type=\"date\" value={form.dueDate} onChange={set('dueDate')} />\n </Field>\n </div>\n <Field label=\"Notes\">\n <TextArea value={form.notes} onChange={set('notes')} />\n </Field>\n </div>\n </Modal>\n );\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"MattersPage.d.ts","sourceRoot":"","sources":["../../../src/proserviceworld/pages/MattersPage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AA+DhC,eAAO,MAAM,WAAW,EAAE,EAgOzB,CAAC"}
1
+ {"version":3,"file":"MattersPage.d.ts","sourceRoot":"","sources":["../../../src/proserviceworld/pages/MattersPage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAgEhC,eAAO,MAAM,WAAW,EAAE,EAgOzB,CAAC"}
@@ -1,67 +1,68 @@
1
1
  import { useClients as e, useCloseMatter as t, useCreateMatter as n, useMatters as r, usePracticeAreas as i, useUpdateMatter as a } from "../hooks/useProServiceWorldApi.js";
2
2
  import { Banner as o, Empty as s, ErrorState as c, Field as l, LoadingBlock as u, MetricCard 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";
3
- import { useAnalytics as w } from "../hooks/useAnalytics.js";
4
- import { impactFeedback as T } from "../utils/native.js";
3
+ import { t as w } from "../i18n/index.js";
4
+ import { useAnalytics as T } from "../hooks/useAnalytics.js";
5
+ import { impactFeedback as ee } from "../utils/native.js";
5
6
  import { TagPicker as E } from "../components/TagPicker.js";
6
- import { LoadMore as ee } from "../components/LoadMore.js";
7
- import { useMemo as te, useState as D } from "react";
8
- import { AlertTriangle as O, CheckCircle2 as k, CircleDot as A, FolderKanban as j, Lock as M, Plus as N, Search as P } from "lucide-react";
9
- import { Fragment as F, jsx as I, jsxs as L } from "react/jsx-runtime";
10
- import { Button as R } from "@burdenoff/fe-libs/ui";
7
+ import { LoadMore as D } from "../components/LoadMore.js";
8
+ import { useMemo as O, useState as k } from "react";
9
+ import { AlertTriangle as te, CheckCircle2 as A, CircleDot as j, FolderKanban as M, Lock as N, Plus as P, Search as F } from "lucide-react";
10
+ import { Fragment as I, jsx as L, jsxs as R } from "react/jsx-runtime";
11
+ import { Button as z } from "@burdenoff/fe-libs/ui";
11
12
  //#region src/proserviceworld/pages/MattersPage.tsx
12
- var z = [
13
+ var B = [
13
14
  "OPEN",
14
15
  "ON_HOLD",
15
16
  "CLOSED",
16
17
  "ARCHIVED"
17
- ], B = [
18
+ ], V = [
18
19
  "LOW",
19
20
  "MEDIUM",
20
21
  "HIGH",
21
22
  "CRITICAL"
22
- ], ne = () => /* @__PURE__ */ I("span", {
23
+ ], ne = () => /* @__PURE__ */ L("span", {
23
24
  className: "inline-flex h-5 w-5 shrink-0 items-center justify-center rounded-md bg-status-warning-bg-subtle text-status-warning-text",
24
25
  title: "Privileged / confidential",
25
26
  "aria-label": "Privileged",
26
- children: /* @__PURE__ */ I(M, { className: "h-3 w-3" })
27
- }), V = 25, H = () => {
28
- let { emitIntent: e, emitFact: n } = w(), [i, l] = D(""), [f, y] = D(""), [B, H] = D(!1), [U, W] = D(null), [G, K] = D({
29
- limit: V,
27
+ children: /* @__PURE__ */ L(N, { className: "h-3 w-3" })
28
+ }), H = 25, U = () => {
29
+ let { emitIntent: e, emitFact: n } = T(), [i, l] = k(""), [f, y] = k(""), [V, U] = k(!1), [W, G] = k(null), [ie, K] = k({
30
+ limit: H,
30
31
  offset: 0
31
32
  }), { data: q, isLoading: J, error: Y, refetch: X } = r({
32
33
  search: i.trim() || void 0,
33
34
  status: f || void 0,
34
- pagination: G
35
- }), Z = t(), ie = a(), Q = te(() => q?.items ?? [], [q]), ae = Q.filter((e) => e.status === "OPEN").length, oe = Q.filter((e) => e.isPrivileged).length, $ = Q.filter((e) => e.priority === "HIGH" || e.priority === "CRITICAL").length;
36
- return /* @__PURE__ */ L("div", {
35
+ pagination: ie
36
+ }), Z = t(), ae = a(), Q = O(() => q?.items ?? [], [q]), oe = Q.filter((e) => e.status === "OPEN").length, se = Q.filter((e) => e.isPrivileged).length, $ = Q.filter((e) => e.priority === "HIGH" || e.priority === "CRITICAL").length;
37
+ return /* @__PURE__ */ R("div", {
37
38
  className: "space-y-6",
38
39
  children: [
39
- /* @__PURE__ */ I(m, {
40
- title: "Matters",
41
- subtitle: "The regulated threads of work — legal matters, audits, filings — with their own deadlines and sensitive-document handling.",
42
- icon: /* @__PURE__ */ I(j, { className: "h-6 w-6" }),
43
- actions: /* @__PURE__ */ L(R, {
40
+ /* @__PURE__ */ L(m, {
41
+ title: w("psw.matters.title"),
42
+ subtitle: w("psw.matters.subtitle"),
43
+ icon: /* @__PURE__ */ L(M, { className: "h-6 w-6" }),
44
+ actions: /* @__PURE__ */ R(z, {
44
45
  onClick: () => {
45
- T("light"), e("psw.matter.create_clicked"), H(!0);
46
+ ee("light"), e("psw.matter.create_clicked"), U(!0);
46
47
  },
47
- children: [/* @__PURE__ */ I(N, { className: "mr-1.5 h-4 w-4" }), "New matter"]
48
+ children: [/* @__PURE__ */ L(P, { className: "mr-1.5 h-4 w-4" }), w("psw.matters.new")]
48
49
  })
49
50
  }),
50
- U && /* @__PURE__ */ I(o, {
51
- tone: U.tone,
52
- onClose: () => W(null),
53
- children: U.text
51
+ W && /* @__PURE__ */ L(o, {
52
+ tone: W.tone,
53
+ onClose: () => G(null),
54
+ children: W.text
54
55
  }),
55
- /* @__PURE__ */ L("div", {
56
+ /* @__PURE__ */ R("div", {
56
57
  className: "flex flex-col gap-2 sm:flex-row sm:items-center",
57
- children: [/* @__PURE__ */ L("div", {
58
+ children: [/* @__PURE__ */ R("div", {
58
59
  className: "relative flex-1",
59
- children: [/* @__PURE__ */ I(P, { className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-tertiary" }), /* @__PURE__ */ I(b, {
60
- placeholder: "Search matters…",
60
+ children: [/* @__PURE__ */ L(F, { className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-tertiary" }), /* @__PURE__ */ L(b, {
61
+ placeholder: w("psw.matters.searchPlaceholder"),
61
62
  value: i,
62
63
  onChange: (e) => {
63
64
  l(e.target.value), K({
64
- limit: V,
65
+ limit: H,
65
66
  offset: 0
66
67
  });
67
68
  },
@@ -73,143 +74,143 @@ var z = [
73
74
  },
74
75
  className: "pl-9"
75
76
  })]
76
- }), /* @__PURE__ */ L(p, {
77
+ }), /* @__PURE__ */ R(p, {
77
78
  value: f,
78
79
  onChange: (e) => {
79
80
  y(e.target.value), K({
80
- limit: V,
81
+ limit: H,
81
82
  offset: 0
82
83
  });
83
84
  },
84
85
  className: "sm:w-48",
85
- children: [/* @__PURE__ */ I("option", {
86
+ children: [/* @__PURE__ */ L("option", {
86
87
  value: "",
87
- children: "All statuses"
88
- }), S(z)]
88
+ children: w("psw.matters.allStatuses")
89
+ }), S(B)]
89
90
  })]
90
91
  }),
91
- J ? /* @__PURE__ */ I(u, {}) : Y ? /* @__PURE__ */ I(c, {
92
+ J ? /* @__PURE__ */ L(u, {}) : Y ? /* @__PURE__ */ L(c, {
92
93
  error: Y,
93
94
  onRetry: () => void X()
94
- }) : !q || q.items.length === 0 ? /* @__PURE__ */ I(s, {
95
- title: "No matters yet",
96
- description: "Open a matter to track a regulated thread of work for a client.",
97
- icon: /* @__PURE__ */ I(j, { className: "h-8 w-8" }),
98
- action: /* @__PURE__ */ L(R, {
99
- onClick: () => H(!0),
100
- children: [/* @__PURE__ */ I(N, { className: "mr-1.5 h-4 w-4" }), "New matter"]
95
+ }) : !q || q.items.length === 0 ? /* @__PURE__ */ L(s, {
96
+ title: w("psw.matters.emptyTitle"),
97
+ description: w("psw.matters.emptyDescription"),
98
+ icon: /* @__PURE__ */ L(M, { className: "h-8 w-8" }),
99
+ action: /* @__PURE__ */ R(z, {
100
+ onClick: () => U(!0),
101
+ children: [/* @__PURE__ */ L(P, { className: "mr-1.5 h-4 w-4" }), w("psw.matters.new")]
101
102
  })
102
- }) : /* @__PURE__ */ L(F, { children: [/* @__PURE__ */ L("div", {
103
+ }) : /* @__PURE__ */ R(I, { children: [/* @__PURE__ */ R("div", {
103
104
  className: "grid grid-cols-2 gap-3 lg:grid-cols-4",
104
105
  children: [
105
- /* @__PURE__ */ I(d, {
106
+ /* @__PURE__ */ L(d, {
106
107
  label: "Matters",
107
108
  value: q.totalCount,
108
- icon: /* @__PURE__ */ I(j, { className: "h-4 w-4" })
109
+ icon: /* @__PURE__ */ L(M, { className: "h-4 w-4" })
109
110
  }),
110
- /* @__PURE__ */ I(d, {
111
+ /* @__PURE__ */ L(d, {
111
112
  label: "Open",
112
- value: ae,
113
- icon: /* @__PURE__ */ I(A, { className: "h-4 w-4" }),
113
+ value: oe,
114
+ icon: /* @__PURE__ */ L(j, { className: "h-4 w-4" }),
114
115
  tone: "accent"
115
116
  }),
116
- /* @__PURE__ */ I(d, {
117
+ /* @__PURE__ */ L(d, {
117
118
  label: "Privileged",
118
- value: oe,
119
- icon: /* @__PURE__ */ I(M, { className: "h-4 w-4" }),
119
+ value: se,
120
+ icon: /* @__PURE__ */ L(N, { className: "h-4 w-4" }),
120
121
  tone: "warning"
121
122
  }),
122
- /* @__PURE__ */ I(d, {
123
+ /* @__PURE__ */ L(d, {
123
124
  label: "High priority",
124
125
  value: $,
125
- icon: /* @__PURE__ */ I(O, { className: "h-4 w-4" }),
126
+ icon: /* @__PURE__ */ L(te, { className: "h-4 w-4" }),
126
127
  tone: $ ? "danger" : "neutral"
127
128
  })
128
129
  ]
129
- }), /* @__PURE__ */ L(h, {
130
+ }), /* @__PURE__ */ R(h, {
130
131
  title: `${q.totalCount} matter${q.totalCount === 1 ? "" : "s"}`,
131
- children: [/* @__PURE__ */ L(_, { children: [/* @__PURE__ */ I("thead", { children: /* @__PURE__ */ L("tr", { children: [
132
- /* @__PURE__ */ I(x, { children: "Matter" }),
133
- /* @__PURE__ */ I(x, { children: "Client" }),
134
- /* @__PURE__ */ I(x, { children: "Priority" }),
135
- /* @__PURE__ */ I(x, { children: "Status" }),
136
- /* @__PURE__ */ I(x, { children: "Due" }),
137
- /* @__PURE__ */ I(x, { children: "Tags" }),
138
- /* @__PURE__ */ I(x, {
132
+ children: [/* @__PURE__ */ R(_, { children: [/* @__PURE__ */ L("thead", { children: /* @__PURE__ */ R("tr", { children: [
133
+ /* @__PURE__ */ L(x, { children: w("psw.matters.tableMatter") }),
134
+ /* @__PURE__ */ L(x, { children: w("psw.matters.tableClient") }),
135
+ /* @__PURE__ */ L(x, { children: w("psw.matters.tablePriority") }),
136
+ /* @__PURE__ */ L(x, { children: w("psw.matters.tableStatus") }),
137
+ /* @__PURE__ */ L(x, { children: w("psw.matters.tableDue") }),
138
+ /* @__PURE__ */ L(x, { children: w("psw.matters.tableTags") }),
139
+ /* @__PURE__ */ L(x, {
139
140
  className: "text-right",
140
- children: "Actions"
141
+ children: w("psw.common.actions")
141
142
  })
142
- ] }) }), /* @__PURE__ */ I("tbody", { children: q.items.map((e) => /* @__PURE__ */ L("tr", {
143
+ ] }) }), /* @__PURE__ */ L("tbody", { children: q.items.map((e) => /* @__PURE__ */ R("tr", {
143
144
  className: "transition-colors hover:bg-bg-sunken/60",
144
145
  children: [
145
- /* @__PURE__ */ L(v, { children: [/* @__PURE__ */ L("span", {
146
+ /* @__PURE__ */ R(v, { children: [/* @__PURE__ */ R("span", {
146
147
  className: "flex items-center gap-2 font-medium text-text-primary",
147
- children: [e.isPrivileged && /* @__PURE__ */ I(ne, {}), /* @__PURE__ */ I("span", {
148
+ children: [e.isPrivileged && /* @__PURE__ */ L(ne, {}), /* @__PURE__ */ L("span", {
148
149
  className: "truncate",
149
150
  children: e.title
150
151
  })]
151
- }), e.reference ? /* @__PURE__ */ L("div", {
152
+ }), e.reference ? /* @__PURE__ */ R("div", {
152
153
  className: "mt-0.5 pl-0 text-xs text-text-tertiary",
153
154
  children: ["Ref: ", e.reference]
154
155
  }) : null] }),
155
- /* @__PURE__ */ I(v, {
156
+ /* @__PURE__ */ L(v, {
156
157
  className: "text-text-primary",
157
158
  children: e.client?.name ?? "—"
158
159
  }),
159
- /* @__PURE__ */ I(v, { children: /* @__PURE__ */ I(g, { status: e.priority }) }),
160
- /* @__PURE__ */ I(v, { children: /* @__PURE__ */ I(g, { status: e.status }) }),
161
- /* @__PURE__ */ I(v, { children: C(e.dueDate) }),
162
- /* @__PURE__ */ I(v, { children: /* @__PURE__ */ I(E, {
160
+ /* @__PURE__ */ L(v, { children: /* @__PURE__ */ L(g, { status: e.priority }) }),
161
+ /* @__PURE__ */ L(v, { children: /* @__PURE__ */ L(g, { status: e.status }) }),
162
+ /* @__PURE__ */ L(v, { children: C(e.dueDate) }),
163
+ /* @__PURE__ */ L(v, { children: /* @__PURE__ */ L(E, {
163
164
  entityType: "PswMatter",
164
165
  entityId: e.id,
165
166
  tags: e.tags ?? [],
166
167
  onChange: async (t) => {
167
- await ie.mutateAsync({
168
+ await ae.mutateAsync({
168
169
  id: e.id,
169
170
  input: { tags: t }
170
171
  }), X();
171
172
  },
172
173
  maxTags: 5
173
174
  }) }),
174
- /* @__PURE__ */ I(v, {
175
+ /* @__PURE__ */ L(v, {
175
176
  className: "text-right",
176
- children: e.status !== "CLOSED" && e.status !== "ARCHIVED" ? /* @__PURE__ */ L(R, {
177
+ children: e.status !== "CLOSED" && e.status !== "ARCHIVED" ? /* @__PURE__ */ R(z, {
177
178
  variant: "ghost",
178
179
  size: "sm",
179
180
  disabled: Z.isPending,
180
181
  onClick: () => Z.mutate(e.id, {
181
182
  onSuccess: () => {
182
- n("psw.matter.closed", { matterId: e.id }), W({
183
+ n("psw.matter.closed", { matterId: e.id }), G({
183
184
  tone: "success",
184
185
  text: `${e.title} closed.`
185
186
  });
186
187
  },
187
- onError: (e) => W({
188
+ onError: (e) => G({
188
189
  tone: "danger",
189
190
  text: e instanceof Error ? e.message : "Failed."
190
191
  })
191
192
  }),
192
- children: [/* @__PURE__ */ I(k, { className: "mr-1 h-4 w-4" }), " Close"]
193
- }) : /* @__PURE__ */ I("span", {
193
+ children: [/* @__PURE__ */ L(A, { className: "mr-1 h-4 w-4" }), " Close"]
194
+ }) : /* @__PURE__ */ L("span", {
194
195
  className: "text-xs text-text-tertiary",
195
196
  children: e.closedAt ? `Closed ${C(e.closedAt)}` : "—"
196
197
  })
197
198
  })
198
199
  ]
199
- }, e.id)) })] }), /* @__PURE__ */ I(ee, {
200
+ }, e.id)) })] }), /* @__PURE__ */ L(D, {
200
201
  hasMore: q?.pageInfo?.hasMore ?? !1,
201
202
  loading: J,
202
203
  loadedCount: Q.length,
203
204
  totalCount: q?.totalCount ?? Q.length,
204
205
  onLoadMore: () => K((e) => ({
205
- limit: V,
206
- offset: e.offset + V
206
+ limit: H,
207
+ offset: e.offset + H
207
208
  }))
208
209
  })]
209
210
  })] }),
210
- B && /* @__PURE__ */ I(re, {
211
- onClose: () => H(!1),
212
- onSaved: (e) => W({
211
+ V && /* @__PURE__ */ L(re, {
212
+ onClose: () => U(!1),
213
+ onSaved: (e) => G({
213
214
  tone: "success",
214
215
  text: `${e} opened.`
215
216
  })
@@ -217,7 +218,7 @@ var z = [
217
218
  ]
218
219
  });
219
220
  }, re = ({ onClose: t, onSaved: r }) => {
220
- let a = n(), { emitFact: s } = w(), c = e({ pagination: { limit: 100 } }), u = i(), [d, m] = D({
221
+ let a = n(), { emitFact: s } = T(), c = e({ pagination: { limit: 100 } }), u = i(), [d, m] = k({
221
222
  clientId: "",
222
223
  practiceAreaId: "",
223
224
  title: "",
@@ -226,20 +227,20 @@ var z = [
226
227
  priority: "MEDIUM",
227
228
  dueDate: "",
228
229
  isPrivileged: !1
229
- }), [h, g] = D(null), _ = (e) => (t) => m((n) => ({
230
+ }), [h, g] = k(null), _ = (e) => (t) => m((n) => ({
230
231
  ...n,
231
232
  [e]: t.target.value
232
233
  }));
233
- return /* @__PURE__ */ I(f, {
234
+ return /* @__PURE__ */ L(f, {
234
235
  open: !0,
235
236
  onClose: t,
236
- title: "New matter",
237
- footer: /* @__PURE__ */ L(F, { children: [/* @__PURE__ */ I(R, {
237
+ title: w("psw.matters.newTitle"),
238
+ footer: /* @__PURE__ */ R(I, { children: [/* @__PURE__ */ L(z, {
238
239
  variant: "outline",
239
240
  onClick: t,
240
241
  disabled: a.isPending,
241
242
  children: "Cancel"
242
- }), /* @__PURE__ */ I(R, {
243
+ }), /* @__PURE__ */ L(z, {
243
244
  onClick: () => {
244
245
  if (g(null), !d.clientId) return g("Select a client.");
245
246
  if (!d.title.trim()) return g("Matter title is required.");
@@ -266,98 +267,98 @@ var z = [
266
267
  disabled: a.isPending,
267
268
  children: a.isPending ? "Opening…" : "Open matter"
268
269
  })] }),
269
- children: /* @__PURE__ */ L("div", {
270
+ children: /* @__PURE__ */ R("div", {
270
271
  className: "space-y-3",
271
272
  children: [
272
- h && /* @__PURE__ */ I(o, {
273
+ h && /* @__PURE__ */ L(o, {
273
274
  tone: "danger",
274
275
  children: h
275
276
  }),
276
- /* @__PURE__ */ I(l, {
277
+ /* @__PURE__ */ L(l, {
277
278
  label: "Client",
278
279
  required: !0,
279
- children: /* @__PURE__ */ L(p, {
280
+ children: /* @__PURE__ */ R(p, {
280
281
  value: d.clientId,
281
282
  onChange: _("clientId"),
282
- children: [/* @__PURE__ */ I("option", {
283
+ children: [/* @__PURE__ */ L("option", {
283
284
  value: "",
284
285
  children: "Select a client…"
285
- }), c.data?.items.map((e) => /* @__PURE__ */ I("option", {
286
+ }), c.data?.items.map((e) => /* @__PURE__ */ L("option", {
286
287
  value: e.id,
287
288
  children: e.name
288
289
  }, e.id))]
289
290
  })
290
291
  }),
291
- /* @__PURE__ */ I(l, {
292
+ /* @__PURE__ */ L(l, {
292
293
  label: "Title",
293
294
  required: !0,
294
- children: /* @__PURE__ */ I(b, {
295
+ children: /* @__PURE__ */ L(b, {
295
296
  value: d.title,
296
297
  onChange: _("title"),
297
298
  placeholder: "Regulatory investigation — SEC inquiry"
298
299
  })
299
300
  }),
300
- /* @__PURE__ */ L("div", {
301
+ /* @__PURE__ */ R("div", {
301
302
  className: "grid grid-cols-2 gap-3",
302
- children: [/* @__PURE__ */ I(l, {
303
+ children: [/* @__PURE__ */ L(l, {
303
304
  label: "Reference",
304
- children: /* @__PURE__ */ I(b, {
305
+ children: /* @__PURE__ */ L(b, {
305
306
  value: d.reference,
306
307
  onChange: _("reference"),
307
308
  placeholder: "MAT-2026-014"
308
309
  })
309
- }), /* @__PURE__ */ I(l, {
310
+ }), /* @__PURE__ */ L(l, {
310
311
  label: "Priority",
311
- children: /* @__PURE__ */ I(p, {
312
+ children: /* @__PURE__ */ L(p, {
312
313
  value: d.priority,
313
314
  onChange: _("priority"),
314
- children: S(B)
315
+ children: S(V)
315
316
  })
316
317
  })]
317
318
  }),
318
- /* @__PURE__ */ L("div", {
319
+ /* @__PURE__ */ R("div", {
319
320
  className: "grid grid-cols-2 gap-3",
320
- children: [/* @__PURE__ */ I(l, {
321
+ children: [/* @__PURE__ */ L(l, {
321
322
  label: "Practice area",
322
- children: /* @__PURE__ */ L(p, {
323
+ children: /* @__PURE__ */ R(p, {
323
324
  value: d.practiceAreaId,
324
325
  onChange: _("practiceAreaId"),
325
- children: [/* @__PURE__ */ I("option", {
326
+ children: [/* @__PURE__ */ L("option", {
326
327
  value: "",
327
328
  children: "Unassigned"
328
- }), u.data?.map((e) => /* @__PURE__ */ I("option", {
329
+ }), u.data?.map((e) => /* @__PURE__ */ L("option", {
329
330
  value: e.id,
330
331
  children: e.name
331
332
  }, e.id))]
332
333
  })
333
- }), /* @__PURE__ */ I(l, {
334
+ }), /* @__PURE__ */ L(l, {
334
335
  label: "Due date",
335
- children: /* @__PURE__ */ I(b, {
336
+ children: /* @__PURE__ */ L(b, {
336
337
  type: "date",
337
338
  value: d.dueDate,
338
339
  onChange: _("dueDate")
339
340
  })
340
341
  })]
341
342
  }),
342
- /* @__PURE__ */ I(l, {
343
+ /* @__PURE__ */ L(l, {
343
344
  label: "Description",
344
- children: /* @__PURE__ */ I(y, {
345
+ children: /* @__PURE__ */ L(y, {
345
346
  value: d.description,
346
347
  onChange: _("description")
347
348
  })
348
349
  }),
349
- /* @__PURE__ */ L("label", {
350
+ /* @__PURE__ */ R("label", {
350
351
  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",
351
- children: [/* @__PURE__ */ I("input", {
352
+ children: [/* @__PURE__ */ L("input", {
352
353
  type: "checkbox",
353
354
  checked: d.isPrivileged,
354
355
  onChange: (e) => m((t) => ({
355
356
  ...t,
356
357
  isPrivileged: e.target.checked
357
358
  }))
358
- }), /* @__PURE__ */ L("span", {
359
+ }), /* @__PURE__ */ R("span", {
359
360
  className: "flex items-center gap-1.5",
360
- children: [/* @__PURE__ */ I(M, { className: "h-3.5 w-3.5 text-status-warning-text" }), "Privileged / confidential matter"]
361
+ children: [/* @__PURE__ */ L(N, { className: "h-3.5 w-3.5 text-status-warning-text" }), "Privileged / confidential matter"]
361
362
  })]
362
363
  })
363
364
  ]
@@ -365,6 +366,6 @@ var z = [
365
366
  });
366
367
  };
367
368
  //#endregion
368
- export { H as MattersPage };
369
+ export { U as MattersPage };
369
370
 
370
371
  //# sourceMappingURL=MattersPage.js.map