@burdenoff/microfe-hookmovies 2026.830.1 → 2026.1024.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/hookmovies/HookMoviesRoutes.d.ts.map +1 -1
  2. package/dist/hookmovies/HookMoviesRoutes.js +42 -30
  3. package/dist/hookmovies/HookMoviesRoutes.js.map +1 -1
  4. package/dist/hookmovies/components/ApplicationCastingActions.d.ts +15 -0
  5. package/dist/hookmovies/components/ApplicationCastingActions.d.ts.map +1 -0
  6. package/dist/hookmovies/components/ApplicationCastingActions.js +408 -0
  7. package/dist/hookmovies/components/ApplicationCastingActions.js.map +1 -0
  8. package/dist/hookmovies/components/StatusBadge.d.ts.map +1 -1
  9. package/dist/hookmovies/components/StatusBadge.js +11 -0
  10. package/dist/hookmovies/components/StatusBadge.js.map +1 -1
  11. package/dist/hookmovies/hooks/useCastingApi.d.ts +263 -0
  12. package/dist/hookmovies/hooks/useCastingApi.d.ts.map +1 -0
  13. package/dist/hookmovies/hooks/useCastingApi.js +134 -0
  14. package/dist/hookmovies/hooks/useCastingApi.js.map +1 -0
  15. package/dist/hookmovies/hooks/useHookMoviesApi.d.ts +5 -0
  16. package/dist/hookmovies/hooks/useHookMoviesApi.d.ts.map +1 -1
  17. package/dist/hookmovies/hooks/useHookMoviesApi.js +1 -1
  18. package/dist/hookmovies/hooks/useHookMoviesApi.js.map +1 -1
  19. package/dist/hookmovies/pages/auditions/AuditionDetailPage.d.ts.map +1 -1
  20. package/dist/hookmovies/pages/auditions/AuditionDetailPage.js +202 -146
  21. package/dist/hookmovies/pages/auditions/AuditionDetailPage.js.map +1 -1
  22. package/dist/hookmovies/pages/casting/MyCastingPage.d.ts +4 -0
  23. package/dist/hookmovies/pages/casting/MyCastingPage.d.ts.map +1 -0
  24. package/dist/hookmovies/pages/casting/MyCastingPage.js +553 -0
  25. package/dist/hookmovies/pages/casting/MyCastingPage.js.map +1 -0
  26. package/dist/hookmovies/pages/casting/SavedSearchesPage.d.ts +4 -0
  27. package/dist/hookmovies/pages/casting/SavedSearchesPage.d.ts.map +1 -0
  28. package/dist/hookmovies/pages/casting/SavedSearchesPage.js +312 -0
  29. package/dist/hookmovies/pages/casting/SavedSearchesPage.js.map +1 -0
  30. package/dist/hookmovies/pages/trust/DisputesPage.d.ts +4 -0
  31. package/dist/hookmovies/pages/trust/DisputesPage.d.ts.map +1 -0
  32. package/dist/hookmovies/pages/trust/DisputesPage.js +170 -0
  33. package/dist/hookmovies/pages/trust/DisputesPage.js.map +1 -0
  34. package/dist/utils/pageContext.d.ts.map +1 -1
  35. package/dist/utils/pageContext.js +12 -0
  36. package/dist/utils/pageContext.js.map +1 -1
  37. package/package.json +1 -1
