@burdenoff/microfe-proserviceworld 2026.801.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.
Files changed (37) hide show
  1. package/dist/index.js +4 -4
  2. package/dist/proserviceworld/hooks/useActorNames.d.ts +16 -0
  3. package/dist/proserviceworld/hooks/useActorNames.d.ts.map +1 -0
  4. package/dist/proserviceworld/hooks/useActorNames.js +18 -0
  5. package/dist/proserviceworld/hooks/useActorNames.js.map +1 -0
  6. package/dist/proserviceworld/hooks/useProServiceWorldApi.d.ts +53 -0
  7. package/dist/proserviceworld/hooks/useProServiceWorldApi.d.ts.map +1 -1
  8. package/dist/proserviceworld/hooks/useProServiceWorldApi.js +289 -227
  9. package/dist/proserviceworld/hooks/useProServiceWorldApi.js.map +1 -1
  10. package/dist/proserviceworld/hooks/useTr.d.ts +19 -0
  11. package/dist/proserviceworld/hooks/useTr.d.ts.map +1 -0
  12. package/dist/proserviceworld/hooks/useTr.js +33 -0
  13. package/dist/proserviceworld/hooks/useTr.js.map +1 -0
  14. package/dist/proserviceworld/i18n/index.d.ts +1 -1
  15. package/dist/proserviceworld/i18n/index.d.ts.map +1 -1
  16. package/dist/proserviceworld/i18n/index.js +723 -18
  17. package/dist/proserviceworld/i18n/index.js.map +1 -1
  18. package/dist/proserviceworld/index.js +4 -4
  19. package/dist/proserviceworld/pages/ClientDetailPage.d.ts.map +1 -1
  20. package/dist/proserviceworld/pages/ClientDetailPage.js +268 -144
  21. package/dist/proserviceworld/pages/ClientDetailPage.js.map +1 -1
  22. package/dist/proserviceworld/pages/ClientsPage.d.ts.map +1 -1
  23. package/dist/proserviceworld/pages/ClientsPage.js +324 -241
  24. package/dist/proserviceworld/pages/ClientsPage.js.map +1 -1
  25. package/dist/proserviceworld/pages/DashboardPage.d.ts.map +1 -1
  26. package/dist/proserviceworld/pages/DashboardPage.js +152 -142
  27. package/dist/proserviceworld/pages/DashboardPage.js.map +1 -1
  28. package/dist/proserviceworld/pages/EngagementDetailPage.d.ts.map +1 -1
  29. package/dist/proserviceworld/pages/EngagementDetailPage.js +420 -186
  30. package/dist/proserviceworld/pages/EngagementDetailPage.js.map +1 -1
  31. package/dist/proserviceworld/pages/EngagementsPage.d.ts.map +1 -1
  32. package/dist/proserviceworld/pages/EngagementsPage.js +135 -135
  33. package/dist/proserviceworld/pages/EngagementsPage.js.map +1 -1
  34. package/dist/proserviceworld/pages/MattersPage.d.ts.map +1 -1
  35. package/dist/proserviceworld/pages/MattersPage.js +204 -197
  36. package/dist/proserviceworld/pages/MattersPage.js.map +1 -1
  37. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"EngagementDetailPage.js","names":[],"sources":["../../../src/proserviceworld/pages/EngagementDetailPage.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useState } from 'react';\nimport { useParams } from 'react-router';\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport {\n ArrowLeft,\n ArrowRight,\n Plus,\n CheckCircle2,\n FileText,\n Flag,\n Clock,\n DollarSign,\n} from 'lucide-react';\nimport {\n useEngagement,\n useTransitionEngagement,\n useCreateDeliverable,\n useTransitionDeliverable,\n useCreateMilestone,\n useCompleteMilestone,\n useTimeEntries,\n type PswEngagementStatus,\n type PswDeliverableStatus,\n} from '../hooks/useProServiceWorldApi';\nimport { useNav } from '../utils/nav';\nimport { useAnalytics } from '../hooks/useAnalytics';\nimport { DiscussionThread } from '../components/DiscussionThread';\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 fmtDate,\n fmtMoney,\n fmtMinutesAsHours,\n humanize,\n} from '../components/ui';\n\n// Mirrors the svc ENGAGEMENT_TRANSITIONS state machine so we only offer valid moves.\nconst NEXT: Record<PswEngagementStatus, PswEngagementStatus[]> = {\n PROPOSAL: ['ACCEPTED', 'CANCELLED'],\n ACCEPTED: ['IN_PROGRESS', 'CANCELLED'],\n IN_PROGRESS: ['REVIEW', 'CANCELLED'],\n REVIEW: ['DELIVERED', 'IN_PROGRESS', 'CANCELLED'],\n DELIVERED: ['INVOICED', 'CANCELLED'],\n INVOICED: ['CLOSED'],\n CLOSED: [],\n CANCELLED: [],\n};\nconst DELIVERABLE_STATUSES: PswDeliverableStatus[] = [\n 'DRAFT',\n 'INTERNAL_REVIEW',\n 'CLIENT_REVIEW',\n 'ACCEPTED',\n 'REJECTED',\n];\n\nexport const EngagementDetailPage: FC = () => {\n const { id = '' } = useParams();\n const nav = useNav();\n const { emitFact } = useAnalytics();\n const { data: e, isLoading, error, refetch } = useEngagement(id);\n const time = useTimeEntries({ engagementId: id });\n const transition = useTransitionEngagement();\n const [addDeliverable, setAddDeliverable] = useState(false);\n const [addMilestone, setAddMilestone] = useState(false);\n const [banner, setBanner] = useState<{ tone: 'success' | 'danger'; text: string } | null>(null);\n\n if (isLoading) return <LoadingBlock />;\n if (error) return <ErrorState error={error} onRetry={() => void refetch()} />;\n if (!e) return <Empty title=\"Engagement not found\" />;\n\n const nextStates = NEXT[e.status] ?? [];\n const loggedMinutes = (time.data?.items ?? []).reduce((sum, t) => sum + t.minutes, 0);\n\n return (\n <div className=\"space-y-6\">\n <button\n type=\"button\"\n onClick={() => nav('engagements')}\n className=\"flex items-center gap-1.5 text-sm text-text-secondary transition-colors hover:text-accent\"\n >\n <ArrowLeft className=\"h-4 w-4\" /> Back to engagements\n </button>\n\n <PageHeader\n title={e.name}\n subtitle={\n e.client ? `${e.client.name} · ${humanize(e.feeArrangement)}` : humanize(e.feeArrangement)\n }\n actions={<StatusPill status={e.status} />}\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-2 gap-3 lg:grid-cols-4\">\n <MetricCard\n label=\"Fee\"\n value={fmtMoney(e.feeAmount, e.currency)}\n hint={humanize(e.feeArrangement)}\n icon={<DollarSign className=\"h-4 w-4\" />}\n tone=\"success\"\n />\n <MetricCard\n label=\"Deliverables\"\n value={e.deliverables.length}\n icon={<FileText className=\"h-4 w-4\" />}\n tone=\"info\"\n />\n <MetricCard\n label=\"Milestones\"\n value={e.milestones.length}\n icon={<Flag className=\"h-4 w-4\" />}\n tone=\"accent\"\n />\n <MetricCard\n label=\"Time logged\"\n value={fmtMinutesAsHours(loggedMinutes)}\n hint={`${time.data?.totalCount ?? 0} entries`}\n icon={<Clock className=\"h-4 w-4\" />}\n tone=\"warning\"\n />\n </div>\n\n {nextStates.length > 0 && (\n <SectionCard title=\"Advance lifecycle\">\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <span>Currently</span>\n <StatusPill status={e.status} />\n </div>\n <div className=\"flex flex-wrap gap-2\">\n {nextStates.map((s) => {\n const isCancel = s === 'CANCELLED';\n return (\n <Button\n key={s}\n size=\"sm\"\n variant={isCancel ? 'outline' : 'default'}\n disabled={transition.isPending}\n onClick={() =>\n transition.mutate(\n { id: e.id, status: s },\n {\n onSuccess: () => {\n emitFact('psw.engagement.transitioned', {\n engagementId: e.id,\n status: s,\n });\n setBanner({ tone: 'success', text: `Moved to ${humanize(s)}.` });\n },\n onError: (err) =>\n setBanner({\n tone: 'danger',\n text: err instanceof Error ? err.message : 'Transition failed.',\n }),\n }\n )\n }\n >\n {humanize(s)}\n {!isCancel && <ArrowRight className=\"ml-1.5 h-4 w-4\" />}\n </Button>\n );\n })}\n </div>\n </div>\n </SectionCard>\n )}\n\n <div className=\"grid grid-cols-1 gap-4 lg:grid-cols-2\">\n <SectionCard\n title=\"Deliverables\"\n action={\n <Button size=\"sm\" variant=\"outline\" onClick={() => setAddDeliverable(true)}>\n <Plus className=\"mr-1.5 h-4 w-4\" />\n Add\n </Button>\n }\n >\n {e.deliverables.length === 0 ? (\n <Empty\n title=\"No deliverables\"\n description=\"Track the tangible outputs of this engagement.\"\n icon={<FileText className=\"h-7 w-7\" />}\n />\n ) : (\n <ul className=\"space-y-2.5\">\n {e.deliverables.map((d) => (\n <li\n key={d.id}\n className=\"rounded-xl border border-border-seam bg-bg-canvas p-3.5 transition-colors hover:border-accent/40\"\n >\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"min-w-0\">\n <div className=\"flex items-center gap-2 text-sm font-medium text-text-primary\">\n <span className=\"truncate\">{d.name}</span>\n <span className=\"shrink-0 rounded-md bg-bg-sunken px-1.5 py-0.5 text-[10px] font-semibold text-text-tertiary\">\n v{d.version}\n </span>\n </div>\n {d.dueDate && (\n <div className=\"mt-0.5 text-xs text-text-tertiary\">\n Due {fmtDate(d.dueDate)}\n </div>\n )}\n </div>\n <DeliverableStatusSelect\n id={d.id}\n engagementId={e.id}\n status={d.status}\n onDone={() => void refetch()}\n />\n </div>\n </li>\n ))}\n </ul>\n )}\n </SectionCard>\n\n <SectionCard\n title=\"Milestones\"\n action={\n <Button size=\"sm\" variant=\"outline\" onClick={() => setAddMilestone(true)}>\n <Plus className=\"mr-1.5 h-4 w-4\" />\n Add\n </Button>\n }\n >\n {e.milestones.length === 0 ? (\n <Empty\n title=\"No milestones\"\n description=\"Add checkpoints — some can trigger billing.\"\n icon={<Flag className=\"h-7 w-7\" />}\n />\n ) : (\n <ul className=\"space-y-2.5\">\n {e.milestones.map((m) => (\n <li\n key={m.id}\n className=\"flex items-center justify-between gap-3 rounded-xl border border-border-seam bg-bg-canvas p-3.5 transition-colors hover:border-accent/40\"\n >\n <div className=\"min-w-0\">\n <div className=\"truncate text-sm font-medium text-text-primary\">{m.name}</div>\n <div className=\"mt-0.5 text-xs text-text-tertiary\">\n {m.triggersInvoice ? `Bills ${fmtMoney(m.triggerAmount, e.currency)} · ` : ''}\n Due {fmtDate(m.dueDate)}\n </div>\n </div>\n <div className=\"flex shrink-0 items-center gap-2\">\n <StatusPill status={m.status} />\n {m.status !== 'COMPLETED' && m.status !== 'CANCELLED' && (\n <CompleteMilestoneButton\n id={m.id}\n engagementId={e.id}\n onDone={() => void refetch()}\n />\n )}\n </div>\n </li>\n ))}\n </ul>\n )}\n </SectionCard>\n </div>\n\n <div className=\"grid grid-cols-1 gap-4 lg:grid-cols-3\">\n <div className=\"lg:col-span-2\">\n <DiscussionThread entityType=\"proserviceworld-engagement\" entityId={e.id} />\n </div>\n\n <SectionCard\n title=\"Time logged\"\n description={fmtMinutesAsHours(loggedMinutes)}\n action={\n <Button size=\"sm\" variant=\"outline\" onClick={() => nav('time')}>\n <Clock className=\"mr-1.5 h-4 w-4\" />\n Log time\n </Button>\n }\n >\n {time.isLoading ? (\n <LoadingBlock label=\"Loading…\" />\n ) : !time.data || time.data.items.length === 0 ? (\n <Empty\n title=\"No time logged\"\n description=\"Time logged against this engagement will appear here.\"\n icon={<Clock className=\"h-7 w-7\" />}\n />\n ) : (\n <ul className=\"space-y-2\">\n {time.data.items.slice(0, 8).map((t) => (\n <li\n key={t.id}\n className=\"rounded-lg border border-border-seam bg-bg-canvas p-3 text-sm\"\n >\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"whitespace-nowrap text-xs text-text-tertiary\">\n {fmtDate(t.date)}\n </span>\n <span className=\"flex items-center gap-2\">\n <span className=\"font-medium text-text-primary\">\n {fmtMinutesAsHours(t.minutes)}\n </span>\n <StatusPill status={t.status} />\n </span>\n </div>\n <div className=\"mt-1 truncate text-text-secondary\">\n {t.narrative || 'Time entry'}\n </div>\n </li>\n ))}\n </ul>\n )}\n </SectionCard>\n </div>\n\n {addDeliverable && (\n <DeliverableModal\n engagementId={e.id}\n onClose={() => setAddDeliverable(false)}\n onDone={() => {\n void refetch();\n setBanner({ tone: 'success', text: 'Deliverable added.' });\n }}\n />\n )}\n {addMilestone && (\n <MilestoneModal\n engagementId={e.id}\n onClose={() => setAddMilestone(false)}\n onDone={() => {\n void refetch();\n setBanner({ tone: 'success', text: 'Milestone added.' });\n }}\n />\n )}\n </div>\n );\n};\n\nconst DeliverableStatusSelect: FC<{\n id: string;\n engagementId: string;\n status: PswDeliverableStatus;\n onDone: () => void;\n}> = ({ id, engagementId, status, onDone }) => {\n const transition = useTransitionDeliverable();\n return (\n <NativeSelect\n value={status}\n disabled={transition.isPending}\n onChange={(ev) =>\n transition.mutate(\n { id, status: ev.target.value as PswDeliverableStatus, engagementId },\n { onSuccess: onDone }\n )\n }\n className=\"w-40 shrink-0\"\n >\n {DELIVERABLE_STATUSES.map((s) => (\n <option key={s} value={s}>\n {humanize(s)}\n </option>\n ))}\n </NativeSelect>\n );\n};\n\nconst CompleteMilestoneButton: FC<{ id: string; engagementId: string; onDone: () => void }> = ({\n id,\n engagementId,\n onDone,\n}) => {\n const complete = useCompleteMilestone();\n return (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n aria-label=\"Complete milestone\"\n disabled={complete.isPending}\n onClick={() => complete.mutate({ id, engagementId }, { onSuccess: onDone })}\n >\n <CheckCircle2 className=\"h-4 w-4\" />\n </Button>\n );\n};\n\nconst DeliverableModal: FC<{ engagementId: string; onClose: () => void; onDone: () => void }> = ({\n engagementId,\n onClose,\n onDone,\n}) => {\n const create = useCreateDeliverable();\n const [form, setForm] = useState({\n name: '',\n description: '',\n dueDate: '',\n acceptanceCriteria: '',\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 const submit = () => {\n setErr(null);\n if (!form.name.trim()) return setErr('Name is required.');\n create.mutate(\n {\n engagementId,\n name: form.name.trim(),\n description: form.description.trim() || null,\n acceptanceCriteria: form.acceptanceCriteria.trim() || null,\n dueDate: form.dueDate ? new Date(form.dueDate).toISOString() : null,\n },\n {\n onSuccess: () => {\n onDone();\n onClose();\n },\n onError: (e) => setErr(e instanceof Error ? e.message : 'Failed.'),\n }\n );\n };\n return (\n <Modal\n open\n onClose={onClose}\n title=\"Add deliverable\"\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 ? 'Adding…' : 'Add'}\n </Button>\n </>\n }\n >\n <div className=\"space-y-3\">\n {err && <Banner tone=\"danger\">{err}</Banner>}\n <Field label=\"Name\" required>\n <TextInput value={form.name} onChange={set('name')} placeholder=\"Draft audit report\" />\n </Field>\n <Field label=\"Due date\">\n <TextInput type=\"date\" value={form.dueDate} onChange={set('dueDate')} />\n </Field>\n <Field label=\"Acceptance criteria\">\n <TextArea value={form.acceptanceCriteria} onChange={set('acceptanceCriteria')} />\n </Field>\n <Field label=\"Description\">\n <TextArea value={form.description} onChange={set('description')} />\n </Field>\n </div>\n </Modal>\n );\n};\n\nconst MilestoneModal: FC<{ engagementId: string; onClose: () => void; onDone: () => void }> = ({\n engagementId,\n onClose,\n onDone,\n}) => {\n const create = useCreateMilestone();\n const [form, setForm] = useState({\n name: '',\n dueDate: '',\n triggerAmount: '',\n triggersInvoice: false,\n });\n const [err, setErr] = useState<string | null>(null);\n const submit = () => {\n setErr(null);\n if (!form.name.trim()) return setErr('Name is required.');\n create.mutate(\n {\n engagementId,\n name: form.name.trim(),\n dueDate: form.dueDate ? new Date(form.dueDate).toISOString() : null,\n triggerAmount: form.triggerAmount ? Number(form.triggerAmount) : 0,\n triggersInvoice: form.triggersInvoice,\n },\n {\n onSuccess: () => {\n onDone();\n onClose();\n },\n onError: (e) => setErr(e instanceof Error ? e.message : 'Failed.'),\n }\n );\n };\n return (\n <Modal\n open\n onClose={onClose}\n title=\"Add milestone\"\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 ? 'Adding…' : 'Add'}\n </Button>\n </>\n }\n >\n <div className=\"space-y-3\">\n {err && <Banner tone=\"danger\">{err}</Banner>}\n <Field label=\"Name\" required>\n <TextInput\n value={form.name}\n onChange={(e) => setForm((f) => ({ ...f, name: e.target.value }))}\n placeholder=\"Phase 1 sign-off\"\n />\n </Field>\n <Field label=\"Due date\">\n <TextInput\n type=\"date\"\n value={form.dueDate}\n onChange={(e) => setForm((f) => ({ ...f, dueDate: e.target.value }))}\n />\n </Field>\n <Field\n label=\"Trigger amount\"\n hint=\"Amount billed when this milestone completes (if it triggers an invoice).\"\n >\n <TextInput\n type=\"number\"\n min=\"0\"\n value={form.triggerAmount}\n onChange={(e) => setForm((f) => ({ ...f, triggerAmount: e.target.value }))}\n />\n </Field>\n <label className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <input\n type=\"checkbox\"\n checked={form.triggersInvoice}\n onChange={(e) => setForm((f) => ({ ...f, triggersInvoice: e.target.checked }))}\n />\n Completing this milestone triggers an invoice\n </label>\n </div>\n </Modal>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"EngagementDetailPage.js","names":[],"sources":["../../../src/proserviceworld/pages/EngagementDetailPage.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useState } from 'react';\nimport { useParams } from 'react-router';\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport { useWorkspaceDirectory } from '@burdenoff/fe-libs/sharing';\nimport {\n ArrowLeft,\n ArrowRight,\n Plus,\n CheckCircle2,\n FileText,\n Flag,\n Clock,\n DollarSign,\n Trash2,\n Users,\n} from 'lucide-react';\nimport {\n useEngagement,\n useTransitionEngagement,\n useCreateDeliverable,\n useTransitionDeliverable,\n useCreateMilestone,\n useCompleteMilestone,\n useTimeEntries,\n usePracticeAreas,\n useTeamAssignments,\n useAddTeamAssignment,\n useRemoveTeamAssignment,\n type PswEngagementStatus,\n type PswDeliverableStatus,\n type PswTeamAssignment,\n type PswTeamRole,\n} from '../hooks/useProServiceWorldApi';\nimport { useActorNames, type UseActorNamesResult } from '../hooks/useActorNames';\nimport { useProServiceWorld } from '../providers/ProServiceWorldProvider';\nimport { useNav } from '../utils/nav';\nimport { useAnalytics } from '../hooks/useAnalytics';\nimport { DiscussionThread } from '../components/DiscussionThread';\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 fmtMinutesAsHours,\n humanize,\n} from '../components/ui';\n\n// Mirrors the svc ENGAGEMENT_TRANSITIONS state machine so we only offer valid moves.\nconst NEXT: Record<PswEngagementStatus, PswEngagementStatus[]> = {\n PROPOSAL: ['ACCEPTED', 'CANCELLED'],\n ACCEPTED: ['IN_PROGRESS', 'CANCELLED'],\n IN_PROGRESS: ['REVIEW', 'CANCELLED'],\n REVIEW: ['DELIVERED', 'IN_PROGRESS', 'CANCELLED'],\n DELIVERED: ['INVOICED', 'CANCELLED'],\n INVOICED: ['CLOSED'],\n CLOSED: [],\n CANCELLED: [],\n};\nconst DELIVERABLE_STATUSES: PswDeliverableStatus[] = [\n 'DRAFT',\n 'INTERNAL_REVIEW',\n 'CLIENT_REVIEW',\n 'ACCEPTED',\n 'REJECTED',\n];\nconst TEAM_ROLES: PswTeamRole[] = ['PARTNER', 'MANAGER', 'ASSOCIATE', 'SPECIALIST', 'SUPPORT'];\n\nexport const EngagementDetailPage: FC = () => {\n const { id = '' } = useParams();\n const nav = useNav();\n const { emitFact } = useAnalytics();\n const { data: e, isLoading, error, refetch } = useEngagement(id);\n const time = useTimeEntries({ engagementId: id });\n const practiceAreas = usePracticeAreas();\n const team = useTeamAssignments({ engagementId: id });\n const transition = useTransitionEngagement();\n const [addDeliverable, setAddDeliverable] = useState(false);\n const [addMilestone, setAddMilestone] = useState(false);\n const [addMember, setAddMember] = useState(false);\n const [banner, setBanner] = useState<{ tone: 'success' | 'danger'; text: string } | null>(null);\n const actors = useActorNames([\n e?.responsiblePartnerId,\n ...(team.data?.items ?? []).map((a) => a.practitionerId),\n ]);\n\n if (isLoading) return <LoadingBlock />;\n if (error) return <ErrorState error={error} onRetry={() => void refetch()} />;\n if (!e) return <Empty title=\"Engagement not found\" />;\n\n const nextStates = NEXT[e.status] ?? [];\n\n // Time roll-ups are computed over the entries this page actually loaded. The\n // service caps a page at 100, so when there are more we say so rather than\n // presenting a partial sum as the engagement total.\n const timeEntries = time.data?.items ?? [];\n const loadedEntries = timeEntries.length;\n const totalEntries = time.data?.totalCount ?? loadedEntries;\n const partialTime = loadedEntries < totalEntries;\n const coverageNote = partialTime ? ` · first ${loadedEntries} of ${totalEntries} entries` : '';\n const loggedMinutes = timeEntries.reduce((sum, t) => sum + t.minutes, 0);\n // Mirrors the service's own unbilled definition (billable && status != BILLED).\n const unbilledMinutes = timeEntries\n .filter((t) => t.billable && t.status !== 'BILLED')\n .reduce((sum, t) => sum + t.minutes, 0);\n const billedMinutes = timeEntries\n .filter((t) => t.status === 'BILLED')\n .reduce((sum, t) => sum + t.minutes, 0);\n\n const milestonesDone = e.milestones.filter((m) => m.status === 'COMPLETED').length;\n const deliverablesInClientReview = e.deliverables.filter(\n (d) => d.status === 'CLIENT_REVIEW'\n ).length;\n\n const practiceAreaName =\n practiceAreas.data?.items.find((a) => a.id === e.practiceAreaId)?.name ?? null;\n const subtitle = [\n e.client?.name,\n practiceAreaName,\n humanize(e.feeArrangement),\n e.responsiblePartnerId ? `Partner: ${actors.nameOf(e.responsiblePartnerId)}` : null,\n ]\n .filter(Boolean)\n .join(' · ');\n\n return (\n <div className=\"space-y-6\">\n <button\n type=\"button\"\n onClick={() => nav('engagements')}\n className=\"flex items-center gap-1.5 text-sm text-text-secondary transition-colors hover:text-accent\"\n >\n <ArrowLeft className=\"h-4 w-4\" /> Back to engagements\n </button>\n\n <PageHeader title={e.name} subtitle={subtitle} actions={<StatusPill status={e.status} />} />\n\n {banner && (\n <Banner tone={banner.tone} onClose={() => setBanner(null)}>\n {banner.text}\n </Banner>\n )}\n\n <div className=\"grid grid-cols-2 gap-3 lg:grid-cols-4\">\n <MetricCard\n label=\"Fee\"\n value={fmtMoney(e.feeAmount, e.currency)}\n hint={humanize(e.feeArrangement)}\n icon={<DollarSign className=\"h-4 w-4\" />}\n tone=\"success\"\n />\n <MetricCard\n label=\"Deliverables\"\n value={e.deliverables.length}\n hint={`${deliverablesInClientReview} in client review`}\n icon={<FileText className=\"h-4 w-4\" />}\n tone=\"info\"\n />\n <MetricCard\n label=\"Milestones\"\n value={`${milestonesDone} of ${e.milestones.length}`}\n hint=\"Completed\"\n icon={<Flag className=\"h-4 w-4\" />}\n tone=\"accent\"\n />\n <MetricCard\n label=\"Unbilled hours\"\n value={fmtMinutesAsHours(unbilledMinutes)}\n hint={`${fmtMinutesAsHours(billedMinutes)} billed · ${fmtMinutesAsHours(loggedMinutes)} logged${coverageNote}`}\n icon={<Clock className=\"h-4 w-4\" />}\n tone=\"warning\"\n />\n </div>\n\n {nextStates.length > 0 && (\n <SectionCard title=\"Advance lifecycle\">\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <span>Currently</span>\n <StatusPill status={e.status} />\n </div>\n <div className=\"flex flex-wrap gap-2\">\n {nextStates.map((s) => {\n const isCancel = s === 'CANCELLED';\n return (\n <Button\n key={s}\n size=\"sm\"\n variant={isCancel ? 'outline' : 'default'}\n disabled={transition.isPending}\n onClick={() =>\n transition.mutate(\n { id: e.id, status: s },\n {\n onSuccess: () => {\n emitFact('psw.engagement.transitioned', {\n engagementId: e.id,\n status: s,\n });\n setBanner({ tone: 'success', text: `Moved to ${humanize(s)}.` });\n },\n onError: (err) =>\n setBanner({\n tone: 'danger',\n text: err instanceof Error ? err.message : 'Transition failed.',\n }),\n }\n )\n }\n >\n {humanize(s)}\n {!isCancel && <ArrowRight className=\"ml-1.5 h-4 w-4\" />}\n </Button>\n );\n })}\n </div>\n </div>\n </SectionCard>\n )}\n\n <div className=\"grid grid-cols-1 gap-4 lg:grid-cols-2\">\n <SectionCard\n title=\"Deliverables\"\n action={\n <Button size=\"sm\" variant=\"outline\" onClick={() => setAddDeliverable(true)}>\n <Plus className=\"mr-1.5 h-4 w-4\" />\n Add\n </Button>\n }\n >\n {e.deliverables.length === 0 ? (\n <Empty\n title=\"No deliverables\"\n description=\"Track the tangible outputs of this engagement.\"\n icon={<FileText className=\"h-7 w-7\" />}\n />\n ) : (\n <ul className=\"space-y-2.5\">\n {e.deliverables.map((d) => (\n <li\n key={d.id}\n className=\"rounded-xl border border-border-seam bg-bg-canvas p-3.5 transition-colors hover:border-accent/40\"\n >\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"min-w-0\">\n <div className=\"flex items-center gap-2 text-sm font-medium text-text-primary\">\n <span className=\"truncate\">{d.name}</span>\n <span className=\"shrink-0 rounded-md bg-bg-sunken px-1.5 py-0.5 text-[10px] font-semibold text-text-tertiary\">\n v{d.version}\n </span>\n </div>\n {d.dueDate && (\n <div className=\"mt-0.5 text-xs text-text-tertiary\">\n Due {fmtDate(d.dueDate)}\n </div>\n )}\n </div>\n <DeliverableStatusSelect\n id={d.id}\n engagementId={e.id}\n status={d.status}\n onDone={() => void refetch()}\n />\n </div>\n </li>\n ))}\n </ul>\n )}\n </SectionCard>\n\n <SectionCard\n title=\"Milestones\"\n action={\n <Button size=\"sm\" variant=\"outline\" onClick={() => setAddMilestone(true)}>\n <Plus className=\"mr-1.5 h-4 w-4\" />\n Add\n </Button>\n }\n >\n {e.milestones.length === 0 ? (\n <Empty\n title=\"No milestones\"\n description=\"Add checkpoints — some can trigger billing.\"\n icon={<Flag className=\"h-7 w-7\" />}\n />\n ) : (\n <ul className=\"space-y-2.5\">\n {e.milestones.map((m) => (\n <li\n key={m.id}\n className=\"flex items-center justify-between gap-3 rounded-xl border border-border-seam bg-bg-canvas p-3.5 transition-colors hover:border-accent/40\"\n >\n <div className=\"min-w-0\">\n <div className=\"truncate text-sm font-medium text-text-primary\">{m.name}</div>\n <div className=\"mt-0.5 text-xs text-text-tertiary\">\n {m.triggersInvoice ? `Bills ${fmtMoney(m.triggerAmount, e.currency)} · ` : ''}\n Due {fmtDate(m.dueDate)}\n </div>\n </div>\n <div className=\"flex shrink-0 items-center gap-2\">\n <StatusPill status={m.status} />\n {m.status !== 'COMPLETED' && m.status !== 'CANCELLED' && (\n <CompleteMilestoneButton\n id={m.id}\n engagementId={e.id}\n onDone={() => void refetch()}\n />\n )}\n </div>\n </li>\n ))}\n </ul>\n )}\n </SectionCard>\n </div>\n\n <SectionCard\n title=\"Team\"\n description={`${team.data?.totalCount ?? 0} staffed on this engagement`}\n action={\n <Button size=\"sm\" variant=\"outline\" onClick={() => setAddMember(true)}>\n <Plus className=\"mr-1.5 h-4 w-4\" />\n Assign\n </Button>\n }\n >\n {team.isLoading ? (\n <LoadingBlock label=\"Loading…\" />\n ) : team.error ? (\n <ErrorState error={team.error} onRetry={() => void team.refetch()} />\n ) : !team.data || team.data.items.length === 0 ? (\n <Empty\n title=\"No one assigned\"\n description=\"Staff the practitioners delivering this engagement, with their role and billing rate.\"\n icon={<Users className=\"h-7 w-7\" />}\n />\n ) : (\n <TableWrap>\n <thead>\n <tr>\n <Th>Practitioner</Th>\n <Th>Role</Th>\n <Th>Allocation</Th>\n <Th>Billing rate</Th>\n <Th className=\"text-right\">Actions</Th>\n </tr>\n </thead>\n <tbody>\n {team.data.items.map((a) => (\n <TeamRow\n key={a.id}\n assignment={a}\n currency={e.currency}\n actors={actors}\n onRemoved={(ok) => {\n void team.refetch();\n setBanner(\n ok\n ? { tone: 'success', text: 'Team assignment removed.' }\n : { tone: 'danger', text: 'Could not remove the assignment.' }\n );\n }}\n />\n ))}\n </tbody>\n </TableWrap>\n )}\n </SectionCard>\n\n <div className=\"grid grid-cols-1 gap-4 lg:grid-cols-3\">\n <div className=\"lg:col-span-2\">\n <DiscussionThread entityType=\"proserviceworld-engagement\" entityId={e.id} />\n </div>\n\n <SectionCard\n title=\"Time logged\"\n description={`${fmtMinutesAsHours(loggedMinutes)}${coverageNote}`}\n action={\n <Button size=\"sm\" variant=\"outline\" onClick={() => nav('time')}>\n <Clock className=\"mr-1.5 h-4 w-4\" />\n Log time\n </Button>\n }\n >\n {time.isLoading ? (\n <LoadingBlock label=\"Loading…\" />\n ) : !time.data || time.data.items.length === 0 ? (\n <Empty\n title=\"No time logged\"\n description=\"Time logged against this engagement will appear here.\"\n icon={<Clock className=\"h-7 w-7\" />}\n />\n ) : (\n <ul className=\"space-y-2\">\n {time.data.items.slice(0, 8).map((t) => (\n <li\n key={t.id}\n className=\"rounded-lg border border-border-seam bg-bg-canvas p-3 text-sm\"\n >\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"whitespace-nowrap text-xs text-text-tertiary\">\n {fmtDate(t.date)}\n </span>\n <span className=\"flex items-center gap-2\">\n <span className=\"font-medium text-text-primary\">\n {fmtMinutesAsHours(t.minutes)}\n </span>\n <StatusPill status={t.status} />\n </span>\n </div>\n <div className=\"mt-1 truncate text-text-secondary\">\n {t.narrative || 'Time entry'}\n </div>\n </li>\n ))}\n </ul>\n )}\n </SectionCard>\n </div>\n\n {addMember && (\n <TeamAssignmentModal\n engagementId={e.id}\n currency={e.currency}\n onClose={() => setAddMember(false)}\n onDone={() => {\n void team.refetch();\n setBanner({ tone: 'success', text: 'Practitioner assigned.' });\n }}\n />\n )}\n\n {addDeliverable && (\n <DeliverableModal\n engagementId={e.id}\n onClose={() => setAddDeliverable(false)}\n onDone={() => {\n void refetch();\n setBanner({ tone: 'success', text: 'Deliverable added.' });\n }}\n />\n )}\n {addMilestone && (\n <MilestoneModal\n engagementId={e.id}\n onClose={() => setAddMilestone(false)}\n onDone={() => {\n void refetch();\n setBanner({ tone: 'success', text: 'Milestone added.' });\n }}\n />\n )}\n </div>\n );\n};\n\n/**\n * One staffing row. `practitionerId` is a workspace actor id — resolved to a\n * person by {@link useActorNames}; billingRate/allocationPct come straight off\n * `PswTeamAssignment` and are never inferred.\n */\nconst TeamRow: FC<{\n assignment: PswTeamAssignment;\n currency: string;\n actors: UseActorNamesResult;\n onRemoved: (ok: boolean) => void;\n}> = ({ assignment, currency, actors, onRemoved }) => {\n const remove = useRemoveTeamAssignment();\n const name = actors.nameOf(assignment.practitionerId);\n const email = actors.profiles[assignment.practitionerId]?.email;\n\n return (\n <tr className=\"transition-colors hover:bg-bg-sunken/60\">\n <Td>\n <div className=\"flex items-center gap-2\">\n <span className=\"font-medium text-text-primary\">{name}</span>\n {assignment.isLead && (\n <span className=\"rounded-full bg-bg-sunken px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wide text-accent\">\n Lead\n </span>\n )}\n </div>\n {email ? <div className=\"text-xs text-text-tertiary\">{email}</div> : null}\n </Td>\n {/* humanize() normalises casing, so a lowercase role renders the same. */}\n <Td className=\"whitespace-nowrap\">{humanize(assignment.role)}</Td>\n <Td className=\"whitespace-nowrap\">{assignment.allocationPct}%</Td>\n <Td className=\"whitespace-nowrap\">\n {assignment.billingRate > 0 ? (\n <>\n {fmtMoney(assignment.billingRate, currency)}\n <span className=\"text-xs text-text-tertiary\"> / hr</span>\n </>\n ) : (\n <span className=\"text-text-tertiary\">—</span>\n )}\n </Td>\n <Td className=\"text-right\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n aria-label={`Remove ${name}`}\n disabled={remove.isPending}\n onClick={() => {\n if (!window.confirm(`Remove ${name} from this engagement?`)) return;\n remove.mutate(assignment.id, {\n onSuccess: (r) => onRemoved(Boolean(r.pswRemoveTeamAssignment)),\n onError: () => onRemoved(false),\n });\n }}\n >\n <Trash2 className=\"h-4 w-4\" />\n </Button>\n </Td>\n </tr>\n );\n};\n\n/**\n * Assign a practitioner (`pswAddTeamAssignment`). The practitioner list is the\n * real workspace directory — if it cannot be read there is nobody we can name,\n * so the form says so and stays disabled rather than offering a UUID box that\n * looks like a picker.\n */\nconst TeamAssignmentModal: FC<{\n engagementId: string;\n currency: string;\n onClose: () => void;\n onDone: () => void;\n}> = ({ engagementId, currency, onClose, onDone }) => {\n const { workspaceId } = useProServiceWorld();\n const directory = useWorkspaceDirectory({ workspaceId: workspaceId ?? '' });\n const add = useAddTeamAssignment();\n const [practitionerId, setPractitionerId] = useState('');\n const [role, setRole] = useState<string>('ASSOCIATE');\n const [isLead, setIsLead] = useState(false);\n const [allocationPct, setAllocationPct] = useState('100');\n const [billingRate, setBillingRate] = useState('');\n const [err, setErr] = useState<string | null>(null);\n\n const submit = () => {\n setErr(null);\n if (!practitionerId) return setErr('Choose a practitioner to assign.');\n const allocation = Number(allocationPct);\n if (!Number.isFinite(allocation) || allocation < 1 || allocation > 100) {\n return setErr('Allocation must be between 1 and 100.');\n }\n const rate = billingRate.trim() ? Number(billingRate) : 0;\n if (!Number.isFinite(rate) || rate < 0)\n return setErr('Billing rate must be a positive number.');\n\n add.mutate(\n {\n engagementId,\n practitionerId,\n role,\n isLead,\n allocationPct: Math.round(allocation),\n billingRate: rate,\n },\n {\n onSuccess: () => {\n onDone();\n onClose();\n },\n onError: (e) => setErr(e instanceof Error ? e.message : 'Could not assign.'),\n }\n );\n };\n\n const noDirectory = !directory.loading && directory.members.length === 0;\n\n return (\n <Modal\n open\n onClose={onClose}\n title=\"Assign practitioner\"\n footer={\n <>\n <Button variant=\"outline\" onClick={onClose} disabled={add.isPending}>\n Cancel\n </Button>\n <Button onClick={submit} disabled={add.isPending || noDirectory}>\n {add.isPending ? 'Assigning…' : 'Assign'}\n </Button>\n </>\n }\n >\n <div className=\"space-y-3\">\n {err && <Banner tone=\"danger\">{err}</Banner>}\n {noDirectory && (\n <Banner tone=\"danger\">\n The workspace member directory could not be read, so there is nobody to assign here.\n </Banner>\n )}\n <Field label=\"Practitioner\" required>\n <NativeSelect\n value={practitionerId}\n onChange={(ev) => setPractitionerId(ev.target.value)}\n disabled={directory.loading || noDirectory}\n >\n <option value=\"\">{directory.loading ? 'Loading members…' : 'Select a member'}</option>\n {directory.members.map((m) => (\n <option key={m.id} value={m.id}>\n {m.email ? `${m.name} · ${m.email}` : m.name}\n </option>\n ))}\n </NativeSelect>\n </Field>\n {directory.hasMore && (\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={directory.fetchMore}\n disabled={directory.loading}\n >\n Load more members\n </Button>\n )}\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n <Field label=\"Role\">\n <NativeSelect value={role} onChange={(ev) => setRole(ev.target.value)}>\n {enumOptions(TEAM_ROLES)}\n </NativeSelect>\n </Field>\n <Field label=\"Allocation %\" hint=\"Share of this person's time on the engagement.\">\n <TextInput\n type=\"number\"\n min={1}\n max={100}\n value={allocationPct}\n onChange={(ev) => setAllocationPct(ev.target.value)}\n />\n </Field>\n </div>\n <Field label={`Billing rate (${currency} / hr)`} hint=\"Leave blank for a non-billed seat.\">\n <TextInput\n type=\"number\"\n min={0}\n value={billingRate}\n onChange={(ev) => setBillingRate(ev.target.value)}\n placeholder=\"0\"\n />\n </Field>\n <label className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <input\n type=\"checkbox\"\n checked={isLead}\n onChange={(ev) => setIsLead(ev.target.checked)}\n className=\"h-4 w-4 rounded border-border-seam accent-accent\"\n />\n Engagement lead\n </label>\n </div>\n </Modal>\n );\n};\n\nconst DeliverableStatusSelect: FC<{\n id: string;\n engagementId: string;\n status: PswDeliverableStatus;\n onDone: () => void;\n}> = ({ id, engagementId, status, onDone }) => {\n const transition = useTransitionDeliverable();\n return (\n <NativeSelect\n value={status}\n disabled={transition.isPending}\n onChange={(ev) =>\n transition.mutate(\n { id, status: ev.target.value as PswDeliverableStatus, engagementId },\n { onSuccess: onDone }\n )\n }\n className=\"w-40 shrink-0\"\n >\n {DELIVERABLE_STATUSES.map((s) => (\n <option key={s} value={s}>\n {humanize(s)}\n </option>\n ))}\n </NativeSelect>\n );\n};\n\nconst CompleteMilestoneButton: FC<{ id: string; engagementId: string; onDone: () => void }> = ({\n id,\n engagementId,\n onDone,\n}) => {\n const complete = useCompleteMilestone();\n return (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n aria-label=\"Complete milestone\"\n disabled={complete.isPending}\n onClick={() => complete.mutate({ id, engagementId }, { onSuccess: onDone })}\n >\n <CheckCircle2 className=\"h-4 w-4\" />\n </Button>\n );\n};\n\nconst DeliverableModal: FC<{ engagementId: string; onClose: () => void; onDone: () => void }> = ({\n engagementId,\n onClose,\n onDone,\n}) => {\n const create = useCreateDeliverable();\n const [form, setForm] = useState({\n name: '',\n description: '',\n dueDate: '',\n acceptanceCriteria: '',\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 const submit = () => {\n setErr(null);\n if (!form.name.trim()) return setErr('Name is required.');\n create.mutate(\n {\n engagementId,\n name: form.name.trim(),\n description: form.description.trim() || null,\n acceptanceCriteria: form.acceptanceCriteria.trim() || null,\n dueDate: form.dueDate ? new Date(form.dueDate).toISOString() : null,\n },\n {\n onSuccess: () => {\n onDone();\n onClose();\n },\n onError: (e) => setErr(e instanceof Error ? e.message : 'Failed.'),\n }\n );\n };\n return (\n <Modal\n open\n onClose={onClose}\n title=\"Add deliverable\"\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 ? 'Adding…' : 'Add'}\n </Button>\n </>\n }\n >\n <div className=\"space-y-3\">\n {err && <Banner tone=\"danger\">{err}</Banner>}\n <Field label=\"Name\" required>\n <TextInput value={form.name} onChange={set('name')} placeholder=\"Draft audit report\" />\n </Field>\n <Field label=\"Due date\">\n <TextInput type=\"date\" value={form.dueDate} onChange={set('dueDate')} />\n </Field>\n <Field label=\"Acceptance criteria\">\n <TextArea value={form.acceptanceCriteria} onChange={set('acceptanceCriteria')} />\n </Field>\n <Field label=\"Description\">\n <TextArea value={form.description} onChange={set('description')} />\n </Field>\n </div>\n </Modal>\n );\n};\n\nconst MilestoneModal: FC<{ engagementId: string; onClose: () => void; onDone: () => void }> = ({\n engagementId,\n onClose,\n onDone,\n}) => {\n const create = useCreateMilestone();\n const [form, setForm] = useState({\n name: '',\n dueDate: '',\n triggerAmount: '',\n triggersInvoice: false,\n });\n const [err, setErr] = useState<string | null>(null);\n const submit = () => {\n setErr(null);\n if (!form.name.trim()) return setErr('Name is required.');\n create.mutate(\n {\n engagementId,\n name: form.name.trim(),\n dueDate: form.dueDate ? new Date(form.dueDate).toISOString() : null,\n triggerAmount: form.triggerAmount ? Number(form.triggerAmount) : 0,\n triggersInvoice: form.triggersInvoice,\n },\n {\n onSuccess: () => {\n onDone();\n onClose();\n },\n onError: (e) => setErr(e instanceof Error ? e.message : 'Failed.'),\n }\n );\n };\n return (\n <Modal\n open\n onClose={onClose}\n title=\"Add milestone\"\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 ? 'Adding…' : 'Add'}\n </Button>\n </>\n }\n >\n <div className=\"space-y-3\">\n {err && <Banner tone=\"danger\">{err}</Banner>}\n <Field label=\"Name\" required>\n <TextInput\n value={form.name}\n onChange={(e) => setForm((f) => ({ ...f, name: e.target.value }))}\n placeholder=\"Phase 1 sign-off\"\n />\n </Field>\n <Field label=\"Due date\">\n <TextInput\n type=\"date\"\n value={form.dueDate}\n onChange={(e) => setForm((f) => ({ ...f, dueDate: e.target.value }))}\n />\n </Field>\n <Field\n label=\"Trigger amount\"\n hint=\"Amount billed when this milestone completes (if it triggers an invoice).\"\n >\n <TextInput\n type=\"number\"\n min=\"0\"\n value={form.triggerAmount}\n onChange={(e) => setForm((f) => ({ ...f, triggerAmount: e.target.value }))}\n />\n </Field>\n <label className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <input\n type=\"checkbox\"\n checked={form.triggersInvoice}\n onChange={(e) => setForm((f) => ({ ...f, triggersInvoice: e.target.checked }))}\n />\n Completing this milestone triggers an invoice\n </label>\n </div>\n </Modal>\n );\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"EngagementsPage.d.ts","sourceRoot":"","sources":["../../../src/proserviceworld/pages/EngagementsPage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAwEhC,eAAO,MAAM,eAAe,EAAE,EAsM7B,CAAC"}
1
+ {"version":3,"file":"EngagementsPage.d.ts","sourceRoot":"","sources":["../../../src/proserviceworld/pages/EngagementsPage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAwEhC,eAAO,MAAM,eAAe,EAAE,EAyN7B,CAAC"}