@burdenoff/microfe-proserviceworld 2026.706.3 → 2026.709.2

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 (119) 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 +3 -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/ProServiceWorldRoutes.js +95 -42
  19. package/dist/proserviceworld/ProServiceWorldRoutes.js.map +1 -1
  20. package/dist/proserviceworld/components/DiscussionThread.d.ts +12 -0
  21. package/dist/proserviceworld/components/DiscussionThread.d.ts.map +1 -0
  22. package/dist/proserviceworld/components/FeatureFlaggedPage.d.ts +8 -0
  23. package/dist/proserviceworld/components/FeatureFlaggedPage.d.ts.map +1 -0
  24. package/dist/proserviceworld/components/FeatureFlaggedPage.js +17 -0
  25. package/dist/proserviceworld/components/FeatureFlaggedPage.js.map +1 -0
  26. package/dist/proserviceworld/components/LoadMore.d.ts +12 -0
  27. package/dist/proserviceworld/components/LoadMore.d.ts.map +1 -0
  28. package/dist/proserviceworld/components/LoadMore.js +30 -0
  29. package/dist/proserviceworld/components/LoadMore.js.map +1 -0
  30. package/dist/proserviceworld/components/TagPicker.d.ts +11 -0
  31. package/dist/proserviceworld/components/TagPicker.d.ts.map +1 -0
  32. package/dist/proserviceworld/components/TagPicker.js +31 -0
  33. package/dist/proserviceworld/components/TagPicker.js.map +1 -0
  34. package/dist/proserviceworld/components/ui.d.ts +82 -0
  35. package/dist/proserviceworld/components/ui.d.ts.map +1 -0
  36. package/dist/proserviceworld/hooks/useAnalytics.d.ts +18 -0
  37. package/dist/proserviceworld/hooks/useAnalytics.d.ts.map +1 -0
  38. package/dist/proserviceworld/hooks/useAnalytics.js +21 -0
  39. package/dist/proserviceworld/hooks/useAnalytics.js.map +1 -0
  40. package/dist/proserviceworld/hooks/useEntityComments.d.ts +27 -0
  41. package/dist/proserviceworld/hooks/useEntityComments.d.ts.map +1 -0
  42. package/dist/proserviceworld/hooks/useFiles.d.ts +23 -0
  43. package/dist/proserviceworld/hooks/useFiles.d.ts.map +1 -0
  44. package/dist/proserviceworld/hooks/usePageViewAnalytics.d.ts +10 -0
  45. package/dist/proserviceworld/hooks/usePageViewAnalytics.d.ts.map +1 -0
  46. package/dist/proserviceworld/hooks/usePageViewAnalytics.js +24 -0
  47. package/dist/proserviceworld/hooks/usePageViewAnalytics.js.map +1 -0
  48. package/dist/proserviceworld/hooks/useProServiceWorldApi.d.ts +351 -0
  49. package/dist/proserviceworld/hooks/useProServiceWorldApi.d.ts.map +1 -0
  50. package/dist/proserviceworld/hooks/useProServiceWorldApi.js +47 -27
  51. package/dist/proserviceworld/hooks/useProServiceWorldApi.js.map +1 -1
  52. package/dist/proserviceworld/i18n/index.d.ts +13 -0
  53. package/dist/proserviceworld/i18n/index.d.ts.map +1 -0
  54. package/dist/proserviceworld/i18n/index.js +171 -0
  55. package/dist/proserviceworld/i18n/index.js.map +1 -0
  56. package/dist/proserviceworld/index.d.ts +6 -0
  57. package/dist/proserviceworld/index.d.ts.map +1 -0
  58. package/dist/proserviceworld/index.js +2 -0
  59. package/dist/proserviceworld/pages/AnalyticsPage.d.ts +4 -0
  60. package/dist/proserviceworld/pages/AnalyticsPage.d.ts.map +1 -0
  61. package/dist/proserviceworld/pages/ClientDetailPage.d.ts +4 -0
  62. package/dist/proserviceworld/pages/ClientDetailPage.d.ts.map +1 -0
  63. package/dist/proserviceworld/pages/ClientsPage.d.ts +9 -0
  64. package/dist/proserviceworld/pages/ClientsPage.d.ts.map +1 -0
  65. package/dist/proserviceworld/pages/ClientsPage.js +218 -155
  66. package/dist/proserviceworld/pages/ClientsPage.js.map +1 -1
  67. package/dist/proserviceworld/pages/CompliancePage.d.ts +4 -0
  68. package/dist/proserviceworld/pages/CompliancePage.d.ts.map +1 -0
  69. package/dist/proserviceworld/pages/ConflictsPage.d.ts +4 -0
  70. package/dist/proserviceworld/pages/ConflictsPage.d.ts.map +1 -0
  71. package/dist/proserviceworld/pages/DashboardPage.d.ts +4 -0
  72. package/dist/proserviceworld/pages/DashboardPage.d.ts.map +1 -0
  73. package/dist/proserviceworld/pages/DocumentsPage.d.ts +4 -0
  74. package/dist/proserviceworld/pages/DocumentsPage.d.ts.map +1 -0
  75. package/dist/proserviceworld/pages/EngagementDetailPage.d.ts +4 -0
  76. package/dist/proserviceworld/pages/EngagementDetailPage.d.ts.map +1 -0
  77. package/dist/proserviceworld/pages/EngagementDetailPage.js +162 -156
  78. package/dist/proserviceworld/pages/EngagementDetailPage.js.map +1 -1
  79. package/dist/proserviceworld/pages/EngagementsPage.d.ts +4 -0
  80. package/dist/proserviceworld/pages/EngagementsPage.d.ts.map +1 -0
  81. package/dist/proserviceworld/pages/EngagementsPage.js +201 -140
  82. package/dist/proserviceworld/pages/EngagementsPage.js.map +1 -1
  83. package/dist/proserviceworld/pages/InvoicesPage.d.ts +4 -0
  84. package/dist/proserviceworld/pages/InvoicesPage.d.ts.map +1 -0
  85. package/dist/proserviceworld/pages/MattersPage.d.ts +4 -0
  86. package/dist/proserviceworld/pages/MattersPage.d.ts.map +1 -0
  87. package/dist/proserviceworld/pages/MattersPage.js +212 -158
  88. package/dist/proserviceworld/pages/MattersPage.js.map +1 -1
  89. package/dist/proserviceworld/pages/PracticeAreasPage.d.ts +4 -0
  90. package/dist/proserviceworld/pages/PracticeAreasPage.d.ts.map +1 -0
  91. package/dist/proserviceworld/pages/TimePage.d.ts +4 -0
  92. package/dist/proserviceworld/pages/TimePage.d.ts.map +1 -0
  93. package/dist/proserviceworld/providers/ProServiceWorldProvider.d.ts +6 -0
  94. package/dist/proserviceworld/providers/ProServiceWorldProvider.d.ts.map +1 -0
  95. package/dist/proserviceworld/services/assistantApi.d.ts +74 -0
  96. package/dist/proserviceworld/services/assistantApi.d.ts.map +1 -0
  97. package/dist/proserviceworld/services/assistantApi.js +203 -0
  98. package/dist/proserviceworld/services/assistantApi.js.map +1 -0
  99. package/dist/proserviceworld/services/createSandboxAssistantTransport.d.ts +28 -0
  100. package/dist/proserviceworld/services/createSandboxAssistantTransport.d.ts.map +1 -0
  101. package/dist/proserviceworld/services/createSandboxAssistantTransport.js +120 -0
  102. package/dist/proserviceworld/services/createSandboxAssistantTransport.js.map +1 -0
  103. package/dist/proserviceworld/types/index.d.ts +57 -0
  104. package/dist/proserviceworld/types/index.d.ts.map +1 -0
  105. package/dist/proserviceworld/utils/cn.d.ts +4 -0
  106. package/dist/proserviceworld/utils/cn.d.ts.map +1 -0
  107. package/dist/proserviceworld/utils/native.d.ts +23 -0
  108. package/dist/proserviceworld/utils/native.d.ts.map +1 -0
  109. package/dist/proserviceworld/utils/native.js +14 -0
  110. package/dist/proserviceworld/utils/native.js.map +1 -0
  111. package/dist/proserviceworld/utils/nav.d.ts +6 -0
  112. package/dist/proserviceworld/utils/nav.d.ts.map +1 -0
  113. package/dist/proserviceworld/utils/navigation.d.ts +2 -0
  114. package/dist/proserviceworld/utils/navigation.d.ts.map +1 -0
  115. package/dist/proserviceworld/utils/pageContext.d.ts +12 -0
  116. package/dist/proserviceworld/utils/pageContext.d.ts.map +1 -0
  117. package/dist/proserviceworld/utils/pageContext.js +74 -0
  118. package/dist/proserviceworld/utils/pageContext.js.map +1 -0
  119. package/package.json +1 -1
