@burdenoff/microfe-buildmyiq 2026.720.3 → 2026.720.5

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.
@@ -5,23 +5,24 @@ import { MetricsCard as n } from "../../components/MetricsCard.js";
5
5
  import { formatDate as r, formatDateTime as i } from "../../utils/formatters.js";
6
6
  import { StatusBadge as a } from "../../components/StatusBadge.js";
7
7
  import { EmptyState as o } from "../../components/EmptyState.js";
8
- import { ErrorView as s, LoadingView as ee } from "../../components/StateViews.js";
9
- import { DataTable as te } from "../../components/DataTable.js";
10
- import { Tabs as c } from "../../components/Tabs.js";
11
- import { Pagination as l } from "../../components/Pagination.js";
12
- import { Avatar as u } from "../../components/Avatar.js";
13
- import { useBuiGradeSubmission as d, useBuiSubmissions as ne } from "../../hooks/useBuildmyiqApi.js";
14
- import { useCursorPager as re } from "../../hooks/useCursorPager.js";
8
+ import { ErrorView as s, LoadingView as c } from "../../components/StateViews.js";
9
+ import { DataTable as l } from "../../components/DataTable.js";
10
+ import { Tabs as u } from "../../components/Tabs.js";
11
+ import { Pagination as d } from "../../components/Pagination.js";
12
+ import { Avatar as f } from "../../components/Avatar.js";
13
+ import { useBuiGradeSubmission as p, useBuiSubmission as m, useBuiSubmissions as h } from "../../hooks/useBuildmyiqApi.js";
14
+ import { useCursorPager as g } from "../../hooks/useCursorPager.js";
15
15
  import "../../hooks/index.js";
16
- import { BuiPermissionButton as ie } from "../../components/BuiPermissionButton.js";
16
+ import { BuiPermissionButton as _ } from "../../components/BuiPermissionButton.js";
17
17
  import "../../components/index.js";
18
- import { useMemo as f, useState as p } from "react";
19
- import { BookOpen as ae, CheckCircle2 as oe, ClipboardList as se, Clock as m, GraduationCap as ce, Undo2 as le } from "lucide-react";
20
- import { Fragment as h, jsx as g, jsxs as _ } from "react/jsx-runtime";
21
- import { Button as v, Input as y, Label as b, Sheet as ue, SheetContent as de, SheetDescription as fe, SheetFooter as pe, SheetHeader as me, SheetTitle as he, Switch as ge, Textarea as _e } from "@burdenoff/fe-libs/ui";
22
- import { useMediaQuery as ve } from "@burdenoff/fe-libs/shared/hooks";
18
+ import { useEffect as v, useMemo as y, useState as b } from "react";
19
+ import { BookOpen as x, CheckCircle2 as S, ClipboardList as C, Clock as w, GraduationCap as T, Undo2 as E } from "lucide-react";
20
+ import { useParams as D } from "react-router-dom";
21
+ import { Fragment as O, jsx as k, jsxs as A } from "react/jsx-runtime";
22
+ import { Button as j, Input as M, Label as N, Sheet as P, SheetContent as F, SheetDescription as I, SheetFooter as L, SheetHeader as R, SheetTitle as z, Switch as B, Textarea as V } from "@burdenoff/fe-libs/ui";
23
+ import { useMediaQuery as H } from "@burdenoff/fe-libs/shared/hooks";
23
24
  //#region src/buildmyiq/pages/submissions/SubmissionsPage.tsx
