@burdenoff/microfe-technospam 2026.828.1 → 2026.830.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.
- package/dist/index.js +4 -3
- package/dist/technospam/TechnoSpamRoot.js +4 -4
- package/dist/technospam/components/PageLayout.d.ts.map +1 -1
- package/dist/technospam/components/PageLayout.js +24 -23
- package/dist/technospam/components/PageLayout.js.map +1 -1
- package/dist/technospam/components/StateViews.d.ts +1 -1
- package/dist/technospam/components/StateViews.d.ts.map +1 -1
- package/dist/technospam/components/StateViews.js +28 -26
- package/dist/technospam/components/StateViews.js.map +1 -1
- package/dist/technospam/components/TagInput.d.ts +1 -1
- package/dist/technospam/components/TagInput.d.ts.map +1 -1
- package/dist/technospam/components/TagInput.js +39 -34
- package/dist/technospam/components/TagInput.js.map +1 -1
- package/dist/technospam/hooks/useTr.d.ts +17 -0
- package/dist/technospam/hooks/useTr.d.ts.map +1 -0
- package/dist/technospam/hooks/useTr.js +12 -0
- package/dist/technospam/hooks/useTr.js.map +1 -0
- package/dist/technospam/index.d.ts +1 -0
- package/dist/technospam/index.d.ts.map +1 -1
- package/dist/technospam/index.js +1 -0
- package/dist/technospam/pages/AnalyticsAnalyticsPagePage.d.ts.map +1 -1
- package/dist/technospam/pages/AnalyticsAnalyticsPagePage.js +198 -189
- package/dist/technospam/pages/AnalyticsAnalyticsPagePage.js.map +1 -1
- package/dist/technospam/pages/ApplicationsProblemsPagePage.d.ts.map +1 -1
- package/dist/technospam/pages/ApplicationsProblemsPagePage.js +165 -163
- package/dist/technospam/pages/ApplicationsProblemsPagePage.js.map +1 -1
- package/dist/technospam/pages/CoursesCoursesPagePage.d.ts.map +1 -1
- package/dist/technospam/pages/CoursesCoursesPagePage.js +117 -113
- package/dist/technospam/pages/CoursesCoursesPagePage.js.map +1 -1
- package/dist/technospam/pages/DashboardDashboardPagePage.d.ts.map +1 -1
- package/dist/technospam/pages/DashboardDashboardPagePage.js +211 -193
- package/dist/technospam/pages/DashboardDashboardPagePage.js.map +1 -1
- package/dist/technospam/pages/HackathonsHackathonsPagePage.d.ts.map +1 -1
- package/dist/technospam/pages/HackathonsHackathonsPagePage.js +110 -110
- package/dist/technospam/pages/HackathonsHackathonsPagePage.js.map +1 -1
- package/dist/technospam/pages/MentorshipMentorsPagePage.d.ts.map +1 -1
- package/dist/technospam/pages/MentorshipMentorsPagePage.js +174 -160
- package/dist/technospam/pages/MentorshipMentorsPagePage.js.map +1 -1
- package/dist/technospam/pages/MentorshipSessionsPagePage.d.ts.map +1 -1
- package/dist/technospam/pages/MentorshipSessionsPagePage.js +156 -151
- package/dist/technospam/pages/MentorshipSessionsPagePage.js.map +1 -1
- package/dist/technospam/utils/i18n.js +1 -1
- package/dist/technospam/utils/i18n.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,54 +1,55 @@
|
|
|
1
1
|
import { useTechnoSpam as e, useTechnoSpamNavigate as t } from "../providers/TechnoSpamProvider.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
2
|
+
import { useTr as n } from "../hooks/useTr.js";
|
|
3
|
+
import { cn as r } from "../utils/cn.js";
|
|
4
|
+
import { PageLayout as i } from "../components/PageLayout.js";
|
|
5
|
+
import { StatCard as a } from "../components/StatCard.js";
|
|
6
|
+
import { humanizeEnum as o } from "../utils/format.js";
|
|
7
|
+
import { EmptyView as s, ErrorView as ee, LoadingGrid as te, LoadingRows as ne } from "../components/StateViews.js";
|
|
7
8
|
import "../components/index.js";
|
|
8
9
|
import { useCertificatesQuery as re, useCoursesQuery as ie, useEnrollmentsQuery as ae, useHackathonsQuery as oe, useProblemsQuery as se, useSessionsQuery as ce, useSubmissionsQuery as le } from "../api/technospamApi.js";
|
|
9
|
-
import { Legend as
|
|
10
|
-
import { Tooltip as
|
|
11
|
-
import { ResponsiveContainer as
|
|
12
|
-
import { Cell as
|
|
10
|
+
import { Legend as c } from "../../node_modules/recharts/es6/component/Legend.js";
|
|
11
|
+
import { Tooltip as l } from "../../node_modules/recharts/es6/component/Tooltip.js";
|
|
12
|
+
import { ResponsiveContainer as u } from "../../node_modules/recharts/es6/component/ResponsiveContainer.js";
|
|
13
|
+
import { Cell as d } from "../../node_modules/recharts/es6/component/Cell.js";
|
|
13
14
|
import { Pie as ue } from "../../node_modules/recharts/es6/polar/Pie.js";
|
|
14
15
|
import { Bar as de } from "../../node_modules/recharts/es6/cartesian/Bar.js";
|
|
15
|
-
import { CartesianGrid as
|
|
16
|
-
import { Area as
|
|
17
|
-
import { XAxis as
|
|
18
|
-
import { YAxis as
|
|
16
|
+
import { CartesianGrid as f } from "../../node_modules/recharts/es6/cartesian/CartesianGrid.js";
|
|
17
|
+
import { Area as p } from "../../node_modules/recharts/es6/cartesian/Area.js";
|
|
18
|
+
import { XAxis as m } from "../../node_modules/recharts/es6/cartesian/XAxis.js";
|
|
19
|
+
import { YAxis as h } from "../../node_modules/recharts/es6/cartesian/YAxis.js";
|
|
19
20
|
import { BarChart as fe } from "../../node_modules/recharts/es6/chart/BarChart.js";
|
|
20
21
|
import { PieChart as pe } from "../../node_modules/recharts/es6/chart/PieChart.js";
|
|
21
22
|
import { AreaChart as me } from "../../node_modules/recharts/es6/chart/AreaChart.js";
|
|
22
|
-
import { useMemo as
|
|
23
|
-
import { Activity as
|
|
23
|
+
import { useMemo as g, useState as _ } from "react";
|
|
24
|
+
import { Activity as v, Award as he, BarChart3 as ge, BookOpen as _e, CalendarRange as y, Code2 as b, GraduationCap as x, Library as ve, Percent as ye, Target as S, TrendingUp as be, Trophy as xe, Users as Se, X as C } from "lucide-react";
|
|
24
25
|
import { jsx as w, jsxs as T } from "react/jsx-runtime";
|
|
25
26
|
import { Button as E, GlassCard as D, Input as O } from "@burdenoff/fe-libs/ui";
|
|
26
27
|
//#region src/technospam/pages/AnalyticsAnalyticsPagePage.tsx
|
|
27
|
-
var
|
|
28
|
+
var Ce = [
|
|
28
29
|
"ENROLLED",
|
|
29
30
|
"IN_PROGRESS",
|
|
30
31
|
"COMPLETED",
|
|
31
32
|
"DROPPED"
|
|
32
|
-
],
|
|
33
|
+
], we = {
|
|
33
34
|
ENROLLED: "var(--color-accent-primary)",
|
|
34
35
|
IN_PROGRESS: "var(--color-accent-teal)",
|
|
35
36
|
COMPLETED: "var(--color-status-success)",
|
|
36
37
|
DROPPED: "var(--color-status-warning)"
|
|
37
|
-
},
|
|
38
|
+
}, Te = [
|
|
38
39
|
"ACCEPTED",
|
|
39
40
|
"WRONG_ANSWER",
|
|
40
41
|
"TIME_LIMIT_EXCEEDED",
|
|
41
42
|
"RUNTIME_ERROR",
|
|
42
43
|
"COMPILE_ERROR",
|
|
43
44
|
"PENDING"
|
|
44
|
-
],
|
|
45
|
+
], Ee = {
|
|
45
46
|
ACCEPTED: "Accepted",
|
|
46
47
|
WRONG_ANSWER: "Wrong",
|
|
47
48
|
TIME_LIMIT_EXCEEDED: "TLE",
|
|
48
49
|
RUNTIME_ERROR: "Runtime",
|
|
49
50
|
COMPILE_ERROR: "Compile",
|
|
50
51
|
PENDING: "Pending"
|
|
51
|
-
},
|
|
52
|
+
}, De = {
|
|
52
53
|
ACCEPTED: "var(--color-status-success)",
|
|
53
54
|
WRONG_ANSWER: "var(--color-status-error)",
|
|
54
55
|
TIME_LIMIT_EXCEEDED: "var(--color-status-warning)",
|
|
@@ -65,7 +66,7 @@ var Se = [
|
|
|
65
66
|
fill: "var(--color-text-muted)",
|
|
66
67
|
fontSize: 12
|
|
67
68
|
};
|
|
68
|
-
function
|
|
69
|
+
function Oe(e) {
|
|
69
70
|
let t = new Date(e);
|
|
70
71
|
if (Number.isNaN(t.getTime())) return {
|
|
71
72
|
key: 0,
|
|
@@ -86,20 +87,20 @@ var M = {
|
|
|
86
87
|
purple: "bg-accent-purple/15 text-accent-purple ring-accent-purple/20",
|
|
87
88
|
indigo: "bg-accent-indigo/15 text-accent-indigo ring-accent-indigo/20"
|
|
88
89
|
};
|
|
89
|
-
function N({ icon: e, title: t, subtitle:
|
|
90
|
+
function N({ icon: e, title: t, subtitle: n, tone: i }) {
|
|
90
91
|
return /* @__PURE__ */ T("div", {
|
|
91
92
|
className: "mb-4 flex items-center gap-3",
|
|
92
93
|
children: [/* @__PURE__ */ w("span", {
|
|
93
|
-
className:
|
|
94
|
+
className: r("flex h-9 w-9 shrink-0 items-center justify-center rounded-xl ring-1", M[i]),
|
|
94
95
|
children: /* @__PURE__ */ w(e, { size: 17 })
|
|
95
96
|
}), /* @__PURE__ */ T("div", {
|
|
96
97
|
className: "min-w-0",
|
|
97
98
|
children: [/* @__PURE__ */ w("h3", {
|
|
98
99
|
className: "truncate text-sm font-semibold text-text-primary",
|
|
99
100
|
children: t
|
|
100
|
-
}),
|
|
101
|
+
}), n ? /* @__PURE__ */ w("p", {
|
|
101
102
|
className: "truncate text-xs text-text-muted",
|
|
102
|
-
children:
|
|
103
|
+
children: n
|
|
103
104
|
}) : null]
|
|
104
105
|
})]
|
|
105
106
|
});
|
|
@@ -115,29 +116,29 @@ function P({ title: e, subtitle: t, icon: n, tone: r = "teal", isEmpty: i, empty
|
|
|
115
116
|
}), i ? /* @__PURE__ */ w("div", {
|
|
116
117
|
className: "flex h-[240px] items-center justify-center text-center text-sm text-text-muted",
|
|
117
118
|
children: a
|
|
118
|
-
}) : /* @__PURE__ */ w(
|
|
119
|
+
}) : /* @__PURE__ */ w(u, {
|
|
119
120
|
width: "100%",
|
|
120
121
|
height: 260,
|
|
121
122
|
children: o
|
|
122
123
|
})]
|
|
123
124
|
});
|
|
124
125
|
}
|
|
125
|
-
function
|
|
126
|
-
let
|
|
126
|
+
function ke({ data: e, title: t, subtitle: n, noData: i, lowestRateLabel: a }) {
|
|
127
|
+
let o = e.length > 1 ? e[e.length - 1] : void 0;
|
|
127
128
|
return /* @__PURE__ */ T(D, {
|
|
128
129
|
className: "p-5 transition-shadow duration-200 hover:shadow-lg",
|
|
129
130
|
children: [/* @__PURE__ */ w(N, {
|
|
130
131
|
icon: S,
|
|
131
|
-
title:
|
|
132
|
-
subtitle:
|
|
132
|
+
title: t,
|
|
133
|
+
subtitle: n,
|
|
133
134
|
tone: "indigo"
|
|
134
135
|
}), e.length === 0 ? /* @__PURE__ */ w("div", {
|
|
135
136
|
className: "flex h-[240px] items-center justify-center text-center text-sm text-text-muted",
|
|
136
|
-
children:
|
|
137
|
+
children: i
|
|
137
138
|
}) : /* @__PURE__ */ T("div", {
|
|
138
139
|
className: "space-y-3",
|
|
139
140
|
children: [e.map((e) => {
|
|
140
|
-
let
|
|
141
|
+
let t = o?.topic === e.topic;
|
|
141
142
|
return /* @__PURE__ */ T("div", { children: [/* @__PURE__ */ T("div", {
|
|
142
143
|
className: "mb-1 flex flex-wrap items-baseline gap-x-2",
|
|
143
144
|
children: [
|
|
@@ -146,7 +147,7 @@ function Oe({ data: e }) {
|
|
|
146
147
|
children: e.topic
|
|
147
148
|
}),
|
|
148
149
|
/* @__PURE__ */ T("span", {
|
|
149
|
-
className:
|
|
150
|
+
className: r("text-sm font-semibold tabular-nums", t ? "text-status-warning-text" : "text-text-secondary"),
|
|
150
151
|
children: [e.rate, "%"]
|
|
151
152
|
}),
|
|
152
153
|
/* @__PURE__ */ T("span", {
|
|
@@ -162,36 +163,25 @@ function Oe({ data: e }) {
|
|
|
162
163
|
}), /* @__PURE__ */ w("div", {
|
|
163
164
|
className: "h-2.5 w-full overflow-hidden rounded-full bg-bg-sunken",
|
|
164
165
|
children: /* @__PURE__ */ w("div", {
|
|
165
|
-
className:
|
|
166
|
+
className: r("h-full rounded-full transition-all duration-500", t ? "bg-status-warning-text" : "bg-accent-primary"),
|
|
166
167
|
style: { width: `${e.rate}%` }
|
|
167
168
|
})
|
|
168
169
|
})] }, e.topic);
|
|
169
|
-
}),
|
|
170
|
+
}), o ? /* @__PURE__ */ w("p", {
|
|
170
171
|
className: "pt-1 text-xs text-text-muted",
|
|
171
|
-
children:
|
|
172
|
-
"Lowest measured rate: ",
|
|
173
|
-
/* @__PURE__ */ w("span", {
|
|
174
|
-
className: "text-text-secondary",
|
|
175
|
-
children: t.topic
|
|
176
|
-
}),
|
|
177
|
-
" —",
|
|
178
|
-
" ",
|
|
179
|
-
t.accepted,
|
|
180
|
-
" of ",
|
|
181
|
-
t.attempted,
|
|
182
|
-
" attempts accepted in the loaded range."
|
|
183
|
-
]
|
|
172
|
+
children: a(o.topic, o.accepted, o.attempted)
|
|
184
173
|
}) : null]
|
|
185
174
|
})]
|
|
186
175
|
});
|
|
187
176
|
}
|
|
188
|
-
function
|
|
177
|
+
function Ae(e) {
|
|
189
178
|
return e ? `${e}T00:00:00.000Z` : void 0;
|
|
190
179
|
}
|
|
191
|
-
function
|
|
180
|
+
function je(e) {
|
|
192
181
|
return e ? `${e}T23:59:59.999Z` : void 0;
|
|
193
182
|
}
|
|
194
|
-
function
|
|
183
|
+
function Me({ start: e, end: t, onStart: n, onEnd: r, onPreset: i, onClear: a, tr: o }) {
|
|
184
|
+
let s = !!(e || t);
|
|
195
185
|
return /* @__PURE__ */ T(D, {
|
|
196
186
|
className: "mb-6 flex flex-col gap-3 p-4 lg:flex-row lg:items-end lg:justify-between",
|
|
197
187
|
children: [/* @__PURE__ */ T("div", {
|
|
@@ -202,12 +192,12 @@ function je({ start: e, end: t, onStart: n, onEnd: r, onPreset: i, onClear: a })
|
|
|
202
192
|
children: [/* @__PURE__ */ w(y, {
|
|
203
193
|
size: 16,
|
|
204
194
|
className: "text-accent-teal"
|
|
205
|
-
}), "Date range"]
|
|
195
|
+
}), o("technospam.analytics.dateRangeTitle", "Date range")]
|
|
206
196
|
}),
|
|
207
197
|
/* @__PURE__ */ T("div", { children: [/* @__PURE__ */ w("label", {
|
|
208
198
|
className: "mb-1 block text-xs font-medium text-text-muted",
|
|
209
199
|
htmlFor: "tec-range-from",
|
|
210
|
-
children: "From"
|
|
200
|
+
children: o("technospam.analytics.from", "From")
|
|
211
201
|
}), /* @__PURE__ */ w(O, {
|
|
212
202
|
id: "tec-range-from",
|
|
213
203
|
type: "date",
|
|
@@ -219,7 +209,7 @@ function je({ start: e, end: t, onStart: n, onEnd: r, onPreset: i, onClear: a })
|
|
|
219
209
|
/* @__PURE__ */ T("div", { children: [/* @__PURE__ */ w("label", {
|
|
220
210
|
className: "mb-1 block text-xs font-medium text-text-muted",
|
|
221
211
|
htmlFor: "tec-range-to",
|
|
222
|
-
children: "To"
|
|
212
|
+
children: o("technospam.analytics.to", "To")
|
|
223
213
|
}), /* @__PURE__ */ w(O, {
|
|
224
214
|
id: "tec-range-to",
|
|
225
215
|
type: "date",
|
|
@@ -228,11 +218,15 @@ function je({ start: e, end: t, onStart: n, onEnd: r, onPreset: i, onClear: a })
|
|
|
228
218
|
onChange: (e) => r(e.target.value),
|
|
229
219
|
className: "w-40"
|
|
230
220
|
})] }),
|
|
231
|
-
|
|
221
|
+
s ? /* @__PURE__ */ T(E, {
|
|
232
222
|
variant: "ghost",
|
|
233
223
|
size: "sm",
|
|
234
224
|
onClick: a,
|
|
235
|
-
children: [
|
|
225
|
+
children: [
|
|
226
|
+
/* @__PURE__ */ w(C, { size: 14 }),
|
|
227
|
+
" ",
|
|
228
|
+
o("technospam.analytics.clear", "Clear")
|
|
229
|
+
]
|
|
236
230
|
}) : null
|
|
237
231
|
]
|
|
238
232
|
}), /* @__PURE__ */ T("div", {
|
|
@@ -242,58 +236,58 @@ function je({ start: e, end: t, onStart: n, onEnd: r, onPreset: i, onClear: a })
|
|
|
242
236
|
variant: "outline",
|
|
243
237
|
size: "sm",
|
|
244
238
|
onClick: () => i(7),
|
|
245
|
-
children: "Last 7 days"
|
|
239
|
+
children: o("technospam.analytics.last7Days", "Last 7 days")
|
|
246
240
|
}),
|
|
247
241
|
/* @__PURE__ */ w(E, {
|
|
248
242
|
variant: "outline",
|
|
249
243
|
size: "sm",
|
|
250
244
|
onClick: () => i(30),
|
|
251
|
-
children: "Last 30 days"
|
|
245
|
+
children: o("technospam.analytics.last30Days", "Last 30 days")
|
|
252
246
|
}),
|
|
253
247
|
/* @__PURE__ */ w(E, {
|
|
254
248
|
variant: "outline",
|
|
255
249
|
size: "sm",
|
|
256
250
|
onClick: () => i(90),
|
|
257
|
-
children: "Last 90 days"
|
|
251
|
+
children: o("technospam.analytics.last90Days", "Last 90 days")
|
|
258
252
|
})
|
|
259
253
|
]
|
|
260
254
|
})]
|
|
261
255
|
});
|
|
262
256
|
}
|
|
263
257
|
function F() {
|
|
264
|
-
let
|
|
258
|
+
let r = t(), { currentUser: y } = e(), S = n(), C = y?.id, [O, M] = _(""), [F, I] = _(""), L = Ae(O), R = je(F), Ne = (e) => {
|
|
265
259
|
let t = /* @__PURE__ */ new Date(), n = /* @__PURE__ */ new Date();
|
|
266
|
-
n.setDate(n.getDate() - e),
|
|
267
|
-
},
|
|
268
|
-
|
|
269
|
-
},
|
|
270
|
-
startDate:
|
|
271
|
-
endDate:
|
|
272
|
-
} : {},
|
|
273
|
-
learnerId:
|
|
274
|
-
...
|
|
275
|
-
} : {}),
|
|
276
|
-
learnerId:
|
|
277
|
-
...
|
|
278
|
-
} : {}),
|
|
279
|
-
let e =
|
|
260
|
+
n.setDate(n.getDate() - e), M(n.toISOString().slice(0, 10)), I(t.toISOString().slice(0, 10));
|
|
261
|
+
}, Pe = () => {
|
|
262
|
+
M(""), I("");
|
|
263
|
+
}, z = L || R ? {
|
|
264
|
+
startDate: L,
|
|
265
|
+
endDate: R
|
|
266
|
+
} : {}, B = ae(C ? {
|
|
267
|
+
learnerId: C,
|
|
268
|
+
...z
|
|
269
|
+
} : {}), V = le(C ? {
|
|
270
|
+
learnerId: C,
|
|
271
|
+
...z
|
|
272
|
+
} : {}), H = ce(C ? { menteeId: C } : {}), U = re(C ? { learnerId: C } : {}), Fe = ie({ status: "PUBLISHED" }), Ie = se({ status: "PUBLISHED" }), Le = oe({}), W = g(() => B.data?.tecListEnrollments?.items ?? [], [B.data]), G = g(() => V.data?.tecListSubmissions?.items ?? [], [V.data]), K = H.data?.tecListSessions?.items ?? [], q = U.data?.tecListCertificates ?? [], Re = Fe.data?.tecListCourses?.items.length ?? 0, ze = Ie.data?.tecListProblems?.items.length ?? 0, Be = Le.data?.tecListHackathons?.items.length ?? 0, J = g(() => {
|
|
273
|
+
let e = W.filter((e) => e.status === "COMPLETED").length, t = W.length ? Math.round(W.reduce((e, t) => e + t.progressPct, 0) / W.length) : 0, n = G.filter((e) => e.verdict === "ACCEPTED");
|
|
280
274
|
return {
|
|
281
275
|
coursesCompleted: e,
|
|
282
276
|
avgProgress: t,
|
|
283
277
|
problemsSolved: new Set(n.map((e) => e.problemId)).size,
|
|
284
|
-
acceptanceRate:
|
|
278
|
+
acceptanceRate: G.length ? Math.round(n.length / G.length * 100) : 0
|
|
285
279
|
};
|
|
286
|
-
}, [
|
|
287
|
-
name:
|
|
288
|
-
value:
|
|
289
|
-
color:
|
|
290
|
-
})).filter((e) => e.value > 0), [
|
|
291
|
-
label:
|
|
292
|
-
count:
|
|
293
|
-
color:
|
|
294
|
-
})).filter((e) => e.count > 0), [
|
|
280
|
+
}, [W, G]), Y = g(() => Ce.map((e) => ({
|
|
281
|
+
name: o(e),
|
|
282
|
+
value: W.filter((t) => t.status === e).length,
|
|
283
|
+
color: we[e]
|
|
284
|
+
})).filter((e) => e.value > 0), [W]), X = g(() => Te.map((e) => ({
|
|
285
|
+
label: Ee[e],
|
|
286
|
+
count: G.filter((t) => t.verdict === e).length,
|
|
287
|
+
color: De[e]
|
|
288
|
+
})).filter((e) => e.count > 0), [G]), Ve = g(() => {
|
|
295
289
|
let e = /* @__PURE__ */ new Map();
|
|
296
|
-
return
|
|
290
|
+
return G.forEach((t) => {
|
|
297
291
|
let n = t.problem?.topic?.trim() || "Untagged", r = e.get(n) ?? {
|
|
298
292
|
accepted: 0,
|
|
299
293
|
attempted: 0
|
|
@@ -305,59 +299,63 @@ function F() {
|
|
|
305
299
|
attempted: t.attempted,
|
|
306
300
|
rate: Math.round(t.accepted / t.attempted * 100)
|
|
307
301
|
})).sort((e, t) => t.rate - e.rate || t.attempted - e.attempted);
|
|
308
|
-
}, [
|
|
302
|
+
}, [G]), Z = g(() => {
|
|
309
303
|
let e = /* @__PURE__ */ new Map(), t = (t, n) => {
|
|
310
|
-
let { key: r, label: i } =
|
|
304
|
+
let { key: r, label: i } = Oe(t), a = e.get(r) ?? {
|
|
311
305
|
label: i,
|
|
312
306
|
submissions: 0,
|
|
313
307
|
enrollments: 0
|
|
314
308
|
};
|
|
315
309
|
a[n] += 1, e.set(r, a);
|
|
316
310
|
};
|
|
317
|
-
return
|
|
318
|
-
}, [
|
|
311
|
+
return G.forEach((e) => t(e.createdAt, "submissions")), W.forEach((e) => t(e.createdAt, "enrollments")), [...e.entries()].sort((e, t) => e[0] - t[0]).slice(-8).map(([, e]) => e);
|
|
312
|
+
}, [G, W]), Q = W.length > 0 || G.length > 0 || K.length > 0 || q.length > 0, He = B.loading || V.loading || H.loading || U.loading, $ = B.error || V.error || H.error || U.error, Ue = He && !Q, We = /* @__PURE__ */ T("div", { children: [
|
|
319
313
|
/* @__PURE__ */ w("h2", {
|
|
320
314
|
className: "mb-3 text-base font-semibold text-text-primary",
|
|
321
|
-
children: "Workspace overview"
|
|
315
|
+
children: S("technospam.analytics.workspaceOverviewTitle", "Workspace overview")
|
|
322
316
|
}),
|
|
323
317
|
/* @__PURE__ */ w("p", {
|
|
324
318
|
className: "mb-4 max-w-2xl text-sm text-text-secondary",
|
|
325
|
-
children: "Live content available across the TechnoSpam learning workspace right now."
|
|
319
|
+
children: S("technospam.analytics.workspaceOverviewDesc", "Live content available across the TechnoSpam learning workspace right now.")
|
|
326
320
|
}),
|
|
327
321
|
/* @__PURE__ */ T("div", {
|
|
328
322
|
className: "grid grid-cols-1 gap-3 sm:grid-cols-3",
|
|
329
323
|
children: [
|
|
330
|
-
/* @__PURE__ */ w(
|
|
331
|
-
label: "Published courses",
|
|
332
|
-
value:
|
|
333
|
-
icon:
|
|
324
|
+
/* @__PURE__ */ w(a, {
|
|
325
|
+
label: S("technospam.analytics.statPublishedCourses", "Published courses"),
|
|
326
|
+
value: Re,
|
|
327
|
+
icon: ve,
|
|
334
328
|
tone: "blue"
|
|
335
329
|
}),
|
|
336
|
-
/* @__PURE__ */ w(
|
|
337
|
-
label: "Published problems",
|
|
338
|
-
value:
|
|
330
|
+
/* @__PURE__ */ w(a, {
|
|
331
|
+
label: S("technospam.analytics.statPublishedProblems", "Published problems"),
|
|
332
|
+
value: ze,
|
|
339
333
|
icon: b,
|
|
340
334
|
tone: "indigo"
|
|
341
335
|
}),
|
|
342
|
-
/* @__PURE__ */ w(
|
|
343
|
-
label: "Hackathons",
|
|
344
|
-
value:
|
|
345
|
-
icon:
|
|
336
|
+
/* @__PURE__ */ w(a, {
|
|
337
|
+
label: S("technospam.analytics.statHackathons", "Hackathons"),
|
|
338
|
+
value: Be,
|
|
339
|
+
icon: xe,
|
|
346
340
|
tone: "purple"
|
|
347
341
|
})
|
|
348
342
|
]
|
|
349
343
|
})
|
|
350
344
|
] });
|
|
351
|
-
return /* @__PURE__ */ w(
|
|
345
|
+
return /* @__PURE__ */ w(i, {
|
|
352
346
|
hero: !0,
|
|
353
|
-
title: "Analytics",
|
|
354
|
-
description: "Your real learning performance across courses, problems, mentoring and certificates.",
|
|
347
|
+
title: S("technospam.analytics.title", "Analytics"),
|
|
348
|
+
description: S("technospam.analytics.description", "Your real learning performance across courses, problems, mentoring and certificates."),
|
|
355
349
|
actions: /* @__PURE__ */ T(E, {
|
|
356
350
|
variant: "outline",
|
|
357
|
-
onClick: () =>
|
|
358
|
-
children: [
|
|
351
|
+
onClick: () => r("/courses/my-learning-page"),
|
|
352
|
+
children: [
|
|
353
|
+
/* @__PURE__ */ w(x, { size: 16 }),
|
|
354
|
+
" ",
|
|
355
|
+
S("technospam.common.myLearning", "My Learning")
|
|
356
|
+
]
|
|
359
357
|
}),
|
|
360
|
-
children:
|
|
358
|
+
children: C ? Ue ? /* @__PURE__ */ T("div", {
|
|
361
359
|
className: "space-y-6",
|
|
362
360
|
children: [/* @__PURE__ */ w(te, {
|
|
363
361
|
count: 4,
|
|
@@ -366,82 +364,83 @@ function F() {
|
|
|
366
364
|
count: 2,
|
|
367
365
|
height: "h-72"
|
|
368
366
|
})]
|
|
369
|
-
}) :
|
|
370
|
-
title: "Couldn't load your analytics",
|
|
371
|
-
error:
|
|
367
|
+
}) : $ && !Q ? /* @__PURE__ */ w(ee, {
|
|
368
|
+
title: S("technospam.common.errorLoadAnalytics", "Couldn't load your analytics"),
|
|
369
|
+
error: $
|
|
372
370
|
}) : /* @__PURE__ */ T("div", {
|
|
373
371
|
className: "space-y-8",
|
|
374
372
|
children: [
|
|
375
|
-
/* @__PURE__ */ w(
|
|
376
|
-
start:
|
|
377
|
-
end:
|
|
378
|
-
onStart:
|
|
379
|
-
onEnd:
|
|
380
|
-
onPreset:
|
|
381
|
-
onClear:
|
|
373
|
+
/* @__PURE__ */ w(Me, {
|
|
374
|
+
start: O,
|
|
375
|
+
end: F,
|
|
376
|
+
onStart: M,
|
|
377
|
+
onEnd: I,
|
|
378
|
+
onPreset: Ne,
|
|
379
|
+
onClear: Pe,
|
|
380
|
+
tr: S
|
|
382
381
|
}),
|
|
383
382
|
/* @__PURE__ */ T("div", {
|
|
384
383
|
className: "grid grid-cols-2 gap-3 sm:grid-cols-3 xl:grid-cols-4",
|
|
385
384
|
children: [
|
|
386
|
-
/* @__PURE__ */ w(
|
|
387
|
-
label: "Courses enrolled",
|
|
388
|
-
value:
|
|
389
|
-
icon:
|
|
385
|
+
/* @__PURE__ */ w(a, {
|
|
386
|
+
label: S("technospam.analytics.statCoursesEnrolled", "Courses enrolled"),
|
|
387
|
+
value: W.length,
|
|
388
|
+
icon: _e,
|
|
390
389
|
tone: "blue"
|
|
391
390
|
}),
|
|
392
|
-
/* @__PURE__ */ w(
|
|
393
|
-
label: "Courses completed",
|
|
394
|
-
value:
|
|
391
|
+
/* @__PURE__ */ w(a, {
|
|
392
|
+
label: S("technospam.analytics.statCoursesCompleted", "Courses completed"),
|
|
393
|
+
value: J.coursesCompleted,
|
|
395
394
|
icon: x,
|
|
396
395
|
tone: "green"
|
|
397
396
|
}),
|
|
398
|
-
/* @__PURE__ */ w(
|
|
399
|
-
label: "Avg progress",
|
|
400
|
-
value: `${
|
|
401
|
-
icon:
|
|
397
|
+
/* @__PURE__ */ w(a, {
|
|
398
|
+
label: S("technospam.analytics.statAvgProgress", "Avg progress"),
|
|
399
|
+
value: `${J.avgProgress}%`,
|
|
400
|
+
icon: be,
|
|
402
401
|
tone: "purple"
|
|
403
402
|
}),
|
|
404
|
-
/* @__PURE__ */ w(
|
|
405
|
-
label: "Problems solved",
|
|
406
|
-
value:
|
|
403
|
+
/* @__PURE__ */ w(a, {
|
|
404
|
+
label: S("technospam.analytics.statProblemsSolved", "Problems solved"),
|
|
405
|
+
value: J.problemsSolved,
|
|
407
406
|
icon: b,
|
|
408
407
|
tone: "indigo"
|
|
409
408
|
}),
|
|
410
|
-
/* @__PURE__ */ w(
|
|
411
|
-
label: "Acceptance rate",
|
|
412
|
-
value: `${
|
|
413
|
-
icon:
|
|
409
|
+
/* @__PURE__ */ w(a, {
|
|
410
|
+
label: S("technospam.analytics.statAcceptanceRate", "Acceptance rate"),
|
|
411
|
+
value: `${J.acceptanceRate}%`,
|
|
412
|
+
icon: ye,
|
|
414
413
|
tone: "teal"
|
|
415
414
|
}),
|
|
416
|
-
/* @__PURE__ */ w(
|
|
417
|
-
label: "Mentor sessions",
|
|
418
|
-
value:
|
|
419
|
-
icon:
|
|
415
|
+
/* @__PURE__ */ w(a, {
|
|
416
|
+
label: S("technospam.analytics.statMentorSessions", "Mentor sessions"),
|
|
417
|
+
value: K.length,
|
|
418
|
+
icon: Se,
|
|
420
419
|
tone: "blue"
|
|
421
420
|
}),
|
|
422
|
-
/* @__PURE__ */ w(
|
|
423
|
-
label: "Certificates",
|
|
424
|
-
value:
|
|
421
|
+
/* @__PURE__ */ w(a, {
|
|
422
|
+
label: S("technospam.analytics.statCertificates", "Certificates"),
|
|
423
|
+
value: q.length,
|
|
425
424
|
icon: he,
|
|
426
425
|
tone: "amber"
|
|
427
426
|
})
|
|
428
427
|
]
|
|
429
428
|
}),
|
|
430
|
-
|
|
429
|
+
Q ? /* @__PURE__ */ T("div", {
|
|
431
430
|
className: "space-y-4",
|
|
432
431
|
children: [
|
|
433
432
|
/* @__PURE__ */ T("div", {
|
|
434
433
|
className: "grid grid-cols-1 gap-4 lg:grid-cols-2",
|
|
435
434
|
children: [/* @__PURE__ */ w(P, {
|
|
436
|
-
title: "Enrollments by status",
|
|
437
|
-
subtitle: "How your courses are progressing",
|
|
438
|
-
icon:
|
|
435
|
+
title: S("technospam.analytics.enrollmentsByStatusTitle", "Enrollments by status"),
|
|
436
|
+
subtitle: S("technospam.analytics.enrollmentsByStatusSubtitle", "How your courses are progressing"),
|
|
437
|
+
icon: _e,
|
|
439
438
|
tone: "blue",
|
|
440
|
-
isEmpty:
|
|
441
|
-
emptyLabel: "No enrollments yet",
|
|
439
|
+
isEmpty: Y.length === 0,
|
|
440
|
+
emptyLabel: S("technospam.analytics.noEnrollments", "No enrollments yet"),
|
|
442
441
|
children: /* @__PURE__ */ T(pe, { children: [
|
|
443
442
|
/* @__PURE__ */ w(ue, {
|
|
444
|
-
data:
|
|
443
|
+
data: Y,
|
|
445
444
|
dataKey: "value",
|
|
446
445
|
nameKey: "name",
|
|
447
446
|
innerRadius: 60,
|
|
@@ -449,26 +448,26 @@ function F() {
|
|
|
449
448
|
paddingAngle: 2,
|
|
450
449
|
stroke: "var(--color-bg-surface)",
|
|
451
450
|
strokeWidth: 2,
|
|
452
|
-
children:
|
|
451
|
+
children: Y.map((e) => /* @__PURE__ */ w(d, { fill: e.color }, e.name))
|
|
453
452
|
}),
|
|
454
|
-
/* @__PURE__ */ w(
|
|
453
|
+
/* @__PURE__ */ w(l, {
|
|
455
454
|
contentStyle: k,
|
|
456
455
|
labelStyle: A
|
|
457
456
|
}),
|
|
458
|
-
/* @__PURE__ */ w(
|
|
457
|
+
/* @__PURE__ */ w(c, {
|
|
459
458
|
iconType: "circle",
|
|
460
459
|
wrapperStyle: { fontSize: 12 }
|
|
461
460
|
})
|
|
462
461
|
] })
|
|
463
462
|
}), /* @__PURE__ */ w(P, {
|
|
464
|
-
title: "Submissions by verdict",
|
|
465
|
-
subtitle: "Outcomes across your attempts",
|
|
463
|
+
title: S("technospam.analytics.submissionsByVerdictTitle", "Submissions by verdict"),
|
|
464
|
+
subtitle: S("technospam.analytics.submissionsByVerdictSubtitle", "Outcomes across your attempts"),
|
|
466
465
|
icon: b,
|
|
467
466
|
tone: "purple",
|
|
468
|
-
isEmpty:
|
|
469
|
-
emptyLabel: "No submissions yet",
|
|
467
|
+
isEmpty: X.length === 0,
|
|
468
|
+
emptyLabel: S("technospam.analytics.noSubmissions", "No submissions yet"),
|
|
470
469
|
children: /* @__PURE__ */ T(fe, {
|
|
471
|
-
data:
|
|
470
|
+
data: X,
|
|
472
471
|
margin: {
|
|
473
472
|
top: 8,
|
|
474
473
|
right: 8,
|
|
@@ -476,24 +475,24 @@ function F() {
|
|
|
476
475
|
bottom: 0
|
|
477
476
|
},
|
|
478
477
|
children: [
|
|
479
|
-
/* @__PURE__ */ w(
|
|
478
|
+
/* @__PURE__ */ w(f, {
|
|
480
479
|
strokeDasharray: "3 3",
|
|
481
480
|
stroke: "var(--color-border-seam)",
|
|
482
481
|
vertical: !1
|
|
483
482
|
}),
|
|
484
|
-
/* @__PURE__ */ w(
|
|
483
|
+
/* @__PURE__ */ w(m, {
|
|
485
484
|
dataKey: "label",
|
|
486
485
|
tick: j,
|
|
487
486
|
axisLine: { stroke: "var(--color-border-seam)" },
|
|
488
487
|
tickLine: !1
|
|
489
488
|
}),
|
|
490
|
-
/* @__PURE__ */ w(
|
|
489
|
+
/* @__PURE__ */ w(h, {
|
|
491
490
|
allowDecimals: !1,
|
|
492
491
|
tick: j,
|
|
493
492
|
axisLine: !1,
|
|
494
493
|
tickLine: !1
|
|
495
494
|
}),
|
|
496
|
-
/* @__PURE__ */ w(
|
|
495
|
+
/* @__PURE__ */ w(l, {
|
|
497
496
|
contentStyle: k,
|
|
498
497
|
labelStyle: A,
|
|
499
498
|
cursor: {
|
|
@@ -511,28 +510,38 @@ function F() {
|
|
|
511
510
|
0
|
|
512
511
|
],
|
|
513
512
|
maxBarSize: 56,
|
|
514
|
-
children:
|
|
513
|
+
children: X.map((e) => /* @__PURE__ */ w(d, { fill: e.color }, e.label))
|
|
515
514
|
})
|
|
516
515
|
]
|
|
517
516
|
})
|
|
518
517
|
})]
|
|
519
518
|
}),
|
|
520
|
-
/* @__PURE__ */ w(
|
|
519
|
+
/* @__PURE__ */ w(ke, {
|
|
520
|
+
data: Ve,
|
|
521
|
+
title: S("technospam.analytics.topicAcceptanceTitle", "Accepted rate by topic"),
|
|
522
|
+
subtitle: S("technospam.analytics.topicAcceptanceSubtitle", "Where your solutions land, and where they don't"),
|
|
523
|
+
noData: S("technospam.analytics.noTopicData", "Solve a practice problem and your per-topic rate builds here"),
|
|
524
|
+
lowestRateLabel: (e, t, n) => S("technospam.analytics.lowestMeasuredRate", "Lowest measured rate: {{topic}} — {{accepted}} of {{attempted}} attempts accepted in the loaded range.", {
|
|
525
|
+
topic: e,
|
|
526
|
+
accepted: t,
|
|
527
|
+
attempted: n
|
|
528
|
+
})
|
|
529
|
+
}),
|
|
521
530
|
/* @__PURE__ */ T(D, {
|
|
522
531
|
className: "p-5 transition-shadow duration-200 hover:shadow-lg",
|
|
523
532
|
children: [/* @__PURE__ */ w(N, {
|
|
524
|
-
icon:
|
|
525
|
-
title: "Learning activity over time",
|
|
526
|
-
subtitle: "Submissions and enrollments per week",
|
|
533
|
+
icon: v,
|
|
534
|
+
title: S("technospam.analytics.activityOverTimeTitle", "Learning activity over time"),
|
|
535
|
+
subtitle: S("technospam.analytics.activityOverTimeSubtitle", "Submissions and enrollments per week"),
|
|
527
536
|
tone: "teal"
|
|
528
|
-
}),
|
|
537
|
+
}), Z.length === 0 ? /* @__PURE__ */ w("div", {
|
|
529
538
|
className: "flex h-[240px] items-center justify-center text-sm text-text-muted",
|
|
530
|
-
children: "No dated activity yet"
|
|
531
|
-
}) : /* @__PURE__ */ w(
|
|
539
|
+
children: S("technospam.analytics.noDatedActivity", "No dated activity yet")
|
|
540
|
+
}) : /* @__PURE__ */ w(u, {
|
|
532
541
|
width: "100%",
|
|
533
542
|
height: 280,
|
|
534
543
|
children: /* @__PURE__ */ T(me, {
|
|
535
|
-
data:
|
|
544
|
+
data: Z,
|
|
536
545
|
margin: {
|
|
537
546
|
top: 8,
|
|
538
547
|
right: 12,
|
|
@@ -571,32 +580,32 @@ function F() {
|
|
|
571
580
|
stopOpacity: 0
|
|
572
581
|
})]
|
|
573
582
|
})] }),
|
|
574
|
-
/* @__PURE__ */ w(
|
|
583
|
+
/* @__PURE__ */ w(f, {
|
|
575
584
|
strokeDasharray: "3 3",
|
|
576
585
|
stroke: "var(--color-border-seam)",
|
|
577
586
|
vertical: !1
|
|
578
587
|
}),
|
|
579
|
-
/* @__PURE__ */ w(
|
|
588
|
+
/* @__PURE__ */ w(m, {
|
|
580
589
|
dataKey: "label",
|
|
581
590
|
tick: j,
|
|
582
591
|
axisLine: { stroke: "var(--color-border-seam)" },
|
|
583
592
|
tickLine: !1
|
|
584
593
|
}),
|
|
585
|
-
/* @__PURE__ */ w(
|
|
594
|
+
/* @__PURE__ */ w(h, {
|
|
586
595
|
allowDecimals: !1,
|
|
587
596
|
tick: j,
|
|
588
597
|
axisLine: !1,
|
|
589
598
|
tickLine: !1
|
|
590
599
|
}),
|
|
591
|
-
/* @__PURE__ */ w(
|
|
600
|
+
/* @__PURE__ */ w(l, {
|
|
592
601
|
contentStyle: k,
|
|
593
602
|
labelStyle: A
|
|
594
603
|
}),
|
|
595
|
-
/* @__PURE__ */ w(
|
|
604
|
+
/* @__PURE__ */ w(c, {
|
|
596
605
|
iconType: "circle",
|
|
597
606
|
wrapperStyle: { fontSize: 12 }
|
|
598
607
|
}),
|
|
599
|
-
/* @__PURE__ */ w(
|
|
608
|
+
/* @__PURE__ */ w(p, {
|
|
600
609
|
type: "monotone",
|
|
601
610
|
dataKey: "submissions",
|
|
602
611
|
name: "Submissions",
|
|
@@ -604,7 +613,7 @@ function F() {
|
|
|
604
613
|
strokeWidth: 2,
|
|
605
614
|
fill: "url(#tec-grad-submissions)"
|
|
606
615
|
}),
|
|
607
|
-
/* @__PURE__ */ w(
|
|
616
|
+
/* @__PURE__ */ w(p, {
|
|
608
617
|
type: "monotone",
|
|
609
618
|
dataKey: "enrollments",
|
|
610
619
|
name: "Enrollments",
|
|
@@ -617,24 +626,24 @@ function F() {
|
|
|
617
626
|
})]
|
|
618
627
|
})
|
|
619
628
|
]
|
|
620
|
-
}) : /* @__PURE__ */ w(
|
|
621
|
-
icon: /* @__PURE__ */ w(
|
|
622
|
-
title: "No learning activity yet",
|
|
623
|
-
description: "Enroll in a course or solve a problem and your progress charts will build here. TechnoSpam is pre-launch — start learning to see your data.",
|
|
629
|
+
}) : /* @__PURE__ */ w(s, {
|
|
630
|
+
icon: /* @__PURE__ */ w(v, { size: 26 }),
|
|
631
|
+
title: S("technospam.analytics.noActivityTitle", "No learning activity yet"),
|
|
632
|
+
description: S("technospam.analytics.noActivityDesc", "Enroll in a course or solve a problem and your progress charts will build here. TechnoSpam is pre-launch — start learning to see your data."),
|
|
624
633
|
action: /* @__PURE__ */ w(E, {
|
|
625
|
-
onClick: () =>
|
|
626
|
-
children: "Browse courses"
|
|
634
|
+
onClick: () => r("/courses/courses-page"),
|
|
635
|
+
children: S("technospam.common.browseCourses", "Browse courses")
|
|
627
636
|
})
|
|
628
637
|
}),
|
|
629
|
-
|
|
638
|
+
We
|
|
630
639
|
]
|
|
631
640
|
}) : /* @__PURE__ */ T("div", {
|
|
632
641
|
className: "space-y-8",
|
|
633
|
-
children: [/* @__PURE__ */ w(
|
|
642
|
+
children: [/* @__PURE__ */ w(s, {
|
|
634
643
|
icon: /* @__PURE__ */ w(ge, { size: 26 }),
|
|
635
|
-
title: "Sign in to view your analytics",
|
|
636
|
-
description: "Your personal learning metrics appear here once you're signed in."
|
|
637
|
-
}),
|
|
644
|
+
title: S("technospam.analytics.signInTitle", "Sign in to view your analytics"),
|
|
645
|
+
description: S("technospam.analytics.signInDesc", "Your personal learning metrics appear here once you're signed in.")
|
|
646
|
+
}), We]
|
|
638
647
|
})
|
|
639
648
|
});
|
|
640
649
|
}
|