@@ -0,0 +1,408 @@
1
+ import { StatusBadge as e } from "./StatusBadge.js";
2
+ import { formatDate as t, formatMinorUnits as n } from "../utils/formatters.js";
3
+ import { useCancelCallback as r, useCompleteCallback as i, useCompleteOffer as a, useMarkOfferPaid as o, useRateTalent as s, useReputation as c, useScheduleCallback as l, useSendOffer as u, useWithdrawOffer as d } from "../hooks/useCastingApi.js";
4
+ import { useState as f } from "react";
5
+ import { CalendarPlus as p, CheckCircle2 as m, FileText as h, Star as g, Wallet as _, XCircle as v } from "lucide-react";
6
+ import { Fragment as y, jsx as b, jsxs as x } from "react/jsx-runtime";
7
+ //#region src/hookmovies/components/ApplicationCastingActions.tsx
8
+ var S = "w-full rounded-lg border border-border-subtle bg-bg-surface px-2.5 py-1.5 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]", C = "mb-1 block text-xs font-medium text-text-secondary", w = "inline-flex items-center gap-1.5 rounded-lg bg-action-primary-bg px-2.5 py-1 text-xs font-medium text-action-primary-text hover:opacity-90 disabled:opacity-50 transition-opacity", T = "inline-flex items-center gap-1.5 rounded-lg border border-border-seam px-2.5 py-1 text-xs font-medium text-text-primary hover:bg-bg-sunken disabled:opacity-50 transition-colors", E = (e) => e instanceof Error ? e.message : "Something went wrong. Please retry.", D = (e) => new Date(e).toISOString(), O = () => Intl.DateTimeFormat().resolvedOptions().timeZone || "UTC", k = ({ applicationId: e, onDone: t }) => {
9
+ let n = l(), [r, i] = f(""), [a, o] = f("60"), [s, c] = f("IN_PERSON"), [u, d] = f(""), [m, h] = f(""), [g, _] = f(null), v = async (i) => {
10
+ i.preventDefault(), _(null);
11
+ try {
12
+ let i = D(r), o = new Date(new Date(i).getTime() + Number(a) * 6e4).toISOString();
13
+ await n.mutateAsync({ input: {
14
+ applicationId: e,
15
+ scheduledStart: i,
16
+ scheduledEnd: o,
17
+ timezone: O(),
18
+ format: s,
19
+ location: s === "IN_PERSON" ? u.trim() : void 0,
20
+ meetingUrl: s === "VIRTUAL" ? u.trim() : void 0,
21
+ notes: m.trim() || void 0
22
+ } }), t();
23
+ } catch (e) {
24
+ _(E(e));
25
+ }
26
+ };
27
+ return /* @__PURE__ */ x("form", {
28
+ onSubmit: (e) => void v(e),
29
+ className: "mt-3 space-y-2 rounded-lg border border-border-seam p-3",
30
+ children: [
31
+ g && /* @__PURE__ */ b("p", {
32
+ role: "alert",
33
+ className: "text-xs text-status-error-text",
34
+ children: g
35
+ }),
36
+ /* @__PURE__ */ x("div", {
37
+ className: "grid grid-cols-2 gap-2",
38
+ children: [
39
+ /* @__PURE__ */ x("div", { children: [/* @__PURE__ */ b("label", {
40
+ htmlFor: `cb-start-${e}`,
41
+ className: C,
42
+ children: "Starts *"
43
+ }), /* @__PURE__ */ b("input", {
44
+ id: `cb-start-${e}`,
45
+ type: "datetime-local",
46
+ required: !0,
47
+ value: r,
48
+ onChange: (e) => i(e.target.value),
49
+ className: S
50
+ })] }),
51
+ /* @__PURE__ */ x("div", { children: [/* @__PURE__ */ b("label", {
52
+ htmlFor: `cb-dur-${e}`,
53
+ className: C,
54
+ children: "Minutes *"
55
+ }), /* @__PURE__ */ b("input", {
56
+ id: `cb-dur-${e}`,
57
+ type: "number",
58
+ min: 5,
59
+ max: 720,
60
+ required: !0,
61
+ value: a,
62
+ onChange: (e) => o(e.target.value),
63
+ className: S
64
+ })] }),
65
+ /* @__PURE__ */ x("div", { children: [/* @__PURE__ */ b("label", {
66
+ htmlFor: `cb-format-${e}`,
67
+ className: C,
68
+ children: "Format"
69
+ }), /* @__PURE__ */ x("select", {
70
+ id: `cb-format-${e}`,
71
+ value: s,
72
+ onChange: (e) => c(e.target.value),
73
+ className: S,
74
+ children: [/* @__PURE__ */ b("option", {
75
+ value: "IN_PERSON",
76
+ children: "In person"
77
+ }), /* @__PURE__ */ b("option", {
78
+ value: "VIRTUAL",
79
+ children: "Online"
80
+ })]
81
+ })] }),
82
+ /* @__PURE__ */ x("div", { children: [/* @__PURE__ */ b("label", {
83
+ htmlFor: `cb-where-${e}`,
84
+ className: C,
85
+ children: s === "VIRTUAL" ? "Meeting link (https) *" : "Location *"
86
+ }), /* @__PURE__ */ b("input", {
87
+ id: `cb-where-${e}`,
88
+ required: !0,
89
+ value: u,
90
+ onChange: (e) => d(e.target.value),
91
+ className: S
92
+ })] })
93
+ ]
94
+ }),
95
+ /* @__PURE__ */ b("textarea", {
96
+ "aria-label": "Notes for the talent",
97
+ value: m,
98
+ onChange: (e) => h(e.target.value),
99
+ rows: 2,
100
+ placeholder: "What to prepare (optional)",
101
+ className: S
102
+ }),
103
+ /* @__PURE__ */ x("button", {
104
+ type: "submit",
105
+ className: w,
106
+ disabled: n.isPending,
107
+ children: [/* @__PURE__ */ b(p, { className: "h-3.5 w-3.5" }), "Send callback invite"]
108
+ })
109
+ ]
110
+ });
111
+ }, A = ({ applicationId: e, defaultPayMinorUnits: t, defaultCurrency: n, onDone: r }) => {
112
+ let i = u(), [a, o] = f(""), [s, c] = f(String(Number(t || "0") / 100)), [l, d] = f(n || "USD"), [p, m] = f(""), [g, _] = f(null), v = async (t) => {
113
+ t.preventDefault(), _(null);
114
+ let n = Number(s);
115
+ if (!Number.isFinite(n) || n < 0) {
116
+ _("Enter a valid pay amount.");
117
+ return;
118
+ }
119
+ try {
120
+ await i.mutateAsync({ input: {
121
+ applicationId: e,
122
+ terms: a.trim(),
123
+ payMinorUnits: String(Math.round(n * 100)),
124
+ currency: l.trim(),
125
+ expiresAt: p ? D(p) : void 0
126
+ } }), r();
127
+ } catch (e) {
128
+ _(E(e));
129
+ }
130
+ };
131
+ return /* @__PURE__ */ x("form", {
132
+ onSubmit: (e) => void v(e),
133
+ className: "mt-3 space-y-2 rounded-lg border border-border-seam p-3",
134
+ children: [
135
+ g && /* @__PURE__ */ b("p", {
136
+ role: "alert",
137
+ className: "text-xs text-status-error-text",
138
+ children: g
139
+ }),
140
+ /* @__PURE__ */ x("div", { children: [/* @__PURE__ */ b("label", {
141
+ htmlFor: `of-terms-${e}`,
142
+ className: C,
143
+ children: "Terms *"
144
+ }), /* @__PURE__ */ b("textarea", {
145
+ id: `of-terms-${e}`,
146
+ required: !0,
147
+ value: a,
148
+ onChange: (e) => o(e.target.value),
149
+ rows: 4,
150
+ maxLength: 2e4,
151
+ placeholder: "Shoot days, location, usage rights, payment schedule…",
152
+ className: S
153
+ })] }),
154
+ /* @__PURE__ */ x("div", {
155
+ className: "grid grid-cols-3 gap-2",
156
+ children: [
157
+ /* @__PURE__ */ x("div", { children: [/* @__PURE__ */ b("label", {
158
+ htmlFor: `of-pay-${e}`,
159
+ className: C,
160
+ children: "Pay"
161
+ }), /* @__PURE__ */ b("input", {
162
+ id: `of-pay-${e}`,
163
+ type: "number",
164
+ min: 0,
165
+ step: "0.01",
166
+ value: s,
167
+ onChange: (e) => c(e.target.value),
168
+ className: S
169
+ })] }),
170
+ /* @__PURE__ */ x("div", { children: [/* @__PURE__ */ b("label", {
171
+ htmlFor: `of-cur-${e}`,
172
+ className: C,
173
+ children: "Currency"
174
+ }), /* @__PURE__ */ b("input", {
175
+ id: `of-cur-${e}`,
176
+ value: l,
177
+ maxLength: 3,
178
+ onChange: (e) => d(e.target.value.toUpperCase()),
179
+ className: S
180
+ })] }),
181
+ /* @__PURE__ */ x("div", { children: [/* @__PURE__ */ b("label", {
182
+ htmlFor: `of-exp-${e}`,
183
+ className: C,
184
+ children: "Respond by"
185
+ }), /* @__PURE__ */ b("input", {
186
+ id: `of-exp-${e}`,
187
+ type: "datetime-local",
188
+ value: p,
189
+ onChange: (e) => m(e.target.value),
190
+ className: S
191
+ })] })
192
+ ]
193
+ }),
194
+ /* @__PURE__ */ b("p", {
195
+ className: "text-xs text-text-secondary",
196
+ children: "Terms are locked once sent; the talent signs this exact text. HookMovies does not hold funds — you pay the talent directly and record it here."
197
+ }),
198
+ /* @__PURE__ */ x("button", {
199
+ type: "submit",
200
+ className: w,
201
+ disabled: i.isPending,
202
+ children: [/* @__PURE__ */ b(h, { className: "h-3.5 w-3.5" }), "Send offer"]
203
+ })
204
+ ]
205
+ });
206
+ }, j = ({ offer: r }) => {
207
+ let i = d(), c = a(), l = o(), u = s(), [p, h] = f(""), [C, w] = f(null), D = r.status === "ACCEPTED" || r.status === "COMPLETED", O = r.ratings.some((e) => e.raterSide === "PRODUCTION"), k = async (e) => {
208
+ w(null);
209
+ try {
210
+ await e();
211
+ } catch (e) {
212
+ w(E(e));
213
+ }
214
+ };
215
+ return /* @__PURE__ */ x("li", {
216
+ className: "rounded-lg border border-border-seam p-2.5",
217
+ "data-testid": "team-offer-row",
218
+ children: [
219
+ /* @__PURE__ */ x("div", {
220
+ className: "flex flex-wrap items-center justify-between gap-2",
221
+ children: [/* @__PURE__ */ x("span", {
222
+ className: "text-xs font-medium text-text-primary",
223
+ children: ["Offer · ", n(r.payMinorUnits, r.currency)]
224
+ }), /* @__PURE__ */ x("span", {
225
+ className: "flex gap-1.5",
226
+ children: [/* @__PURE__ */ b(e, { status: r.status }), D && /* @__PURE__ */ b(e, { status: r.paymentStatus })]
227
+ })]
228
+ }),
229
+ r.signedAt && /* @__PURE__ */ x("p", {
230
+ className: "mt-1 text-xs text-text-secondary",
231
+ children: [
232
+ "Signed by ",
233
+ r.signerName,
234
+ " on ",
235
+ t(r.signedAt)
236
+ ]
237
+ }),
238
+ r.disputes.some((e) => e.status === "OPEN" || e.status === "UNDER_REVIEW") && /* @__PURE__ */ b("p", {
239
+ className: "mt-1 text-xs text-status-warning-text",
240
+ children: "Open dispute with trust & safety"
241
+ }),
242
+ C && /* @__PURE__ */ b("p", {
243
+ role: "alert",
244
+ className: "mt-1 text-xs text-status-error-text",
245
+ children: C
246
+ }),
247
+ /* @__PURE__ */ x("div", {
248
+ className: "mt-2 flex flex-wrap items-center gap-1.5",
249
+ children: [
250
+ r.status === "SENT" && /* @__PURE__ */ x("button", {
251
+ type: "button",
252
+ className: T,
253
+ disabled: i.isPending,
254
+ onClick: () => void k(() => i.mutateAsync({ id: r.id })),
255
+ children: [/* @__PURE__ */ b(v, { className: "h-3.5 w-3.5" }), "Withdraw"]
256
+ }),
257
+ D && r.paymentStatus === "UNPAID" && /* @__PURE__ */ x(y, { children: [/* @__PURE__ */ b("input", {
258
+ "aria-label": "Payment reference",
259
+ value: p,
260
+ onChange: (e) => h(e.target.value),
261
+ placeholder: "Payment ref (UTR / txn id)",
262
+ className: `${S} max-w-[11rem] py-1 text-xs`
263
+ }), /* @__PURE__ */ x("button", {
264
+ type: "button",
265
+ className: T,
266
+ disabled: l.isPending,
267
+ onClick: () => void k(() => l.mutateAsync({
268
+ id: r.id,
269
+ paymentReference: p.trim() || void 0
270
+ })),
271
+ children: [/* @__PURE__ */ b(_, { className: "h-3.5 w-3.5" }), "Mark paid"]
272
+ })] }),
273
+ r.status === "ACCEPTED" && /* @__PURE__ */ x("button", {
274
+ type: "button",
275
+ className: T,
276
+ disabled: c.isPending,
277
+ onClick: () => void k(() => c.mutateAsync({ id: r.id })),
278
+ children: [/* @__PURE__ */ b(m, { className: "h-3.5 w-3.5" }), "Mark engagement complete"]
279
+ }),
280
+ r.status === "COMPLETED" && !O && /* @__PURE__ */ b("span", {
281
+ className: "flex items-center gap-0.5",
282
+ role: "group",
283
+ "aria-label": "Rate this talent",
284
+ children: [
285
+ 1,
286
+ 2,
287
+ 3,
288
+ 4,
289
+ 5
290
+ ].map((e) => /* @__PURE__ */ b("button", {
291
+ type: "button",
292
+ "aria-label": `Rate talent ${e} of 5`,
293
+ disabled: u.isPending,
294
+ onClick: () => void k(() => u.mutateAsync({ input: {
295
+ offerId: r.id,
296
+ score: e
297
+ } })),
298
+ className: "rounded p-0.5",
299
+ children: /* @__PURE__ */ b(g, { className: "h-4 w-4 text-text-muted hover:text-status-warning-text" })
300
+ }, e))
301
+ }),
302
+ O && /* @__PURE__ */ b("span", {
303
+ className: "text-xs text-text-secondary",
304
+ children: "Talent rated"
305
+ })
306
+ ]
307
+ })
308
+ ]
309
+ });
310
+ }, M = ({ applicationId: n, applicantId: a, applicationStatus: o, defaultPayMinorUnits: s, defaultCurrency: l, callbacks: u, offers: d }) => {
311
+ let [m, _] = f("none"), v = c("PERSON", a), y = r(), S = i(), [C, w] = f(null), D = o.toUpperCase(), O = [
312
+ "SUBMITTED",
313
+ "SHORTLISTED",
314
+ "CALLBACK"
315
+ ].includes(D), M = d.some((e) => e.status === "SENT" || e.status === "ACCEPTED"), N = !["REJECTED", "WITHDRAWN"].includes(D) && !M, P = async (e) => {
316
+ w(null);
317
+ try {
318
+ await e();
319
+ } catch (e) {
320
+ w(E(e));
321
+ }
322
+ };
323
+ return /* @__PURE__ */ x("div", {
324
+ className: "mt-3 border-t border-border-seam pt-3",
325
+ "data-testid": "application-casting-actions",
326
+ children: [
327
+ /* @__PURE__ */ x("p", {
328
+ className: "flex items-center gap-1.5 text-xs text-text-secondary",
329
+ children: [/* @__PURE__ */ b(g, { className: "h-3.5 w-3.5" }), v.data && v.data.ratingCount > 0 ? `${v.data.averageScore?.toFixed(1) ?? "—"} / 5 from ${v.data.ratingCount} production${v.data.ratingCount === 1 ? "" : "s"}` : "No ratings from productions yet"]
330
+ }),
331
+ u.length > 0 && /* @__PURE__ */ b("ul", {
332
+ className: "mt-2 space-y-1.5",
333
+ children: u.map((n) => /* @__PURE__ */ x("li", {
334
+ className: "flex flex-wrap items-center justify-between gap-2 text-xs",
335
+ "data-testid": "team-callback-row",
336
+ children: [/* @__PURE__ */ x("span", {
337
+ className: "text-text-primary",
338
+ children: [
339
+ "Callback ",
340
+ t(n.scheduledStart),
341
+ " ·",
342
+ " ",
343
+ n.format === "VIRTUAL" ? "online" : n.location ?? "in person"
344
+ ]
345
+ }), /* @__PURE__ */ x("span", {
346
+ className: "flex items-center gap-1.5",
347
+ children: [
348
+ /* @__PURE__ */ b(e, { status: n.status }),
349
+ (n.status === "PROPOSED" || n.status === "CONFIRMED") && /* @__PURE__ */ b("button", {
350
+ type: "button",
351
+ className: T,
352
+ disabled: y.isPending,
353
+ onClick: () => void P(() => y.mutateAsync({ id: n.id })),
354
+ children: "Cancel"
355
+ }),
356
+ n.status === "CONFIRMED" && /* @__PURE__ */ b("button", {
357
+ type: "button",
358
+ className: T,
359
+ disabled: S.isPending,
360
+ onClick: () => void P(() => S.mutateAsync({ id: n.id })),
361
+ children: "Done"
362
+ })
363
+ ]
364
+ })]
365
+ }, n.id))
366
+ }),
367
+ d.length > 0 && /* @__PURE__ */ b("ul", {
368
+ className: "mt-2 space-y-1.5",
369
+ children: d.map((e) => /* @__PURE__ */ b(j, { offer: e }, e.id))
370
+ }),
371
+ C && /* @__PURE__ */ b("p", {
372
+ role: "alert",
373
+ className: "mt-2 text-xs text-status-error-text",
374
+ children: C
375
+ }),
376
+ /* @__PURE__ */ x("div", {
377
+ className: "mt-2 flex flex-wrap gap-1.5",
378
+ children: [O && /* @__PURE__ */ x("button", {
379
+ type: "button",
380
+ className: T,
381
+ "aria-expanded": m === "callback",
382
+ onClick: () => _((e) => e === "callback" ? "none" : "callback"),
383
+ children: [/* @__PURE__ */ b(p, { className: "h-3.5 w-3.5" }), "Schedule callback"]
384
+ }), N && /* @__PURE__ */ x("button", {
385
+ type: "button",
386
+ className: T,
387
+ "aria-expanded": m === "offer",
388
+ onClick: () => _((e) => e === "offer" ? "none" : "offer"),
389
+ children: [/* @__PURE__ */ b(h, { className: "h-3.5 w-3.5" }), "Make an offer"]
390
+ })]
391
+ }),
392
+ m === "callback" && /* @__PURE__ */ b(k, {
393
+ applicationId: n,
394
+ onDone: () => _("none")
395
+ }),
396
+ m === "offer" && /* @__PURE__ */ b(A, {
397
+ applicationId: n,
398
+ defaultPayMinorUnits: s,
399
+ defaultCurrency: l,
400
+ onDone: () => _("none")
401
+ })
402
+ ]
403
+ });
404
+ };
405
+ //#endregion
406
+ export { M as ApplicationCastingActions };
407
+
408
+ //# sourceMappingURL=ApplicationCastingActions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ApplicationCastingActions.js","names":[],"sources":["../../../src/hookmovies/components/ApplicationCastingActions.tsx"],"sourcesContent":["/**\n * Casting-team actions for one application (BOFF-4245)\n * @module hookmovies/components\n *\n * Rendered inside each applicant card on the audition page: the applicant's\n * two-sided reputation, their callbacks and offers, and the team's actions —\n * schedule / cancel / complete a callback, send / withdraw / complete an\n * offer, record an off-platform payment, and rate the talent once the\n * engagement is completed.\n */\n\nimport { type FC, type FormEvent, useState } from 'react';\nimport { CalendarPlus, CheckCircle2, FileText, Star, Wallet, XCircle } from 'lucide-react';\nimport { StatusBadge } from './StatusBadge';\nimport {\n type HokCallback,\n type HokCallbackFormat,\n type HokOffer,\n useCancelCallback,\n useCompleteCallback,\n useCompleteOffer,\n useMarkOfferPaid,\n useRateTalent,\n useReputation,\n useScheduleCallback,\n useSendOffer,\n useWithdrawOffer,\n} from '../hooks/useCastingApi';\nimport { formatDate, formatMinorUnits } from '../utils/formatters';\n\nconst fieldClass =\n 'w-full rounded-lg border border-border-subtle bg-bg-surface px-2.5 py-1.5 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]';\nconst labelClass = 'mb-1 block text-xs font-medium text-text-secondary';\nconst smallPrimary =\n 'inline-flex items-center gap-1.5 rounded-lg bg-action-primary-bg px-2.5 py-1 text-xs font-medium text-action-primary-text hover:opacity-90 disabled:opacity-50 transition-opacity';\nconst smallSecondary =\n 'inline-flex items-center gap-1.5 rounded-lg border border-border-seam px-2.5 py-1 text-xs font-medium text-text-primary hover:bg-bg-sunken disabled:opacity-50 transition-colors';\n\nconst errorText = (err: unknown): string =>\n err instanceof Error ? err.message : 'Something went wrong. Please retry.';\n\n/** `datetime-local` value → ISO string (interpreted in the browser's zone). */\nconst localToIso = (value: string): string => new Date(value).toISOString();\n\nconst browserZone = (): string => Intl.DateTimeFormat().resolvedOptions().timeZone || 'UTC';\n\ninterface Props {\n applicationId: string;\n applicantId: string;\n applicationStatus: string;\n defaultPayMinorUnits: string;\n defaultCurrency: string;\n callbacks: HokCallback[];\n offers: HokOffer[];\n}\n\ntype Panel = 'none' | 'callback' | 'offer';\n\nconst ScheduleCallbackForm: FC<{ applicationId: string; onDone: () => void }> = ({\n applicationId,\n onDone,\n}) => {\n const schedule = useScheduleCallback();\n const [start, setStart] = useState('');\n const [durationMins, setDurationMins] = useState('60');\n const [format, setFormat] = useState<HokCallbackFormat>('IN_PERSON');\n const [where, setWhere] = useState('');\n const [notes, setNotes] = useState('');\n const [error, setError] = useState<string | null>(null);\n\n const submit = async (e: FormEvent) => {\n e.preventDefault();\n setError(null);\n try {\n const startIso = localToIso(start);\n const endIso = new Date(\n new Date(startIso).getTime() + Number(durationMins) * 60_000\n ).toISOString();\n await schedule.mutateAsync({\n input: {\n applicationId,\n scheduledStart: startIso,\n scheduledEnd: endIso,\n timezone: browserZone(),\n format,\n location: format === 'IN_PERSON' ? where.trim() : undefined,\n meetingUrl: format === 'VIRTUAL' ? where.trim() : undefined,\n notes: notes.trim() || undefined,\n },\n });\n onDone();\n } catch (err) {\n setError(errorText(err));\n }\n };\n\n return (\n <form\n onSubmit={(e) => void submit(e)}\n className=\"mt-3 space-y-2 rounded-lg border border-border-seam p-3\"\n >\n {error && (\n <p role=\"alert\" className=\"text-xs text-status-error-text\">\n {error}\n </p>\n )}\n <div className=\"grid grid-cols-2 gap-2\">\n <div>\n <label htmlFor={`cb-start-${applicationId}`} className={labelClass}>\n Starts *\n </label>\n <input\n id={`cb-start-${applicationId}`}\n type=\"datetime-local\"\n required\n value={start}\n onChange={(e) => setStart(e.target.value)}\n className={fieldClass}\n />\n </div>\n <div>\n <label htmlFor={`cb-dur-${applicationId}`} className={labelClass}>\n Minutes *\n </label>\n <input\n id={`cb-dur-${applicationId}`}\n type=\"number\"\n min={5}\n max={720}\n required\n value={durationMins}\n onChange={(e) => setDurationMins(e.target.value)}\n className={fieldClass}\n />\n </div>\n <div>\n <label htmlFor={`cb-format-${applicationId}`} className={labelClass}>\n Format\n </label>\n <select\n id={`cb-format-${applicationId}`}\n value={format}\n onChange={(e) => setFormat(e.target.value as HokCallbackFormat)}\n className={fieldClass}\n >\n <option value=\"IN_PERSON\">In person</option>\n <option value=\"VIRTUAL\">Online</option>\n </select>\n </div>\n <div>\n <label htmlFor={`cb-where-${applicationId}`} className={labelClass}>\n {format === 'VIRTUAL' ? 'Meeting link (https) *' : 'Location *'}\n </label>\n <input\n id={`cb-where-${applicationId}`}\n required\n value={where}\n onChange={(e) => setWhere(e.target.value)}\n className={fieldClass}\n />\n </div>\n </div>\n <textarea\n aria-label=\"Notes for the talent\"\n value={notes}\n onChange={(e) => setNotes(e.target.value)}\n rows={2}\n placeholder=\"What to prepare (optional)\"\n className={fieldClass}\n />\n <button type=\"submit\" className={smallPrimary} disabled={schedule.isPending}>\n <CalendarPlus className=\"h-3.5 w-3.5\" />\n Send callback invite\n </button>\n </form>\n );\n};\n\nconst SendOfferForm: FC<{\n applicationId: string;\n defaultPayMinorUnits: string;\n defaultCurrency: string;\n onDone: () => void;\n}> = ({ applicationId, defaultPayMinorUnits, defaultCurrency, onDone }) => {\n const send = useSendOffer();\n const [terms, setTerms] = useState('');\n const [pay, setPay] = useState(String(Number(defaultPayMinorUnits || '0') / 100));\n const [currency, setCurrency] = useState(defaultCurrency || 'USD');\n const [expires, setExpires] = useState('');\n const [error, setError] = useState<string | null>(null);\n\n const submit = async (e: FormEvent) => {\n e.preventDefault();\n setError(null);\n const major = Number(pay);\n if (!Number.isFinite(major) || major < 0) {\n setError('Enter a valid pay amount.');\n return;\n }\n try {\n await send.mutateAsync({\n input: {\n applicationId,\n terms: terms.trim(),\n payMinorUnits: String(Math.round(major * 100)),\n currency: currency.trim(),\n expiresAt: expires ? localToIso(expires) : undefined,\n },\n });\n onDone();\n } catch (err) {\n setError(errorText(err));\n }\n };\n\n return (\n <form\n onSubmit={(e) => void submit(e)}\n className=\"mt-3 space-y-2 rounded-lg border border-border-seam p-3\"\n >\n {error && (\n <p role=\"alert\" className=\"text-xs text-status-error-text\">\n {error}\n </p>\n )}\n <div>\n <label htmlFor={`of-terms-${applicationId}`} className={labelClass}>\n Terms *\n </label>\n <textarea\n id={`of-terms-${applicationId}`}\n required\n value={terms}\n onChange={(e) => setTerms(e.target.value)}\n rows={4}\n maxLength={20000}\n placeholder=\"Shoot days, location, usage rights, payment schedule…\"\n className={fieldClass}\n />\n </div>\n <div className=\"grid grid-cols-3 gap-2\">\n <div>\n <label htmlFor={`of-pay-${applicationId}`} className={labelClass}>\n Pay\n </label>\n <input\n id={`of-pay-${applicationId}`}\n type=\"number\"\n min={0}\n step=\"0.01\"\n value={pay}\n onChange={(e) => setPay(e.target.value)}\n className={fieldClass}\n />\n </div>\n <div>\n <label htmlFor={`of-cur-${applicationId}`} className={labelClass}>\n Currency\n </label>\n <input\n id={`of-cur-${applicationId}`}\n value={currency}\n maxLength={3}\n onChange={(e) => setCurrency(e.target.value.toUpperCase())}\n className={fieldClass}\n />\n </div>\n <div>\n <label htmlFor={`of-exp-${applicationId}`} className={labelClass}>\n Respond by\n </label>\n <input\n id={`of-exp-${applicationId}`}\n type=\"datetime-local\"\n value={expires}\n onChange={(e) => setExpires(e.target.value)}\n className={fieldClass}\n />\n </div>\n </div>\n <p className=\"text-xs text-text-secondary\">\n Terms are locked once sent; the talent signs this exact text. HookMovies does not hold funds\n — you pay the talent directly and record it here.\n </p>\n <button type=\"submit\" className={smallPrimary} disabled={send.isPending}>\n <FileText className=\"h-3.5 w-3.5\" />\n Send offer\n </button>\n </form>\n );\n};\n\nconst OfferRow: FC<{ offer: HokOffer }> = ({ offer }) => {\n const withdraw = useWithdrawOffer();\n const complete = useCompleteOffer();\n const markPaid = useMarkOfferPaid();\n const rate = useRateTalent();\n const [reference, setReference] = useState('');\n const [error, setError] = useState<string | null>(null);\n const engaged = offer.status === 'ACCEPTED' || offer.status === 'COMPLETED';\n const ratedTalent = offer.ratings.some((r) => r.raterSide === 'PRODUCTION');\n\n const run = async (fn: () => Promise<unknown>) => {\n setError(null);\n try {\n await fn();\n } catch (err) {\n setError(errorText(err));\n }\n };\n\n return (\n <li className=\"rounded-lg border border-border-seam p-2.5\" data-testid=\"team-offer-row\">\n <div className=\"flex flex-wrap items-center justify-between gap-2\">\n <span className=\"text-xs font-medium text-text-primary\">\n Offer · {formatMinorUnits(offer.payMinorUnits, offer.currency)}\n </span>\n <span className=\"flex gap-1.5\">\n <StatusBadge status={offer.status} />\n {engaged && <StatusBadge status={offer.paymentStatus} />}\n </span>\n </div>\n {offer.signedAt && (\n <p className=\"mt-1 text-xs text-text-secondary\">\n Signed by {offer.signerName} on {formatDate(offer.signedAt)}\n </p>\n )}\n {offer.disputes.some((d) => d.status === 'OPEN' || d.status === 'UNDER_REVIEW') && (\n <p className=\"mt-1 text-xs text-status-warning-text\">\n Open dispute with trust &amp; safety\n </p>\n )}\n {error && (\n <p role=\"alert\" className=\"mt-1 text-xs text-status-error-text\">\n {error}\n </p>\n )}\n <div className=\"mt-2 flex flex-wrap items-center gap-1.5\">\n {offer.status === 'SENT' && (\n <button\n type=\"button\"\n className={smallSecondary}\n disabled={withdraw.isPending}\n onClick={() => void run(() => withdraw.mutateAsync({ id: offer.id }))}\n >\n <XCircle className=\"h-3.5 w-3.5\" />\n Withdraw\n </button>\n )}\n {engaged && offer.paymentStatus === 'UNPAID' && (\n <>\n <input\n aria-label=\"Payment reference\"\n value={reference}\n onChange={(e) => setReference(e.target.value)}\n placeholder=\"Payment ref (UTR / txn id)\"\n className={`${fieldClass} max-w-[11rem] py-1 text-xs`}\n />\n <button\n type=\"button\"\n className={smallSecondary}\n disabled={markPaid.isPending}\n onClick={() =>\n void run(() =>\n markPaid.mutateAsync({\n id: offer.id,\n paymentReference: reference.trim() || undefined,\n })\n )\n }\n >\n <Wallet className=\"h-3.5 w-3.5\" />\n Mark paid\n </button>\n </>\n )}\n {offer.status === 'ACCEPTED' && (\n <button\n type=\"button\"\n className={smallSecondary}\n disabled={complete.isPending}\n onClick={() => void run(() => complete.mutateAsync({ id: offer.id }))}\n >\n <CheckCircle2 className=\"h-3.5 w-3.5\" />\n Mark engagement complete\n </button>\n )}\n {offer.status === 'COMPLETED' && !ratedTalent && (\n <span className=\"flex items-center gap-0.5\" role=\"group\" aria-label=\"Rate this talent\">\n {[1, 2, 3, 4, 5].map((n) => (\n <button\n key={n}\n type=\"button\"\n aria-label={`Rate talent ${n} of 5`}\n disabled={rate.isPending}\n onClick={() =>\n void run(() => rate.mutateAsync({ input: { offerId: offer.id, score: n } }))\n }\n className=\"rounded p-0.5\"\n >\n <Star className=\"h-4 w-4 text-text-muted hover:text-status-warning-text\" />\n </button>\n ))}\n </span>\n )}\n {ratedTalent && <span className=\"text-xs text-text-secondary\">Talent rated</span>}\n </div>\n </li>\n );\n};\n\nexport const ApplicationCastingActions: FC<Props> = ({\n applicationId,\n applicantId,\n applicationStatus,\n defaultPayMinorUnits,\n defaultCurrency,\n callbacks,\n offers,\n}) => {\n const [panel, setPanel] = useState<Panel>('none');\n const reputation = useReputation('PERSON', applicantId);\n const cancel = useCancelCallback();\n const completeCallback = useCompleteCallback();\n const [error, setError] = useState<string | null>(null);\n const status = applicationStatus.toUpperCase();\n const canCallback = ['SUBMITTED', 'SHORTLISTED', 'CALLBACK'].includes(status);\n const liveOffer = offers.some((o) => o.status === 'SENT' || o.status === 'ACCEPTED');\n const canOffer = !['REJECTED', 'WITHDRAWN'].includes(status) && !liveOffer;\n\n const run = async (fn: () => Promise<unknown>) => {\n setError(null);\n try {\n await fn();\n } catch (err) {\n setError(errorText(err));\n }\n };\n\n return (\n <div\n className=\"mt-3 border-t border-border-seam pt-3\"\n data-testid=\"application-casting-actions\"\n >\n <p className=\"flex items-center gap-1.5 text-xs text-text-secondary\">\n <Star className=\"h-3.5 w-3.5\" />\n {reputation.data && reputation.data.ratingCount > 0\n ? `${reputation.data.averageScore?.toFixed(1) ?? '—'} / 5 from ${reputation.data.ratingCount} production${reputation.data.ratingCount === 1 ? '' : 's'}`\n : 'No ratings from productions yet'}\n </p>\n\n {callbacks.length > 0 && (\n <ul className=\"mt-2 space-y-1.5\">\n {callbacks.map((c) => (\n <li\n key={c.id}\n className=\"flex flex-wrap items-center justify-between gap-2 text-xs\"\n data-testid=\"team-callback-row\"\n >\n <span className=\"text-text-primary\">\n Callback {formatDate(c.scheduledStart)} ·{' '}\n {c.format === 'VIRTUAL' ? 'online' : (c.location ?? 'in person')}\n </span>\n <span className=\"flex items-center gap-1.5\">\n <StatusBadge status={c.status} />\n {(c.status === 'PROPOSED' || c.status === 'CONFIRMED') && (\n <button\n type=\"button\"\n className={smallSecondary}\n disabled={cancel.isPending}\n onClick={() => void run(() => cancel.mutateAsync({ id: c.id }))}\n >\n Cancel\n </button>\n )}\n {c.status === 'CONFIRMED' && (\n <button\n type=\"button\"\n className={smallSecondary}\n disabled={completeCallback.isPending}\n onClick={() => void run(() => completeCallback.mutateAsync({ id: c.id }))}\n >\n Done\n </button>\n )}\n </span>\n </li>\n ))}\n </ul>\n )}\n\n {offers.length > 0 && (\n <ul className=\"mt-2 space-y-1.5\">\n {offers.map((o) => (\n <OfferRow key={o.id} offer={o} />\n ))}\n </ul>\n )}\n\n {error && (\n <p role=\"alert\" className=\"mt-2 text-xs text-status-error-text\">\n {error}\n </p>\n )}\n\n <div className=\"mt-2 flex flex-wrap gap-1.5\">\n {canCallback && (\n <button\n type=\"button\"\n className={smallSecondary}\n aria-expanded={panel === 'callback'}\n onClick={() => setPanel((p) => (p === 'callback' ? 'none' : 'callback'))}\n >\n <CalendarPlus className=\"h-3.5 w-3.5\" />\n Schedule callback\n </button>\n )}\n {canOffer && (\n <button\n type=\"button\"\n className={smallSecondary}\n aria-expanded={panel === 'offer'}\n onClick={() => setPanel((p) => (p === 'offer' ? 'none' : 'offer'))}\n >\n <FileText className=\"h-3.5 w-3.5\" />\n Make an offer\n </button>\n )}\n </div>\n {panel === 'callback' && (\n <ScheduleCallbackForm applicationId={applicationId} onDone={() => setPanel('none')} />\n )}\n {panel === 'offer' && (\n <SendOfferForm\n applicationId={applicationId}\n defaultPayMinorUnits={defaultPayMinorUnits}\n defaultCurrency={defaultCurrency}\n onDone={() => setPanel('none')}\n />\n )}\n </div>\n );\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"StatusBadge.d.ts","sourceRoot":"","sources":["../../../src/hookmovies/components/StatusBadge.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAGhC,UAAU,gBAAgB;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA+ED,eAAO,MAAM,WAAW,EAAE,EAAE,CAAC,gBAAgB,CAuB5C,CAAC"}
1
+ {"version":3,"file":"StatusBadge.d.ts","sourceRoot":"","sources":["../../../src/hookmovies/components/StatusBadge.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAGhC,UAAU,gBAAgB;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA4FD,eAAO,MAAM,WAAW,EAAE,EAAE,CAAC,gBAAgB,CAuB5C,CAAC"}
@@ -38,6 +38,17 @@ var r = {
38
38
  active: "success",
39
39
  expired: "outline",
40
40
  revoked: "destructive",
41
+ proposed: "warning",
42
+ confirmed: "success",
43
+ declined: "destructive",
44
+ sent: "warning",
45
+ accepted: "success",
46
+ unpaid: "secondary",
47
+ marked_paid: "info",
48
+ receipt_confirmed: "success",
49
+ under_review: "warning",
50
+ resolved: "success",
51
+ dismissed: "outline",
41
52
  inactive: "secondary",
42
53
  error: "destructive",
43
54
  failed: "destructive",
@@ -1 +1 @@
1
- {"version":3,"file":"StatusBadge.js","names":[],"sources":["../../../src/hookmovies/components/StatusBadge.tsx"],"sourcesContent":["/**\n * Status Badge Component\n * @module hookmovies/components\n *\n * A colored badge based on status value with semantic color mapping\n * for various order, cart, and investment statuses.\n */\n\nimport type { FC } from 'react';\nimport { cn } from '../utils/cn';\n\ninterface StatusBadgeProps {\n status: string;\n className?: string;\n}\n\ntype BadgeVariant = 'success' | 'warning' | 'destructive' | 'secondary' | 'info' | 'outline';\n\nconst variantStyles: Record<BadgeVariant, string> = {\n success: 'bg-status-success-bg-subtle text-status-success-text',\n warning: 'bg-status-warning-bg-subtle text-status-warning-text',\n destructive: 'bg-status-error-bg-subtle text-status-error-text',\n secondary: 'bg-bg-sunken text-text-secondary',\n info: 'bg-status-info-bg-subtle text-status-info-text',\n outline: 'border border-border-seam text-text-primary',\n};\n\n/** Statuses that represent a live/active state get an opacity-only glow pulse on their dot. */\nconst liveVariants: ReadonlySet<BadgeVariant> = new Set<BadgeVariant>(['success', 'info']);\n\nconst statusVariantMap: Record<string, BadgeVariant> = {\n // Title statuses\n draft: 'secondary',\n in_review: 'warning',\n scheduled: 'info',\n published: 'success',\n unpublished: 'outline',\n archived: 'outline',\n\n // Production statuses\n development: 'secondary',\n greenlit: 'info',\n in_production: 'warning',\n post_production: 'warning',\n released: 'success',\n shelved: 'destructive',\n\n // Audition statuses\n open: 'success',\n reviewing: 'warning',\n callbacks: 'info',\n closed: 'outline',\n cancelled: 'destructive',\n\n // Application statuses\n submitted: 'secondary',\n shortlisted: 'info',\n callback: 'info',\n offered: 'success',\n rejected: 'destructive',\n withdrawn: 'outline',\n\n // Review statuses\n pending: 'secondary',\n hidden: 'outline',\n removed: 'destructive',\n\n // Rights window / entitlement statuses\n active: 'success',\n expired: 'outline',\n revoked: 'destructive',\n\n // Generic\n inactive: 'secondary',\n error: 'destructive',\n failed: 'destructive',\n processing: 'warning',\n completed: 'success',\n};\n\nconst dotColor: Record<BadgeVariant, string> = {\n success: 'bg-status-success-text',\n warning: 'bg-status-warning-text',\n destructive: 'bg-status-error-text',\n secondary: 'bg-text-muted',\n info: 'bg-status-info-text',\n outline: 'bg-text-muted',\n};\n\nfunction formatStatusLabel(status: string): string {\n return status.replace(/_/g, ' ').replace(/\\b\\w/g, (char) => char.toUpperCase());\n}\n\nexport const StatusBadge: FC<StatusBadgeProps> = ({ status, className }) => {\n const variant = statusVariantMap[status.toLowerCase()] || 'secondary';\n const isLive = liveVariants.has(variant);\n\n return (\n <span\n className={cn(\n 'inline-flex items-center gap-1.5 rounded-full px-2.5 py-0.5 text-xs font-medium',\n variantStyles[variant],\n className\n )}\n >\n <span\n className={cn(\n 'size-1.5 rounded-full',\n dotColor[variant],\n isLive && 'motion-safe:animate-vc-glow-pulse'\n )}\n aria-hidden=\"true\"\n />\n {formatStatusLabel(status)}\n </span>\n );\n};\n"],"mappings":";;;AAkBA,IAAM,IAA8C;CAClD,SAAS;CACT,SAAS;CACT,aAAa;CACb,WAAW;CACX,MAAM;CACN,SAAS;CACV,EAGK,IAA0C,IAAI,IAAkB,CAAC,WAAW,OAAO,CAAC,EAEpF,IAAiD;CAErD,OAAO;CACP,WAAW;CACX,WAAW;CACX,WAAW;CACX,aAAa;CACb,UAAU;CAGV,aAAa;CACb,UAAU;CACV,eAAe;CACf,iBAAiB;CACjB,UAAU;CACV,SAAS;CAGT,MAAM;CACN,WAAW;CACX,WAAW;CACX,QAAQ;CACR,WAAW;CAGX,WAAW;CACX,aAAa;CACb,UAAU;CACV,SAAS;CACT,UAAU;CACV,WAAW;CAGX,SAAS;CACT,QAAQ;CACR,SAAS;CAGT,QAAQ;CACR,SAAS;CACT,SAAS;CAGT,UAAU;CACV,OAAO;CACP,QAAQ;CACR,YAAY;CACZ,WAAW;CACZ,EAEK,IAAyC;CAC7C,SAAS;CACT,SAAS;CACT,aAAa;CACb,WAAW;CACX,MAAM;CACN,SAAS;CACV;AAED,SAAS,EAAkB,GAAwB;AACjD,QAAO,EAAO,QAAQ,MAAM,IAAI,CAAC,QAAQ,UAAU,MAAS,EAAK,aAAa,CAAC;;AAGjF,IAAa,KAAqC,EAAE,WAAQ,mBAAgB;CAC1E,IAAM,IAAU,EAAiB,EAAO,aAAa,KAAK,aACpD,IAAS,EAAa,IAAI,EAAQ;AAExC,QACE,kBAAC,QAAD;EACE,WAAW,EACT,mFACA,EAAc,IACd,EACD;YALH,CAOE,kBAAC,QAAD;GACE,WAAW,EACT,yBACA,EAAS,IACT,KAAU,oCACX;GACD,eAAY;GACZ,CAAA,EACD,EAAkB,EAAO,CACrB"}
1
+ {"version":3,"file":"StatusBadge.js","names":[],"sources":["../../../src/hookmovies/components/StatusBadge.tsx"],"sourcesContent":["/**\n * Status Badge Component\n * @module hookmovies/components\n *\n * A colored badge based on status value with semantic color mapping\n * for various order, cart, and investment statuses.\n */\n\nimport type { FC } from 'react';\nimport { cn } from '../utils/cn';\n\ninterface StatusBadgeProps {\n status: string;\n className?: string;\n}\n\ntype BadgeVariant = 'success' | 'warning' | 'destructive' | 'secondary' | 'info' | 'outline';\n\nconst variantStyles: Record<BadgeVariant, string> = {\n success: 'bg-status-success-bg-subtle text-status-success-text',\n warning: 'bg-status-warning-bg-subtle text-status-warning-text',\n destructive: 'bg-status-error-bg-subtle text-status-error-text',\n secondary: 'bg-bg-sunken text-text-secondary',\n info: 'bg-status-info-bg-subtle text-status-info-text',\n outline: 'border border-border-seam text-text-primary',\n};\n\n/** Statuses that represent a live/active state get an opacity-only glow pulse on their dot. */\nconst liveVariants: ReadonlySet<BadgeVariant> = new Set<BadgeVariant>(['success', 'info']);\n\nconst statusVariantMap: Record<string, BadgeVariant> = {\n // Title statuses\n draft: 'secondary',\n in_review: 'warning',\n scheduled: 'info',\n published: 'success',\n unpublished: 'outline',\n archived: 'outline',\n\n // Production statuses\n development: 'secondary',\n greenlit: 'info',\n in_production: 'warning',\n post_production: 'warning',\n released: 'success',\n shelved: 'destructive',\n\n // Audition statuses\n open: 'success',\n reviewing: 'warning',\n callbacks: 'info',\n closed: 'outline',\n cancelled: 'destructive',\n\n // Application statuses\n submitted: 'secondary',\n shortlisted: 'info',\n callback: 'info',\n offered: 'success',\n rejected: 'destructive',\n withdrawn: 'outline',\n\n // Review statuses\n pending: 'secondary',\n hidden: 'outline',\n removed: 'destructive',\n\n // Rights window / entitlement statuses\n active: 'success',\n expired: 'outline',\n revoked: 'destructive',\n\n // Casting trust layer (callbacks, offers, payment, disputes)\n proposed: 'warning',\n confirmed: 'success',\n declined: 'destructive',\n sent: 'warning',\n accepted: 'success',\n unpaid: 'secondary',\n marked_paid: 'info',\n receipt_confirmed: 'success',\n under_review: 'warning',\n resolved: 'success',\n dismissed: 'outline',\n\n // Generic\n inactive: 'secondary',\n error: 'destructive',\n failed: 'destructive',\n processing: 'warning',\n completed: 'success',\n};\n\nconst dotColor: Record<BadgeVariant, string> = {\n success: 'bg-status-success-text',\n warning: 'bg-status-warning-text',\n destructive: 'bg-status-error-text',\n secondary: 'bg-text-muted',\n info: 'bg-status-info-text',\n outline: 'bg-text-muted',\n};\n\nfunction formatStatusLabel(status: string): string {\n return status.replace(/_/g, ' ').replace(/\\b\\w/g, (char) => char.toUpperCase());\n}\n\nexport const StatusBadge: FC<StatusBadgeProps> = ({ status, className }) => {\n const variant = statusVariantMap[status.toLowerCase()] || 'secondary';\n const isLive = liveVariants.has(variant);\n\n return (\n <span\n className={cn(\n 'inline-flex items-center gap-1.5 rounded-full px-2.5 py-0.5 text-xs font-medium',\n variantStyles[variant],\n className\n )}\n >\n <span\n className={cn(\n 'size-1.5 rounded-full',\n dotColor[variant],\n isLive && 'motion-safe:animate-vc-glow-pulse'\n )}\n aria-hidden=\"true\"\n />\n {formatStatusLabel(status)}\n </span>\n );\n};\n"],"mappings":";;;AAkBA,IAAM,IAA8C;CAClD,SAAS;CACT,SAAS;CACT,aAAa;CACb,WAAW;CACX,MAAM;CACN,SAAS;CACV,EAGK,IAA0C,IAAI,IAAkB,CAAC,WAAW,OAAO,CAAC,EAEpF,IAAiD;CAErD,OAAO;CACP,WAAW;CACX,WAAW;CACX,WAAW;CACX,aAAa;CACb,UAAU;CAGV,aAAa;CACb,UAAU;CACV,eAAe;CACf,iBAAiB;CACjB,UAAU;CACV,SAAS;CAGT,MAAM;CACN,WAAW;CACX,WAAW;CACX,QAAQ;CACR,WAAW;CAGX,WAAW;CACX,aAAa;CACb,UAAU;CACV,SAAS;CACT,UAAU;CACV,WAAW;CAGX,SAAS;CACT,QAAQ;CACR,SAAS;CAGT,QAAQ;CACR,SAAS;CACT,SAAS;CAGT,UAAU;CACV,WAAW;CACX,UAAU;CACV,MAAM;CACN,UAAU;CACV,QAAQ;CACR,aAAa;CACb,mBAAmB;CACnB,cAAc;CACd,UAAU;CACV,WAAW;CAGX,UAAU;CACV,OAAO;CACP,QAAQ;CACR,YAAY;CACZ,WAAW;CACZ,EAEK,IAAyC;CAC7C,SAAS;CACT,SAAS;CACT,aAAa;CACb,WAAW;CACX,MAAM;CACN,SAAS;CACV;AAED,SAAS,EAAkB,GAAwB;AACjD,QAAO,EAAO,QAAQ,MAAM,IAAI,CAAC,QAAQ,UAAU,MAAS,EAAK,aAAa,CAAC;;AAGjF,IAAa,KAAqC,EAAE,WAAQ,mBAAgB;CAC1E,IAAM,IAAU,EAAiB,EAAO,aAAa,KAAK,aACpD,IAAS,EAAa,IAAI,EAAQ;AAExC,QACE,kBAAC,QAAD;EACE,WAAW,EACT,mFACA,EAAc,IACd,EACD;YALH,CAOE,kBAAC,QAAD;GACE,WAAW,EACT,yBACA,EAAS,IACT,KAAU,oCACX;GACD,eAAY;GACZ,CAAA,EACD,EAAkB,EAAO,CACrB"}