@burdenoff/microfe-proserviceworld 2026.706.2 → 2026.709.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/dist/dev/main.d.ts +2 -0
  2. package/dist/dev/main.d.ts.map +1 -0
  3. package/dist/generated/global-operations.d.ts +2 -0
  4. package/dist/generated/global-operations.d.ts.map +1 -0
  5. package/dist/generated/global-types.d.ts +18199 -0
  6. package/dist/generated/global-types.d.ts.map +1 -0
  7. package/dist/generated/wspace-operations.d.ts +2 -0
  8. package/dist/generated/wspace-operations.d.ts.map +1 -0
  9. package/dist/generated/wspace-types.d.ts +43046 -0
  10. package/dist/generated/wspace-types.d.ts.map +1 -0
  11. package/dist/index.d.ts +2 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +2 -1
  14. package/dist/proserviceworld/ProServiceWorldRoot.d.ts +5 -0
  15. package/dist/proserviceworld/ProServiceWorldRoot.d.ts.map +1 -0
  16. package/dist/proserviceworld/ProServiceWorldRoutes.d.ts +2 -0
  17. package/dist/proserviceworld/ProServiceWorldRoutes.d.ts.map +1 -0
  18. package/dist/proserviceworld/components/DiscussionThread.d.ts +12 -0
  19. package/dist/proserviceworld/components/DiscussionThread.d.ts.map +1 -0
  20. package/dist/proserviceworld/components/DiscussionThread.js +1 -1
  21. package/dist/proserviceworld/components/DiscussionThread.js.map +1 -1
  22. package/dist/proserviceworld/components/ui.d.ts +82 -0
  23. package/dist/proserviceworld/components/ui.d.ts.map +1 -0
  24. package/dist/proserviceworld/components/ui.js +18 -18
  25. package/dist/proserviceworld/components/ui.js.map +1 -1
  26. package/dist/proserviceworld/hooks/useAnalytics.d.ts +18 -0
  27. package/dist/proserviceworld/hooks/useAnalytics.d.ts.map +1 -0
  28. package/dist/proserviceworld/hooks/useAnalytics.js +21 -0
  29. package/dist/proserviceworld/hooks/useAnalytics.js.map +1 -0
  30. package/dist/proserviceworld/hooks/useEntityComments.d.ts +27 -0
  31. package/dist/proserviceworld/hooks/useEntityComments.d.ts.map +1 -0
  32. package/dist/proserviceworld/hooks/useEntityComments.js.map +1 -1
  33. package/dist/proserviceworld/hooks/useFiles.d.ts +23 -0
  34. package/dist/proserviceworld/hooks/useFiles.d.ts.map +1 -0
  35. package/dist/proserviceworld/hooks/useProServiceWorldApi.d.ts +351 -0
  36. package/dist/proserviceworld/hooks/useProServiceWorldApi.d.ts.map +1 -0
  37. package/dist/proserviceworld/index.d.ts +5 -0
  38. package/dist/proserviceworld/index.d.ts.map +1 -0
  39. package/dist/proserviceworld/index.js +1 -0
  40. package/dist/proserviceworld/pages/AnalyticsPage.d.ts +4 -0
  41. package/dist/proserviceworld/pages/AnalyticsPage.d.ts.map +1 -0
  42. package/dist/proserviceworld/pages/AnalyticsPage.js +277 -111
  43. package/dist/proserviceworld/pages/AnalyticsPage.js.map +1 -1
  44. package/dist/proserviceworld/pages/ClientDetailPage.d.ts +4 -0
  45. package/dist/proserviceworld/pages/ClientDetailPage.d.ts.map +1 -0
  46. package/dist/proserviceworld/pages/ClientDetailPage.js +219 -151
  47. package/dist/proserviceworld/pages/ClientDetailPage.js.map +1 -1
  48. package/dist/proserviceworld/pages/ClientsPage.d.ts +9 -0
  49. package/dist/proserviceworld/pages/ClientsPage.d.ts.map +1 -0
  50. package/dist/proserviceworld/pages/ClientsPage.js +180 -148
  51. package/dist/proserviceworld/pages/ClientsPage.js.map +1 -1
  52. package/dist/proserviceworld/pages/CompliancePage.d.ts +4 -0
  53. package/dist/proserviceworld/pages/CompliancePage.d.ts.map +1 -0
  54. package/dist/proserviceworld/pages/CompliancePage.js +140 -96
  55. package/dist/proserviceworld/pages/CompliancePage.js.map +1 -1
  56. package/dist/proserviceworld/pages/ConflictsPage.d.ts +4 -0
  57. package/dist/proserviceworld/pages/ConflictsPage.d.ts.map +1 -0
  58. package/dist/proserviceworld/pages/DashboardPage.d.ts +4 -0
  59. package/dist/proserviceworld/pages/DashboardPage.d.ts.map +1 -0
  60. package/dist/proserviceworld/pages/DashboardPage.js +221 -104
  61. package/dist/proserviceworld/pages/DashboardPage.js.map +1 -1
  62. package/dist/proserviceworld/pages/DocumentsPage.d.ts +4 -0
  63. package/dist/proserviceworld/pages/DocumentsPage.d.ts.map +1 -0
  64. package/dist/proserviceworld/pages/EngagementDetailPage.d.ts +4 -0
  65. package/dist/proserviceworld/pages/EngagementDetailPage.d.ts.map +1 -0
  66. package/dist/proserviceworld/pages/EngagementDetailPage.js +233 -197
  67. package/dist/proserviceworld/pages/EngagementDetailPage.js.map +1 -1
  68. package/dist/proserviceworld/pages/EngagementsPage.d.ts +4 -0
  69. package/dist/proserviceworld/pages/EngagementsPage.d.ts.map +1 -0
  70. package/dist/proserviceworld/pages/EngagementsPage.js +187 -136
  71. package/dist/proserviceworld/pages/EngagementsPage.js.map +1 -1
  72. package/dist/proserviceworld/pages/InvoicesPage.d.ts +4 -0
  73. package/dist/proserviceworld/pages/InvoicesPage.d.ts.map +1 -0
  74. package/dist/proserviceworld/pages/InvoicesPage.js +144 -129
  75. package/dist/proserviceworld/pages/InvoicesPage.js.map +1 -1
  76. package/dist/proserviceworld/pages/MattersPage.d.ts +4 -0
  77. package/dist/proserviceworld/pages/MattersPage.d.ts.map +1 -0
  78. package/dist/proserviceworld/pages/MattersPage.js +198 -142
  79. package/dist/proserviceworld/pages/MattersPage.js.map +1 -1
  80. package/dist/proserviceworld/pages/PracticeAreasPage.d.ts +4 -0
  81. package/dist/proserviceworld/pages/PracticeAreasPage.d.ts.map +1 -0
  82. package/dist/proserviceworld/pages/TimePage.d.ts +4 -0
  83. package/dist/proserviceworld/pages/TimePage.d.ts.map +1 -0
  84. package/dist/proserviceworld/pages/TimePage.js +112 -92
  85. package/dist/proserviceworld/pages/TimePage.js.map +1 -1
  86. package/dist/proserviceworld/providers/ProServiceWorldProvider.d.ts +6 -0
  87. package/dist/proserviceworld/providers/ProServiceWorldProvider.d.ts.map +1 -0
  88. package/dist/proserviceworld/services/assistantApi.d.ts +74 -0
  89. package/dist/proserviceworld/services/assistantApi.d.ts.map +1 -0
  90. package/dist/proserviceworld/services/assistantApi.js +203 -0
  91. package/dist/proserviceworld/services/assistantApi.js.map +1 -0
  92. package/dist/proserviceworld/services/createSandboxAssistantTransport.d.ts +28 -0
  93. package/dist/proserviceworld/services/createSandboxAssistantTransport.d.ts.map +1 -0
  94. package/dist/proserviceworld/services/createSandboxAssistantTransport.js +120 -0
  95. package/dist/proserviceworld/services/createSandboxAssistantTransport.js.map +1 -0
  96. package/dist/proserviceworld/types/index.d.ts +57 -0
  97. package/dist/proserviceworld/types/index.d.ts.map +1 -0
  98. package/dist/proserviceworld/utils/cn.d.ts +4 -0
  99. package/dist/proserviceworld/utils/cn.d.ts.map +1 -0
  100. package/dist/proserviceworld/utils/nav.d.ts +6 -0
  101. package/dist/proserviceworld/utils/nav.d.ts.map +1 -0
  102. package/dist/proserviceworld/utils/navigation.d.ts +2 -0
  103. package/dist/proserviceworld/utils/navigation.d.ts.map +1 -0
  104. package/dist/proserviceworld/utils/pageContext.d.ts +12 -0
  105. package/dist/proserviceworld/utils/pageContext.d.ts.map +1 -0
  106. package/dist/proserviceworld/utils/pageContext.js +74 -0
  107. package/dist/proserviceworld/utils/pageContext.js.map +1 -0
  108. package/package.json +1 -1
