@burdenoff/microfe-proserviceworld 2026.1026.2 → 2026.1031.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 (105) hide show
  1. package/dist/proserviceworld/components/CredentialDirectory.js +44 -43
  2. package/dist/proserviceworld/components/CredentialDirectory.js.map +1 -1
  3. package/dist/proserviceworld/components/CredentialReminderPanel.js +5 -4
  4. package/dist/proserviceworld/components/CredentialReminderPanel.js.map +1 -1
  5. package/dist/proserviceworld/components/ui.d.ts +7 -3
  6. package/dist/proserviceworld/components/ui.d.ts.map +1 -1
  7. package/dist/proserviceworld/components/ui.js +135 -121
  8. package/dist/proserviceworld/components/ui.js.map +1 -1
  9. package/dist/proserviceworld/hooks/useProServiceWorldApi.d.ts +28 -0
  10. package/dist/proserviceworld/hooks/useProServiceWorldApi.d.ts.map +1 -1
  11. package/dist/proserviceworld/hooks/useProServiceWorldApi.js +95 -73
  12. package/dist/proserviceworld/hooks/useProServiceWorldApi.js.map +1 -1
  13. package/dist/proserviceworld/hooks/useTr.d.ts +49 -8
  14. package/dist/proserviceworld/hooks/useTr.d.ts.map +1 -1
  15. package/dist/proserviceworld/hooks/useTr.js +45 -21
  16. package/dist/proserviceworld/hooks/useTr.js.map +1 -1
  17. package/dist/proserviceworld/i18n/catalog/analytics.d.ts +5 -0
  18. package/dist/proserviceworld/i18n/catalog/analytics.d.ts.map +1 -0
  19. package/dist/proserviceworld/i18n/catalog/analytics.js +271 -0
  20. package/dist/proserviceworld/i18n/catalog/analytics.js.map +1 -0
  21. package/dist/proserviceworld/i18n/catalog/common.d.ts +9 -0
  22. package/dist/proserviceworld/i18n/catalog/common.d.ts.map +1 -0
  23. package/dist/proserviceworld/i18n/catalog/common.js +163 -0
  24. package/dist/proserviceworld/i18n/catalog/common.js.map +1 -0
  25. package/dist/proserviceworld/i18n/catalog/compliance.d.ts +5 -0
  26. package/dist/proserviceworld/i18n/catalog/compliance.d.ts.map +1 -0
  27. package/dist/proserviceworld/i18n/catalog/compliance.js +157 -0
  28. package/dist/proserviceworld/i18n/catalog/compliance.js.map +1 -0
  29. package/dist/proserviceworld/i18n/catalog/conflicts.d.ts +5 -0
  30. package/dist/proserviceworld/i18n/catalog/conflicts.d.ts.map +1 -0
  31. package/dist/proserviceworld/i18n/catalog/conflicts.js +145 -0
  32. package/dist/proserviceworld/i18n/catalog/conflicts.js.map +1 -0
  33. package/dist/proserviceworld/i18n/catalog/documents.d.ts +5 -0
  34. package/dist/proserviceworld/i18n/catalog/documents.d.ts.map +1 -0
  35. package/dist/proserviceworld/i18n/catalog/documents.js +157 -0
  36. package/dist/proserviceworld/i18n/catalog/documents.js.map +1 -0
  37. package/dist/proserviceworld/i18n/catalog/enums.d.ts +10 -0
  38. package/dist/proserviceworld/i18n/catalog/enums.d.ts.map +1 -0
  39. package/dist/proserviceworld/i18n/catalog/enums.js +481 -0
  40. package/dist/proserviceworld/i18n/catalog/enums.js.map +1 -0
  41. package/dist/proserviceworld/i18n/catalog/index.d.ts +9 -0
  42. package/dist/proserviceworld/i18n/catalog/index.d.ts.map +1 -0
  43. package/dist/proserviceworld/i18n/catalog/index.js +25 -0
  44. package/dist/proserviceworld/i18n/catalog/index.js.map +1 -0
  45. package/dist/proserviceworld/i18n/catalog/invoices.d.ts +5 -0
  46. package/dist/proserviceworld/i18n/catalog/invoices.d.ts.map +1 -0
  47. package/dist/proserviceworld/i18n/catalog/invoices.js +247 -0
  48. package/dist/proserviceworld/i18n/catalog/invoices.js.map +1 -0
  49. package/dist/proserviceworld/i18n/catalog/practiceAreas.d.ts +5 -0
  50. package/dist/proserviceworld/i18n/catalog/practiceAreas.d.ts.map +1 -0
  51. package/dist/proserviceworld/i18n/catalog/practiceAreas.js +97 -0
  52. package/dist/proserviceworld/i18n/catalog/practiceAreas.js.map +1 -0
  53. package/dist/proserviceworld/i18n/catalog/time.d.ts +5 -0
  54. package/dist/proserviceworld/i18n/catalog/time.d.ts.map +1 -0
  55. package/dist/proserviceworld/i18n/catalog/time.js +301 -0
  56. package/dist/proserviceworld/i18n/catalog/time.js.map +1 -0
  57. package/dist/proserviceworld/i18n/index.d.ts +10 -9
  58. package/dist/proserviceworld/i18n/index.d.ts.map +1 -1
  59. package/dist/proserviceworld/i18n/index.js +16 -12
  60. package/dist/proserviceworld/i18n/index.js.map +1 -1
  61. package/dist/proserviceworld/i18n/types.d.ts +13 -0
  62. package/dist/proserviceworld/i18n/types.d.ts.map +1 -0
  63. package/dist/proserviceworld/i18n/types.js +18 -0
  64. package/dist/proserviceworld/i18n/types.js.map +1 -0
  65. package/dist/proserviceworld/pages/AnalyticsPage.d.ts.map +1 -1
  66. package/dist/proserviceworld/pages/AnalyticsPage.js +236 -152
  67. package/dist/proserviceworld/pages/AnalyticsPage.js.map +1 -1
  68. package/dist/proserviceworld/pages/ClientDetailPage.js +99 -98
  69. package/dist/proserviceworld/pages/ClientDetailPage.js.map +1 -1
  70. package/dist/proserviceworld/pages/ClientsPage.d.ts.map +1 -1
  71. package/dist/proserviceworld/pages/ClientsPage.js +181 -181
  72. package/dist/proserviceworld/pages/ClientsPage.js.map +1 -1
  73. package/dist/proserviceworld/pages/CompliancePage.d.ts.map +1 -1
  74. package/dist/proserviceworld/pages/CompliancePage.js +210 -209
  75. package/dist/proserviceworld/pages/CompliancePage.js.map +1 -1
  76. package/dist/proserviceworld/pages/ConflictsPage.d.ts.map +1 -1
  77. package/dist/proserviceworld/pages/ConflictsPage.js +139 -138
  78. package/dist/proserviceworld/pages/ConflictsPage.js.map +1 -1
  79. package/dist/proserviceworld/pages/DocumentsPage.d.ts.map +1 -1
  80. package/dist/proserviceworld/pages/DocumentsPage.js +150 -149
  81. package/dist/proserviceworld/pages/DocumentsPage.js.map +1 -1
  82. package/dist/proserviceworld/pages/EngagementDetailPage.js +105 -104
  83. package/dist/proserviceworld/pages/EngagementDetailPage.js.map +1 -1
  84. package/dist/proserviceworld/pages/EngagementsPage.d.ts.map +1 -1
  85. package/dist/proserviceworld/pages/EngagementsPage.js +137 -137
  86. package/dist/proserviceworld/pages/EngagementsPage.js.map +1 -1
  87. package/dist/proserviceworld/pages/InvoicesPage.d.ts.map +1 -1
  88. package/dist/proserviceworld/pages/InvoicesPage.js +275 -258
  89. package/dist/proserviceworld/pages/InvoicesPage.js.map +1 -1
  90. package/dist/proserviceworld/pages/MattersPage.d.ts.map +1 -1
  91. package/dist/proserviceworld/pages/MattersPage.js +166 -166
  92. package/dist/proserviceworld/pages/MattersPage.js.map +1 -1
  93. package/dist/proserviceworld/pages/PracticeAreasPage.d.ts.map +1 -1
  94. package/dist/proserviceworld/pages/PracticeAreasPage.js +100 -99
  95. package/dist/proserviceworld/pages/PracticeAreasPage.js.map +1 -1
  96. package/dist/proserviceworld/pages/PractitionerCredentialsPage.js +30 -29
  97. package/dist/proserviceworld/pages/PractitionerCredentialsPage.js.map +1 -1
  98. package/dist/proserviceworld/pages/TimePage.d.ts.map +1 -1
  99. package/dist/proserviceworld/pages/TimePage.js +343 -350
  100. package/dist/proserviceworld/pages/TimePage.js.map +1 -1
  101. package/dist/proserviceworld/utils/humanize.d.ts +3 -0
  102. package/dist/proserviceworld/utils/humanize.d.ts.map +1 -0
  103. package/dist/proserviceworld/utils/humanize.js +6 -0
  104. package/dist/proserviceworld/utils/humanize.js.map +1 -0
  105. package/package.json +1 -1
