@burdenoff/microfe-proserviceworld 2026.827.1 → 2026.830.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.
@@ -1 +1 @@
1
- {"version":3,"file":"EngagementsPage.js","names":[],"sources":["../../../src/proserviceworld/pages/EngagementsPage.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useMemo, useState } from 'react';\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport { Plus, Search, Briefcase, ChevronRight } from 'lucide-react';\nimport {\n useEngagements,\n useCreateEngagement,\n useUpdateEngagement,\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 { impactFeedback } from '../utils/native';\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';\nimport { TagPicker } from '../components/TagPicker';\nimport { LoadMore } from '../components/LoadMore';\nimport { t } from '../i18n';\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\nconst PAGE_SIZE = 25;\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 [pagination, setPagination] = useState({ limit: PAGE_SIZE, offset: 0 });\n const clients = useClients({ pagination: { limit: 100 } });\n const update = useUpdateEngagement();\n const { data, isLoading, error, refetch } = useEngagements({\n search: search.trim() || undefined,\n status: statusFilter || undefined,\n clientId: clientFilter || undefined,\n pagination,\n });\n\n const allItems = useMemo(() => data?.items ?? [], [data]);\n\n return (\n <div className=\"space-y-6\">\n <PageHeader\n title={t('psw.engagements.title')}\n subtitle={t('psw.engagements.subtitle')}\n icon={<Briefcase className=\"h-6 w-6\" />}\n actions={\n <Button\n onClick={() => {\n void impactFeedback('light');\n emitIntent('psw.engagement.create_clicked');\n setCreating(true);\n }}\n >\n <Plus className=\"mr-1.5 h-4 w-4\" />\n {t('psw.engagements.new')}\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={t('psw.engagements.searchPlaceholder')}\n value={search}\n onChange={(e) => {\n setSearch(e.target.value);\n setPagination({ limit: PAGE_SIZE, offset: 0 });\n }}\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) => {\n setStatusFilter(e.target.value as PswEngagementStatus | '');\n setPagination({ limit: PAGE_SIZE, offset: 0 });\n }}\n className=\"sm:w-44\"\n >\n <option value=\"\">{t('psw.engagements.allStatuses')}</option>\n {enumOptions(STATUSES)}\n </NativeSelect>\n <NativeSelect\n value={clientFilter}\n onChange={(e) => {\n setClientFilter(e.target.value);\n setPagination({ limit: PAGE_SIZE, offset: 0 });\n }}\n className=\"sm:w-48\"\n >\n <option value=\"\">{t('psw.engagements.allClients')}</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={t('psw.engagements.emptyTitle')}\n description={t('psw.engagements.emptyDescription')}\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 {t('psw.engagements.new')}\n </Button>\n }\n />\n ) : (\n <SectionCard title={`${data.totalCount} engagement${data.totalCount === 1 ? '' : 's'}`}>\n <TableWrap>\n <thead>\n <tr>\n <Th>{t('psw.engagements.tableEngagement')}</Th>\n <Th>{t('psw.engagements.tableClient')}</Th>\n <Th>{t('psw.engagements.tableFee')}</Th>\n <Th>{t('psw.engagements.tableStatus')}</Th>\n <Th>{t('psw.engagements.tableStarted')}</Th>\n <Th>{t('psw.engagements.tableTags')}</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 <Td>\n <div onClick={(ev) => ev.stopPropagation()} role=\"presentation\">\n <TagPicker\n entityType=\"PswEngagement\"\n entityId={e.id}\n tags={e.tags ?? []}\n onChange={async (tags) => {\n await update.mutateAsync({ id: e.id, input: { tags } });\n void refetch();\n }}\n maxTags={5}\n />\n </div>\n </Td>\n </tr>\n ))}\n </tbody>\n </TableWrap>\n <LoadMore\n hasMore={data?.pageInfo?.hasMore ?? false}\n loading={isLoading}\n loadedCount={allItems.length}\n totalCount={data?.totalCount ?? allItems.length}\n onLoadMore={() =>\n setPagination((p) => ({ limit: PAGE_SIZE, offset: p.offset + PAGE_SIZE }))\n }\n />\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={t('psw.engagements.newTitle')}\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?.items.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 { useMemo, useState } from 'react';\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport { Plus, Search, Briefcase, ChevronRight } from 'lucide-react';\nimport {\n useEngagements,\n useCreateEngagement,\n useUpdateEngagement,\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 { useTr } from '../hooks/useTr';\nimport { impactFeedback } from '../utils/native';\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';\nimport { TagPicker } from '../components/TagPicker';\nimport { LoadMore } from '../components/LoadMore';\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\nconst PAGE_SIZE = 25;\n\nexport const EngagementsPage: FC = () => {\n const nav = useNav();\n const tr = useTr();\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 [pagination, setPagination] = useState({ limit: PAGE_SIZE, offset: 0 });\n const clients = useClients({ pagination: { limit: 100 } });\n const update = useUpdateEngagement();\n const { data, isLoading, error, refetch } = useEngagements({\n search: search.trim() || undefined,\n status: statusFilter || undefined,\n clientId: clientFilter || undefined,\n pagination,\n });\n\n const allItems = useMemo(() => data?.items ?? [], [data]);\n\n return (\n <div className=\"space-y-6\">\n <PageHeader\n title={tr('psw.engagements.title', 'Engagements')}\n subtitle={tr(\n 'psw.engagements.subtitle',\n 'The commercial containers of contracted work — scope, fee arrangement, delivery lifecycle, and billing.'\n )}\n icon={<Briefcase className=\"h-6 w-6\" />}\n actions={\n <Button\n onClick={() => {\n void impactFeedback('light');\n emitIntent('psw.engagement.create_clicked');\n setCreating(true);\n }}\n >\n <Plus className=\"mr-1.5 h-4 w-4\" />\n {tr('psw.engagements.new', '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={tr('psw.engagements.searchPlaceholder', 'Search engagements…')}\n value={search}\n onChange={(e) => {\n setSearch(e.target.value);\n setPagination({ limit: PAGE_SIZE, offset: 0 });\n }}\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) => {\n setStatusFilter(e.target.value as PswEngagementStatus | '');\n setPagination({ limit: PAGE_SIZE, offset: 0 });\n }}\n className=\"sm:w-44\"\n >\n <option value=\"\">{tr('psw.engagements.allStatuses', 'All statuses')}</option>\n {enumOptions(STATUSES)}\n </NativeSelect>\n <NativeSelect\n value={clientFilter}\n onChange={(e) => {\n setClientFilter(e.target.value);\n setPagination({ limit: PAGE_SIZE, offset: 0 });\n }}\n className=\"sm:w-48\"\n >\n <option value=\"\">{tr('psw.engagements.allClients', '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={tr('psw.engagements.emptyTitle', 'No engagements yet')}\n description={tr(\n 'psw.engagements.emptyDescription',\n 'Create your first engagement to scope work, set fees, and track delivery.'\n )}\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 {tr('psw.engagements.new', 'New engagement')}\n </Button>\n }\n />\n ) : (\n <SectionCard\n title={\n data.totalCount === 1\n ? tr('psw.engagements.count', '{{count}} engagement', { count: data.totalCount })\n : tr('psw.engagements.countPlural', '{{count}} engagements', {\n count: data.totalCount,\n })\n }\n >\n <TableWrap>\n <thead>\n <tr>\n <Th>{tr('psw.engagements.tableEngagement', 'Engagement')}</Th>\n <Th>{tr('psw.engagements.tableClient', 'Client')}</Th>\n <Th>{tr('psw.engagements.tableFee', 'Fee')}</Th>\n <Th>{tr('psw.engagements.tableStatus', 'Status')}</Th>\n <Th>{tr('psw.engagements.tableStarted', 'Started')}</Th>\n <Th>{tr('psw.engagements.tableTags', 'Tags')}</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 ?? tr('psw.common.dash', '—')} />\n <span className=\"text-text-secondary\">\n {e.client?.name ?? tr('psw.common.dash', '—')}\n </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 <Td>\n <div onClick={(ev) => ev.stopPropagation()} role=\"presentation\">\n <TagPicker\n entityType=\"PswEngagement\"\n entityId={e.id}\n tags={e.tags ?? []}\n onChange={async (tags) => {\n await update.mutateAsync({ id: e.id, input: { tags } });\n void refetch();\n }}\n maxTags={5}\n />\n </div>\n </Td>\n </tr>\n ))}\n </tbody>\n </TableWrap>\n <LoadMore\n hasMore={data?.pageInfo?.hasMore ?? false}\n loading={isLoading}\n loadedCount={allItems.length}\n totalCount={data?.totalCount ?? allItems.length}\n onLoadMore={() =>\n setPagination((p) => ({ limit: PAGE_SIZE, offset: p.offset + PAGE_SIZE }))\n }\n />\n </SectionCard>\n )}\n\n {creating && (\n <EngagementModal\n onClose={() => setCreating(false)}\n onSaved={(name) =>\n setBanner(tr('psw.engagements.created', '{{name}} created.', { name }))\n }\n />\n )}\n </div>\n );\n};\n\nconst EngagementModal: FC<{ onClose: () => void; onSaved: (name: string) => void }> = ({\n onClose,\n onSaved,\n}) => {\n const tr = useTr();\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(tr('psw.engagements.selectClient', 'Select a client.'));\n if (!form.name.trim())\n return setErr(tr('psw.engagements.nameRequired', '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) =>\n setErr(e instanceof Error ? e.message : tr('psw.engagements.createFailed', 'Failed.')),\n }\n );\n };\n\n return (\n <Modal\n open\n onClose={onClose}\n title={tr('psw.engagements.newTitle', 'New engagement')}\n footer={\n <>\n <Button variant=\"outline\" onClick={onClose} disabled={create.isPending}>\n {tr('psw.common.cancel', 'Cancel')}\n </Button>\n <Button onClick={submit} disabled={create.isPending}>\n {create.isPending\n ? tr('psw.common.creating', 'Creating…')\n : tr('psw.common.create', 'Create engagement')}\n </Button>\n </>\n }\n >\n <div className=\"space-y-3\">\n {err && <Banner tone=\"danger\">{err}</Banner>}\n <Field label={tr('psw.engagements.client', 'Client')} required>\n <NativeSelect value={form.clientId} onChange={set('clientId')}>\n <option value=\"\">\n {tr('psw.engagements.selectClientPlaceholder', 'Select a client…')}\n </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={tr('psw.engagements.name', 'Name')} required>\n <TextInput\n value={form.name}\n onChange={set('name')}\n placeholder={tr('psw.engagements.namePlaceholder', 'FY26 Statutory Audit')}\n />\n </Field>\n <Field label={tr('psw.engagements.practiceArea', 'Practice area')}>\n <NativeSelect value={form.practiceAreaId} onChange={set('practiceAreaId')}>\n <option value=\"\">{tr('psw.engagements.unassigned', 'Unassigned')}</option>\n {practiceAreas.data?.items.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={tr('psw.engagements.feeType', 'Fee type')}>\n <NativeSelect value={form.feeArrangement} onChange={set('feeArrangement')}>\n {enumOptions(FEE_ARRANGEMENTS)}\n </NativeSelect>\n </Field>\n <Field label={tr('psw.engagements.feeAmount', '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={tr('psw.engagements.currency', 'Currency')}>\n <TextInput value={form.currency} onChange={set('currency')} maxLength={3} />\n </Field>\n </div>\n <Field label={tr('psw.engagements.startDate', 'Start date')}>\n <TextInput type=\"date\" value={form.startDate} onChange={set('startDate')} />\n </Field>\n <Field label={tr('psw.engagements.description', 'Description')}>\n <TextArea value={form.description} onChange={set('description')} />\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;AAgEhC,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;AAmEhC,eAAO,MAAM,WAAW,EAAE,EAmQzB,CAAC"}