@@ -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 } 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';\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 outstanding = (data?.items ?? [])\n .filter((i) => i.status === 'SENT' || i.status === 'OVERDUE')\n .reduce((s, i) => s + i.total, 0);\n const collected = (data?.items ?? [])\n .filter((i) => i.status === 'PAID')\n .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-3 gap-3\">\n <MetricCard label=\"Invoices\" value={data?.totalCount ?? 0} />\n <MetricCard label=\"Outstanding\" value={fmtMoney(outstanding)} tone=\"warning\" />\n <MetricCard label=\"Collected\" value={fmtMoney(collected)} tone=\"success\" />\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=\"hover:bg-bg-sunken/50\">\n <Td>\n <span className=\"font-medium text-text-primary\">{i.number}</span>\n </Td>\n <Td>{clientName.get(i.clientId) ?? '—'}</Td>\n <Td>{fmtMoney(i.total, i.currency)}</Td>\n <Td>\n <StatusPill status={i.status} />\n </Td>\n <Td>{fmtDate(i.dueDate)}</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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"}
@@ -0,0 +1,4 @@
1
+ import { FC } from 'react';
2
+
3
+ export declare const MattersPage: FC;
4
+ //# sourceMappingURL=MattersPage.d.ts.map
@@ -0,0 +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;AAyDhC,eAAO,MAAM,WAAW,EAAE,EAgMzB,CAAC"}
@@ -1,135 +1,184 @@
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, Modal as u, NativeSelect as d, PageHeader as f, SectionCard as p, StatusPill as m, TableWrap as h, Td as g, TextArea as _, TextInput as v, Th as y, enumOptions as b, fmtDate as x } from "../components/ui.js";
3
- import { useState as S } from "react";
4
- import { CheckCircle2 as C, FolderKanban as w, Lock as T, Plus as E, Search as D } from "lucide-react";
5
- import { Fragment as O, jsx as k, jsxs as A } from "react/jsx-runtime";
6
- import { Button as j } from "@burdenoff/fe-libs/ui";
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 { useAnalytics as C } from "../hooks/useAnalytics.js";
4
+ import { useState as w } from "react";
5
+ import { AlertTriangle as T, CheckCircle2 as E, CircleDot as D, FolderKanban as O, Lock as k, Plus as A, Search as j } from "lucide-react";
6
+ import { Fragment as M, jsx as N, jsxs as P } from "react/jsx-runtime";
7
+ import { Button as F } from "@burdenoff/fe-libs/ui";
7
8
  //#region src/proserviceworld/pages/MattersPage.tsx