@@ -1,4 +1,5 @@
1
- import { Empty as e, ErrorState as t, LoadingBlock as n, SectionCard as r, humanize as i } from "./ui.js";
1
+ import { humanize as e } from "../utils/humanize.js";
2
+ import { Empty as t, ErrorState as n, LoadingBlock as r, SectionCard as i } from "./ui.js";
2
3
  import { useCredentialDirectory as a, useEducationCredits as o } from "../hooks/usePractitionerCredentials.js";
3
4
  import { credentialSourceLink as s } from "../utils/credentialSourceLink.js";
4
5
  import { useState as c } from "react";
@@ -7,12 +8,12 @@ import { Button as d } from "@burdenoff/fe-libs/ui";
7
8
  //#region src/proserviceworld/components/CredentialDirectory.tsx
8
9
  function f() {
9
10
  let [f, p] = c(0), [m, h] = c(), [g, _] = c(0), v = a(f), y = o(m, g), b = v.data;
10
- if (v.isLoading) return /* @__PURE__ */ l(n, {});
11
- if (v.error) return /* @__PURE__ */ l(t, {
11
+ if (v.isLoading) return /* @__PURE__ */ l(r, {});
12
+ if (v.error) return /* @__PURE__ */ l(n, {
12
13
  error: v.error,
13
14
  onRetry: () => void v.refetch()
14
15
  });
15
- if (!b) return /* @__PURE__ */ l(e, {
16
+ if (!b) return /* @__PURE__ */ l(t, {
16
17
  title: "Choose a workspace",
17
18
  description: "Sign in to read firm records."
18
19
  });
@@ -20,7 +21,7 @@ function f() {
20
21
  return /* @__PURE__ */ u("div", {
21
22
  className: "space-y-4",
22
23
  children: [
23
- /* @__PURE__ */ l(r, {
24
+ /* @__PURE__ */ l(i, {
24
25
  title: "Practitioners and issuing bodies",
25
26
  children: /* @__PURE__ */ u("div", {
26
27
  className: "grid gap-4 sm:grid-cols-2",
@@ -70,74 +71,74 @@ function f() {
70
71
  }, e.id))] })]
71
72
  })
72
73
  }),
73
- /* @__PURE__ */ u(r, {
74
+ /* @__PURE__ */ u(i, {
74
75
  title: `Sourced obligations (${b.pswComplianceObligations.totalCount})`,
75
76
  children: [b.pswComplianceObligations.items.length === 0 && /* @__PURE__ */ l("p", { children: "No sourced obligations on this page." }), /* @__PURE__ */ l("div", {
76
77
  className: "space-y-3",
77
- children: b.pswComplianceObligations.items.map((e) => /* @__PURE__ */ u("article", {
78
+ children: b.pswComplianceObligations.items.map((t) => /* @__PURE__ */ u("article", {
78
79
  className: "min-w-0 rounded border border-border p-3",
79
80
  children: [
80
81
  /* @__PURE__ */ l("h3", {
81
82
  className: "font-semibold",
82
- children: e.title
83
+ children: t.title
83
84
  }),
84
85
  /* @__PURE__ */ u("p", {
85
86
  className: "break-all text-xs",
86
87
  children: [
87
88
  "ID: ",
88
- e.id,
89
+ t.id,
89
90
  " · Revision ",
90
- e.revision
91
+ t.revision
91
92
  ]
92
93
  }),
93
- /* @__PURE__ */ l("p", { children: e.category === null ? "Category unknown; completion cannot be inferred." : `${e.acceptedUnits} accepted / ${e.requiredUnits} required ${e.unitLabel} · ${e.category}` }),
94
+ /* @__PURE__ */ l("p", { children: t.category === null ? "Category unknown; completion cannot be inferred." : `${t.acceptedUnits} accepted / ${t.requiredUnits} required ${t.unitLabel} · ${t.category}` }),
94
95
  /* @__PURE__ */ l("p", {
95
96
  className: "break-words",
96
- children: e.policyDescription
97
+ children: t.policyDescription
97
98
  }),
98
- s(e.policySourceUrl) && /* @__PURE__ */ u("a", {
99
- href: s(e.policySourceUrl) ?? void 0,
99
+ s(t.policySourceUrl) && /* @__PURE__ */ u("a", {
100
+ href: s(t.policySourceUrl) ?? void 0,
100
101
  target: "_blank",
101
102
  rel: "noopener noreferrer",
102
103
  className: "block underline",
103
104
  children: [
104
105
  "Policy source reference:",
105
106
  " ",
106
- new URL(s(e.policySourceUrl) ?? e.policySourceUrl).hostname
107
+ new URL(s(t.policySourceUrl) ?? t.policySourceUrl).hostname
107
108
  ]
108
109
  }),
109
110
  /* @__PURE__ */ u("p", {
110
111
  className: "text-sm",
111
112
  children: [
112
113
  "Period ",
113
- e.periodStart,
114
+ t.periodStart,
114
115
  " to ",
115
- e.periodEnd,
116
+ t.periodEnd,
116
117
  " (exclusive). Due ",
117
- e.dueAt,
118
+ t.dueAt,
118
119
  ". Source zone ",
119
- e.sourceTimezone,
120
+ t.sourceTimezone,
120
121
  "."
121
122
  ]
122
123
  }),
123
124
  /* @__PURE__ */ u("p", {
124
125
  className: "text-sm",
125
126
  children: [
126
- i(e.state),
127
+ e(t.state),
127
128
  " · Reminder: ",
128
- i(e.reminderState)
129
+ e(t.reminderState)
129
130
  ]
130
131
  }),
131
132
  /* @__PURE__ */ l(d, {
132
133
  variant: "outline",
133
134
  size: "sm",
134
135
  onClick: () => {
135
- h(e.id), _(0);
136
+ h(t.id), _(0);
136
137
  },
137
138
  children: "Education credits"
138
139
  })
139
140
  ]
140
- }, e.id))
141
+ }, t.id))
141
142
  })]
142
143
  }),
143
144
  /* @__PURE__ */ u("div", {
@@ -162,73 +163,73 @@ function f() {
162
163
  })
163
164
  ]
164
165
  }),
165
- m && /* @__PURE__ */ u(r, {
166
+ m && /* @__PURE__ */ u(i, {
166
167
  title: "Education credit history",
167
- children: [y.isLoading ? /* @__PURE__ */ l(n, {}) : y.error ? /* @__PURE__ */ l(t, {
168
+ children: [y.isLoading ? /* @__PURE__ */ l(r, {}) : y.error ? /* @__PURE__ */ l(n, {
168
169
  error: y.error,
169
170
  onRetry: () => void y.refetch()
170
171
  }) : /* @__PURE__ */ u("div", {
171
172
  className: "space-y-3",
172
- children: [y.data?.items.length === 0 && /* @__PURE__ */ l("p", { children: "No education credits recorded." }), y.data?.items.map((e) => /* @__PURE__ */ u("article", {
173
+ children: [y.data?.items.length === 0 && /* @__PURE__ */ l("p", { children: "No education credits recorded." }), y.data?.items.map((t) => /* @__PURE__ */ u("article", {
173
174
  className: "min-w-0 rounded border border-border p-3",
174
175
  children: [
175
176
  /* @__PURE__ */ u("h3", {
176
177
  className: "font-semibold",
177
178
  children: [
178
- e.provider,
179
+ t.provider,
179
180
  " · ",
180
- e.amount,
181
+ t.amount,
181
182
  " ",
182
- e.unitLabel
183
+ t.unitLabel
183
184
  ]
184
185
  }),
185
186
  /* @__PURE__ */ u("p", { children: [
186
- e.category ?? "Category unknown",
187
+ t.category ?? "Category unknown",
187
188
  " · ",
188
- i(e.reviewState)
189
+ e(t.reviewState)
189
190
  ] }),
190
191
  /* @__PURE__ */ u("p", {
191
192
  className: "break-all text-xs",
192
193
  children: [
193
194
  "ID: ",
194
- e.id,
195
+ t.id,
195
196
  " · Revision ",
196
- e.revision,
197
+ t.revision,
197
198
  " · Policy revision",
198
199
  " ",
199
- e.obligationRevision
200
+ t.obligationRevision
200
201
  ]
201
202
  }),
202
203
  /* @__PURE__ */ u("p", {
203
204
  className: "break-words",
204
205
  children: [
205
206
  "Activity: ",
206
- e.activityReference ?? "Unknown",
207
+ t.activityReference ?? "Unknown",
207
208
  " · Completed",
208
209
  " ",
209
- e.completedAt
210
+ t.completedAt
210
211
  ]
211
212
  }),
212
- e.duplicateReviewRequired && /* @__PURE__ */ l("p", { children: "Possible duplicate: review required before counting." }),
213
- e.predecessorId && /* @__PURE__ */ u("p", {
213
+ t.duplicateReviewRequired && /* @__PURE__ */ l("p", { children: "Possible duplicate: review required before counting." }),
214
+ t.predecessorId && /* @__PURE__ */ u("p", {
214
215
  className: "break-all text-xs",
215
- children: ["Corrects credit ", e.predecessorId]
216
+ children: ["Corrects credit ", t.predecessorId]
216
217
  }),
217
218
  /* @__PURE__ */ l("p", {
218
219
  className: "break-words",
219
- children: e.reviewNote
220
+ children: t.reviewNote
220
221
  }),
221
222
  /* @__PURE__ */ u("p", {
222
223
  className: "break-all text-xs",
223
224
  children: [
224
225
  "Evidence version ",
225
- e.evidenceVersionId,
226
+ t.evidenceVersionId,
226
227
  " · SHA-256 ",
227
- e.evidenceSha256
228
+ t.evidenceSha256
228
229
  ]
229
230
  })
230
231
  ]
231
- }, e.id))]
232
+ }, t.id))]
232
233
  }), /* @__PURE__ */ u("div", {
233
234
  className: "mt-4 flex flex-wrap justify-between gap-2",
234
235
  children: [/* @__PURE__ */ l(d, {
@@ -1 +1 @@
1
- {"version":3,"file":"CredentialDirectory.js","names":[],"sources":["../../../src/proserviceworld/components/CredentialDirectory.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport { useCredentialDirectory, useEducationCredits } from '../hooks/usePractitionerCredentials';\nimport { credentialSourceLink } from '../utils/credentialSourceLink';\nimport { Empty, ErrorState, LoadingBlock, SectionCard, humanize } from './ui';\n\n/** Parent keys this view by the complete actor/workspace/tenant tuple. */\nexport function CredentialDirectory() {\n const [offset, setOffset] = useState(0);\n const [obligationId, setObligationId] = useState<string>();\n const [creditOffset, setCreditOffset] = useState(0);\n const query = useCredentialDirectory(offset);\n const credits = useEducationCredits(obligationId, creditOffset);\n const data = query.data;\n if (query.isLoading) return <LoadingBlock />;\n if (query.error) return <ErrorState error={query.error} onRetry={() => void query.refetch()} />;\n if (!data)\n return <Empty title=\"Choose a workspace\" description=\"Sign in to read firm records.\" />;\n const more =\n data.pswPractitioners.hasMore ||\n data.pswIssuingBodies.hasMore ||\n data.pswComplianceObligations.hasMore;\n return (\n <div className=\"space-y-4\">\n <SectionCard title=\"Practitioners and issuing bodies\">\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <div>\n <h3 className=\"font-medium\">Practitioners ({data.pswPractitioners.totalCount})</h3>\n {data.pswPractitioners.items.map((record) => (\n <p key={record.id} className=\"my-2 break-all\">\n {record.displayName}\n <span className=\"block text-xs\">\n ID: {record.id} · Revision {record.revision}\n </span>\n </p>\n ))}\n </div>\n <div>\n <h3 className=\"font-medium\">Issuing bodies ({data.pswIssuingBodies.totalCount})</h3>\n {data.pswIssuingBodies.items.map((record) => (\n <p key={record.id} className=\"my-2 break-all\">\n {record.displayName} · {record.jurisdiction}\n <span className=\"block text-xs\">\n {record.credentialCategory ?? 'Category unknown'} · ID: {record.id} · Revision{' '}\n {record.revision}\n </span>\n </p>\n ))}\n </div>\n </div>\n </SectionCard>\n <SectionCard title={`Sourced obligations (${data.pswComplianceObligations.totalCount})`}>\n {data.pswComplianceObligations.items.length === 0 && (\n <p>No sourced obligations on this page.</p>\n )}\n <div className=\"space-y-3\">\n {data.pswComplianceObligations.items.map((record) => (\n <article key={record.id} className=\"min-w-0 rounded border border-border p-3\">\n <h3 className=\"font-semibold\">{record.title}</h3>\n <p className=\"break-all text-xs\">\n ID: {record.id} · Revision {record.revision}\n </p>\n <p>\n {record.category === null\n ? 'Category unknown; completion cannot be inferred.'\n : `${record.acceptedUnits} accepted / ${record.requiredUnits} required ${record.unitLabel} · ${record.category}`}\n </p>\n <p className=\"break-words\">{record.policyDescription}</p>\n {credentialSourceLink(record.policySourceUrl) && (\n <a\n href={credentialSourceLink(record.policySourceUrl) ?? undefined}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"block underline\"\n >\n Policy source reference:{' '}\n {\n new URL(credentialSourceLink(record.policySourceUrl) ?? record.policySourceUrl)\n .hostname\n }\n </a>\n )}\n <p className=\"text-sm\">\n Period {record.periodStart} to {record.periodEnd} (exclusive). Due {record.dueAt}.\n Source zone {record.sourceTimezone}.\n </p>\n <p className=\"text-sm\">\n {humanize(record.state)} · Reminder: {humanize(record.reminderState)}\n </p>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => {\n setObligationId(record.id);\n setCreditOffset(0);\n }}\n >\n Education credits\n </Button>\n </article>\n ))}\n </div>\n </SectionCard>\n <div className=\"flex flex-wrap items-center justify-between gap-2\">\n <Button\n variant=\"outline\"\n disabled={!offset || query.isFetching}\n onClick={() => {\n setOffset(Math.max(0, offset - 25));\n setObligationId(undefined);\n }}\n >\n Previous records\n </Button>\n <span>Page {Math.floor(offset / 25) + 1}</span>\n <Button\n variant=\"outline\"\n disabled={!more || query.isFetching}\n onClick={() => {\n setOffset(offset + 25);\n setObligationId(undefined);\n }}\n >\n Next records\n </Button>\n </div>\n {obligationId && (\n <SectionCard title=\"Education credit history\">\n {credits.isLoading ? (\n <LoadingBlock />\n ) : credits.error ? (\n <ErrorState error={credits.error} onRetry={() => void credits.refetch()} />\n ) : (\n <div className=\"space-y-3\">\n {credits.data?.items.length === 0 && <p>No education credits recorded.</p>}\n {credits.data?.items.map((credit) => (\n <article key={credit.id} className=\"min-w-0 rounded border border-border p-3\">\n <h3 className=\"font-semibold\">\n {credit.provider} · {credit.amount} {credit.unitLabel}\n </h3>\n <p>\n {credit.category ?? 'Category unknown'} · {humanize(credit.reviewState)}\n </p>\n <p className=\"break-all text-xs\">\n ID: {credit.id} · Revision {credit.revision} · Policy revision{' '}\n {credit.obligationRevision}\n </p>\n <p className=\"break-words\">\n Activity: {credit.activityReference ?? 'Unknown'} · Completed{' '}\n {credit.completedAt}\n </p>\n {credit.duplicateReviewRequired && (\n <p>Possible duplicate: review required before counting.</p>\n )}\n {credit.predecessorId && (\n <p className=\"break-all text-xs\">Corrects credit {credit.predecessorId}</p>\n )}\n <p className=\"break-words\">{credit.reviewNote}</p>\n <p className=\"break-all text-xs\">\n Evidence version {credit.evidenceVersionId} · SHA-256 {credit.evidenceSha256}\n </p>\n </article>\n ))}\n </div>\n )}\n <div className=\"mt-4 flex flex-wrap justify-between gap-2\">\n <Button\n variant=\"outline\"\n disabled={!creditOffset || credits.isFetching}\n onClick={() => setCreditOffset(Math.max(0, creditOffset - 25))}\n >\n Previous credits\n </Button>\n <Button\n variant=\"outline\"\n disabled={!credits.data?.hasMore || credits.isFetching}\n onClick={() => setCreditOffset(creditOffset + 25)}\n >\n Next credits\n </Button>\n </div>\n </SectionCard>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"CredentialDirectory.js","names":[],"sources":["../../../src/proserviceworld/components/CredentialDirectory.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport { useCredentialDirectory, useEducationCredits } from '../hooks/usePractitionerCredentials';\nimport { credentialSourceLink } from '../utils/credentialSourceLink';\nimport { Empty, ErrorState, LoadingBlock, SectionCard, humanize } from './ui';\n\n/** Parent keys this view by the complete actor/workspace/tenant tuple. */\nexport function CredentialDirectory() {\n const [offset, setOffset] = useState(0);\n const [obligationId, setObligationId] = useState<string>();\n const [creditOffset, setCreditOffset] = useState(0);\n const query = useCredentialDirectory(offset);\n const credits = useEducationCredits(obligationId, creditOffset);\n const data = query.data;\n if (query.isLoading) return <LoadingBlock />;\n if (query.error) return <ErrorState error={query.error} onRetry={() => void query.refetch()} />;\n if (!data)\n return <Empty title=\"Choose a workspace\" description=\"Sign in to read firm records.\" />;\n const more =\n data.pswPractitioners.hasMore ||\n data.pswIssuingBodies.hasMore ||\n data.pswComplianceObligations.hasMore;\n return (\n <div className=\"space-y-4\">\n <SectionCard title=\"Practitioners and issuing bodies\">\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <div>\n <h3 className=\"font-medium\">Practitioners ({data.pswPractitioners.totalCount})</h3>\n {data.pswPractitioners.items.map((record) => (\n <p key={record.id} className=\"my-2 break-all\">\n {record.displayName}\n <span className=\"block text-xs\">\n ID: {record.id} · Revision {record.revision}\n </span>\n </p>\n ))}\n </div>\n <div>\n <h3 className=\"font-medium\">Issuing bodies ({data.pswIssuingBodies.totalCount})</h3>\n {data.pswIssuingBodies.items.map((record) => (\n <p key={record.id} className=\"my-2 break-all\">\n {record.displayName} · {record.jurisdiction}\n <span className=\"block text-xs\">\n {record.credentialCategory ?? 'Category unknown'} · ID: {record.id} · Revision{' '}\n {record.revision}\n </span>\n </p>\n ))}\n </div>\n </div>\n </SectionCard>\n <SectionCard title={`Sourced obligations (${data.pswComplianceObligations.totalCount})`}>\n {data.pswComplianceObligations.items.length === 0 && (\n <p>No sourced obligations on this page.</p>\n )}\n <div className=\"space-y-3\">\n {data.pswComplianceObligations.items.map((record) => (\n <article key={record.id} className=\"min-w-0 rounded border border-border p-3\">\n <h3 className=\"font-semibold\">{record.title}</h3>\n <p className=\"break-all text-xs\">\n ID: {record.id} · Revision {record.revision}\n </p>\n <p>\n {record.category === null\n ? 'Category unknown; completion cannot be inferred.'\n : `${record.acceptedUnits} accepted / ${record.requiredUnits} required ${record.unitLabel} · ${record.category}`}\n </p>\n <p className=\"break-words\">{record.policyDescription}</p>\n {credentialSourceLink(record.policySourceUrl) && (\n <a\n href={credentialSourceLink(record.policySourceUrl) ?? undefined}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"block underline\"\n >\n Policy source reference:{' '}\n {\n new URL(credentialSourceLink(record.policySourceUrl) ?? record.policySourceUrl)\n .hostname\n }\n </a>\n )}\n <p className=\"text-sm\">\n Period {record.periodStart} to {record.periodEnd} (exclusive). Due {record.dueAt}.\n Source zone {record.sourceTimezone}.\n </p>\n <p className=\"text-sm\">\n {humanize(record.state)} · Reminder: {humanize(record.reminderState)}\n </p>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => {\n setObligationId(record.id);\n setCreditOffset(0);\n }}\n >\n Education credits\n </Button>\n </article>\n ))}\n </div>\n </SectionCard>\n <div className=\"flex flex-wrap items-center justify-between gap-2\">\n <Button\n variant=\"outline\"\n disabled={!offset || query.isFetching}\n onClick={() => {\n setOffset(Math.max(0, offset - 25));\n setObligationId(undefined);\n }}\n >\n Previous records\n </Button>\n <span>Page {Math.floor(offset / 25) + 1}</span>\n <Button\n variant=\"outline\"\n disabled={!more || query.isFetching}\n onClick={() => {\n setOffset(offset + 25);\n setObligationId(undefined);\n }}\n >\n Next records\n </Button>\n </div>\n {obligationId && (\n <SectionCard title=\"Education credit history\">\n {credits.isLoading ? (\n <LoadingBlock />\n ) : credits.error ? (\n <ErrorState error={credits.error} onRetry={() => void credits.refetch()} />\n ) : (\n <div className=\"space-y-3\">\n {credits.data?.items.length === 0 && <p>No education credits recorded.</p>}\n {credits.data?.items.map((credit) => (\n <article key={credit.id} className=\"min-w-0 rounded border border-border p-3\">\n <h3 className=\"font-semibold\">\n {credit.provider} · {credit.amount} {credit.unitLabel}\n </h3>\n <p>\n {credit.category ?? 'Category unknown'} · {humanize(credit.reviewState)}\n </p>\n <p className=\"break-all text-xs\">\n ID: {credit.id} · Revision {credit.revision} · Policy revision{' '}\n {credit.obligationRevision}\n </p>\n <p className=\"break-words\">\n Activity: {credit.activityReference ?? 'Unknown'} · Completed{' '}\n {credit.completedAt}\n </p>\n {credit.duplicateReviewRequired && (\n <p>Possible duplicate: review required before counting.</p>\n )}\n {credit.predecessorId && (\n <p className=\"break-all text-xs\">Corrects credit {credit.predecessorId}</p>\n )}\n <p className=\"break-words\">{credit.reviewNote}</p>\n <p className=\"break-all text-xs\">\n Evidence version {credit.evidenceVersionId} · SHA-256 {credit.evidenceSha256}\n </p>\n </article>\n ))}\n </div>\n )}\n <div className=\"mt-4 flex flex-wrap justify-between gap-2\">\n <Button\n variant=\"outline\"\n disabled={!creditOffset || credits.isFetching}\n onClick={() => setCreditOffset(Math.max(0, creditOffset - 25))}\n >\n Previous credits\n </Button>\n <Button\n variant=\"outline\"\n disabled={!credits.data?.hasMore || credits.isFetching}\n onClick={() => setCreditOffset(creditOffset + 25)}\n >\n Next credits\n </Button>\n </div>\n </SectionCard>\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;;AAOA,SAAgB,IAAsB;CACpC,IAAM,CAAC,GAAQ,KAAa,EAAS,CAAC,GAChC,CAAC,GAAc,KAAmB,EAAiB,GACnD,CAAC,GAAc,KAAmB,EAAS,CAAC,GAC5C,IAAQ,EAAuB,CAAM,GACrC,IAAU,EAAoB,GAAc,CAAY,GACxD,IAAO,EAAM;CACnB,IAAI,EAAM,WAAW,OAAO,kBAAC,GAAD,CAAe,CAAA;CAC3C,IAAI,EAAM,OAAO,OAAO,kBAAC,GAAD;EAAY,OAAO,EAAM;EAAO,eAAe,KAAK,EAAM,QAAQ;CAAI,CAAA;CAC9F,IAAI,CAAC,GACH,OAAO,kBAAC,GAAD;EAAO,OAAM;EAAqB,aAAY;CAAiC,CAAA;CACxF,IAAM,IACJ,EAAK,iBAAiB,WACtB,EAAK,iBAAiB,WACtB,EAAK,yBAAyB;CAChC,OACE,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,GAAD;IAAa,OAAM;cACjB,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;MAAI,WAAU;gBAAd;OAA4B;OAAgB,EAAK,iBAAiB;OAAW;MAAK;SACjF,EAAK,iBAAiB,MAAM,KAAK,MAChC,kBAAC,KAAD;MAAmB,WAAU;gBAA7B,CACG,EAAO,aACR,kBAAC,QAAD;OAAM,WAAU;iBAAhB;QAAgC;QACzB,EAAO;QAAG;QAAa,EAAO;OAC/B;QACL;QALK,EAAO,EAKZ,CACJ,CACE,EAAA,CAAA,GACL,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;MAAI,WAAU;gBAAd;OAA4B;OAAiB,EAAK,iBAAiB;OAAW;MAAK;SAClF,EAAK,iBAAiB,MAAM,KAAK,MAChC,kBAAC,KAAD;MAAmB,WAAU;gBAA7B;OACG,EAAO;OAAY;OAAI,EAAO;OAC/B,kBAAC,QAAD;QAAM,WAAU;kBAAhB;SACG,EAAO,sBAAsB;SAAmB;SAAQ,EAAO;SAAG;SAAY;SAC9E,EAAO;QACJ;;MACL;QANK,EAAO,EAMZ,CACJ,CACE,EAAA,CAAA,CACF;;GACM,CAAA;GACb,kBAAC,GAAD;IAAa,OAAO,wBAAwB,EAAK,yBAAyB,WAAW;cAArF,CACG,EAAK,yBAAyB,MAAM,WAAW,KAC9C,kBAAC,KAAD,EAAA,UAAG,uCAAuC,CAAA,GAE5C,kBAAC,OAAD;KAAK,WAAU;eACZ,EAAK,yBAAyB,MAAM,KAAK,MACxC,kBAAC,WAAD;MAAyB,WAAU;gBAAnC;OACE,kBAAC,MAAD;QAAI,WAAU;kBAAiB,EAAO;OAAU,CAAA;OAChD,kBAAC,KAAD;QAAG,WAAU;kBAAb;SAAiC;SAC1B,EAAO;SAAG;SAAa,EAAO;QAClC;;OACH,kBAAC,KAAD,EAAA,UACG,EAAO,aAAa,OACjB,qDACA,GAAG,EAAO,cAAc,cAAc,EAAO,cAAc,YAAY,EAAO,UAAU,KAAK,EAAO,WACvG,CAAA;OACH,kBAAC,KAAD;QAAG,WAAU;kBAAe,EAAO;OAAqB,CAAA;OACvD,EAAqB,EAAO,eAAe,KAC1C,kBAAC,KAAD;QACE,MAAM,EAAqB,EAAO,eAAe,KAAK,KAAA;QACtD,QAAO;QACP,KAAI;QACJ,WAAU;kBAJZ;SAKC;SAC0B;SAEvB,IAAI,IAAI,EAAqB,EAAO,eAAe,KAAK,EAAO,eAAe,CAAC,CAC5E;QAEJ;;OAEL,kBAAC,KAAD;QAAG,WAAU;kBAAb;SAAuB;SACb,EAAO;SAAY;SAAK,EAAO;SAAU;SAAmB,EAAO;SAAM;SACpE,EAAO;SAAe;QAClC;;OACH,kBAAC,KAAD;QAAG,WAAU;kBAAb;SACG,EAAS,EAAO,KAAK;SAAE;SAAc,EAAS,EAAO,aAAa;QAClE;;OACH,kBAAC,GAAD;QACE,SAAQ;QACR,MAAK;QACL,eAAe;SAEb,AADA,EAAgB,EAAO,EAAE,GACzB,EAAgB,CAAC;QACnB;kBACD;OAEO,CAAA;MACD;QA1CK,EAAO,EA0CZ,CACV;IACE,CAAA,CACM;;GACb,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,GAAD;MACE,SAAQ;MACR,UAAU,CAAC,KAAU,EAAM;MAC3B,eAAe;OAEb,AADA,EAAU,KAAK,IAAI,GAAG,IAAS,EAAE,CAAC,GAClC,EAAgB,KAAA,CAAS;MAC3B;gBACD;KAEO,CAAA;KACR,kBAAC,QAAD,EAAA,UAAA,CAAM,SAAM,KAAK,MAAM,IAAS,EAAE,IAAI,CAAQ,EAAA,CAAA;KAC9C,kBAAC,GAAD;MACE,SAAQ;MACR,UAAU,CAAC,KAAQ,EAAM;MACzB,eAAe;OAEb,AADA,EAAU,IAAS,EAAE,GACrB,EAAgB,KAAA,CAAS;MAC3B;gBACD;KAEO,CAAA;IACL;;GACJ,KACC,kBAAC,GAAD;IAAa,OAAM;cAAnB,CACG,EAAQ,YACP,kBAAC,GAAD,CAAe,CAAA,IACb,EAAQ,QACV,kBAAC,GAAD;KAAY,OAAO,EAAQ;KAAO,eAAe,KAAK,EAAQ,QAAQ;IAAI,CAAA,IAE1E,kBAAC,OAAD;KAAK,WAAU;eAAf,CACG,EAAQ,MAAM,MAAM,WAAW,KAAK,kBAAC,KAAD,EAAA,UAAG,iCAAiC,CAAA,GACxE,EAAQ,MAAM,MAAM,KAAK,MACxB,kBAAC,WAAD;MAAyB,WAAU;gBAAnC;OACE,kBAAC,MAAD;QAAI,WAAU;kBAAd;SACG,EAAO;SAAS;SAAI,EAAO;SAAO;SAAE,EAAO;QAC1C;;OACJ,kBAAC,KAAD,EAAA,UAAA;QACG,EAAO,YAAY;QAAmB;QAAI,EAAS,EAAO,WAAW;OACrE,EAAA,CAAA;OACH,kBAAC,KAAD;QAAG,WAAU;kBAAb;SAAiC;SAC1B,EAAO;SAAG;SAAa,EAAO;SAAS;SAAmB;SAC9D,EAAO;QACP;;OACH,kBAAC,KAAD;QAAG,WAAU;kBAAb;SAA2B;SACd,EAAO,qBAAqB;SAAU;SAAa;SAC7D,EAAO;QACP;;OACF,EAAO,2BACN,kBAAC,KAAD,EAAA,UAAG,uDAAuD,CAAA;OAE3D,EAAO,iBACN,kBAAC,KAAD;QAAG,WAAU;kBAAb,CAAiC,oBAAiB,EAAO,aAAiB;;OAE5E,kBAAC,KAAD;QAAG,WAAU;kBAAe,EAAO;OAAc,CAAA;OACjD,kBAAC,KAAD;QAAG,WAAU;kBAAb;SAAiC;SACb,EAAO;SAAkB;SAAY,EAAO;QAC7D;;MACI;QAzBK,EAAO,EAyBZ,CACV,CACE;QAEP,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD;MACE,SAAQ;MACR,UAAU,CAAC,KAAgB,EAAQ;MACnC,eAAe,EAAgB,KAAK,IAAI,GAAG,IAAe,EAAE,CAAC;gBAC9D;KAEO,CAAA,GACR,kBAAC,GAAD;MACE,SAAQ;MACR,UAAU,CAAC,EAAQ,MAAM,WAAW,EAAQ;MAC5C,eAAe,EAAgB,IAAe,EAAE;gBACjD;KAEO,CAAA,CACL;MACM;;EAEZ;;AAET"}
@@ -1,6 +1,7 @@
1
1
  import { useProServiceWorld as e } from "../providers/ProServiceWorldProvider.js";
2
2
  import { pswQuery as t } from "../hooks/useProServiceWorldApi.js";
3
- import { ErrorState as n, SectionCard as r, humanize as i } from "./ui.js";
3
+ import { humanize as n } from "../utils/humanize.js";
4
+ import { ErrorState as r, SectionCard as i } from "./ui.js";
4
5
  import { writeCredential as a } from "../hooks/credentialWrites.js";
5
6
  import { useRef as o, useState as s } from "react";
6
7
  import { useQuery as c } from "@tanstack/react-query";
@@ -37,7 +38,7 @@ function g({ preparedId: g }) {
37
38
  }
38
39
  }
39
40
  }
40
- return /* @__PURE__ */ u(r, {
41
+ return /* @__PURE__ */ u(i, {
41
42
  title: "My in-app reminder status",
42
43
  children: [
43
44
  /* @__PURE__ */ l("p", {
@@ -64,7 +65,7 @@ function g({ preparedId: g }) {
64
65
  children: "Read reminder"
65
66
  })]
66
67
  }),
67
- j.error && /* @__PURE__ */ l(n, {
68
+ j.error && /* @__PURE__ */ l(r, {
68
69
  error: j.error,
69
70
  onRetry: () => void j.refetch()
70
71
  }),
@@ -81,7 +82,7 @@ function g({ preparedId: g }) {
81
82
  className: "space-y-2",
82
83
  children: [
83
84
  /* @__PURE__ */ u("p", { children: [
84
- i(M.state),
85
+ n(M.state),
85
86
  " · Scheduled ",
86
87
  M.scheduledAt,
87
88
  " · Revision",
@@ -1 +1 @@
1
- {"version":3,"file":"CredentialReminderPanel.js","names":[],"sources":["../../../src/proserviceworld/components/CredentialReminderPanel.tsx"],"sourcesContent":["import type { PswObligationReminder } from '../../generated/wspace-types';\nimport { useRef, useState } from 'react';\nimport { useQuery } from '@tanstack/react-query';\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport { useProServiceWorld } from '../providers/ProServiceWorldProvider';\nimport { pswQuery } from '../hooks/useProServiceWorldApi';\nimport { writeCredential } from '../hooks/credentialWrites';\nimport { ErrorState, SectionCard, humanize } from './ui';\n\ntype Reminder = Omit<PswObligationReminder, '__typename'>;\nconst FIELDS = `id obligationId obligationRevision credentialRevision revision recipientId\n consentGrantedAt consentRevokedAt scheduledAt state scheduleId notificationId notificationStatus attemptStartedAt`;\nconst SCHEDULE = `mutation PswScheduleReminder($id: ID!) { pswScheduleObligationReminder(id: $id) { ${FIELDS} } }`;\nconst REFRESH = `mutation PswRefreshReminder($id: ID!) { pswRefreshObligationReminderStatus(id: $id) { ${FIELDS} } }`;\nconst REVOKE = `mutation PswRevokeReminder($id: ID!, $expectedRevision: Int!) { pswRevokeObligationReminderConsent(id: $id, expectedRevision: $expectedRevision) { ${FIELDS} } }`;\n\n/** Scheduling is explicit; this view never sends a notification directly. */\nexport function CredentialReminderPanel({ preparedId }: { preparedId?: string }) {\n const { workspaceId, tenantId, currentUser } = useProServiceWorld();\n const [draftId, setDraftId] = useState(preparedId ?? '');\n const [id, setId] = useState(preparedId ?? '');\n const [message, setMessage] = useState('');\n const [busy, setBusy] = useState(false);\n const [uncertain, setUncertain] = useState(false);\n const lock = useRef(false);\n const query = useQuery({\n queryKey: ['proserviceworld', 'credentialReminder', tenantId, workspaceId, currentUser?.id, id],\n enabled: Boolean(id && tenantId && workspaceId && currentUser?.id),\n queryFn: async () => {\n const data = await pswQuery<{ pswObligationReminder: Reminder | null }>(\n `query PswReminder($id: ID!) { pswObligationReminder(id: $id) { ${FIELDS} } }`,\n { id }\n );\n return data.pswObligationReminder;\n },\n });\n const reminder = query.data;\n const ownRecipient = Boolean(reminder && reminder.recipientId === currentUser?.id);\n async function act(kind: 'schedule' | 'refresh' | 'revoke') {\n if (!reminder || !ownRecipient || lock.current || uncertain || query.isError) return;\n if (kind === 'schedule' && reminder.state !== 'PREPARED') return;\n lock.current = true;\n setBusy(true);\n setMessage('');\n try {\n await writeCredential<Record<string, unknown>>(\n kind === 'schedule' ? SCHEDULE : kind === 'refresh' ? REFRESH : REVOKE,\n kind === 'revoke' ? { id, expectedRevision: reminder.revision } : { id }\n );\n setMessage(\n 'Request acknowledged. Read the retained state below; an acknowledgment is not proof of recipient delivery.'\n );\n } catch {\n setUncertain(true);\n setMessage('Request outcome unconfirmed. Read retained status before taking another action.');\n } finally {\n const fresh = await query.refetch();\n setUncertain(Boolean(fresh.error));\n lock.current = false;\n setBusy(false);\n }\n }\n return (\n <SectionCard title=\"My in-app reminder status\">\n <p className=\"mb-3 text-sm\">\n Prepare a reminder with your own consent first. Its acknowledged or reconciled save opens\n here automatically. Unknown attempts are retained without automatic resend.\n </p>\n <form\n className=\"mb-4 flex flex-wrap gap-2\"\n onSubmit={(event) => {\n event.preventDefault();\n setId(draftId.trim());\n setMessage('');\n }}\n >\n <label className=\"min-w-0 flex-1 text-sm\">\n Reminder record ID\n <input\n required\n maxLength={100}\n className=\"block w-full rounded border border-border bg-bg-surface p-2\"\n value={draftId}\n onChange={(event) => setDraftId(event.target.value)}\n />\n </label>\n <Button type=\"submit\" disabled={busy}>\n Read reminder\n </Button>\n </form>\n {query.error && <ErrorState error={query.error} onRetry={() => void query.refetch()} />}\n {id && (\n <Button\n variant=\"outline\"\n disabled={busy || query.isFetching}\n onClick={() => {\n void query.refetch().then((fresh) => setUncertain(Boolean(fresh.error)));\n }}\n >\n Read retained status\n </Button>\n )}\n {id && !query.isFetching && query.data === null && (\n <p>Reminder not found in this workspace.</p>\n )}\n {reminder && (\n <div className=\"space-y-2\">\n <p>\n {humanize(reminder.state)} · Scheduled {reminder.scheduledAt} · Revision{' '}\n {reminder.revision}\n </p>\n <p>Notification status: {reminder.notificationStatus ?? 'Not observed'}</p>\n <p className=\"break-all text-xs\">\n Schedule: {reminder.scheduleId ?? 'Not acknowledged'} · Notification:{' '}\n {reminder.notificationId ?? 'Not acknowledged'}\n </p>\n <p className=\"text-sm\">\n Revoking consent suppresses future dispatch. An already in-flight notification cannot be\n recalled.\n </p>\n <div className=\"flex flex-wrap gap-2\">\n <Button\n disabled={\n !ownRecipient ||\n busy ||\n query.isFetching ||\n uncertain ||\n query.isError ||\n reminder.state !== 'PREPARED'\n }\n onClick={() => void act('schedule')}\n >\n Schedule my reminder\n </Button>\n <Button\n variant=\"outline\"\n disabled={!ownRecipient || busy || query.isFetching || uncertain || query.isError}\n onClick={() => void act('refresh')}\n >\n Refresh provider status\n </Button>\n <Button\n variant=\"outline\"\n disabled={\n !ownRecipient || busy || query.isFetching || Boolean(reminder.consentRevokedAt)\n }\n onClick={() => void act('revoke')}\n >\n Revoke my consent\n </Button>\n </div>\n </div>\n )}\n {message && (\n <p role=\"status\" className=\"mt-3 break-words\">\n {message}\n </p>\n )}\n </SectionCard>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"CredentialReminderPanel.js","names":[],"sources":["../../../src/proserviceworld/components/CredentialReminderPanel.tsx"],"sourcesContent":["import type { PswObligationReminder } from '../../generated/wspace-types';\nimport { useRef, useState } from 'react';\nimport { useQuery } from '@tanstack/react-query';\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport { useProServiceWorld } from '../providers/ProServiceWorldProvider';\nimport { pswQuery } from '../hooks/useProServiceWorldApi';\nimport { writeCredential } from '../hooks/credentialWrites';\nimport { ErrorState, SectionCard, humanize } from './ui';\n\ntype Reminder = Omit<PswObligationReminder, '__typename'>;\nconst FIELDS = `id obligationId obligationRevision credentialRevision revision recipientId\n consentGrantedAt consentRevokedAt scheduledAt state scheduleId notificationId notificationStatus attemptStartedAt`;\nconst SCHEDULE = `mutation PswScheduleReminder($id: ID!) { pswScheduleObligationReminder(id: $id) { ${FIELDS} } }`;\nconst REFRESH = `mutation PswRefreshReminder($id: ID!) { pswRefreshObligationReminderStatus(id: $id) { ${FIELDS} } }`;\nconst REVOKE = `mutation PswRevokeReminder($id: ID!, $expectedRevision: Int!) { pswRevokeObligationReminderConsent(id: $id, expectedRevision: $expectedRevision) { ${FIELDS} } }`;\n\n/** Scheduling is explicit; this view never sends a notification directly. */\nexport function CredentialReminderPanel({ preparedId }: { preparedId?: string }) {\n const { workspaceId, tenantId, currentUser } = useProServiceWorld();\n const [draftId, setDraftId] = useState(preparedId ?? '');\n const [id, setId] = useState(preparedId ?? '');\n const [message, setMessage] = useState('');\n const [busy, setBusy] = useState(false);\n const [uncertain, setUncertain] = useState(false);\n const lock = useRef(false);\n const query = useQuery({\n queryKey: ['proserviceworld', 'credentialReminder', tenantId, workspaceId, currentUser?.id, id],\n enabled: Boolean(id && tenantId && workspaceId && currentUser?.id),\n queryFn: async () => {\n const data = await pswQuery<{ pswObligationReminder: Reminder | null }>(\n `query PswReminder($id: ID!) { pswObligationReminder(id: $id) { ${FIELDS} } }`,\n { id }\n );\n return data.pswObligationReminder;\n },\n });\n const reminder = query.data;\n const ownRecipient = Boolean(reminder && reminder.recipientId === currentUser?.id);\n async function act(kind: 'schedule' | 'refresh' | 'revoke') {\n if (!reminder || !ownRecipient || lock.current || uncertain || query.isError) return;\n if (kind === 'schedule' && reminder.state !== 'PREPARED') return;\n lock.current = true;\n setBusy(true);\n setMessage('');\n try {\n await writeCredential<Record<string, unknown>>(\n kind === 'schedule' ? SCHEDULE : kind === 'refresh' ? REFRESH : REVOKE,\n kind === 'revoke' ? { id, expectedRevision: reminder.revision } : { id }\n );\n setMessage(\n 'Request acknowledged. Read the retained state below; an acknowledgment is not proof of recipient delivery.'\n );\n } catch {\n setUncertain(true);\n setMessage('Request outcome unconfirmed. Read retained status before taking another action.');\n } finally {\n const fresh = await query.refetch();\n setUncertain(Boolean(fresh.error));\n lock.current = false;\n setBusy(false);\n }\n }\n return (\n <SectionCard title=\"My in-app reminder status\">\n <p className=\"mb-3 text-sm\">\n Prepare a reminder with your own consent first. Its acknowledged or reconciled save opens\n here automatically. Unknown attempts are retained without automatic resend.\n </p>\n <form\n className=\"mb-4 flex flex-wrap gap-2\"\n onSubmit={(event) => {\n event.preventDefault();\n setId(draftId.trim());\n setMessage('');\n }}\n >\n <label className=\"min-w-0 flex-1 text-sm\">\n Reminder record ID\n <input\n required\n maxLength={100}\n className=\"block w-full rounded border border-border bg-bg-surface p-2\"\n value={draftId}\n onChange={(event) => setDraftId(event.target.value)}\n />\n </label>\n <Button type=\"submit\" disabled={busy}>\n Read reminder\n </Button>\n </form>\n {query.error && <ErrorState error={query.error} onRetry={() => void query.refetch()} />}\n {id && (\n <Button\n variant=\"outline\"\n disabled={busy || query.isFetching}\n onClick={() => {\n void query.refetch().then((fresh) => setUncertain(Boolean(fresh.error)));\n }}\n >\n Read retained status\n </Button>\n )}\n {id && !query.isFetching && query.data === null && (\n <p>Reminder not found in this workspace.</p>\n )}\n {reminder && (\n <div className=\"space-y-2\">\n <p>\n {humanize(reminder.state)} · Scheduled {reminder.scheduledAt} · Revision{' '}\n {reminder.revision}\n </p>\n <p>Notification status: {reminder.notificationStatus ?? 'Not observed'}</p>\n <p className=\"break-all text-xs\">\n Schedule: {reminder.scheduleId ?? 'Not acknowledged'} · Notification:{' '}\n {reminder.notificationId ?? 'Not acknowledged'}\n </p>\n <p className=\"text-sm\">\n Revoking consent suppresses future dispatch. An already in-flight notification cannot be\n recalled.\n </p>\n <div className=\"flex flex-wrap gap-2\">\n <Button\n disabled={\n !ownRecipient ||\n busy ||\n query.isFetching ||\n uncertain ||\n query.isError ||\n reminder.state !== 'PREPARED'\n }\n onClick={() => void act('schedule')}\n >\n Schedule my reminder\n </Button>\n <Button\n variant=\"outline\"\n disabled={!ownRecipient || busy || query.isFetching || uncertain || query.isError}\n onClick={() => void act('refresh')}\n >\n Refresh provider status\n </Button>\n <Button\n variant=\"outline\"\n disabled={\n !ownRecipient || busy || query.isFetching || Boolean(reminder.consentRevokedAt)\n }\n onClick={() => void act('revoke')}\n >\n Revoke my consent\n </Button>\n </div>\n </div>\n )}\n {message && (\n <p role=\"status\" className=\"mt-3 break-words\">\n {message}\n </p>\n )}\n </SectionCard>\n );\n}\n"],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import { FC, ReactNode } from 'react';
2
+ import { humanize } from '../utils/humanize';
2
3
 
3
- export declare const humanize: (v: string | null | undefined) => string;
4
+ export { humanize };
4
5
  export declare const fmtDate: (iso: string | null | undefined) => string;
5
6
  export declare const fmtMoney: (amount: number | null | undefined, currency?: string) => string;
6
7
  export declare const fmtHours: (h: number | null | undefined) => string;
@@ -40,8 +41,11 @@ export declare const Field: FC<{
40
41
  export declare const TextInput: FC<React.InputHTMLAttributes<HTMLInputElement>>;
41
42
  export declare const TextArea: FC<React.TextareaHTMLAttributes<HTMLTextAreaElement>>;
42
43
  export declare const NativeSelect: FC<React.SelectHTMLAttributes<HTMLSelectElement>>;
43
- /** Turn an enum-value list into <option>s with humanized labels. */
44
- export declare const enumOptions: (values: readonly string[]) => ReactNode;
44
+ /**
45
+ * Turn an enum-value list into <option>s. Pass the `useEnumLabel()` function
46
+ * to localize the labels; without it they are humanized English.
47
+ */
48
+ export declare const enumOptions: (values: readonly string[], label?: (value: string) => string) => ReactNode;
45
49
  export declare const Banner: FC<{
46
50
  tone?: 'success' | 'danger' | 'info';
47
51
  children: ReactNode;
@@ -1 +1 @@
1
- {"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../../../src/proserviceworld/components/ui.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../../../src/proserviceworld/components/ui.tsx"],"names":[],"mappings":"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"}