24
- var x = 24, ye = [
25
+ var U = 24, W = [
25
26
  {
26
27
  value: "ALL",
27
28
  label: "All"
@@ -42,183 +43,414 @@ var x = 24, ye = [
42
43
  value: "RETURNED",
43
44
  label: "Returned"
44
45
  }
45
- ], be = [{
46
+ ], G = [{
46
47
  value: "submission",
47
48
  label: "Submission"
48
49
  }, {
49
50
  value: "details",
50
51
  label: "Details"
51
- }], S = (e) => e.length > 10 ? `${e.slice(0, 8)}…` : e, xe = (e) => r(e, {
52
+ }], K = (e) => e.length > 10 ? `${e.slice(0, 8)}…` : e, ee = (e) => r(e, {
52
53
  day: void 0,
53
54
  month: void 0,
54
55
  year: void 0,
55
56
  hour: "numeric",
56
57
  minute: "2-digit"
57
- }), C = (e) => typeof e == "object" && !!e && !Array.isArray(e), w = (e) => e == null ? "—" : typeof e == "string" ? e : typeof e == "number" || typeof e == "boolean" ? String(e) : JSON.stringify(e, null, 2), T = ({ answers: e }) => {
58
- if (e == null) return /* @__PURE__ */ g("p", {
58
+ }), q = (e) => typeof e == "object" && !!e && !Array.isArray(e), J = (e) => e == null ? "—" : typeof e == "string" ? e : typeof e == "number" || typeof e == "boolean" ? String(e) : JSON.stringify(e, null, 2), Y = ({ answers: e }) => {
59
+ if (e == null) return /* @__PURE__ */ k("p", {
59
60
  className: "text-sm text-text-secondary",
60
61
  children: "No answers were submitted."
61
62
  });
62
- if (C(e)) {
63
+ if (q(e)) {
63
64
  let t = Object.entries(e);
64
- return t.length === 0 ? /* @__PURE__ */ g("p", {
65
+ return t.length === 0 ? /* @__PURE__ */ k("p", {
65
66
  className: "text-sm text-text-secondary",
66
67
  children: "No answers were submitted."
67
- }) : /* @__PURE__ */ g("ol", {
68
+ }) : /* @__PURE__ */ k("ol", {
68
69
  className: "grid gap-2.5",
69
- children: t.map(([e, t], n) => /* @__PURE__ */ _("li", {
70
+ children: t.map(([e, t], n) => /* @__PURE__ */ A("li", {
70
71
  className: "grid gap-1 rounded-lg border border-border-seam/70 bg-bg-surface/60 p-3 sm:grid-cols-[minmax(0,7rem)_1fr] sm:gap-3",
71
- children: [/* @__PURE__ */ _("div", {
72
+ children: [/* @__PURE__ */ A("div", {
72
73
  className: "flex items-baseline gap-2 sm:col-span-1",
73
- children: [/* @__PURE__ */ _("span", {
74
+ children: [/* @__PURE__ */ A("span", {
74
75
  className: "shrink-0 text-xs font-semibold text-[var(--color-accent-teal)] tabular-nums",
75
76
  children: ["Q", n + 1]
76
- }), /* @__PURE__ */ g("span", {
77
+ }), /* @__PURE__ */ k("span", {
77
78
  className: "break-words font-mono text-xs text-text-secondary",
78
79
  children: e
79
80
  })]
80
- }), /* @__PURE__ */ g("span", {
81
+ }), /* @__PURE__ */ k("span", {
81
82
  className: "whitespace-pre-wrap break-words text-sm text-text-primary sm:col-span-1",
82
- children: w(t)
83
+ children: J(t)
83
84
  })]
84
85
  }, e))
85
86
  });
86
87
  }
87
- return /* @__PURE__ */ g("pre", {
88
+ return /* @__PURE__ */ k("pre", {
88
89
  className: "overflow-x-auto whitespace-pre-wrap break-words rounded-lg border border-border-seam/70 bg-bg-surface/60 p-3 text-xs text-text-primary",
89
90
  children: JSON.stringify(e, null, 2)
90
91
  });
91
- }, E = ({ label: e, children: t }) => /* @__PURE__ */ _("div", {
92
+ }, X = ({ label: e, children: t }) => /* @__PURE__ */ A("div", {
92
93
  className: "min-w-0",
93
- children: [/* @__PURE__ */ g("p", {
94
+ children: [/* @__PURE__ */ k("p", {
94
95
  className: "text-xs font-medium uppercase tracking-wide text-text-secondary",
95
96
  children: e
96
- }), /* @__PURE__ */ g("div", {
97
+ }), /* @__PURE__ */ k("div", {
97
98
  className: "mt-0.5 text-sm text-text-primary",
98
99
  children: t
99
100
  })]
100
- }), D = () => {
101
- let { currentUser: C } = e(), w = ve("(min-width: 768px)"), [D, O] = p("ALL"), k = re(), [A, j] = p(null), [M, N] = p("submission"), [P, F] = p(!1), [I, L] = p(""), [R, z] = p(!1), [B, V] = p(""), [H, U] = p(null), { data: W, isLoading: Se, isError: Ce, refetch: we } = ne({
102
- status: D === "ALL" ? void 0 : D,
103
- cursor: k.cursor,
104
- limit: x
105
- }), G = d(), K = f(() => W?.items ?? [], [W]), q = f(() => {
106
- if (!C) return;
107
- let e = [C.firstName, C.lastName].filter(Boolean).join(" ").trim();
108
- return C.name?.trim() || e || C.username || C.email;
109
- }, [C]), J = f(() => {
101
+ }), te = ({ submission: e, currentUser: t, meName: n, isMe: r, learnerLabel: o, gradeSubmission: s, onClose: c }) => {
102
+ let [l, d] = b("submission"), [p, m] = b(!1), [h, g] = b(e.score == null ? "" : String(e.score)), [v, y] = b(e.passed ?? !1), [x, S] = b(e.feedback ?? ""), [C, w] = b(null), T = e.status === "SUBMITTED" || e.status === "GRADING", E = e.status === "GRADED" || e.status === "RETURNED", D = e.status === "IN_PROGRESS", P = T || p;
103
+ return /* @__PURE__ */ A(O, { children: [
104
+ /* @__PURE__ */ A(R, {
105
+ className: "border-b border-border-seam p-5 pr-12",
106
+ children: [
107
+ /* @__PURE__ */ A("div", {
108
+ className: "flex items-center gap-3",
109
+ children: [/* @__PURE__ */ k(f, {
110
+ size: "md",
111
+ name: r(e.learnerId) ? n : void 0,
112
+ seed: e.learnerId,
113
+ src: r(e.learnerId) ? t?.avatar : void 0
114
+ }), /* @__PURE__ */ A("div", {
115
+ className: "min-w-0",
116
+ children: [/* @__PURE__ */ k(z, {
117
+ className: "truncate text-lg",
118
+ children: o(e.learnerId)
119
+ }), /* @__PURE__ */ A(I, {
120
+ className: "truncate font-mono text-xs",
121
+ title: e.assessmentId,
122
+ children: ["Assessment ", K(e.assessmentId)]
123
+ })]
124
+ })]
125
+ }),
126
+ /* @__PURE__ */ A("p", {
127
+ className: "text-xs text-text-secondary",
128
+ children: [
129
+ "Attempt #",
130
+ e.attempt,
131
+ " · Submitted ",
132
+ i(e.submittedAt)
133
+ ]
134
+ }),
135
+ /* @__PURE__ */ k("div", {
136
+ className: "pt-1",
137
+ children: /* @__PURE__ */ k(a, { status: e.status })
138
+ })
139
+ ]
140
+ }),
141
+ /* @__PURE__ */ A("div", {
142
+ className: "flex-1 overflow-y-auto px-5 py-4",
143
+ children: [
144
+ /* @__PURE__ */ k(u, {
145
+ items: G,
146
+ value: l,
147
+ onChange: d,
148
+ className: "mb-4"
149
+ }),
150
+ l === "submission" ? /* @__PURE__ */ A("div", { children: [/* @__PURE__ */ A("p", {
151
+ className: "mb-2 text-sm font-semibold text-text-primary",
152
+ children: ["Answers ", /* @__PURE__ */ k("span", {
153
+ className: "font-normal text-text-secondary",
154
+ children: "(read-only)"
155
+ })]
156
+ }), /* @__PURE__ */ k(Y, { answers: e.answers })] }) : /* @__PURE__ */ A("div", {
157
+ className: "grid grid-cols-2 gap-4 rounded-xl bg-bg-sunken/60 p-4",
158
+ children: [
159
+ /* @__PURE__ */ k(X, {
160
+ label: "Status",
161
+ children: /* @__PURE__ */ k(a, { status: e.status })
162
+ }),
163
+ /* @__PURE__ */ k(X, {
164
+ label: "Attempt",
165
+ children: /* @__PURE__ */ A("span", {
166
+ className: "tabular-nums",
167
+ children: ["#", e.attempt]
168
+ })
169
+ }),
170
+ /* @__PURE__ */ k(X, {
171
+ label: "Submitted",
172
+ children: i(e.submittedAt)
173
+ }),
174
+ /* @__PURE__ */ k(X, {
175
+ label: "Assessment",
176
+ children: /* @__PURE__ */ k("span", {
177
+ className: "font-mono text-xs",
178
+ title: e.assessmentId,
179
+ children: K(e.assessmentId)
180
+ })
181
+ }),
182
+ e.enrollmentId && /* @__PURE__ */ k(X, {
183
+ label: "Enrollment",
184
+ children: /* @__PURE__ */ k("span", {
185
+ className: "font-mono text-xs",
186
+ title: e.enrollmentId,
187
+ children: K(e.enrollmentId)
188
+ })
189
+ }),
190
+ e.gradedAt && /* @__PURE__ */ k(X, {
191
+ label: "Graded",
192
+ children: i(e.gradedAt)
193
+ })
194
+ ]
195
+ }),
196
+ /* @__PURE__ */ A("div", {
197
+ className: "mt-6 border-t border-border-seam pt-5",
198
+ children: [
199
+ /* @__PURE__ */ k("p", {
200
+ className: "mb-3 text-sm font-semibold text-text-primary",
201
+ children: "Grade"
202
+ }),
203
+ D && /* @__PURE__ */ k("p", {
204
+ className: "rounded-lg bg-bg-sunken/60 px-4 py-3 text-sm text-text-secondary",
205
+ children: "This attempt is still in progress — there is nothing to grade until the learner submits."
206
+ }),
207
+ E && !p && /* @__PURE__ */ A("div", {
208
+ className: "rounded-xl border border-border-seam p-4",
209
+ children: [/* @__PURE__ */ A("div", {
210
+ className: "flex items-start justify-between gap-3",
211
+ children: [/* @__PURE__ */ A("div", {
212
+ className: "grid grid-cols-2 gap-4",
213
+ children: [/* @__PURE__ */ k(X, {
214
+ label: "Score",
215
+ children: /* @__PURE__ */ k("span", {
216
+ className: "tabular-nums font-semibold",
217
+ children: e.score ?? "—"
218
+ })
219
+ }), /* @__PURE__ */ k(X, {
220
+ label: "Result",
221
+ children: e.passed == null ? /* @__PURE__ */ k("span", {
222
+ className: "text-text-secondary",
223
+ children: "—"
224
+ }) : /* @__PURE__ */ k(a, { status: e.passed ? "GRADED" : "RETURNED" })
225
+ })]
226
+ }), /* @__PURE__ */ k(j, {
227
+ variant: "outline",
228
+ size: "sm",
229
+ onClick: () => m(!0),
230
+ children: "Re-grade"
231
+ })]
232
+ }), /* @__PURE__ */ k("div", {
233
+ className: "mt-3",
234
+ children: /* @__PURE__ */ k(X, {
235
+ label: "Feedback",
236
+ children: e.feedback ? /* @__PURE__ */ k("span", {
237
+ className: "whitespace-pre-wrap",
238
+ children: e.feedback
239
+ }) : /* @__PURE__ */ k("span", {
240
+ className: "text-text-secondary",
241
+ children: "No feedback provided."
242
+ })
243
+ })
244
+ })]
245
+ }),
246
+ P && /* @__PURE__ */ A("div", {
247
+ className: "grid gap-4",
248
+ children: [
249
+ /* @__PURE__ */ A("div", {
250
+ className: "grid gap-4 sm:grid-cols-2",
251
+ children: [/* @__PURE__ */ A("div", {
252
+ className: "grid gap-1.5",
253
+ children: [/* @__PURE__ */ k(N, {
254
+ htmlFor: "grade-score",
255
+ children: "Score"
256
+ }), /* @__PURE__ */ k(M, {
257
+ id: "grade-score",
258
+ type: "number",
259
+ min: "0",
260
+ step: "1",
261
+ value: h,
262
+ onChange: (e) => g(e.target.value),
263
+ placeholder: "e.g. 85"
264
+ })]
265
+ }), /* @__PURE__ */ A("div", {
266
+ className: "grid gap-1.5",
267
+ children: [/* @__PURE__ */ k(N, {
268
+ htmlFor: "grade-passed",
269
+ children: "Result"
270
+ }), /* @__PURE__ */ A("div", {
271
+ className: "flex h-10 items-center gap-3",
272
+ children: [/* @__PURE__ */ k(B, {
273
+ id: "grade-passed",
274
+ checked: v,
275
+ onCheckedChange: y
276
+ }), /* @__PURE__ */ k("span", {
277
+ className: "text-sm text-text-secondary",
278
+ children: v ? "Passed" : "Not passed"
279
+ })]
280
+ })]
281
+ })]
282
+ }),
283
+ /* @__PURE__ */ A("div", {
284
+ className: "grid gap-1.5",
285
+ children: [/* @__PURE__ */ k(N, {
286
+ htmlFor: "grade-feedback",
287
+ children: "Feedback"
288
+ }), /* @__PURE__ */ k(V, {
289
+ id: "grade-feedback",
290
+ value: x,
291
+ onChange: (e) => S(e.target.value),
292
+ placeholder: "Notes, corrections or encouragement for the learner (optional).",
293
+ rows: 4
294
+ })]
295
+ }),
296
+ C && /* @__PURE__ */ k("p", {
297
+ className: "text-sm text-status-error-text",
298
+ children: C
299
+ })
300
+ ]
301
+ })
302
+ ]
303
+ })
304
+ ]
305
+ }),
306
+ /* @__PURE__ */ A(L, {
307
+ className: "flex-row justify-end gap-3 border-t border-border-seam p-4",
308
+ children: [/* @__PURE__ */ k(j, {
309
+ variant: "outline",
310
+ onClick: c,
311
+ children: P ? "Cancel" : "Close"
312
+ }), P && /* @__PURE__ */ k(_, {
313
+ resource: "buildmyiq-submission",
314
+ action: "update",
315
+ deniedBehavior: "hide",
316
+ children: /* @__PURE__ */ k(j, {
317
+ onClick: async () => {
318
+ let t = h.trim(), n = Number(t);
319
+ if (t === "" || Number.isNaN(n)) {
320
+ w("Enter a numeric score.");
321
+ return;
322
+ }
323
+ if (n < 0) {
324
+ w("Score cannot be negative.");
325
+ return;
326
+ }
327
+ try {
328
+ await s.mutateAsync({
329
+ id: e.id,
330
+ input: {
331
+ score: n,
332
+ passed: v,
333
+ feedback: x.trim() || void 0
334
+ }
335
+ }), c();
336
+ } catch (e) {
337
+ w(e instanceof Error ? e.message : "Failed to save grade.");
338
+ }
339
+ },
340
+ disabled: s.isPending,
341
+ children: s.isPending ? "Saving…" : E ? "Update grade" : "Grade submission"
342
+ })
343
+ })]
344
+ })
345
+ ] });
346
+ }, Z = () => {
347
+ let { currentUser: i, navigateTo: _ } = e(), { submissionId: O } = D(), j = H("(min-width: 768px)"), [M, N] = b("ALL"), I = g(), { data: L, isLoading: R, isError: z, refetch: B } = h({
348
+ status: M === "ALL" ? void 0 : M,
349
+ cursor: I.cursor,
350
+ limit: U
351
+ }), V = p(), G = m(O), q = y(() => L?.items ?? [], [L]), J = O ?? null, Y = y(() => J ? q.find((e) => e.id === J) ?? (G.data?.id === J ? G.data : null) : null, [
352
+ J,
353
+ q,
354
+ G.data
355
+ ]), X = y(() => {
356
+ if (!i) return;
357
+ let e = [i.firstName, i.lastName].filter(Boolean).join(" ").trim();
358
+ return i.name?.trim() || e || i.username || i.email;
359
+ }, [i]), Z = y(() => {
110
360
  let e = {
111
- total: K.length,
361
+ total: q.length,
112
362
  awaiting: 0,
113
363
  graded: 0,
114
364
  returned: 0
115
365
  };
116
- for (let t of K) t.status === "SUBMITTED" || t.status === "GRADING" ? e.awaiting += 1 : t.status === "GRADED" ? e.graded += 1 : t.status === "RETURNED" && (e.returned += 1);
366
+ for (let t of q) t.status === "SUBMITTED" || t.status === "GRADING" ? e.awaiting += 1 : t.status === "GRADED" ? e.graded += 1 : t.status === "RETURNED" && (e.returned += 1);
117
367
  return e;
118
- }, [K]), Y = (e) => e === C?.id, Te = (e) => Y(e) ? "You" : `Learner ${S(e)}`, Ee = (e) => {
119
- j(e), N("submission"), L(e.score == null ? "" : String(e.score)), z(e.passed ?? !1), V(e.feedback ?? ""), F(!1), U(null);
120
- }, X = () => {
121
- j(null), F(!1), U(null);
122
- }, De = (e) => {
123
- O(e), k.reset();
124
- }, Oe = async () => {
125
- if (!A) return;
126
- let e = I.trim(), t = Number(e);
127
- if (e === "" || Number.isNaN(t)) {
128
- U("Enter a numeric score.");
129
- return;
130
- }
131
- if (t < 0) {
132
- U("Score cannot be negative.");
133
- return;
134
- }
135
- try {
136
- await G.mutateAsync({
137
- id: A.id,
138
- input: {
139
- score: t,
140
- passed: R,
141
- feedback: B.trim() || void 0
142
- }
143
- }), X();
144
- } catch (e) {
145
- U(e instanceof Error ? e.message : "Failed to save grade.");
146
- }
147
- }, Z = A != null && (A.status === "SUBMITTED" || A.status === "GRADING"), Q = A != null && (A.status === "GRADED" || A.status === "RETURNED"), ke = A != null && A.status === "IN_PROGRESS", $ = A != null && (Z || P);
148
- return /* @__PURE__ */ _(t, {
368
+ }, [q]), Q = (e) => e === i?.id, ne = (e) => Q(e) ? "You" : `Learner ${K(e)}`, re = (e) => _(`submissions/${e.id}`), $ = () => _("submissions");
369
+ return v(() => {
370
+ !J || Y || !G.isLoading && (G.isError || G.data === null) && _("submissions");
371
+ }, [
372
+ J,
373
+ Y,
374
+ G.isLoading,
375
+ G.isError,
376
+ G.data,
377
+ _
378
+ ]), /* @__PURE__ */ A(t, {
149
379
  title: "Grading",
150
380
  description: "Review and grade assessment submissions across every course in your workspace.",
151
381
  titleGradient: !0,
152
382
  aurora: !0,
153
- children: [/* @__PURE__ */ _("div", {
383
+ children: [/* @__PURE__ */ A("div", {
154
384
  className: "flex flex-col gap-6",
155
385
  children: [
156
- /* @__PURE__ */ _("div", {
386
+ /* @__PURE__ */ A("div", {
157
387
  className: "grid grid-cols-2 gap-4 xl:grid-cols-4",
158
388
  children: [
159
- /* @__PURE__ */ g(n, {
160
- icon: /* @__PURE__ */ g(se, { className: "h-5 w-5" }),
161
- value: J.total,
389
+ /* @__PURE__ */ k(n, {
390
+ icon: /* @__PURE__ */ k(C, { className: "h-5 w-5" }),
391
+ value: Z.total,
162
392
  label: "Submissions (this page)",
163
393
  featured: !0
164
394
  }),
165
- /* @__PURE__ */ g(n, {
166
- icon: /* @__PURE__ */ g(m, { className: "h-5 w-5" }),
167
- value: J.awaiting,
395
+ /* @__PURE__ */ k(n, {
396
+ icon: /* @__PURE__ */ k(w, { className: "h-5 w-5" }),
397
+ value: Z.awaiting,
168
398
  label: "Awaiting grade (this page)",
169
399
  accent: "warning"
170
400
  }),
171
- /* @__PURE__ */ g(n, {
172
- icon: /* @__PURE__ */ g(oe, { className: "h-5 w-5" }),
173
- value: J.graded,
401
+ /* @__PURE__ */ k(n, {
402
+ icon: /* @__PURE__ */ k(S, { className: "h-5 w-5" }),
403
+ value: Z.graded,
174
404
  label: "Graded (this page)",
175
405
  accent: "success"
176
406
  }),
177
- /* @__PURE__ */ g(n, {
178
- icon: /* @__PURE__ */ g(le, { className: "h-5 w-5" }),
179
- value: J.returned,
407
+ /* @__PURE__ */ k(n, {
408
+ icon: /* @__PURE__ */ k(E, { className: "h-5 w-5" }),
409
+ value: Z.returned,
180
410
  label: "Returned (this page)"
181
411
  })
182
412
  ]
183
413
  }),
184
- /* @__PURE__ */ g(c, {
185
- items: ye,
186
- value: D,
187
- onChange: De
414
+ /* @__PURE__ */ k(u, {
415
+ items: W,
416
+ value: M,
417
+ onChange: (e) => {
418
+ N(e), I.reset();
419
+ }
188
420
  }),
189
- Se ? /* @__PURE__ */ g(ee, { label: "Loading submissions…" }) : Ce ? /* @__PURE__ */ g(s, {
421
+ R ? /* @__PURE__ */ k(c, { label: "Loading submissions…" }) : z ? /* @__PURE__ */ k(s, {
190
422
  title: "Couldn't load submissions",
191
423
  message: "The grading queue failed to load.",
192
- onRetry: () => we()
193
- }) : K.length === 0 ? /* @__PURE__ */ g(o, {
424
+ onRetry: () => B()
425
+ }) : q.length === 0 ? /* @__PURE__ */ k(o, {
194
426
  illustration: "empty-data",
195
- icon: /* @__PURE__ */ g(ce, { className: "h-10 w-10" }),
196
- title: D === "ALL" ? "No submissions yet" : "Nothing in this status",
197
- description: D === "ALL" ? "When learners submit assessments, their attempts will appear here for grading." : "No submissions currently match this status filter."
198
- }) : /* @__PURE__ */ _("div", {
427
+ icon: /* @__PURE__ */ k(T, { className: "h-10 w-10" }),
428
+ title: M === "ALL" ? "No submissions yet" : "Nothing in this status",
429
+ description: M === "ALL" ? "When learners submit assessments, their attempts will appear here for grading." : "No submissions currently match this status filter."
430
+ }) : /* @__PURE__ */ A("div", {
199
431
  className: "flex flex-col gap-4",
200
- children: [/* @__PURE__ */ g(te, {
432
+ children: [/* @__PURE__ */ k(l, {
201
433
  columns: [
202
434
  {
203
435
  key: "learner",
204
436
  header: "Learner",
205
- sortValue: (e) => Y(e.learnerId) ? "" : e.learnerId,
206
- render: (e) => /* @__PURE__ */ _("div", {
437
+ sortValue: (e) => Q(e.learnerId) ? "" : e.learnerId,
438
+ render: (e) => /* @__PURE__ */ A("div", {
207
439
  className: "flex items-center gap-3",
208
- children: [/* @__PURE__ */ g(u, {
440
+ children: [/* @__PURE__ */ k(f, {
209
441
  size: "sm",
210
- name: Y(e.learnerId) ? q : void 0,
442
+ name: Q(e.learnerId) ? X : void 0,
211
443
  seed: e.learnerId,
212
- src: Y(e.learnerId) ? C?.avatar : void 0
213
- }), /* @__PURE__ */ _("div", {
444
+ src: Q(e.learnerId) ? i?.avatar : void 0
445
+ }), /* @__PURE__ */ A("div", {
214
446
  className: "min-w-0",
215
- children: [/* @__PURE__ */ g("span", {
447
+ children: [/* @__PURE__ */ k("span", {
216
448
  className: "block truncate font-medium text-text-primary",
217
449
  title: e.learnerId,
218
- children: Y(e.learnerId) ? "You" : S(e.learnerId)
219
- }), Y(e.learnerId) && q && /* @__PURE__ */ g("span", {
450
+ children: Q(e.learnerId) ? "You" : K(e.learnerId)
451
+ }), Q(e.learnerId) && X && /* @__PURE__ */ k("span", {
220
452
  className: "block truncate text-xs text-text-secondary",
221
- children: q
453
+ children: X
222
454
  })]
223
455
  })]
224
456
  })
@@ -227,12 +459,12 @@ var x = 24, ye = [
227
459
  key: "assessment",
228
460
  header: "Assessment",
229
461
  hideOnMobile: !0,
230
- render: (e) => /* @__PURE__ */ _("span", {
462
+ render: (e) => /* @__PURE__ */ A("span", {
231
463
  className: "inline-flex items-center gap-2 text-text-secondary",
232
- children: [/* @__PURE__ */ g(ae, { className: "h-4 w-4 shrink-0 opacity-70" }), /* @__PURE__ */ g("span", {
464
+ children: [/* @__PURE__ */ k(x, { className: "h-4 w-4 shrink-0 opacity-70" }), /* @__PURE__ */ k("span", {
233
465
  className: "font-mono text-xs",
234
466
  title: e.assessmentId,
235
- children: S(e.assessmentId)
467
+ children: K(e.assessmentId)
236
468
  })]
237
469
  })
238
470
  },
@@ -242,7 +474,7 @@ var x = 24, ye = [
242
474
  align: "right",
243
475
  hideOnMobile: !0,
244
476
  sortValue: (e) => e.attempt,
245
- render: (e) => /* @__PURE__ */ _("span", {
477
+ render: (e) => /* @__PURE__ */ A("span", {
246
478
  className: "tabular-nums text-text-secondary",
247
479
  children: ["#", e.attempt]
248
480
  })
@@ -251,17 +483,17 @@ var x = 24, ye = [
251
483
  key: "status",
252
484
  header: "Status",
253
485
  sortValue: (e) => e.status,
254
- render: (e) => /* @__PURE__ */ g(a, { status: e.status })
486
+ render: (e) => /* @__PURE__ */ k(a, { status: e.status })
255
487
  },
256
488
  {
257
489
  key: "score",
258
490
  header: "Score",
259
491
  align: "right",
260
492
  sortValue: (e) => e.score ?? -1,
261
- render: (e) => e.score == null ? /* @__PURE__ */ g("span", {
493
+ render: (e) => e.score == null ? /* @__PURE__ */ k("span", {
262
494
  className: "text-text-secondary",
263
495
  children: "—"
264
- }) : /* @__PURE__ */ g("span", {
496
+ }) : /* @__PURE__ */ k("span", {
265
497
  className: "tabular-nums font-semibold text-text-primary",
266
498
  children: e.score
267
499
  })
@@ -272,268 +504,59 @@ var x = 24, ye = [
272
504
  align: "right",
273
505
  hideOnMobile: !0,
274
506
  sortValue: (e) => e.submittedAt ?? e.createdAt,
275
- render: (e) => /* @__PURE__ */ _("div", {
507
+ render: (e) => /* @__PURE__ */ A("div", {
276
508
  className: "whitespace-nowrap text-right",
277
- children: [/* @__PURE__ */ g("div", {
509
+ children: [/* @__PURE__ */ k("div", {
278
510
  className: "text-text-primary",
279
511
  children: r(e.submittedAt)
280
- }), e.submittedAt && /* @__PURE__ */ g("div", {
512
+ }), e.submittedAt && /* @__PURE__ */ k("div", {
281
513
  className: "text-xs text-text-secondary",
282
- children: xe(e.submittedAt)
514
+ children: ee(e.submittedAt)
283
515
  })]
284
516
  })
285
517
  }
286
518
  ],
287
- rows: K,
519
+ rows: q,
288
520
  rowKey: (e) => e.id,
289
- onRowClick: Ee,
521
+ onRowClick: re,
290
522
  defaultSort: {
291
523
  key: "submittedAt",
292
524
  dir: "desc"
293
525
  }
294
- }), /* @__PURE__ */ g(l, {
295
- page: k.page,
296
- pageSize: x,
297
- itemCount: K.length,
298
- hasMore: W?.pageInfo?.hasMore ?? !1,
299
- onPageChange: (e) => k.onPageChange(e, W?.pageInfo?.cursor)
526
+ }), /* @__PURE__ */ k(d, {
527
+ page: I.page,
528
+ pageSize: U,
529
+ itemCount: q.length,
530
+ hasMore: L?.pageInfo?.hasMore ?? !1,
531
+ onPageChange: (e) => I.onPageChange(e, L?.pageInfo?.cursor)
300
532
  })]
301
533
  })
302
534
  ]
303
- }), /* @__PURE__ */ g(ue, {
304
- open: A != null,
535
+ }), /* @__PURE__ */ k(P, {
536
+ open: J != null,
305
537
  onOpenChange: (e) => {
306
- e || X();
538
+ e || $();
307
539
  },
308
- children: /* @__PURE__ */ g(de, {
309
- side: w ? "right" : "bottom",
310
- className: w ? "flex w-full max-w-none flex-col gap-0 p-0 sm:max-w-xl" : "flex max-h-[92vh] w-full flex-col gap-0 rounded-t-2xl p-0",
311
- children: A && /* @__PURE__ */ _(h, { children: [
312
- /* @__PURE__ */ _(me, {
313
- className: "border-b border-border-seam p-5 pr-12",
314
- children: [
315
- /* @__PURE__ */ _("div", {
316
- className: "flex items-center gap-3",
317
- children: [/* @__PURE__ */ g(u, {
318
- size: "md",
319
- name: Y(A.learnerId) ? q : void 0,
320
- seed: A.learnerId,
321
- src: Y(A.learnerId) ? C?.avatar : void 0
322
- }), /* @__PURE__ */ _("div", {
323
- className: "min-w-0",
324
- children: [/* @__PURE__ */ g(he, {
325
- className: "truncate text-lg",
326
- children: Te(A.learnerId)
327
- }), /* @__PURE__ */ _(fe, {
328
- className: "truncate font-mono text-xs",
329
- title: A.assessmentId,
330
- children: ["Assessment ", S(A.assessmentId)]
331
- })]
332
- })]
333
- }),
334
- /* @__PURE__ */ _("p", {
335
- className: "text-xs text-text-secondary",
336
- children: [
337
- "Attempt #",
338
- A.attempt,
339
- " · Submitted ",
340
- i(A.submittedAt)
341
- ]
342
- }),
343
- /* @__PURE__ */ g("div", {
344
- className: "pt-1",
345
- children: /* @__PURE__ */ g(a, { status: A.status })
346
- })
347
- ]
348
- }),
349
- /* @__PURE__ */ _("div", {
350
- className: "flex-1 overflow-y-auto px-5 py-4",
351
- children: [
352
- /* @__PURE__ */ g(c, {
353
- items: be,
354
- value: M,
355
- onChange: N,
356
- className: "mb-4"
357
- }),
358
- M === "submission" ? /* @__PURE__ */ _("div", { children: [/* @__PURE__ */ _("p", {
359
- className: "mb-2 text-sm font-semibold text-text-primary",
360
- children: ["Answers ", /* @__PURE__ */ g("span", {
361
- className: "font-normal text-text-secondary",
362
- children: "(read-only)"
363
- })]
364
- }), /* @__PURE__ */ g(T, { answers: A.answers })] }) : /* @__PURE__ */ _("div", {
365
- className: "grid grid-cols-2 gap-4 rounded-xl bg-bg-sunken/60 p-4",
366
- children: [
367
- /* @__PURE__ */ g(E, {
368
- label: "Status",
369
- children: /* @__PURE__ */ g(a, { status: A.status })
370
- }),
371
- /* @__PURE__ */ g(E, {
372
- label: "Attempt",
373
- children: /* @__PURE__ */ _("span", {
374
- className: "tabular-nums",
375
- children: ["#", A.attempt]
376
- })
377
- }),
378
- /* @__PURE__ */ g(E, {
379
- label: "Submitted",
380
- children: i(A.submittedAt)
381
- }),
382
- /* @__PURE__ */ g(E, {
383
- label: "Assessment",
384
- children: /* @__PURE__ */ g("span", {
385
- className: "font-mono text-xs",
386
- title: A.assessmentId,
387
- children: S(A.assessmentId)
388
- })
389
- }),
390
- A.enrollmentId && /* @__PURE__ */ g(E, {
391
- label: "Enrollment",
392
- children: /* @__PURE__ */ g("span", {
393
- className: "font-mono text-xs",
394
- title: A.enrollmentId,
395
- children: S(A.enrollmentId)
396
- })
397
- }),
398
- A.gradedAt && /* @__PURE__ */ g(E, {
399
- label: "Graded",
400
- children: i(A.gradedAt)
401
- })
402
- ]
403
- }),
404
- /* @__PURE__ */ _("div", {
405
- className: "mt-6 border-t border-border-seam pt-5",
406
- children: [
407
- /* @__PURE__ */ g("p", {
408
- className: "mb-3 text-sm font-semibold text-text-primary",
409
- children: "Grade"
410
- }),
411
- ke && /* @__PURE__ */ g("p", {
412
- className: "rounded-lg bg-bg-sunken/60 px-4 py-3 text-sm text-text-secondary",
413
- children: "This attempt is still in progress — there is nothing to grade until the learner submits."
414
- }),
415
- Q && !P && /* @__PURE__ */ _("div", {
416
- className: "rounded-xl border border-border-seam p-4",
417
- children: [/* @__PURE__ */ _("div", {
418
- className: "flex items-start justify-between gap-3",
419
- children: [/* @__PURE__ */ _("div", {
420
- className: "grid grid-cols-2 gap-4",
421
- children: [/* @__PURE__ */ g(E, {
422
- label: "Score",
423
- children: /* @__PURE__ */ g("span", {
424
- className: "tabular-nums font-semibold",
425
- children: A.score ?? "—"
426
- })
427
- }), /* @__PURE__ */ g(E, {
428
- label: "Result",
429
- children: A.passed == null ? /* @__PURE__ */ g("span", {
430
- className: "text-text-secondary",
431
- children: "—"
432
- }) : /* @__PURE__ */ g(a, { status: A.passed ? "GRADED" : "RETURNED" })
433
- })]
434
- }), /* @__PURE__ */ g(v, {
435
- variant: "outline",
436
- size: "sm",
437
- onClick: () => F(!0),
438
- children: "Re-grade"
439
- })]
440
- }), /* @__PURE__ */ g("div", {
441
- className: "mt-3",
442
- children: /* @__PURE__ */ g(E, {
443
- label: "Feedback",
444
- children: A.feedback ? /* @__PURE__ */ g("span", {
445
- className: "whitespace-pre-wrap",
446
- children: A.feedback
447
- }) : /* @__PURE__ */ g("span", {
448
- className: "text-text-secondary",
449
- children: "No feedback provided."
450
- })
451
- })
452
- })]
453
- }),
454
- $ && /* @__PURE__ */ _("div", {
455
- className: "grid gap-4",
456
- children: [
457
- /* @__PURE__ */ _("div", {
458
- className: "grid gap-4 sm:grid-cols-2",
459
- children: [/* @__PURE__ */ _("div", {
460
- className: "grid gap-1.5",
461
- children: [/* @__PURE__ */ g(b, {
462
- htmlFor: "grade-score",
463
- children: "Score"
464
- }), /* @__PURE__ */ g(y, {
465
- id: "grade-score",
466
- type: "number",
467
- min: "0",
468
- step: "1",
469
- value: I,
470
- onChange: (e) => L(e.target.value),
471
- placeholder: "e.g. 85"
472
- })]
473
- }), /* @__PURE__ */ _("div", {
474
- className: "grid gap-1.5",
475
- children: [/* @__PURE__ */ g(b, {
476
- htmlFor: "grade-passed",
477
- children: "Result"
478
- }), /* @__PURE__ */ _("div", {
479
- className: "flex h-10 items-center gap-3",
480
- children: [/* @__PURE__ */ g(ge, {
481
- id: "grade-passed",
482
- checked: R,
483
- onCheckedChange: z
484
- }), /* @__PURE__ */ g("span", {
485
- className: "text-sm text-text-secondary",
486
- children: R ? "Passed" : "Not passed"
487
- })]
488
- })]
489
- })]
490
- }),
491
- /* @__PURE__ */ _("div", {
492
- className: "grid gap-1.5",
493
- children: [/* @__PURE__ */ g(b, {
494
- htmlFor: "grade-feedback",
495
- children: "Feedback"
496
- }), /* @__PURE__ */ g(_e, {
497
- id: "grade-feedback",
498
- value: B,
499
- onChange: (e) => V(e.target.value),
500
- placeholder: "Notes, corrections or encouragement for the learner (optional).",
501
- rows: 4
502
- })]
503
- }),
504
- H && /* @__PURE__ */ g("p", {
505
- className: "text-sm text-status-error-text",
506
- children: H
507
- })
508
- ]
509
- })
510
- ]
511
- })
512
- ]
513
- }),
514
- /* @__PURE__ */ _(pe, {
515
- className: "flex-row justify-end gap-3 border-t border-border-seam p-4",
516
- children: [/* @__PURE__ */ g(v, {
517
- variant: "outline",
518
- onClick: X,
519
- children: $ ? "Cancel" : "Close"
520
- }), $ && /* @__PURE__ */ g(ie, {
521
- resource: "buildmyiq-submission",
522
- action: "update",
523
- deniedBehavior: "hide",
524
- children: /* @__PURE__ */ g(v, {
525
- onClick: Oe,
526
- disabled: G.isPending,
527
- children: G.isPending ? "Saving…" : Q ? "Update grade" : "Grade submission"
528
- })
529
- })]
530
- })
531
- ] })
540
+ children: /* @__PURE__ */ k(F, {
541
+ side: j ? "right" : "bottom",
542
+ className: j ? "flex w-full max-w-none flex-col gap-0 p-0 sm:max-w-xl" : "flex max-h-[92vh] w-full flex-col gap-0 rounded-t-2xl p-0",
543
+ children: Y ? /* @__PURE__ */ k(te, {
544
+ submission: Y,
545
+ currentUser: i,
546
+ meName: X,
547
+ isMe: Q,
548
+ learnerLabel: ne,
549
+ gradeSubmission: V,
550
+ onClose: $
551
+ }, Y.id) : J ? /* @__PURE__ */ k("div", {
552
+ className: "flex min-h-[300px] items-center justify-center p-5",
553
+ children: /* @__PURE__ */ k(c, { label: "Loading submission…" })
554
+ }) : null
532
555
  })
533
556
  })]
534
557
  });
535
558
  };
536
559
  //#endregion
537
- export { D as SubmissionsPage };
560
+ export { Z as SubmissionsPage };
538
561
 
539
562
  //# sourceMappingURL=SubmissionsPage.js.map