@@ -1,12 +1,16 @@
1
- import { useClients as e, useCreateEngagement as t, useEngagements as n, usePracticeAreas as r } from "../hooks/useProServiceWorldApi.js";
2
- import { useNav as i } from "../utils/nav.js";
3
- import { Banner as a, Empty as o, ErrorState as s, Field as c, LoadingBlock as l, Modal as u, NativeSelect as d, PageHeader as f, SectionCard as p, StatusPill as m, TableWrap as h, Td as g, TextArea as _, TextInput as v, Th as y, enumOptions as b, fmtDate as x, fmtMoney as S, humanize as C } from "../components/ui.js";
4
- import { useState as w } from "react";
5
- import { Briefcase as T, ChevronRight as E, Plus as D, Search as O } from "lucide-react";
6
- import { Fragment as k, jsx as A, jsxs as j } from "react/jsx-runtime";
7
- import { Button as M } from "@burdenoff/fe-libs/ui";
1
+ import { useClients as e, useCreateEngagement as t, useEngagements as n, usePracticeAreas as r, useUpdateEngagement as i } from "../hooks/useProServiceWorldApi.js";
2
+ import { useNav as a } from "../utils/nav.js";
3
+ import { Banner as o, Empty as s, ErrorState as c, Field as l, LoadingBlock 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, fmtMoney as ee, humanize as C } from "../components/ui.js";
4
+ import { useAnalytics as w } from "../hooks/useAnalytics.js";
5
+ import { impactFeedback as T } from "../utils/native.js";
6
+ import { TagPicker as E } from "../components/TagPicker.js";
7
+ import { LoadMore as te } from "../components/LoadMore.js";
8
+ import { useMemo as ne, useState as D } from "react";
9
+ import { Briefcase as O, ChevronRight as k, Plus as A, Search as re } from "lucide-react";
10
+ import { Fragment as j, jsx as M, jsxs as N } from "react/jsx-runtime";
11
+ import { Button as P } from "@burdenoff/fe-libs/ui";
8
12
  //#region src/proserviceworld/pages/EngagementsPage.tsx
