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