@burdenoff/microfe-technospam 2026.709.2 → 2026.709.4
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.
- package/dist/index.js +4 -4
- package/dist/technospam/TechnoSpamRoutes.d.ts.map +1 -1
- package/dist/technospam/TechnoSpamRoutes.js +100 -74
- package/dist/technospam/TechnoSpamRoutes.js.map +1 -1
- package/dist/technospam/components/PageLayout.d.ts.map +1 -1
- package/dist/technospam/components/PageLayout.js +26 -23
- package/dist/technospam/components/PageLayout.js.map +1 -1
- package/dist/technospam/components/TagInput.d.ts +18 -0
- package/dist/technospam/components/TagInput.d.ts.map +1 -0
- package/dist/technospam/components/TagInput.js +58 -0
- package/dist/technospam/components/TagInput.js.map +1 -0
- package/dist/technospam/components/TagStrip.d.ts +12 -0
- package/dist/technospam/components/TagStrip.d.ts.map +1 -0
- package/dist/technospam/components/TagStrip.js +20 -0
- package/dist/technospam/components/TagStrip.js.map +1 -0
- package/dist/technospam/components/index.d.ts +2 -0
- package/dist/technospam/components/index.d.ts.map +1 -1
- package/dist/technospam/components/index.js +2 -0
- package/dist/technospam/hooks/useNativeControls.d.ts +27 -0
- package/dist/technospam/hooks/useNativeControls.d.ts.map +1 -0
- package/dist/technospam/hooks/useNativeControls.js +18 -0
- package/dist/technospam/hooks/useNativeControls.js.map +1 -0
- package/dist/technospam/hooks/useTechnoSpamAnalytics.d.ts +1 -1
- package/dist/technospam/hooks/useTechnoSpamAnalytics.d.ts.map +1 -1
- package/dist/technospam/hooks/useTechnoSpamAnalytics.js.map +1 -1
- package/dist/technospam/hooks/useTechnoSpamPageView.d.ts +14 -0
- package/dist/technospam/hooks/useTechnoSpamPageView.d.ts.map +1 -0
- package/dist/technospam/hooks/useTechnoSpamPageView.js +26 -0
- package/dist/technospam/hooks/useTechnoSpamPageView.js.map +1 -0
- package/dist/technospam/index.js +1 -1
- package/dist/technospam/pages/AdminAdminDashboardPagePage.d.ts.map +1 -1
- package/dist/technospam/pages/AdminAdminDashboardPagePage.js +408 -399
- package/dist/technospam/pages/AdminAdminDashboardPagePage.js.map +1 -1
- package/dist/technospam/pages/ApplicationsProblemDetailsPagePage.d.ts.map +1 -1
- package/dist/technospam/pages/ApplicationsProblemDetailsPagePage.js +50 -55
- package/dist/technospam/pages/ApplicationsProblemDetailsPagePage.js.map +1 -1
- package/dist/technospam/pages/ApplicationsProblemsPagePage.js +25 -25
- package/dist/technospam/pages/CoursesCourseDetailsPagePage.d.ts.map +1 -1
- package/dist/technospam/pages/CoursesCourseDetailsPagePage.js +142 -144
- package/dist/technospam/pages/CoursesCourseDetailsPagePage.js.map +1 -1
- package/dist/technospam/pages/CoursesCoursesPagePage.js +30 -30
- package/dist/technospam/pages/HackathonsHackathonsPagePage.js +29 -29
- package/dist/technospam/pages/MentorshipMentorProfilePagePage.js +54 -54
- package/dist/technospam/pages/MentorshipMentorsPagePage.js +61 -61
- package/dist/technospam/pages/MentorshipSessionsPagePage.js +42 -42
- package/package.json +2 -2
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { useTechnoSpam as e } from "../providers/TechnoSpamProvider.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
2
|
+
import { useTechnoSpamAnalytics as t } from "../hooks/useTechnoSpamAnalytics.js";
|
|
3
|
+
import { cn as n } from "../utils/cn.js";
|
|
4
|
+
import { PageLayout as r } from "../components/PageLayout.js";
|
|
5
|
+
import { StatCard as i } from "../components/StatCard.js";
|
|
6
|
+
import { formatDateTime as a, humanizeEnum as o } from "../utils/format.js";
|
|
7
|
+
import { StatusBadge as s } from "../components/StatusBadge.js";
|
|
8
|
+
import { EmptyView as c, ErrorView as l, LoadingRows as ee } from "../components/StateViews.js";
|
|
9
|
+
import { TagStrip as te } from "../components/TagStrip.js";
|
|
8
10
|
import "../components/index.js";
|
|
9
|
-
import { notify as
|
|
10
|
-
import { useProblemQuery as
|
|
11
|
-
import { useTechnoSpamAnalytics as f } from "../hooks/useTechnoSpamAnalytics.js";
|
|
11
|
+
import { notify as u } from "../lib/toast.js";
|
|
12
|
+
import { useProblemQuery as d, useSubmissionsQuery as f, useSubmitSolution as ne } from "../api/technospamApi.js";
|
|
12
13
|
import { useEffect as p, useMemo as m, useRef as h, useState as g } from "react";
|
|
13
|
-
import { Clock as _, Code2 as v, FileText as y, Layers as b, Send as
|
|
14
|
+
import { Clock as _, Code2 as v, FileText as y, Layers as b, Send as x, Trophy as S } from "lucide-react";
|
|
14
15
|
import { useSearchParams as C } from "react-router-dom";
|
|
15
16
|
import { jsx as w, jsxs as T } from "react/jsx-runtime";
|
|
16
17
|
import { Badge as E, Button as D, GlassCard as O, Select as re, SelectContent as ie, SelectItem as ae, SelectTrigger as oe, SelectValue as se, Skeleton as k, Textarea as ce } from "@burdenoff/fe-libs/ui";
|
|
@@ -20,7 +21,7 @@ var A = [
|
|
|
20
21
|
"python",
|
|
21
22
|
"typescript"
|
|
22
23
|
];
|
|
23
|
-
function j({ label: e, children:
|
|
24
|
+
function j({ label: e, children: t, bodyClassName: r }) {
|
|
24
25
|
return /* @__PURE__ */ T("div", {
|
|
25
26
|
className: "overflow-hidden rounded-xl border border-border-strong bg-bg-sunken shadow-sm",
|
|
26
27
|
children: [/* @__PURE__ */ T("div", {
|
|
@@ -41,8 +42,8 @@ function j({ label: e, children: n, bodyClassName: r }) {
|
|
|
41
42
|
]
|
|
42
43
|
})]
|
|
43
44
|
}), /* @__PURE__ */ w("pre", {
|
|
44
|
-
className:
|
|
45
|
-
children:
|
|
45
|
+
className: n("overflow-auto p-4 font-mono text-xs leading-relaxed text-text-primary", r),
|
|
46
|
+
children: t
|
|
46
47
|
})]
|
|
47
48
|
});
|
|
48
49
|
}
|
|
@@ -50,13 +51,13 @@ function M({ s: e }) {
|
|
|
50
51
|
return /* @__PURE__ */ T("div", {
|
|
51
52
|
className: "flex flex-wrap items-center gap-x-4 gap-y-1 rounded-lg border border-transparent px-2 py-3 transition-colors hover:border-border-seam hover:bg-bg-sunken",
|
|
52
53
|
children: [
|
|
53
|
-
/* @__PURE__ */ w(
|
|
54
|
+
/* @__PURE__ */ w(s, { status: e.verdict }),
|
|
54
55
|
/* @__PURE__ */ T("span", {
|
|
55
56
|
className: "inline-flex items-center gap-1 text-sm font-medium text-text-primary",
|
|
56
57
|
children: [
|
|
57
58
|
/* @__PURE__ */ w(v, { size: 13 }),
|
|
58
59
|
" ",
|
|
59
|
-
|
|
60
|
+
o(e.language)
|
|
60
61
|
]
|
|
61
62
|
}),
|
|
62
63
|
/* @__PURE__ */ T("span", {
|
|
@@ -79,47 +80,47 @@ function M({ s: e }) {
|
|
|
79
80
|
}),
|
|
80
81
|
/* @__PURE__ */ w("span", {
|
|
81
82
|
className: "ml-auto text-xs text-text-muted",
|
|
82
|
-
children:
|
|
83
|
+
children: a(e.createdAt)
|
|
83
84
|
})
|
|
84
85
|
]
|
|
85
86
|
});
|
|
86
87
|
}
|
|
87
88
|
function N() {
|
|
88
|
-
let [
|
|
89
|
+
let [n] = C(), a = n.get("id") ?? "", { currentUser: _, workspaceId: N } = e(), P = _?.id, { emit: F } = t(), { data: I, loading: L, error: R, refetch: z } = d(a);
|
|
89
90
|
p(() => {
|
|
90
|
-
|
|
91
|
+
a && F("technospam.problem.viewed", {
|
|
91
92
|
workspaceId: N,
|
|
92
|
-
entityId:
|
|
93
|
+
entityId: a,
|
|
93
94
|
entityType: "TEC_PROBLEM"
|
|
94
95
|
});
|
|
95
96
|
}, [
|
|
96
|
-
|
|
97
|
+
a,
|
|
97
98
|
N,
|
|
98
99
|
F
|
|
99
100
|
]);
|
|
100
|
-
let { data: B, loading: V, error: H, refetch: U } =
|
|
101
|
+
let { data: B, loading: V, error: H, refetch: U } = f({
|
|
101
102
|
...P ? { learnerId: P } : {},
|
|
102
|
-
problemId:
|
|
103
|
-
}), [W, { loading: G }] =
|
|
103
|
+
problemId: a
|
|
104
|
+
}), [W, { loading: G }] = ne(), K = I?.tecProblem ?? null, q = m(() => K?.languages?.length ? K.languages : A, [K]), [J, Y] = g(""), [X, Z] = g(""), Q = h(!1);
|
|
104
105
|
p(() => {
|
|
105
106
|
K && !Q.current && (Y(K.languages[0] ?? A[0]), Z(K.starterCode ?? ""), Q.current = !0);
|
|
106
107
|
}, [K]);
|
|
107
108
|
let $ = m(() => [...B?.tecListSubmissions.items ?? []].sort((e, t) => new Date(t.createdAt).getTime() - new Date(e.createdAt).getTime()), [B]);
|
|
108
|
-
return L && !K ? /* @__PURE__ */ T(
|
|
109
|
+
return L && !K ? /* @__PURE__ */ T(r, {
|
|
109
110
|
title: "Problem",
|
|
110
111
|
backPath: "/applications/problems-page",
|
|
111
112
|
children: [/* @__PURE__ */ w(k, { className: "mb-4 h-28 w-full rounded-xl" }), /* @__PURE__ */ w(k, { className: "h-72 w-full rounded-xl" })]
|
|
112
|
-
}) : R || !K ? /* @__PURE__ */ w(
|
|
113
|
+
}) : R || !K ? /* @__PURE__ */ w(r, {
|
|
113
114
|
title: "Problem",
|
|
114
115
|
backPath: "/applications/problems-page",
|
|
115
|
-
children: R ? /* @__PURE__ */ w(
|
|
116
|
+
children: R ? /* @__PURE__ */ w(l, {
|
|
116
117
|
title: "Couldn't load problem",
|
|
117
118
|
error: R
|
|
118
|
-
}) : /* @__PURE__ */ w(
|
|
119
|
+
}) : /* @__PURE__ */ w(c, {
|
|
119
120
|
title: "Problem not found",
|
|
120
121
|
description: "This problem may have been unpublished."
|
|
121
122
|
})
|
|
122
|
-
}) : /* @__PURE__ */ T(
|
|
123
|
+
}) : /* @__PURE__ */ T(r, {
|
|
123
124
|
hero: !0,
|
|
124
125
|
backPath: "/applications/problems-page",
|
|
125
126
|
title: K.title,
|
|
@@ -128,11 +129,11 @@ function N() {
|
|
|
128
129
|
/* @__PURE__ */ T("div", {
|
|
129
130
|
className: "mb-5 flex flex-wrap items-center gap-2",
|
|
130
131
|
children: [
|
|
131
|
-
/* @__PURE__ */ w(
|
|
132
|
+
/* @__PURE__ */ w(s, {
|
|
132
133
|
status: K.difficulty,
|
|
133
134
|
kind: "level"
|
|
134
135
|
}),
|
|
135
|
-
/* @__PURE__ */ w(
|
|
136
|
+
/* @__PURE__ */ w(s, { status: K.status }),
|
|
136
137
|
K.topic ? /* @__PURE__ */ T(E, {
|
|
137
138
|
variant: "outline",
|
|
138
139
|
className: "gap-1",
|
|
@@ -142,37 +143,31 @@ function N() {
|
|
|
142
143
|
K.topic
|
|
143
144
|
]
|
|
144
145
|
}) : null,
|
|
145
|
-
|
|
146
|
-
variant: "secondary",
|
|
147
|
-
children: [/* @__PURE__ */ w(x, {
|
|
148
|
-
size: 10,
|
|
149
|
-
className: "mr-1"
|
|
150
|
-
}), e]
|
|
151
|
-
}, e))
|
|
146
|
+
/* @__PURE__ */ w(te, { tags: K.tags })
|
|
152
147
|
]
|
|
153
148
|
}),
|
|
154
149
|
/* @__PURE__ */ T("div", {
|
|
155
150
|
className: "mb-6 grid grid-cols-2 gap-3 sm:grid-cols-4",
|
|
156
151
|
children: [
|
|
157
|
-
/* @__PURE__ */ w(
|
|
152
|
+
/* @__PURE__ */ w(i, {
|
|
158
153
|
label: "Points",
|
|
159
154
|
value: K.points,
|
|
160
155
|
icon: S,
|
|
161
156
|
tone: "amber"
|
|
162
157
|
}),
|
|
163
|
-
/* @__PURE__ */ w(
|
|
158
|
+
/* @__PURE__ */ w(i, {
|
|
164
159
|
label: "Languages",
|
|
165
160
|
value: q.length,
|
|
166
161
|
icon: v,
|
|
167
162
|
tone: "blue"
|
|
168
163
|
}),
|
|
169
|
-
/* @__PURE__ */ w(
|
|
164
|
+
/* @__PURE__ */ w(i, {
|
|
170
165
|
label: "Difficulty",
|
|
171
|
-
value:
|
|
166
|
+
value: o(K.difficulty),
|
|
172
167
|
icon: b,
|
|
173
168
|
tone: "purple"
|
|
174
169
|
}),
|
|
175
|
-
/* @__PURE__ */ w(
|
|
170
|
+
/* @__PURE__ */ w(i, {
|
|
176
171
|
label: "My submissions",
|
|
177
172
|
value: $.length,
|
|
178
173
|
icon: y,
|
|
@@ -204,7 +199,7 @@ function N() {
|
|
|
204
199
|
className: "mb-3 text-base font-semibold text-text-primary",
|
|
205
200
|
children: "Starter code"
|
|
206
201
|
}), /* @__PURE__ */ w(j, {
|
|
207
|
-
label:
|
|
202
|
+
label: o(q[0] ?? "code"),
|
|
208
203
|
bodyClassName: "max-h-72",
|
|
209
204
|
children: K.starterCode
|
|
210
205
|
})]
|
|
@@ -230,7 +225,7 @@ function N() {
|
|
|
230
225
|
children: /* @__PURE__ */ w(se, { placeholder: "Choose a language" })
|
|
231
226
|
}), /* @__PURE__ */ w(ie, { children: q.map((e) => /* @__PURE__ */ w(ae, {
|
|
232
227
|
value: e,
|
|
233
|
-
children:
|
|
228
|
+
children: o(e)
|
|
234
229
|
}, e)) })]
|
|
235
230
|
})]
|
|
236
231
|
})]
|
|
@@ -251,7 +246,7 @@ function N() {
|
|
|
251
246
|
children: [
|
|
252
247
|
/* @__PURE__ */ w(v, { size: 13 }),
|
|
253
248
|
" ",
|
|
254
|
-
J ?
|
|
249
|
+
J ? o(J) : "solution"
|
|
255
250
|
]
|
|
256
251
|
})]
|
|
257
252
|
}), /* @__PURE__ */ w(ce, {
|
|
@@ -265,36 +260,36 @@ function N() {
|
|
|
265
260
|
/* @__PURE__ */ T(D, {
|
|
266
261
|
className: "mt-4 w-full",
|
|
267
262
|
onClick: async () => {
|
|
268
|
-
if (!
|
|
263
|
+
if (!a) return;
|
|
269
264
|
if (!J) {
|
|
270
|
-
|
|
265
|
+
u.error("Pick a language", "Choose a language before submitting.");
|
|
271
266
|
return;
|
|
272
267
|
}
|
|
273
268
|
if (!X.trim()) {
|
|
274
|
-
|
|
269
|
+
u.error("Add your solution", "Write some code before submitting.");
|
|
275
270
|
return;
|
|
276
271
|
}
|
|
277
272
|
F("technospam.problem.submit_clicked", {
|
|
278
273
|
workspaceId: N,
|
|
279
|
-
entityId:
|
|
274
|
+
entityId: a,
|
|
280
275
|
entityType: "TEC_PROBLEM",
|
|
281
276
|
language: J
|
|
282
277
|
});
|
|
283
278
|
let e = await W({ variables: { input: {
|
|
284
|
-
problemId:
|
|
279
|
+
problemId: a,
|
|
285
280
|
language: J,
|
|
286
281
|
code: X
|
|
287
282
|
} } });
|
|
288
283
|
e.data?.tecSubmitSolution && (F("technospam.problem.submitted", {
|
|
289
284
|
workspaceId: N,
|
|
290
|
-
entityId:
|
|
285
|
+
entityId: a,
|
|
291
286
|
entityType: "TEC_PROBLEM",
|
|
292
287
|
submissionId: e.data.tecSubmitSolution.id
|
|
293
|
-
}),
|
|
288
|
+
}), u.success("Solution submitted", "Your submission was recorded."), await Promise.all([z(), U()]));
|
|
294
289
|
},
|
|
295
290
|
disabled: G || !X.trim(),
|
|
296
291
|
children: [
|
|
297
|
-
/* @__PURE__ */ w(
|
|
292
|
+
/* @__PURE__ */ w(x, { size: 16 }),
|
|
298
293
|
" ",
|
|
299
294
|
G ? "Submitting…" : "Submit solution"
|
|
300
295
|
]
|
|
@@ -312,10 +307,10 @@ function N() {
|
|
|
312
307
|
}), V && !$.length ? /* @__PURE__ */ w(ee, {
|
|
313
308
|
count: 3,
|
|
314
309
|
height: "h-12"
|
|
315
|
-
}) : H ? /* @__PURE__ */ w(
|
|
310
|
+
}) : H ? /* @__PURE__ */ w(l, {
|
|
316
311
|
title: "Couldn't load submissions",
|
|
317
312
|
error: H
|
|
318
|
-
}) : $.length === 0 ? /* @__PURE__ */ w(
|
|
313
|
+
}) : $.length === 0 ? /* @__PURE__ */ w(c, {
|
|
319
314
|
icon: /* @__PURE__ */ w(y, { size: 24 }),
|
|
320
315
|
title: "No submissions yet",
|
|
321
316
|
description: "Submit a solution above to see your verdicts and points here."
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ApplicationsProblemDetailsPagePage.js","names":[],"sources":["../../../src/technospam/pages/ApplicationsProblemDetailsPagePage.tsx"],"sourcesContent":["import { useEffect, useMemo, useRef, useState, type ReactNode } from 'react';\nimport { useSearchParams } from 'react-router-dom';\nimport { Clock, Code2, FileText, Layers, Send, Tag, Trophy } from 'lucide-react';\nimport {\n Badge,\n Button,\n GlassCard,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Skeleton,\n Textarea,\n} from '@burdenoff/fe-libs/ui';\nimport {\n EmptyView,\n ErrorView,\n LoadingRows,\n PageLayout,\n StatCard,\n StatusBadge,\n} from '../components';\nimport { useTechnoSpam } from '../providers/TechnoSpamProvider';\nimport {\n useProblemQuery,\n useSubmissionsQuery,\n useSubmitSolution,\n type TecSubmission,\n} from '../api/technospamApi';\nimport { formatDateTime, humanizeEnum } from '../utils/format';\nimport { cn } from '../utils/cn';\nimport { notify } from '../lib/toast';\nimport { useTechnoSpamAnalytics } from '../hooks/useTechnoSpamAnalytics';\n\nconst FALLBACK_LANGUAGES = ['javascript', 'python', 'typescript'];\n\n/**\n * A dark, editor-window styled code surface: mac-style traffic-light dots plus a\n * language label header over a scrollable monospace body so read-only code reads\n * like a real IDE panel rather than a flat block.\n */\nfunction CodePanel({\n label,\n children,\n bodyClassName,\n}: {\n label: string;\n children: ReactNode;\n bodyClassName?: string;\n}) {\n return (\n <div className=\"overflow-hidden rounded-xl border border-border-strong bg-bg-sunken shadow-sm\">\n <div className=\"flex items-center justify-between gap-2 border-b border-border-seam bg-bg-canvas/40 px-4 py-2\">\n <div className=\"flex items-center gap-1.5\">\n <span className=\"h-2.5 w-2.5 rounded-full bg-status-error-border\" />\n <span className=\"h-2.5 w-2.5 rounded-full bg-status-warning-border\" />\n <span className=\"h-2.5 w-2.5 rounded-full bg-status-success-border\" />\n </div>\n <span className=\"inline-flex items-center gap-1.5 font-mono text-xs text-text-muted\">\n <Code2 size={13} /> {label}\n </span>\n </div>\n <pre\n className={cn(\n 'overflow-auto p-4 font-mono text-xs leading-relaxed text-text-primary',\n bodyClassName\n )}\n >\n {children}\n </pre>\n </div>\n );\n}\n\nfunction SubmissionRow({ s }: { s: TecSubmission }) {\n return (\n <div className=\"flex flex-wrap items-center gap-x-4 gap-y-1 rounded-lg border border-transparent px-2 py-3 transition-colors hover:border-border-seam hover:bg-bg-sunken\">\n <StatusBadge status={s.verdict} />\n <span className=\"inline-flex items-center gap-1 text-sm font-medium text-text-primary\">\n <Code2 size={13} /> {humanizeEnum(s.language)}\n </span>\n <span className=\"inline-flex items-center gap-1 text-xs text-text-muted\">\n <Clock size={12} /> {s.runtimeMs} ms\n </span>\n <span className=\"inline-flex items-center gap-1 text-xs text-text-muted\">\n <Trophy size={12} /> {s.pointsAwarded} pts\n </span>\n <span className=\"ml-auto text-xs text-text-muted\">{formatDateTime(s.createdAt)}</span>\n </div>\n );\n}\n\nexport function ApplicationsProblemDetailsPagePage() {\n const [params] = useSearchParams();\n const id = params.get('id') ?? '';\n const { currentUser, workspaceId } = useTechnoSpam();\n const learnerId = currentUser?.id;\n const { emit } = useTechnoSpamAnalytics();\n\n const { data, loading, error, refetch } = useProblemQuery(id);\n\n useEffect(() => {\n if (id) {\n emit('technospam.problem.viewed', {\n workspaceId,\n entityId: id,\n entityType: 'TEC_PROBLEM',\n });\n }\n }, [id, workspaceId, emit]);\n const {\n data: subsData,\n loading: subsLoading,\n error: subsError,\n refetch: refetchSubs,\n } = useSubmissionsQuery({ ...(learnerId ? { learnerId } : {}), problemId: id });\n const [submit, { loading: submitting }] = useSubmitSolution();\n\n const problem = data?.tecProblem ?? null;\n\n const languages = useMemo(\n () => (problem?.languages?.length ? problem.languages : FALLBACK_LANGUAGES),\n [problem]\n );\n\n const [language, setLanguage] = useState('');\n const [code, setCode] = useState('');\n const initedRef = useRef(false);\n\n useEffect(() => {\n if (problem && !initedRef.current) {\n setLanguage(problem.languages[0] ?? FALLBACK_LANGUAGES[0]!);\n setCode(problem.starterCode ?? '');\n initedRef.current = true;\n }\n }, [problem]);\n\n const submissions = useMemo(\n () =>\n [...(subsData?.tecListSubmissions.items ?? [])].sort(\n (a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()\n ),\n [subsData]\n );\n\n const handleSubmit = async () => {\n if (!id) return;\n if (!language) {\n notify.error('Pick a language', 'Choose a language before submitting.');\n return;\n }\n if (!code.trim()) {\n notify.error('Add your solution', 'Write some code before submitting.');\n return;\n }\n emit('technospam.problem.submit_clicked', {\n workspaceId,\n entityId: id,\n entityType: 'TEC_PROBLEM',\n language,\n });\n const res = await submit({ variables: { input: { problemId: id, language, code } } });\n if (res.data?.tecSubmitSolution) {\n emit('technospam.problem.submitted', {\n workspaceId,\n entityId: id,\n entityType: 'TEC_PROBLEM',\n submissionId: res.data.tecSubmitSolution.id,\n });\n notify.success('Solution submitted', 'Your submission was recorded.');\n await Promise.all([refetch(), refetchSubs()]);\n }\n };\n\n if (loading && !problem) {\n return (\n <PageLayout title=\"Problem\" backPath=\"/applications/problems-page\">\n <Skeleton className=\"mb-4 h-28 w-full rounded-xl\" />\n <Skeleton className=\"h-72 w-full rounded-xl\" />\n </PageLayout>\n );\n }\n\n if (error || !problem) {\n return (\n <PageLayout title=\"Problem\" backPath=\"/applications/problems-page\">\n {error ? (\n <ErrorView title=\"Couldn't load problem\" error={error} />\n ) : (\n <EmptyView\n title=\"Problem not found\"\n description=\"This problem may have been unpublished.\"\n />\n )}\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n hero\n backPath=\"/applications/problems-page\"\n title={problem.title}\n description={problem.topic ?? undefined}\n >\n <div className=\"mb-5 flex flex-wrap items-center gap-2\">\n <StatusBadge status={problem.difficulty} kind=\"level\" />\n <StatusBadge status={problem.status} />\n {problem.topic ? (\n <Badge variant=\"outline\" className=\"gap-1\">\n <Layers size={12} /> {problem.topic}\n </Badge>\n ) : null}\n {problem.tags.map((t) => (\n <Badge key={t} variant=\"secondary\">\n <Tag size={10} className=\"mr-1\" />\n {t}\n </Badge>\n ))}\n </div>\n\n <div className=\"mb-6 grid grid-cols-2 gap-3 sm:grid-cols-4\">\n <StatCard label=\"Points\" value={problem.points} icon={Trophy} tone=\"amber\" />\n <StatCard label=\"Languages\" value={languages.length} icon={Code2} tone=\"blue\" />\n <StatCard\n label=\"Difficulty\"\n value={humanizeEnum(problem.difficulty)}\n icon={Layers}\n tone=\"purple\"\n />\n <StatCard label=\"My submissions\" value={submissions.length} icon={FileText} tone=\"teal\" />\n </div>\n\n <div className=\"grid grid-cols-1 gap-5 lg:grid-cols-3\">\n <div className=\"space-y-5 lg:col-span-2\">\n <GlassCard className=\"p-5\">\n <h2 className=\"mb-2 text-base font-semibold text-text-primary\">Problem statement</h2>\n {problem.statement ? (\n <p className=\"whitespace-pre-wrap text-sm leading-relaxed text-text-secondary\">\n {problem.statement}\n </p>\n ) : (\n <p className=\"py-4 text-center text-sm text-text-muted\">\n The statement for this problem is being prepared.\n </p>\n )}\n </GlassCard>\n\n {problem.starterCode ? (\n <GlassCard className=\"p-5\">\n <h2 className=\"mb-3 text-base font-semibold text-text-primary\">Starter code</h2>\n <CodePanel label={humanizeEnum(languages[0] ?? 'code')} bodyClassName=\"max-h-72\">\n {problem.starterCode}\n </CodePanel>\n </GlassCard>\n ) : null}\n\n <GlassCard className=\"p-5\">\n <div className=\"mb-3 flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between\">\n <h2 className=\"text-base font-semibold text-text-primary\">Submit a solution</h2>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm text-text-secondary\">Language</span>\n <Select value={language} onValueChange={setLanguage}>\n <SelectTrigger className=\"w-full sm:w-48\">\n <SelectValue placeholder=\"Choose a language\" />\n </SelectTrigger>\n <SelectContent>\n {languages.map((l) => (\n <SelectItem key={l} value={l}>\n {humanizeEnum(l)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n </div>\n\n <div className=\"overflow-hidden rounded-xl border border-border-strong bg-bg-sunken shadow-sm\">\n <div className=\"flex items-center justify-between gap-2 border-b border-border-seam bg-bg-canvas/40 px-4 py-2\">\n <div className=\"flex items-center gap-1.5\">\n <span className=\"h-2.5 w-2.5 rounded-full bg-status-error-border\" />\n <span className=\"h-2.5 w-2.5 rounded-full bg-status-warning-border\" />\n <span className=\"h-2.5 w-2.5 rounded-full bg-status-success-border\" />\n </div>\n <span className=\"inline-flex items-center gap-1.5 font-mono text-xs text-text-muted\">\n <Code2 size={13} /> {language ? humanizeEnum(language) : 'solution'}\n </span>\n </div>\n <Textarea\n value={code}\n onChange={(e) => setCode(e.target.value)}\n placeholder=\"Write your solution…\"\n className=\"min-h-[280px] resize-y rounded-none border-0 bg-transparent font-mono text-xs leading-relaxed focus-visible:ring-0 focus-visible:ring-offset-0\"\n spellCheck={false}\n />\n </div>\n\n <Button\n className=\"mt-4 w-full\"\n onClick={handleSubmit}\n disabled={submitting || !code.trim()}\n >\n <Send size={16} /> {submitting ? 'Submitting…' : 'Submit solution'}\n </Button>\n </GlassCard>\n </div>\n\n <div className=\"lg:col-span-1\">\n <GlassCard className=\"p-5\">\n <h2 className=\"mb-3 text-base font-semibold text-text-primary\">My submissions</h2>\n {subsLoading && !submissions.length ? (\n <LoadingRows count={3} height=\"h-12\" />\n ) : subsError ? (\n <ErrorView title=\"Couldn't load submissions\" error={subsError} />\n ) : submissions.length === 0 ? (\n <EmptyView\n icon={<FileText size={24} />}\n title=\"No submissions yet\"\n description=\"Submit a solution above to see your verdicts and points here.\"\n />\n ) : (\n <div className=\"space-y-1\">\n {submissions.map((s) => (\n <SubmissionRow key={s.id} s={s} />\n ))}\n </div>\n )}\n </GlassCard>\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ApplicationsProblemDetailsPagePage.js","names":[],"sources":["../../../src/technospam/pages/ApplicationsProblemDetailsPagePage.tsx"],"sourcesContent":["import { useEffect, useMemo, useRef, useState, type ReactNode } from 'react';\nimport { useSearchParams } from 'react-router-dom';\nimport { Clock, Code2, FileText, Layers, Send, Tag, Trophy } from 'lucide-react';\nimport {\n Badge,\n Button,\n GlassCard,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Skeleton,\n Textarea,\n} from '@burdenoff/fe-libs/ui';\nimport {\n EmptyView,\n ErrorView,\n LoadingRows,\n PageLayout,\n StatCard,\n StatusBadge,\n TagStrip,\n} from '../components';\nimport { useTechnoSpam } from '../providers/TechnoSpamProvider';\nimport {\n useProblemQuery,\n useSubmissionsQuery,\n useSubmitSolution,\n type TecSubmission,\n} from '../api/technospamApi';\nimport { formatDateTime, humanizeEnum } from '../utils/format';\nimport { cn } from '../utils/cn';\nimport { notify } from '../lib/toast';\nimport { useTechnoSpamAnalytics } from '../hooks/useTechnoSpamAnalytics';\n\nconst FALLBACK_LANGUAGES = ['javascript', 'python', 'typescript'];\n\n/**\n * A dark, editor-window styled code surface: mac-style traffic-light dots plus a\n * language label header over a scrollable monospace body so read-only code reads\n * like a real IDE panel rather than a flat block.\n */\nfunction CodePanel({\n label,\n children,\n bodyClassName,\n}: {\n label: string;\n children: ReactNode;\n bodyClassName?: string;\n}) {\n return (\n <div className=\"overflow-hidden rounded-xl border border-border-strong bg-bg-sunken shadow-sm\">\n <div className=\"flex items-center justify-between gap-2 border-b border-border-seam bg-bg-canvas/40 px-4 py-2\">\n <div className=\"flex items-center gap-1.5\">\n <span className=\"h-2.5 w-2.5 rounded-full bg-status-error-border\" />\n <span className=\"h-2.5 w-2.5 rounded-full bg-status-warning-border\" />\n <span className=\"h-2.5 w-2.5 rounded-full bg-status-success-border\" />\n </div>\n <span className=\"inline-flex items-center gap-1.5 font-mono text-xs text-text-muted\">\n <Code2 size={13} /> {label}\n </span>\n </div>\n <pre\n className={cn(\n 'overflow-auto p-4 font-mono text-xs leading-relaxed text-text-primary',\n bodyClassName\n )}\n >\n {children}\n </pre>\n </div>\n );\n}\n\nfunction SubmissionRow({ s }: { s: TecSubmission }) {\n return (\n <div className=\"flex flex-wrap items-center gap-x-4 gap-y-1 rounded-lg border border-transparent px-2 py-3 transition-colors hover:border-border-seam hover:bg-bg-sunken\">\n <StatusBadge status={s.verdict} />\n <span className=\"inline-flex items-center gap-1 text-sm font-medium text-text-primary\">\n <Code2 size={13} /> {humanizeEnum(s.language)}\n </span>\n <span className=\"inline-flex items-center gap-1 text-xs text-text-muted\">\n <Clock size={12} /> {s.runtimeMs} ms\n </span>\n <span className=\"inline-flex items-center gap-1 text-xs text-text-muted\">\n <Trophy size={12} /> {s.pointsAwarded} pts\n </span>\n <span className=\"ml-auto text-xs text-text-muted\">{formatDateTime(s.createdAt)}</span>\n </div>\n );\n}\n\nexport function ApplicationsProblemDetailsPagePage() {\n const [params] = useSearchParams();\n const id = params.get('id') ?? '';\n const { currentUser, workspaceId } = useTechnoSpam();\n const learnerId = currentUser?.id;\n const { emit } = useTechnoSpamAnalytics();\n\n const { data, loading, error, refetch } = useProblemQuery(id);\n\n useEffect(() => {\n if (id) {\n emit('technospam.problem.viewed', {\n workspaceId,\n entityId: id,\n entityType: 'TEC_PROBLEM',\n });\n }\n }, [id, workspaceId, emit]);\n const {\n data: subsData,\n loading: subsLoading,\n error: subsError,\n refetch: refetchSubs,\n } = useSubmissionsQuery({ ...(learnerId ? { learnerId } : {}), problemId: id });\n const [submit, { loading: submitting }] = useSubmitSolution();\n\n const problem = data?.tecProblem ?? null;\n\n const languages = useMemo(\n () => (problem?.languages?.length ? problem.languages : FALLBACK_LANGUAGES),\n [problem]\n );\n\n const [language, setLanguage] = useState('');\n const [code, setCode] = useState('');\n const initedRef = useRef(false);\n\n useEffect(() => {\n if (problem && !initedRef.current) {\n setLanguage(problem.languages[0] ?? FALLBACK_LANGUAGES[0]!);\n setCode(problem.starterCode ?? '');\n initedRef.current = true;\n }\n }, [problem]);\n\n const submissions = useMemo(\n () =>\n [...(subsData?.tecListSubmissions.items ?? [])].sort(\n (a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()\n ),\n [subsData]\n );\n\n const handleSubmit = async () => {\n if (!id) return;\n if (!language) {\n notify.error('Pick a language', 'Choose a language before submitting.');\n return;\n }\n if (!code.trim()) {\n notify.error('Add your solution', 'Write some code before submitting.');\n return;\n }\n emit('technospam.problem.submit_clicked', {\n workspaceId,\n entityId: id,\n entityType: 'TEC_PROBLEM',\n language,\n });\n const res = await submit({ variables: { input: { problemId: id, language, code } } });\n if (res.data?.tecSubmitSolution) {\n emit('technospam.problem.submitted', {\n workspaceId,\n entityId: id,\n entityType: 'TEC_PROBLEM',\n submissionId: res.data.tecSubmitSolution.id,\n });\n notify.success('Solution submitted', 'Your submission was recorded.');\n await Promise.all([refetch(), refetchSubs()]);\n }\n };\n\n if (loading && !problem) {\n return (\n <PageLayout title=\"Problem\" backPath=\"/applications/problems-page\">\n <Skeleton className=\"mb-4 h-28 w-full rounded-xl\" />\n <Skeleton className=\"h-72 w-full rounded-xl\" />\n </PageLayout>\n );\n }\n\n if (error || !problem) {\n return (\n <PageLayout title=\"Problem\" backPath=\"/applications/problems-page\">\n {error ? (\n <ErrorView title=\"Couldn't load problem\" error={error} />\n ) : (\n <EmptyView\n title=\"Problem not found\"\n description=\"This problem may have been unpublished.\"\n />\n )}\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n hero\n backPath=\"/applications/problems-page\"\n title={problem.title}\n description={problem.topic ?? undefined}\n >\n <div className=\"mb-5 flex flex-wrap items-center gap-2\">\n <StatusBadge status={problem.difficulty} kind=\"level\" />\n <StatusBadge status={problem.status} />\n {problem.topic ? (\n <Badge variant=\"outline\" className=\"gap-1\">\n <Layers size={12} /> {problem.topic}\n </Badge>\n ) : null}\n <TagStrip tags={problem.tags} />\n </div>\n\n <div className=\"mb-6 grid grid-cols-2 gap-3 sm:grid-cols-4\">\n <StatCard label=\"Points\" value={problem.points} icon={Trophy} tone=\"amber\" />\n <StatCard label=\"Languages\" value={languages.length} icon={Code2} tone=\"blue\" />\n <StatCard\n label=\"Difficulty\"\n value={humanizeEnum(problem.difficulty)}\n icon={Layers}\n tone=\"purple\"\n />\n <StatCard label=\"My submissions\" value={submissions.length} icon={FileText} tone=\"teal\" />\n </div>\n\n <div className=\"grid grid-cols-1 gap-5 lg:grid-cols-3\">\n <div className=\"space-y-5 lg:col-span-2\">\n <GlassCard className=\"p-5\">\n <h2 className=\"mb-2 text-base font-semibold text-text-primary\">Problem statement</h2>\n {problem.statement ? (\n <p className=\"whitespace-pre-wrap text-sm leading-relaxed text-text-secondary\">\n {problem.statement}\n </p>\n ) : (\n <p className=\"py-4 text-center text-sm text-text-muted\">\n The statement for this problem is being prepared.\n </p>\n )}\n </GlassCard>\n\n {problem.starterCode ? (\n <GlassCard className=\"p-5\">\n <h2 className=\"mb-3 text-base font-semibold text-text-primary\">Starter code</h2>\n <CodePanel label={humanizeEnum(languages[0] ?? 'code')} bodyClassName=\"max-h-72\">\n {problem.starterCode}\n </CodePanel>\n </GlassCard>\n ) : null}\n\n <GlassCard className=\"p-5\">\n <div className=\"mb-3 flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between\">\n <h2 className=\"text-base font-semibold text-text-primary\">Submit a solution</h2>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm text-text-secondary\">Language</span>\n <Select value={language} onValueChange={setLanguage}>\n <SelectTrigger className=\"w-full sm:w-48\">\n <SelectValue placeholder=\"Choose a language\" />\n </SelectTrigger>\n <SelectContent>\n {languages.map((l) => (\n <SelectItem key={l} value={l}>\n {humanizeEnum(l)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n </div>\n\n <div className=\"overflow-hidden rounded-xl border border-border-strong bg-bg-sunken shadow-sm\">\n <div className=\"flex items-center justify-between gap-2 border-b border-border-seam bg-bg-canvas/40 px-4 py-2\">\n <div className=\"flex items-center gap-1.5\">\n <span className=\"h-2.5 w-2.5 rounded-full bg-status-error-border\" />\n <span className=\"h-2.5 w-2.5 rounded-full bg-status-warning-border\" />\n <span className=\"h-2.5 w-2.5 rounded-full bg-status-success-border\" />\n </div>\n <span className=\"inline-flex items-center gap-1.5 font-mono text-xs text-text-muted\">\n <Code2 size={13} /> {language ? humanizeEnum(language) : 'solution'}\n </span>\n </div>\n <Textarea\n value={code}\n onChange={(e) => setCode(e.target.value)}\n placeholder=\"Write your solution…\"\n className=\"min-h-[280px] resize-y rounded-none border-0 bg-transparent font-mono text-xs leading-relaxed focus-visible:ring-0 focus-visible:ring-offset-0\"\n spellCheck={false}\n />\n </div>\n\n <Button\n className=\"mt-4 w-full\"\n onClick={handleSubmit}\n disabled={submitting || !code.trim()}\n >\n <Send size={16} /> {submitting ? 'Submitting…' : 'Submit solution'}\n </Button>\n </GlassCard>\n </div>\n\n <div className=\"lg:col-span-1\">\n <GlassCard className=\"p-5\">\n <h2 className=\"mb-3 text-base font-semibold text-text-primary\">My submissions</h2>\n {subsLoading && !submissions.length ? (\n <LoadingRows count={3} height=\"h-12\" />\n ) : subsError ? (\n <ErrorView title=\"Couldn't load submissions\" error={subsError} />\n ) : submissions.length === 0 ? (\n <EmptyView\n icon={<FileText size={24} />}\n title=\"No submissions yet\"\n description=\"Submit a solution above to see your verdicts and points here.\"\n />\n ) : (\n <div className=\"space-y-1\">\n {submissions.map((s) => (\n <SubmissionRow key={s.id} s={s} />\n ))}\n </div>\n )}\n </GlassCard>\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAoCA,IAAM,IAAqB;CAAC;CAAc;CAAU;CAAa;AAOjE,SAAS,EAAU,EACjB,UACA,aACA,oBAKC;AACD,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,QAAD,EAAM,WAAU,mDAAoD,CAAA;KACpE,kBAAC,QAAD,EAAM,WAAU,qDAAsD,CAAA;KACtE,kBAAC,QAAD,EAAM,WAAU,qDAAsD,CAAA;KAClE;OACN,kBAAC,QAAD;IAAM,WAAU;cAAhB;KACE,kBAAC,GAAD,EAAO,MAAM,IAAM,CAAA;;KAAE;KAChB;MACH;MACN,kBAAC,OAAD;GACE,WAAW,EACT,yEACA,EACD;GAEA;GACG,CAAA,CACF;;;AAIV,SAAS,EAAc,EAAE,QAA2B;AAClD,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,GAAD,EAAa,QAAQ,EAAE,SAAW,CAAA;GAClC,kBAAC,QAAD;IAAM,WAAU;cAAhB;KACE,kBAAC,GAAD,EAAO,MAAM,IAAM,CAAA;;KAAE,EAAa,EAAE,SAAS;KACxC;;GACP,kBAAC,QAAD;IAAM,WAAU;cAAhB;KACE,kBAAC,GAAD,EAAO,MAAM,IAAM,CAAA;;KAAE,EAAE;KAAU;KAC5B;;GACP,kBAAC,QAAD;IAAM,WAAU;cAAhB;KACE,kBAAC,GAAD,EAAQ,MAAM,IAAM,CAAA;;KAAE,EAAE;KAAc;KACjC;;GACP,kBAAC,QAAD;IAAM,WAAU;cAAmC,EAAe,EAAE,UAAU;IAAQ,CAAA;GAClF;;;AAIV,SAAgB,IAAqC;CACnD,IAAM,CAAC,KAAU,GAAiB,EAC5B,IAAK,EAAO,IAAI,KAAK,IAAI,IACzB,EAAE,gBAAa,mBAAgB,GAAe,EAC9C,IAAY,GAAa,IACzB,EAAE,YAAS,GAAwB,EAEnC,EAAE,SAAM,YAAS,UAAO,eAAY,EAAgB,EAAG;AAE7D,SAAgB;AACd,EAAI,KACF,EAAK,6BAA6B;GAChC;GACA,UAAU;GACV,YAAY;GACb,CAAC;IAEH;EAAC;EAAI;EAAa;EAAK,CAAC;CAC3B,IAAM,EACJ,MAAM,GACN,SAAS,GACT,OAAO,GACP,SAAS,MACP,EAAoB;EAAE,GAAI,IAAY,EAAE,cAAW,GAAG,EAAE;EAAG,WAAW;EAAI,CAAC,EACzE,CAAC,GAAQ,EAAE,SAAS,OAAgB,IAAmB,EAEvD,IAAU,GAAM,cAAc,MAE9B,IAAY,QACT,GAAS,WAAW,SAAS,EAAQ,YAAY,GACxD,CAAC,EAAQ,CACV,EAEK,CAAC,GAAU,KAAe,EAAS,GAAG,EACtC,CAAC,GAAM,KAAW,EAAS,GAAG,EAC9B,IAAY,EAAO,GAAM;AAE/B,SAAgB;AACd,EAAI,KAAW,CAAC,EAAU,YACxB,EAAY,EAAQ,UAAU,MAAM,EAAmB,GAAI,EAC3D,EAAQ,EAAQ,eAAe,GAAG,EAClC,EAAU,UAAU;IAErB,CAAC,EAAQ,CAAC;CAEb,IAAM,IAAc,QAEhB,CAAC,GAAI,GAAU,mBAAmB,SAAS,EAAE,CAAE,CAAC,MAC7C,GAAG,MAAM,IAAI,KAAK,EAAE,UAAU,CAAC,SAAS,GAAG,IAAI,KAAK,EAAE,UAAU,CAAC,SAAS,CAC5E,EACH,CAAC,EAAS,CACX;AAuDD,QAxBI,KAAW,CAAC,IAEZ,kBAAC,GAAD;EAAY,OAAM;EAAU,UAAS;YAArC,CACE,kBAAC,GAAD,EAAU,WAAU,+BAAgC,CAAA,EACpD,kBAAC,GAAD,EAAU,WAAU,0BAA2B,CAAA,CACpC;MAIb,KAAS,CAAC,IAEV,kBAAC,GAAD;EAAY,OAAM;EAAU,UAAS;YAClC,IACC,kBAAC,GAAD;GAAW,OAAM;GAA+B;GAAS,CAAA,GAEzD,kBAAC,GAAD;GACE,OAAM;GACN,aAAY;GACZ,CAAA;EAEO,CAAA,GAKf,kBAAC,GAAD;EACE,MAAA;EACA,UAAS;EACT,OAAO,EAAQ;EACf,aAAa,EAAQ,SAAS,KAAA;YAJhC;GAME,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,GAAD;MAAa,QAAQ,EAAQ;MAAY,MAAK;MAAU,CAAA;KACxD,kBAAC,GAAD,EAAa,QAAQ,EAAQ,QAAU,CAAA;KACtC,EAAQ,QACP,kBAAC,GAAD;MAAO,SAAQ;MAAU,WAAU;gBAAnC;OACE,kBAAC,GAAD,EAAQ,MAAM,IAAM,CAAA;;OAAE,EAAQ;OACxB;UACN;KACJ,kBAAC,IAAD,EAAU,MAAM,EAAQ,MAAQ,CAAA;KAC5B;;GAEN,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,GAAD;MAAU,OAAM;MAAS,OAAO,EAAQ;MAAQ,MAAM;MAAQ,MAAK;MAAU,CAAA;KAC7E,kBAAC,GAAD;MAAU,OAAM;MAAY,OAAO,EAAU;MAAQ,MAAM;MAAO,MAAK;MAAS,CAAA;KAChF,kBAAC,GAAD;MACE,OAAM;MACN,OAAO,EAAa,EAAQ,WAAW;MACvC,MAAM;MACN,MAAK;MACL,CAAA;KACF,kBAAC,GAAD;MAAU,OAAM;MAAiB,OAAO,EAAY;MAAQ,MAAM;MAAU,MAAK;MAAS,CAAA;KACtF;;GAEN,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf;MACE,kBAAC,GAAD;OAAW,WAAU;iBAArB,CACE,kBAAC,MAAD;QAAI,WAAU;kBAAiD;QAAsB,CAAA,EACpF,EAAQ,YACP,kBAAC,KAAD;QAAG,WAAU;kBACV,EAAQ;QACP,CAAA,GAEJ,kBAAC,KAAD;QAAG,WAAU;kBAA2C;QAEpD,CAAA,CAEI;;MAEX,EAAQ,cACP,kBAAC,GAAD;OAAW,WAAU;iBAArB,CACE,kBAAC,MAAD;QAAI,WAAU;kBAAiD;QAAiB,CAAA,EAChF,kBAAC,GAAD;QAAW,OAAO,EAAa,EAAU,MAAM,OAAO;QAAE,eAAc;kBACnE,EAAQ;QACC,CAAA,CACF;WACV;MAEJ,kBAAC,GAAD;OAAW,WAAU;iBAArB;QACE,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,MAAD;UAAI,WAAU;oBAA4C;UAAsB,CAAA,EAChF,kBAAC,OAAD;UAAK,WAAU;oBAAf,CACE,kBAAC,QAAD;WAAM,WAAU;qBAA8B;WAAe,CAAA,EAC7D,kBAAC,IAAD;WAAQ,OAAO;WAAU,eAAe;qBAAxC,CACE,kBAAC,IAAD;YAAe,WAAU;sBACvB,kBAAC,IAAD,EAAa,aAAY,qBAAsB,CAAA;YACjC,CAAA,EAChB,kBAAC,IAAD,EAAA,UACG,EAAU,KAAK,MACd,kBAAC,IAAD;YAAoB,OAAO;sBACxB,EAAa,EAAE;YACL,EAFI,EAEJ,CACb,EACY,CAAA,CACT;aACL;YACF;;QAEN,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,OAAD;UAAK,WAAU;oBAAf,CACE,kBAAC,OAAD;WAAK,WAAU;qBAAf;YACE,kBAAC,QAAD,EAAM,WAAU,mDAAoD,CAAA;YACpE,kBAAC,QAAD,EAAM,WAAU,qDAAsD,CAAA;YACtE,kBAAC,QAAD,EAAM,WAAU,qDAAsD,CAAA;YAClE;cACN,kBAAC,QAAD;WAAM,WAAU;qBAAhB;YACE,kBAAC,GAAD,EAAO,MAAM,IAAM,CAAA;;YAAE,IAAW,EAAa,EAAS,GAAG;YACpD;aACH;aACN,kBAAC,IAAD;UACE,OAAO;UACP,WAAW,MAAM,EAAQ,EAAE,OAAO,MAAM;UACxC,aAAY;UACZ,WAAU;UACV,YAAY;UACZ,CAAA,CACE;;QAEN,kBAAC,GAAD;SACE,WAAU;SACV,SArJS,YAAY;AAC/B,cAAI,CAAC,EAAI;AACT,cAAI,CAAC,GAAU;AACb,aAAO,MAAM,mBAAmB,uCAAuC;AACvE;;AAEF,cAAI,CAAC,EAAK,MAAM,EAAE;AAChB,aAAO,MAAM,qBAAqB,qCAAqC;AACvE;;AAEF,YAAK,qCAAqC;WACxC;WACA,UAAU;WACV,YAAY;WACZ;WACD,CAAC;UACF,IAAM,IAAM,MAAM,EAAO,EAAE,WAAW,EAAE,OAAO;WAAE,WAAW;WAAI;WAAU;WAAM,EAAE,EAAE,CAAC;AACrF,UAAI,EAAI,MAAM,sBACZ,EAAK,gCAAgC;WACnC;WACA,UAAU;WACV,YAAY;WACZ,cAAc,EAAI,KAAK,kBAAkB;WAC1C,CAAC,EACF,EAAO,QAAQ,sBAAsB,gCAAgC,EACrE,MAAM,QAAQ,IAAI,CAAC,GAAS,EAAE,GAAa,CAAC,CAAC;;SA6HrC,UAAU,KAAc,CAAC,EAAK,MAAM;mBAHtC;UAKE,kBAAC,GAAD,EAAM,MAAM,IAAM,CAAA;;UAAE,IAAa,gBAAgB;UAC1C;;QACC;;MACR;QAEN,kBAAC,OAAD;KAAK,WAAU;eACb,kBAAC,GAAD;MAAW,WAAU;gBAArB,CACE,kBAAC,MAAD;OAAI,WAAU;iBAAiD;OAAmB,CAAA,EACjF,KAAe,CAAC,EAAY,SAC3B,kBAAC,IAAD;OAAa,OAAO;OAAG,QAAO;OAAS,CAAA,GACrC,IACF,kBAAC,GAAD;OAAW,OAAM;OAA4B,OAAO;OAAa,CAAA,GAC/D,EAAY,WAAW,IACzB,kBAAC,GAAD;OACE,MAAM,kBAAC,GAAD,EAAU,MAAM,IAAM,CAAA;OAC5B,OAAM;OACN,aAAY;OACZ,CAAA,GAEF,kBAAC,OAAD;OAAK,WAAU;iBACZ,EAAY,KAAK,MAChB,kBAAC,GAAD,EAA6B,MAAK,EAAd,EAAE,GAAY,CAClC;OACE,CAAA,CAEE;;KACR,CAAA,CACF;;GACK"}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { useTechnoSpam as e, useTechnoSpamNavigate as t } from "../providers/TechnoSpamProvider.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
2
|
+
import { useTechnoSpamAnalytics as n } from "../hooks/useTechnoSpamAnalytics.js";
|
|
3
|
+
import { PageLayout as r } from "../components/PageLayout.js";
|
|
4
|
+
import { StatCard as i } from "../components/StatCard.js";
|
|
5
|
+
import { MediaCover as a, topicIcon as o } from "../components/MediaCover.js";
|
|
6
|
+
import { StatusBadge as s } from "../components/StatusBadge.js";
|
|
7
|
+
import { LoadMore as c } from "../components/LoadMore.js";
|
|
8
|
+
import { EmptyView as l, ErrorView as u, LoadingGrid as d } from "../components/StateViews.js";
|
|
8
9
|
import "../components/index.js";
|
|
9
|
-
import { pageArg as
|
|
10
|
-
import { useTechnoSpamAnalytics as h } from "../hooks/useTechnoSpamAnalytics.js";
|
|
10
|
+
import { pageArg as f, usePageLimit as p, useProblemsQuery as m, useSubmissionsQuery as h } from "../api/technospamApi.js";
|
|
11
11
|
import { useMemo as g, useState as _ } from "react";
|
|
12
12
|
import { CheckCircle2 as v, Code2 as y, Flame as b, Gauge as x, Layers as S, Search as C, Tag as w, Trophy as T } from "lucide-react";
|
|
13
13
|
import { jsx as E, jsxs as D } from "react/jsx-runtime";
|
|
@@ -35,13 +35,13 @@ function F({ problem: e, solved: t, onOpen: n }) {
|
|
|
35
35
|
return /* @__PURE__ */ D(k, {
|
|
36
36
|
className: "group flex cursor-pointer flex-col overflow-hidden transition-all duration-200 hover:-translate-y-1 hover:shadow-lg",
|
|
37
37
|
onClick: n,
|
|
38
|
-
children: [/* @__PURE__ */ D(
|
|
38
|
+
children: [/* @__PURE__ */ D(a, {
|
|
39
39
|
seed: `${e.topic ?? ""} ${e.difficulty} ${e.title}`,
|
|
40
|
-
icon:
|
|
40
|
+
icon: o(e.topic ?? e.title),
|
|
41
41
|
children: [t ? /* @__PURE__ */ D("span", {
|
|
42
42
|
className: "inline-flex items-center gap-1 rounded-full bg-status-success-bg-subtle px-2 py-0.5 text-[11px] font-medium text-status-success-text ring-1 ring-status-success-border/30",
|
|
43
43
|
children: [/* @__PURE__ */ E(v, { size: 12 }), " Solved"]
|
|
44
|
-
}) : /* @__PURE__ */ E("span", {}), /* @__PURE__ */ E(
|
|
44
|
+
}) : /* @__PURE__ */ E("span", {}), /* @__PURE__ */ E(s, {
|
|
45
45
|
status: e.difficulty,
|
|
46
46
|
kind: "level"
|
|
47
47
|
})]
|
|
@@ -106,15 +106,15 @@ function F({ problem: e, solved: t, onOpen: n }) {
|
|
|
106
106
|
});
|
|
107
107
|
}
|
|
108
108
|
function I() {
|
|
109
|
-
let
|
|
109
|
+
let a = t(), { currentUser: o, workspaceId: s } = e(), { emit: S } = n(), w = o?.id, [T, O] = _("ALL"), [k, I] = _(""), { limit: L, more: R } = p(), { data: z, loading: B, error: V } = m({
|
|
110
110
|
status: "PUBLISHED",
|
|
111
|
-
pagination:
|
|
111
|
+
pagination: f(L),
|
|
112
112
|
...T === "ALL" ? {} : { difficulty: T }
|
|
113
|
-
}), { data: H } =
|
|
113
|
+
}), { data: H } = h(w ? { learnerId: w } : {}), U = z?.tecListProblems.items ?? [], W = z?.tecListProblems.pageInfo.hasMore ?? !1, G = g(() => new Set((H?.tecListSubmissions.items ?? []).filter((e) => e.verdict === "ACCEPTED").map((e) => e.problemId)), [H]), K = U.filter((e) => G.has(e.id)).length, q = U.filter((e) => e.difficulty === "EASY").length, J = U.filter((e) => e.difficulty === "HARD").length, Y = g(() => {
|
|
114
114
|
let e = k.trim().toLowerCase();
|
|
115
115
|
return e ? U.filter((t) => t.title.toLowerCase().includes(e) || (t.topic ?? "").toLowerCase().includes(e) || t.tags.some((t) => t.toLowerCase().includes(e))) : U;
|
|
116
116
|
}, [U, k]);
|
|
117
|
-
return /* @__PURE__ */ D(
|
|
117
|
+
return /* @__PURE__ */ D(r, {
|
|
118
118
|
hero: !0,
|
|
119
119
|
title: "Coding Problems",
|
|
120
120
|
description: "Sharpen your problem-solving with hands-on, mentor-judged challenges across topics and difficulty.",
|
|
@@ -122,25 +122,25 @@ function I() {
|
|
|
122
122
|
/* @__PURE__ */ D("div", {
|
|
123
123
|
className: "mb-5 grid grid-cols-2 gap-3 sm:grid-cols-4",
|
|
124
124
|
children: [
|
|
125
|
-
/* @__PURE__ */ E(
|
|
125
|
+
/* @__PURE__ */ E(i, {
|
|
126
126
|
label: "Problems",
|
|
127
127
|
value: U.length,
|
|
128
128
|
icon: y,
|
|
129
129
|
tone: "blue"
|
|
130
130
|
}),
|
|
131
|
-
/* @__PURE__ */ E(
|
|
131
|
+
/* @__PURE__ */ E(i, {
|
|
132
132
|
label: "Solved",
|
|
133
133
|
value: K,
|
|
134
134
|
icon: v,
|
|
135
135
|
tone: "green"
|
|
136
136
|
}),
|
|
137
|
-
/* @__PURE__ */ E(
|
|
137
|
+
/* @__PURE__ */ E(i, {
|
|
138
138
|
label: "Easy",
|
|
139
139
|
value: q,
|
|
140
140
|
icon: x,
|
|
141
141
|
tone: "teal"
|
|
142
142
|
}),
|
|
143
|
-
/* @__PURE__ */ E(
|
|
143
|
+
/* @__PURE__ */ E(i, {
|
|
144
144
|
label: "Hard",
|
|
145
145
|
value: J,
|
|
146
146
|
icon: b,
|
|
@@ -170,7 +170,7 @@ function I() {
|
|
|
170
170
|
onBlur: () => {
|
|
171
171
|
let e = k.trim();
|
|
172
172
|
e && S("technospam.search.performed", {
|
|
173
|
-
workspaceId:
|
|
173
|
+
workspaceId: s,
|
|
174
174
|
entityType: "problem",
|
|
175
175
|
queryLength: e.length
|
|
176
176
|
});
|
|
@@ -178,10 +178,10 @@ function I() {
|
|
|
178
178
|
})]
|
|
179
179
|
})]
|
|
180
180
|
}),
|
|
181
|
-
B && !U.length ? /* @__PURE__ */ E(
|
|
181
|
+
B && !U.length ? /* @__PURE__ */ E(d, {}) : V ? /* @__PURE__ */ E(u, {
|
|
182
182
|
title: "Couldn't load problems",
|
|
183
183
|
error: V
|
|
184
|
-
}) : Y.length === 0 ? /* @__PURE__ */ E(
|
|
184
|
+
}) : Y.length === 0 ? /* @__PURE__ */ E(l, {
|
|
185
185
|
icon: /* @__PURE__ */ E(y, { size: 26 }),
|
|
186
186
|
title: k || T !== "ALL" ? "No matching problems" : "No problems published yet",
|
|
187
187
|
description: k || T !== "ALL" ? "Try a different search or difficulty filter." : "Published problems will appear here. Check back soon — TechnoSpam is pre-launch."
|
|
@@ -192,14 +192,14 @@ function I() {
|
|
|
192
192
|
solved: G.has(e.id),
|
|
193
193
|
onOpen: () => {
|
|
194
194
|
S("technospam.problem.viewed", {
|
|
195
|
-
workspaceId:
|
|
195
|
+
workspaceId: s,
|
|
196
196
|
entityId: e.id,
|
|
197
197
|
entityType: "TEC_PROBLEM"
|
|
198
|
-
}),
|
|
198
|
+
}), a(`/applications/problem-details-page?id=${e.id}`);
|
|
199
199
|
}
|
|
200
200
|
}, e.id))
|
|
201
201
|
}),
|
|
202
|
-
/* @__PURE__ */ E(
|
|
202
|
+
/* @__PURE__ */ E(c, {
|
|
203
203
|
hasMore: W,
|
|
204
204
|
loading: B,
|
|
205
205
|
onClick: R
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CoursesCourseDetailsPagePage.d.ts","sourceRoot":"","sources":["../../../src/technospam/pages/CoursesCourseDetailsPagePage.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"CoursesCourseDetailsPagePage.d.ts","sourceRoot":"","sources":["../../../src/technospam/pages/CoursesCourseDetailsPagePage.tsx"],"names":[],"mappings":"AAmIA,wBAAgB,4BAA4B,gCA+Q3C"}
|