9
- var N = [
13
+ var F = [
10
14
  "PROPOSAL",
11
15
  "ACCEPTED",
12
16
  "IN_PROGRESS",
@@ -15,140 +19,193 @@ var N = [
15
19
  "INVOICED",
16
20
  "CLOSED",
17
21
  "CANCELLED"
18
- ], P = [
22
+ ], I = [
19
23
  "FIXED",
20
24
  "HOURLY",
21
25
  "RETAINER",
22
26
  "VALUE_BASED"
23
- ], F = (e) => e.split(/\s+/).filter(Boolean).slice(0, 2).map((e) => e[0]?.toUpperCase() ?? "").join("") || "?", I = ({ name: e }) => /* @__PURE__ */ A("span", {
27
+ ], L = (e) => e.split(/\s+/).filter(Boolean).slice(0, 2).map((e) => e[0]?.toUpperCase() ?? "").join("") || "?", ie = ({ name: e }) => /* @__PURE__ */ M("span", {
24
28
  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",
25
29
  "aria-hidden": !0,
26
- children: F(e)
27
- }), L = () => {
28
- let t = i(), [r, c] = w(""), [u, _] = w(""), [k, P] = w(""), [F, L] = w(!1), [z, B] = w(null), V = e({ pagination: { limit: 100 } }), { data: H, isLoading: U, error: W, refetch: G } = n({
29
- search: r.trim() || void 0,
30
- status: u || void 0,
31
- clientId: k || void 0
32
- });
33
- return /* @__PURE__ */ j("div", {
30
+ children: L(e)
31
+ }), R = 25, z = () => {
32
+ let t = a(), { emitIntent: r, emitFact: l } = w(), [d, v] = D(""), [j, I] = D(""), [L, z] = D(""), [V, H] = D(!1), [U, W] = D(null), [G, K] = D({
33
+ limit: R,
34
+ offset: 0
35
+ }), q = e({ pagination: { limit: 100 } }), J = i(), { data: Y, isLoading: X, error: Z, refetch: Q } = n({
36
+ search: d.trim() || void 0,
37
+ status: j || void 0,
38
+ clientId: L || void 0,
39
+ pagination: G
40
+ }), $ = ne(() => Y?.items ?? [], [Y]);
41
+ return /* @__PURE__ */ N("div", {
34
42
  className: "space-y-6",
35
43
  children: [
36
- /* @__PURE__ */ A(f, {
44
+ /* @__PURE__ */ M(p, {
37
45
  title: "Engagements",
38
46
  subtitle: "The commercial containers of contracted work — scope, fee arrangement, delivery lifecycle, and billing.",
39
- icon: /* @__PURE__ */ A(T, { className: "h-6 w-6" }),
40
- actions: /* @__PURE__ */ j(M, {
41
- onClick: () => L(!0),
42
- children: [/* @__PURE__ */ A(D, { className: "mr-1.5 h-4 w-4" }), "New engagement"]
47
+ icon: /* @__PURE__ */ M(O, { className: "h-6 w-6" }),
48
+ actions: /* @__PURE__ */ N(P, {
49
+ onClick: () => {
50
+ T("light"), r("psw.engagement.create_clicked"), H(!0);
51
+ },
52
+ children: [/* @__PURE__ */ M(A, { className: "mr-1.5 h-4 w-4" }), "New engagement"]
43
53
  })
44
54
  }),
45
- z && /* @__PURE__ */ A(a, {
55
+ U && /* @__PURE__ */ M(o, {
46
56
  tone: "success",
47
- onClose: () => B(null),
48
- children: z
57
+ onClose: () => W(null),
58
+ children: U
49
59
  }),
50
- /* @__PURE__ */ j("div", {
60
+ /* @__PURE__ */ N("div", {
51
61
  className: "flex flex-col gap-2 sm:flex-row sm:items-center",
52
62
  children: [
53
- /* @__PURE__ */ j("div", {
63
+ /* @__PURE__ */ N("div", {
54
64
  className: "relative flex-1",
55
- children: [/* @__PURE__ */ A(O, { className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-tertiary" }), /* @__PURE__ */ A(v, {
65
+ children: [/* @__PURE__ */ M(re, { className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-tertiary" }), /* @__PURE__ */ M(y, {
56
66
  placeholder: "Search engagements…",
57
- value: r,
58
- onChange: (e) => c(e.target.value),
67
+ value: d,
68
+ onChange: (e) => {
69
+ v(e.target.value), K({
70
+ limit: R,
71
+ offset: 0
72
+ });
73
+ },
74
+ onKeyDown: (e) => {
75
+ e.key === "Enter" && d.trim() && l("psw.search.performed", {
76
+ entityType: "engagement",
77
+ queryLength: d.trim().length
78
+ });
79
+ },
59
80
  className: "pl-9"
60
81
  })]
61
82
  }),
62
- /* @__PURE__ */ j(d, {
63
- value: u,
64
- onChange: (e) => _(e.target.value),
83
+ /* @__PURE__ */ N(f, {
84
+ value: j,
85
+ onChange: (e) => {
86
+ I(e.target.value), K({
87
+ limit: R,
88
+ offset: 0
89
+ });
90
+ },
65
91
  className: "sm:w-44",
66
- children: [/* @__PURE__ */ A("option", {
92
+ children: [/* @__PURE__ */ M("option", {
67
93
  value: "",
68
94
  children: "All statuses"
69
- }), b(N)]
95
+ }), x(F)]
70
96
  }),
71
- /* @__PURE__ */ j(d, {
72
- value: k,
73
- onChange: (e) => P(e.target.value),
97
+ /* @__PURE__ */ N(f, {
98
+ value: L,
99
+ onChange: (e) => {
100
+ z(e.target.value), K({
101
+ limit: R,
102
+ offset: 0
103
+ });
104
+ },
74
105
  className: "sm:w-48",
75
- children: [/* @__PURE__ */ A("option", {
106
+ children: [/* @__PURE__ */ M("option", {
76
107
  value: "",
77
108
  children: "All clients"
78
- }), V.data?.items.map((e) => /* @__PURE__ */ A("option", {
109
+ }), q.data?.items.map((e) => /* @__PURE__ */ M("option", {
79
110
  value: e.id,
80
111
  children: e.name
81
112
  }, e.id))]
82
113
  })
83
114
  ]
84
115
  }),
85
- U ? /* @__PURE__ */ A(l, {}) : W ? /* @__PURE__ */ A(s, {
86
- error: W,
87
- onRetry: () => void G()
88
- }) : !H || H.items.length === 0 ? /* @__PURE__ */ A(o, {
116
+ X ? /* @__PURE__ */ M(u, {}) : Z ? /* @__PURE__ */ M(c, {
117
+ error: Z,
118
+ onRetry: () => void Q()
119
+ }) : !Y || Y.items.length === 0 ? /* @__PURE__ */ M(s, {
89
120
  title: "No engagements yet",
90
121
  description: "Scope your first engagement against a client to begin delivery and billing.",
91
- icon: /* @__PURE__ */ A(T, { className: "h-8 w-8" }),
92
- action: /* @__PURE__ */ j(M, {
93
- onClick: () => L(!0),
94
- children: [/* @__PURE__ */ A(D, { className: "mr-1.5 h-4 w-4" }), "New engagement"]
122
+ icon: /* @__PURE__ */ M(O, { className: "h-8 w-8" }),
123
+ action: /* @__PURE__ */ N(P, {
124
+ onClick: () => H(!0),
125
+ children: [/* @__PURE__ */ M(A, { className: "mr-1.5 h-4 w-4" }), "New engagement"]
95
126
  })
96
- }) : /* @__PURE__ */ A(p, {
97
- title: `${H.totalCount} engagement${H.totalCount === 1 ? "" : "s"}`,
98
- children: /* @__PURE__ */ j(h, { children: [/* @__PURE__ */ A("thead", { children: /* @__PURE__ */ j("tr", { children: [
99
- /* @__PURE__ */ A(y, { children: "Engagement" }),
100
- /* @__PURE__ */ A(y, { children: "Client" }),
101
- /* @__PURE__ */ A(y, { children: "Fee" }),
102
- /* @__PURE__ */ A(y, { children: "Status" }),
103
- /* @__PURE__ */ A(y, { children: "Started" })
104
- ] }) }), /* @__PURE__ */ A("tbody", { children: H.items.map((e) => /* @__PURE__ */ j("tr", {
127
+ }) : /* @__PURE__ */ N(m, {
128
+ title: `${Y.totalCount} engagement${Y.totalCount === 1 ? "" : "s"}`,
129
+ children: [/* @__PURE__ */ N(g, { children: [/* @__PURE__ */ M("thead", { children: /* @__PURE__ */ N("tr", { children: [
130
+ /* @__PURE__ */ M(b, { children: "Engagement" }),
131
+ /* @__PURE__ */ M(b, { children: "Client" }),
132
+ /* @__PURE__ */ M(b, { children: "Fee" }),
133
+ /* @__PURE__ */ M(b, { children: "Status" }),
134
+ /* @__PURE__ */ M(b, { children: "Started" }),
135
+ /* @__PURE__ */ M(b, { children: "Tags" })
136
+ ] }) }), /* @__PURE__ */ M("tbody", { children: Y.items.map((e) => /* @__PURE__ */ N("tr", {
105
137
  className: "group cursor-pointer transition-colors hover:bg-bg-sunken/60",
106
138
  onClick: () => t(`engagements/${e.id}`),
107
139
  children: [
108
- /* @__PURE__ */ j(g, { children: [/* @__PURE__ */ j("div", {
140
+ /* @__PURE__ */ N(_, { children: [/* @__PURE__ */ N("div", {
109
141
  className: "flex items-center gap-1 font-medium text-text-primary transition-colors group-hover:text-accent",
110
- children: [/* @__PURE__ */ A("span", { children: e.name }), /* @__PURE__ */ A(E, { className: "h-3.5 w-3.5 shrink-0 text-text-tertiary opacity-0 transition-opacity group-hover:opacity-100" })]
111
- }), e.description ? /* @__PURE__ */ A("div", {
142
+ children: [/* @__PURE__ */ M("span", { children: e.name }), /* @__PURE__ */ M(k, { className: "h-3.5 w-3.5 shrink-0 text-text-tertiary opacity-0 transition-opacity group-hover:opacity-100" })]
143
+ }), e.description ? /* @__PURE__ */ M("div", {
112
144
  className: "mt-0.5 max-w-md truncate text-xs text-text-tertiary",
113
145
  children: e.description
114
146
  }) : null] }),
115
- /* @__PURE__ */ A(g, { children: /* @__PURE__ */ j("span", {
147
+ /* @__PURE__ */ M(_, { children: /* @__PURE__ */ N("span", {
116
148
  className: "inline-flex items-center gap-2.5",
117
- children: [/* @__PURE__ */ A(I, { name: e.client?.name ?? "—" }), /* @__PURE__ */ A("span", {
149
+ children: [/* @__PURE__ */ M(ie, { name: e.client?.name ?? "—" }), /* @__PURE__ */ M("span", {
118
150
  className: "text-text-secondary",
119
151
  children: e.client?.name ?? "—"
120
152
  })]
121
153
  }) }),
122
- /* @__PURE__ */ j(g, {
154
+ /* @__PURE__ */ N(_, {
123
155
  className: "whitespace-nowrap",
124
156
  children: [
125
- /* @__PURE__ */ A("span", {
157
+ /* @__PURE__ */ M("span", {
126
158
  className: "font-medium text-text-primary",
127
- children: S(e.feeAmount, e.currency)
159
+ children: ee(e.feeAmount, e.currency)
128
160
  }),
129
161
  " ",
130
- /* @__PURE__ */ j("span", {
162
+ /* @__PURE__ */ N("span", {
131
163
  className: "text-xs text-text-tertiary",
132
164
  children: ["/ ", C(e.feeArrangement)]
133
165
  })
134
166
  ]
135
167
  }),
136
- /* @__PURE__ */ A(g, { children: /* @__PURE__ */ A(m, { status: e.status }) }),
137
- /* @__PURE__ */ A(g, {
168
+ /* @__PURE__ */ M(_, { children: /* @__PURE__ */ M(h, { status: e.status }) }),
169
+ /* @__PURE__ */ M(_, {
138
170
  className: "whitespace-nowrap",
139
- children: x(e.startDate)
140
- })
171
+ children: S(e.startDate)
172
+ }),
173
+ /* @__PURE__ */ M(_, { children: /* @__PURE__ */ M("div", {
174
+ onClick: (e) => e.stopPropagation(),
175
+ role: "presentation",
176
+ children: /* @__PURE__ */ M(E, {
177
+ entityType: "PswEngagement",
178
+ entityId: e.id,
179
+ tags: e.tags ?? [],
180
+ onChange: async (t) => {
181
+ await J.mutateAsync({
182
+ id: e.id,
183
+ input: { tags: t }
184
+ }), Q();
185
+ },
186
+ maxTags: 5
187
+ })
188
+ }) })
141
189
  ]
142
- }, e.id)) })] })
190
+ }, e.id)) })] }), /* @__PURE__ */ M(te, {
191
+ hasMore: Y?.pageInfo?.hasMore ?? !1,
192
+ loading: X,
193
+ loadedCount: $.length,
194
+ totalCount: Y?.totalCount ?? $.length,
195
+ onLoadMore: () => K((e) => ({
196
+ limit: R,
197
+ offset: e.offset + R
198
+ }))
199
+ })]
143
200
  }),
144
- F && /* @__PURE__ */ A(R, {
145
- onClose: () => L(!1),
146
- onSaved: (e) => B(`${e} created.`)
201
+ V && /* @__PURE__ */ M(B, {
202
+ onClose: () => H(!1),
203
+ onSaved: (e) => W(`${e} created.`)
147
204
  })
148
205
  ]
149
206
  });
150
- }, R = ({ onClose: n, onSaved: i }) => {
151
- let o = t(), s = e({ pagination: { limit: 100 } }), l = r(), [f, p] = w({
207
+ }, B = ({ onClose: n, onSaved: i }) => {
208
+ let a = t(), { emitFact: s } = w(), c = e({ pagination: { limit: 100 } }), u = r(), [p, m] = D({
152
209
  clientId: "",
153
210
  practiceAreaId: "",
154
211
  name: "",
@@ -157,131 +214,135 @@ var N = [
157
214
  feeAmount: "",
158
215
  currency: "USD",
159
216
  startDate: ""
160
- }), [m, h] = w(null), g = (e) => (t) => p((n) => ({
217
+ }), [h, g] = D(null), _ = (e) => (t) => m((n) => ({
161
218
  ...n,
162
219
  [e]: t.target.value
163
220
  }));
164
- return /* @__PURE__ */ A(u, {
221
+ return /* @__PURE__ */ M(d, {
165
222
  open: !0,
166
223
  onClose: n,
167
224
  title: "New engagement",
168
- footer: /* @__PURE__ */ j(k, { children: [/* @__PURE__ */ A(M, {
225
+ footer: /* @__PURE__ */ N(j, { children: [/* @__PURE__ */ M(P, {
169
226
  variant: "outline",
170
227
  onClick: n,
171
- disabled: o.isPending,
228
+ disabled: a.isPending,
172
229
  children: "Cancel"
173
- }), /* @__PURE__ */ A(M, {
230
+ }), /* @__PURE__ */ M(P, {
174
231
  onClick: () => {
175
- if (h(null), !f.clientId) return h("Select a client.");
176
- if (!f.name.trim()) return h("Engagement name is required.");
177
- o.mutate({
178
- clientId: f.clientId,
179
- practiceAreaId: f.practiceAreaId || null,
180
- name: f.name.trim(),
181
- description: f.description.trim() || null,
182
- feeArrangement: f.feeArrangement,
183
- feeAmount: f.feeAmount ? Number(f.feeAmount) : 0,
184
- currency: f.currency || "USD",
185
- startDate: f.startDate ? new Date(f.startDate).toISOString() : null
232
+ if (g(null), !p.clientId) return g("Select a client.");
233
+ if (!p.name.trim()) return g("Engagement name is required.");
234
+ a.mutate({
235
+ clientId: p.clientId,
236
+ practiceAreaId: p.practiceAreaId || null,
237
+ name: p.name.trim(),
238
+ description: p.description.trim() || null,
239
+ feeArrangement: p.feeArrangement,
240
+ feeAmount: p.feeAmount ? Number(p.feeAmount) : 0,
241
+ currency: p.currency || "USD",
242
+ startDate: p.startDate ? new Date(p.startDate).toISOString() : null
186
243
  }, {
187
- onSuccess: () => {
188
- i(f.name.trim()), n();
244
+ onSuccess: (e) => {
245
+ let t = e.pswCreateEngagement;
246
+ s("psw.engagement.created", {
247
+ engagementId: t.id,
248
+ clientId: p.clientId
249
+ }), i(p.name.trim()), n();
189
250
  },
190
- onError: (e) => h(e instanceof Error ? e.message : "Failed.")
251
+ onError: (e) => g(e instanceof Error ? e.message : "Failed.")
191
252
  });
192
253
  },
193
- disabled: o.isPending,
194
- children: o.isPending ? "Creating…" : "Create engagement"
254
+ disabled: a.isPending,
255
+ children: a.isPending ? "Creating…" : "Create engagement"
195
256
  })] }),
196
- children: /* @__PURE__ */ j("div", {
257
+ children: /* @__PURE__ */ N("div", {
197
258
  className: "space-y-3",
198
259
  children: [
199
- m && /* @__PURE__ */ A(a, {
260
+ h && /* @__PURE__ */ M(o, {
200
261
  tone: "danger",
201
- children: m
262
+ children: h
202
263
  }),
203
- /* @__PURE__ */ A(c, {
264
+ /* @__PURE__ */ M(l, {
204
265
  label: "Client",
205
266
  required: !0,
206
- children: /* @__PURE__ */ j(d, {
207
- value: f.clientId,
208
- onChange: g("clientId"),
209
- children: [/* @__PURE__ */ A("option", {
267
+ children: /* @__PURE__ */ N(f, {
268
+ value: p.clientId,
269
+ onChange: _("clientId"),
270
+ children: [/* @__PURE__ */ M("option", {
210
271
  value: "",
211
272
  children: "Select a client…"
212
- }), s.data?.items.map((e) => /* @__PURE__ */ A("option", {
273
+ }), c.data?.items.map((e) => /* @__PURE__ */ M("option", {
213
274
  value: e.id,
214
275
  children: e.name
215
276
  }, e.id))]
216
277
  })
217
278
  }),
218
- /* @__PURE__ */ A(c, {
279
+ /* @__PURE__ */ M(l, {
219
280
  label: "Name",
220
281
  required: !0,
221
- children: /* @__PURE__ */ A(v, {
222
- value: f.name,
223
- onChange: g("name"),
282
+ children: /* @__PURE__ */ M(y, {
283
+ value: p.name,
284
+ onChange: _("name"),
224
285
  placeholder: "FY26 Statutory Audit"
225
286
  })
226
287
  }),
227
- /* @__PURE__ */ A(c, {
288
+ /* @__PURE__ */ M(l, {
228
289
  label: "Practice area",
229
- children: /* @__PURE__ */ j(d, {
230
- value: f.practiceAreaId,
231
- onChange: g("practiceAreaId"),
232
- children: [/* @__PURE__ */ A("option", {
290
+ children: /* @__PURE__ */ N(f, {
291
+ value: p.practiceAreaId,
292
+ onChange: _("practiceAreaId"),
293
+ children: [/* @__PURE__ */ M("option", {
233
294
  value: "",
234
295
  children: "Unassigned"
235
- }), l.data?.map((e) => /* @__PURE__ */ A("option", {
296
+ }), u.data?.map((e) => /* @__PURE__ */ M("option", {
236
297
  value: e.id,
237
298
  children: e.name
238
299
  }, e.id))]
239
300
  })
240
301
  }),
241
- /* @__PURE__ */ j("div", {
302
+ /* @__PURE__ */ N("div", {
242
303
  className: "grid grid-cols-3 gap-3",
243
304
  children: [
244
- /* @__PURE__ */ A(c, {
305
+ /* @__PURE__ */ M(l, {
245
306
  label: "Fee type",
246
- children: /* @__PURE__ */ A(d, {
247
- value: f.feeArrangement,
248
- onChange: g("feeArrangement"),
249
- children: b(P)
307
+ children: /* @__PURE__ */ M(f, {
308
+ value: p.feeArrangement,
309
+ onChange: _("feeArrangement"),
310
+ children: x(I)
250
311
  })
251
312
  }),
252
- /* @__PURE__ */ A(c, {
313
+ /* @__PURE__ */ M(l, {
253
314
  label: "Fee amount",
254
- children: /* @__PURE__ */ A(v, {
315
+ children: /* @__PURE__ */ M(y, {
255
316
  type: "number",
256
317
  min: "0",
257
- value: f.feeAmount,
258
- onChange: g("feeAmount"),
318
+ value: p.feeAmount,
319
+ onChange: _("feeAmount"),
259
320
  placeholder: "50000"
260
321
  })
261
322
  }),
262
- /* @__PURE__ */ A(c, {
323
+ /* @__PURE__ */ M(l, {
263
324
  label: "Currency",
264
- children: /* @__PURE__ */ A(v, {
265
- value: f.currency,
266
- onChange: g("currency"),
325
+ children: /* @__PURE__ */ M(y, {
326
+ value: p.currency,
327
+ onChange: _("currency"),
267
328
  maxLength: 3
268
329
  })
269
330
  })
270
331
  ]
271
332
  }),
272
- /* @__PURE__ */ A(c, {
333
+ /* @__PURE__ */ M(l, {
273
334
  label: "Start date",
274
- children: /* @__PURE__ */ A(v, {
335
+ children: /* @__PURE__ */ M(y, {
275
336
  type: "date",
276
- value: f.startDate,
277
- onChange: g("startDate")
337
+ value: p.startDate,
338
+ onChange: _("startDate")
278
339
  })
279
340
  }),
280
- /* @__PURE__ */ A(c, {
341
+ /* @__PURE__ */ M(l, {
281
342
  label: "Description",
282
- children: /* @__PURE__ */ A(_, {
283
- value: f.description,
284
- onChange: g("description")
343
+ children: /* @__PURE__ */ M(v, {
344
+ value: p.description,
345
+ onChange: _("description")
285
346
  })
286
347
  })
287
348
  ]
@@ -289,6 +350,6 @@ var N = [
289
350
  });
290
351
  };
291
352
  //#endregion
292
- export { L as EngagementsPage };
353
+ export { z as EngagementsPage };
293
354
 
294
355
  //# sourceMappingURL=EngagementsPage.js.map
@@ -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 { 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';\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=\"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 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 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) => {\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=\"\">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=\"\">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 <Th>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 ?? '—'} />\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=\"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;AA+DhC,eAAO,MAAM,WAAW,EAAE,EAgOzB,CAAC"}