8
- var M = [
9
+ var I = [
9
10
  "OPEN",
10
11
  "ON_HOLD",
11
12
  "CLOSED",
12
13
  "ARCHIVED"
13
- ], N = [
14
+ ], L = [
14
15
  "LOW",
15
16
  "MEDIUM",
16
17
  "HIGH",
17
18
  "CRITICAL"
18
- ], P = () => {
19
- let [e, n] = S(""), [i, c] = S(""), [u, _] = S(!1), [O, N] = S(null), { data: P, isLoading: I, error: L, refetch: R } = r({
20
- search: e.trim() || void 0,
21
- status: i || void 0
22
- }), z = t();
23
- return /* @__PURE__ */ A("div", {
19
+ ], R = () => /* @__PURE__ */ N("span", {
20
+ className: "inline-flex h-5 w-5 shrink-0 items-center justify-center rounded-md bg-status-warning-bg-subtle text-status-warning-text",
21
+ title: "Privileged / confidential",
22
+ "aria-label": "Privileged",
23
+ children: /* @__PURE__ */ N(k, { className: "h-3 w-3" })
24
+ }), z = () => {
25
+ let { emitIntent: e, emitFact: n } = C(), [i, c] = w(""), [d, v] = w(""), [L, z] = w(!1), [V, H] = w(null), { data: U, isLoading: W, error: G, refetch: K } = r({
26
+ search: i.trim() || void 0,
27
+ status: d || void 0
28
+ }), q = t(), J = U?.items ?? [], Y = J.filter((e) => e.status === "OPEN").length, X = J.filter((e) => e.isPrivileged).length, Z = J.filter((e) => e.priority === "HIGH" || e.priority === "CRITICAL").length;
29
+ return /* @__PURE__ */ P("div", {
24
30
  className: "space-y-6",
25
31
  children: [
26
- /* @__PURE__ */ k(f, {
32
+ /* @__PURE__ */ N(p, {
27
33
  title: "Matters",
28
34
  subtitle: "The regulated threads of work — legal matters, audits, filings — with their own deadlines and sensitive-document handling.",
29
- icon: /* @__PURE__ */ k(w, { className: "h-6 w-6" }),
30
- actions: /* @__PURE__ */ A(j, {
31
- onClick: () => _(!0),
32
- children: [/* @__PURE__ */ k(E, { className: "mr-1.5 h-4 w-4" }), "New matter"]
35
+ icon: /* @__PURE__ */ N(O, { className: "h-6 w-6" }),
36
+ actions: /* @__PURE__ */ P(F, {
37
+ onClick: () => {
38
+ e("psw.matter.create_clicked"), z(!0);
39
+ },
40
+ children: [/* @__PURE__ */ N(A, { className: "mr-1.5 h-4 w-4" }), "New matter"]
33
41
  })
34
42
  }),
35
- O && /* @__PURE__ */ k(a, {
36
- tone: O.tone,
37
- onClose: () => N(null),
38
- children: O.text
43
+ V && /* @__PURE__ */ N(a, {
44
+ tone: V.tone,
45
+ onClose: () => H(null),
46
+ children: V.text
39
47
  }),
40
- /* @__PURE__ */ A("div", {
48
+ /* @__PURE__ */ P("div", {
41
49
  className: "flex flex-col gap-2 sm:flex-row sm:items-center",
42
- children: [/* @__PURE__ */ A("div", {
50
+ children: [/* @__PURE__ */ P("div", {
43
51
  className: "relative flex-1",
44
- children: [/* @__PURE__ */ k(D, { className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-tertiary" }), /* @__PURE__ */ k(v, {
52
+ children: [/* @__PURE__ */ N(j, { className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-tertiary" }), /* @__PURE__ */ N(y, {
45
53
  placeholder: "Search matters…",
46
- value: e,
47
- onChange: (e) => n(e.target.value),
54
+ value: i,
55
+ onChange: (e) => c(e.target.value),
56
+ onKeyDown: (e) => {
57
+ e.key === "Enter" && i.trim() && n("psw.search.performed", {
58
+ entityType: "matter",
59
+ queryLength: i.trim().length
60
+ });
61
+ },
48
62
  className: "pl-9"
49
63
  })]
50
- }), /* @__PURE__ */ A(d, {
51
- value: i,
52
- onChange: (e) => c(e.target.value),
64
+ }), /* @__PURE__ */ P(f, {
65
+ value: d,
66
+ onChange: (e) => v(e.target.value),
53
67
  className: "sm:w-48",
54
- children: [/* @__PURE__ */ k("option", {
68
+ children: [/* @__PURE__ */ N("option", {
55
69
  value: "",
56
70
  children: "All statuses"
57
- }), b(M)]
71
+ }), x(I)]
58
72
  })]
59
73
  }),
60
- I ? /* @__PURE__ */ k(l, {}) : L ? /* @__PURE__ */ k(s, {
61
- error: L,
62
- onRetry: () => void R()
63
- }) : !P || P.items.length === 0 ? /* @__PURE__ */ k(o, {
74
+ W ? /* @__PURE__ */ N(l, {}) : G ? /* @__PURE__ */ N(s, {
75
+ error: G,
76
+ onRetry: () => void K()
77
+ }) : !U || U.items.length === 0 ? /* @__PURE__ */ N(o, {
64
78
  title: "No matters yet",
65
79
  description: "Open a matter to track a regulated thread of work for a client.",
66
- icon: /* @__PURE__ */ k(w, { className: "h-8 w-8" }),
67
- action: /* @__PURE__ */ A(j, {
68
- onClick: () => _(!0),
69
- children: [/* @__PURE__ */ k(E, { className: "mr-1.5 h-4 w-4" }), "New matter"]
80
+ icon: /* @__PURE__ */ N(O, { className: "h-8 w-8" }),
81
+ action: /* @__PURE__ */ P(F, {
82
+ onClick: () => z(!0),
83
+ children: [/* @__PURE__ */ N(A, { className: "mr-1.5 h-4 w-4" }), "New matter"]
70
84
  })
71
- }) : /* @__PURE__ */ k(p, {
72
- title: `${P.totalCount} matter${P.totalCount === 1 ? "" : "s"}`,
73
- children: /* @__PURE__ */ A(h, { children: [/* @__PURE__ */ k("thead", { children: /* @__PURE__ */ A("tr", { children: [
74
- /* @__PURE__ */ k(y, { children: "Matter" }),
75
- /* @__PURE__ */ k(y, { children: "Client" }),
76
- /* @__PURE__ */ k(y, { children: "Priority" }),
77
- /* @__PURE__ */ k(y, { children: "Status" }),
78
- /* @__PURE__ */ k(y, { children: "Due" }),
79
- /* @__PURE__ */ k(y, {
85
+ }) : /* @__PURE__ */ P(M, { children: [/* @__PURE__ */ P("div", {
86
+ className: "grid grid-cols-2 gap-3 lg:grid-cols-4",
87
+ children: [
88
+ /* @__PURE__ */ N(u, {
89
+ label: "Matters",
90
+ value: U.totalCount,
91
+ icon: /* @__PURE__ */ N(O, { className: "h-4 w-4" })
92
+ }),
93
+ /* @__PURE__ */ N(u, {
94
+ label: "Open",
95
+ value: Y,
96
+ icon: /* @__PURE__ */ N(D, { className: "h-4 w-4" }),
97
+ tone: "accent"
98
+ }),
99
+ /* @__PURE__ */ N(u, {
100
+ label: "Privileged",
101
+ value: X,
102
+ icon: /* @__PURE__ */ N(k, { className: "h-4 w-4" }),
103
+ tone: "warning"
104
+ }),
105
+ /* @__PURE__ */ N(u, {
106
+ label: "High priority",
107
+ value: Z,
108
+ icon: /* @__PURE__ */ N(T, { className: "h-4 w-4" }),
109
+ tone: Z ? "danger" : "neutral"
110
+ })
111
+ ]
112
+ }), /* @__PURE__ */ N(m, {
113
+ title: `${U.totalCount} matter${U.totalCount === 1 ? "" : "s"}`,
114
+ children: /* @__PURE__ */ P(g, { children: [/* @__PURE__ */ N("thead", { children: /* @__PURE__ */ P("tr", { children: [
115
+ /* @__PURE__ */ N(b, { children: "Matter" }),
116
+ /* @__PURE__ */ N(b, { children: "Client" }),
117
+ /* @__PURE__ */ N(b, { children: "Priority" }),
118
+ /* @__PURE__ */ N(b, { children: "Status" }),
119
+ /* @__PURE__ */ N(b, { children: "Due" }),
120
+ /* @__PURE__ */ N(b, {
80
121
  className: "text-right",
81
122
  children: "Actions"
82
123
  })
83
- ] }) }), /* @__PURE__ */ k("tbody", { children: P.items.map((e) => /* @__PURE__ */ A("tr", {
84
- className: "hover:bg-bg-sunken/50",
124
+ ] }) }), /* @__PURE__ */ N("tbody", { children: U.items.map((e) => /* @__PURE__ */ P("tr", {
125
+ className: "transition-colors hover:bg-bg-sunken/60",
85
126
  children: [
86
- /* @__PURE__ */ A(g, { children: [/* @__PURE__ */ A("span", {
87
- className: "flex items-center gap-1.5 font-medium text-text-primary",
88
- children: [e.isPrivileged && /* @__PURE__ */ k(T, {
89
- className: "h-3.5 w-3.5 text-status-warning-text",
90
- "aria-label": "Privileged"
91
- }), e.title]
92
- }), e.reference ? /* @__PURE__ */ k("div", {
93
- className: "text-xs text-text-tertiary",
94
- children: e.reference
127
+ /* @__PURE__ */ P(_, { children: [/* @__PURE__ */ P("span", {
128
+ className: "flex items-center gap-2 font-medium text-text-primary",
129
+ children: [e.isPrivileged && /* @__PURE__ */ N(R, {}), /* @__PURE__ */ N("span", {
130
+ className: "truncate",
131
+ children: e.title
132
+ })]
133
+ }), e.reference ? /* @__PURE__ */ P("div", {
134
+ className: "mt-0.5 pl-0 text-xs text-text-tertiary",
135
+ children: ["Ref: ", e.reference]
95
136
  }) : null] }),
96
- /* @__PURE__ */ k(g, { children: e.client?.name ?? "—" }),
97
- /* @__PURE__ */ k(g, { children: /* @__PURE__ */ k(m, { status: e.priority }) }),
98
- /* @__PURE__ */ k(g, { children: /* @__PURE__ */ k(m, { status: e.status }) }),
99
- /* @__PURE__ */ k(g, { children: x(e.dueDate) }),
100
- /* @__PURE__ */ k(g, {
137
+ /* @__PURE__ */ N(_, {
138
+ className: "text-text-primary",
139
+ children: e.client?.name ?? "—"
140
+ }),
141
+ /* @__PURE__ */ N(_, { children: /* @__PURE__ */ N(h, { status: e.priority }) }),
142
+ /* @__PURE__ */ N(_, { children: /* @__PURE__ */ N(h, { status: e.status }) }),
143
+ /* @__PURE__ */ N(_, { children: S(e.dueDate) }),
144
+ /* @__PURE__ */ N(_, {
101
145
  className: "text-right",
102
- children: e.status !== "CLOSED" && e.status !== "ARCHIVED" && /* @__PURE__ */ A(j, {
146
+ children: e.status !== "CLOSED" && e.status !== "ARCHIVED" ? /* @__PURE__ */ P(F, {
103
147
  variant: "ghost",
104
148
  size: "sm",
105
- disabled: z.isPending,
106
- onClick: () => z.mutate(e.id, {
107
- onSuccess: () => N({
108
- tone: "success",
109
- text: `${e.title} closed.`
110
- }),
111
- onError: (e) => N({
149
+ disabled: q.isPending,
150
+ onClick: () => q.mutate(e.id, {
151
+ onSuccess: () => {
152
+ n("psw.matter.closed", { matterId: e.id }), H({
153
+ tone: "success",
154
+ text: `${e.title} closed.`
155
+ });
156
+ },
157
+ onError: (e) => H({
112
158
  tone: "danger",
113
159
  text: e instanceof Error ? e.message : "Failed."
114
160
  })
115
161
  }),
116
- children: [/* @__PURE__ */ k(C, { className: "mr-1 h-4 w-4" }), " Close"]
162
+ children: [/* @__PURE__ */ N(E, { className: "mr-1 h-4 w-4" }), " Close"]
163
+ }) : /* @__PURE__ */ N("span", {
164
+ className: "text-xs text-text-tertiary",
165
+ children: e.closedAt ? `Closed ${S(e.closedAt)}` : "—"
117
166
  })
118
167
  })
119
168
  ]
120
169
  }, e.id)) })] })
121
- }),
122
- u && /* @__PURE__ */ k(F, {
123
- onClose: () => _(!1),
124
- onSaved: (e) => N({
170
+ })] }),
171
+ L && /* @__PURE__ */ N(B, {
172
+ onClose: () => z(!1),
173
+ onSaved: (e) => H({
125
174
  tone: "success",
126
175
  text: `${e} opened.`
127
176
  })
128
177
  })
129
178
  ]
130
179
  });
131
- }, F = ({ onClose: t, onSaved: r }) => {
132
- let o = n(), s = e({ pagination: { limit: 100 } }), l = i(), [f, p] = S({
180
+ }, B = ({ onClose: t, onSaved: r }) => {
181
+ let o = n(), { emitFact: s } = C(), l = e({ pagination: { limit: 100 } }), u = i(), [p, m] = w({
133
182
  clientId: "",
134
183
  practiceAreaId: "",
135
184
  title: "",
@@ -138,138 +187,145 @@ var M = [
138
187
  priority: "MEDIUM",
139
188
  dueDate: "",
140
189
  isPrivileged: !1
141
- }), [m, h] = S(null), g = (e) => (t) => p((n) => ({
190
+ }), [h, g] = w(null), _ = (e) => (t) => m((n) => ({
142
191
  ...n,
143
192
  [e]: t.target.value
144
193
  }));
145
- return /* @__PURE__ */ k(u, {
194
+ return /* @__PURE__ */ N(d, {
146
195
  open: !0,
147
196
  onClose: t,
148
197
  title: "New matter",
149
- footer: /* @__PURE__ */ A(O, { children: [/* @__PURE__ */ k(j, {
198
+ footer: /* @__PURE__ */ P(M, { children: [/* @__PURE__ */ N(F, {
150
199
  variant: "outline",
151
200
  onClick: t,
152
201
  disabled: o.isPending,
153
202
  children: "Cancel"
154
- }), /* @__PURE__ */ k(j, {
203
+ }), /* @__PURE__ */ N(F, {
155
204
  onClick: () => {
156
- if (h(null), !f.clientId) return h("Select a client.");
157
- if (!f.title.trim()) return h("Matter title is required.");
205
+ if (g(null), !p.clientId) return g("Select a client.");
206
+ if (!p.title.trim()) return g("Matter title is required.");
158
207
  o.mutate({
159
- clientId: f.clientId,
160
- practiceAreaId: f.practiceAreaId || null,
161
- title: f.title.trim(),
162
- reference: f.reference.trim() || null,
163
- description: f.description.trim() || null,
164
- priority: f.priority,
165
- isPrivileged: f.isPrivileged,
166
- dueDate: f.dueDate ? new Date(f.dueDate).toISOString() : null
208
+ clientId: p.clientId,
209
+ practiceAreaId: p.practiceAreaId || null,
210
+ title: p.title.trim(),
211
+ reference: p.reference.trim() || null,
212
+ description: p.description.trim() || null,
213
+ priority: p.priority,
214
+ isPrivileged: p.isPrivileged,
215
+ dueDate: p.dueDate ? new Date(p.dueDate).toISOString() : null
167
216
  }, {
168
- onSuccess: () => {
169
- r(f.title.trim()), t();
217
+ onSuccess: (e) => {
218
+ let n = e.pswCreateMatter;
219
+ s("psw.matter.created", {
220
+ matterId: n.id,
221
+ clientId: p.clientId
222
+ }), r(p.title.trim()), t();
170
223
  },
171
- onError: (e) => h(e instanceof Error ? e.message : "Failed.")
224
+ onError: (e) => g(e instanceof Error ? e.message : "Failed.")
172
225
  });
173
226
  },
174
227
  disabled: o.isPending,
175
228
  children: o.isPending ? "Opening…" : "Open matter"
176
229
  })] }),
177
- children: /* @__PURE__ */ A("div", {
230
+ children: /* @__PURE__ */ P("div", {
178
231
  className: "space-y-3",
179
232
  children: [
180
- m && /* @__PURE__ */ k(a, {
233
+ h && /* @__PURE__ */ N(a, {
181
234
  tone: "danger",
182
- children: m
235
+ children: h
183
236
  }),
184
- /* @__PURE__ */ k(c, {
237
+ /* @__PURE__ */ N(c, {
185
238
  label: "Client",
186
239
  required: !0,
187
- children: /* @__PURE__ */ A(d, {
188
- value: f.clientId,
189
- onChange: g("clientId"),
190
- children: [/* @__PURE__ */ k("option", {
240
+ children: /* @__PURE__ */ P(f, {
241
+ value: p.clientId,
242
+ onChange: _("clientId"),
243
+ children: [/* @__PURE__ */ N("option", {
191
244
  value: "",
192
245
  children: "Select a client…"
193
- }), s.data?.items.map((e) => /* @__PURE__ */ k("option", {
246
+ }), l.data?.items.map((e) => /* @__PURE__ */ N("option", {
194
247
  value: e.id,
195
248
  children: e.name
196
249
  }, e.id))]
197
250
  })
198
251
  }),
199
- /* @__PURE__ */ k(c, {
252
+ /* @__PURE__ */ N(c, {
200
253
  label: "Title",
201
254
  required: !0,
202
- children: /* @__PURE__ */ k(v, {
203
- value: f.title,
204
- onChange: g("title"),
255
+ children: /* @__PURE__ */ N(y, {
256
+ value: p.title,
257
+ onChange: _("title"),
205
258
  placeholder: "Regulatory investigation — SEC inquiry"
206
259
  })
207
260
  }),
208
- /* @__PURE__ */ A("div", {
261
+ /* @__PURE__ */ P("div", {
209
262
  className: "grid grid-cols-2 gap-3",
210
- children: [/* @__PURE__ */ k(c, {
263
+ children: [/* @__PURE__ */ N(c, {
211
264
  label: "Reference",
212
- children: /* @__PURE__ */ k(v, {
213
- value: f.reference,
214
- onChange: g("reference"),
265
+ children: /* @__PURE__ */ N(y, {
266
+ value: p.reference,
267
+ onChange: _("reference"),
215
268
  placeholder: "MAT-2026-014"
216
269
  })
217
- }), /* @__PURE__ */ k(c, {
270
+ }), /* @__PURE__ */ N(c, {
218
271
  label: "Priority",
219
- children: /* @__PURE__ */ k(d, {
220
- value: f.priority,
221
- onChange: g("priority"),
222
- children: b(N)
272
+ children: /* @__PURE__ */ N(f, {
273
+ value: p.priority,
274
+ onChange: _("priority"),
275
+ children: x(L)
223
276
  })
224
277
  })]
225
278
  }),
226
- /* @__PURE__ */ A("div", {
279
+ /* @__PURE__ */ P("div", {
227
280
  className: "grid grid-cols-2 gap-3",
228
- children: [/* @__PURE__ */ k(c, {
281
+ children: [/* @__PURE__ */ N(c, {
229
282
  label: "Practice area",
230
- children: /* @__PURE__ */ A(d, {
231
- value: f.practiceAreaId,
232
- onChange: g("practiceAreaId"),
233
- children: [/* @__PURE__ */ k("option", {
283
+ children: /* @__PURE__ */ P(f, {
284
+ value: p.practiceAreaId,
285
+ onChange: _("practiceAreaId"),
286
+ children: [/* @__PURE__ */ N("option", {
234
287
  value: "",
235
288
  children: "Unassigned"
236
- }), l.data?.map((e) => /* @__PURE__ */ k("option", {
289
+ }), u.data?.map((e) => /* @__PURE__ */ N("option", {
237
290
  value: e.id,
238
291
  children: e.name
239
292
  }, e.id))]
240
293
  })
241
- }), /* @__PURE__ */ k(c, {
294
+ }), /* @__PURE__ */ N(c, {
242
295
  label: "Due date",
243
- children: /* @__PURE__ */ k(v, {
296
+ children: /* @__PURE__ */ N(y, {
244
297
  type: "date",
245
- value: f.dueDate,
246
- onChange: g("dueDate")
298
+ value: p.dueDate,
299
+ onChange: _("dueDate")
247
300
  })
248
301
  })]
249
302
  }),
250
- /* @__PURE__ */ k(c, {
303
+ /* @__PURE__ */ N(c, {
251
304
  label: "Description",
252
- children: /* @__PURE__ */ k(_, {
253
- value: f.description,
254
- onChange: g("description")
305
+ children: /* @__PURE__ */ N(v, {
306
+ value: p.description,
307
+ onChange: _("description")
255
308
  })
256
309
  }),
257
- /* @__PURE__ */ A("label", {
258
- className: "flex items-center gap-2 text-sm text-text-secondary",
259
- children: [/* @__PURE__ */ k("input", {
310
+ /* @__PURE__ */ P("label", {
311
+ 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",
312
+ children: [/* @__PURE__ */ N("input", {
260
313
  type: "checkbox",
261
- checked: f.isPrivileged,
262
- onChange: (e) => p((t) => ({
314
+ checked: p.isPrivileged,
315
+ onChange: (e) => m((t) => ({
263
316
  ...t,
264
317
  isPrivileged: e.target.checked
265
318
  }))
266
- }), "Privileged / confidential matter"]
319
+ }), /* @__PURE__ */ P("span", {
320
+ className: "flex items-center gap-1.5",
321
+ children: [/* @__PURE__ */ N(k, { className: "h-3.5 w-3.5 text-status-warning-text" }), "Privileged / confidential matter"]
322
+ })]
267
323
  })
268
324
  ]
269
325
  })
270
326
  });
271
327
  };
272
328
  //#endregion
273
- export { P as MattersPage };
329
+ export { z as MattersPage };
274
330
 
275
331
  //# sourceMappingURL=MattersPage.js.map