@olinfo/quizms-firebase 4.1.3 → 5.0.0
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/cli.js +14 -14
- package/dist/cli.js.map +1 -1
- package/dist/package.json.js +1 -1
- package/dist/src/cli/definalize.js +17 -17
- package/dist/src/cli/definalize.js.map +1 -1
- package/dist/src/cli/export.js +42 -34
- package/dist/src/cli/export.js.map +1 -1
- package/dist/src/cli/files/firestore-indexes.json.js +1 -1
- package/dist/src/cli/files/firestore.rules.js +27 -27
- package/dist/src/cli/files/firestore.rules.js.map +1 -1
- package/dist/src/cli/files/functions-index.js +3 -3
- package/dist/src/cli/files/functions-index.js.map +1 -1
- package/dist/src/cli/files/storage.rules.js +3 -3
- package/dist/src/cli/files/storage.rules.js.map +1 -1
- package/dist/src/cli/import.js +65 -71
- package/dist/src/cli/import.js.map +1 -1
- package/dist/src/cli/update-scores.js +7 -7
- package/dist/src/cli/update-scores.js.map +1 -1
- package/dist/src/cli/utils/converters-admin.js +23 -22
- package/dist/src/cli/utils/converters-admin.js.map +1 -1
- package/dist/src/functions/api/index.js +18 -18
- package/dist/src/functions/api/index.js.map +1 -1
- package/dist/src/functions/api/queries.js +21 -21
- package/dist/src/functions/api/queries.js.map +1 -1
- package/dist/src/functions/api/student.js +46 -47
- package/dist/src/functions/api/student.js.map +1 -1
- package/dist/src/functions/api/teacher.js +92 -95
- package/dist/src/functions/api/teacher.js.map +1 -1
- package/dist/src/functions/submissions.js +11 -7
- package/dist/src/functions/submissions.js.map +1 -1
- package/dist/src/functions/update-scores.js +14 -14
- package/dist/src/functions/update-scores.js.map +1 -1
- package/dist/src/models/submission.js +13 -0
- package/dist/src/models/submission.js.map +1 -0
- package/dist/src/web/admin/announcements.js +45 -42
- package/dist/src/web/admin/announcements.js.map +1 -1
- package/dist/src/web/admin/dashboard.js +43 -43
- package/dist/src/web/admin/dashboard.js.map +1 -1
- package/dist/src/web/admin/export.js +56 -52
- package/dist/src/web/admin/export.js.map +1 -1
- package/dist/src/web/admin/provider.js +28 -28
- package/dist/src/web/admin/provider.js.map +1 -1
- package/dist/src/web/admin/school-table.js +20 -24
- package/dist/src/web/admin/school-table.js.map +1 -1
- package/dist/src/web/common/api.js +25 -25
- package/dist/src/web/common/api.js.map +1 -1
- package/dist/src/web/common/converters.js +38 -39
- package/dist/src/web/common/converters.js.map +1 -1
- package/dist/src/web/entry/student-statement.js +1 -1
- package/dist/src/web/entry/student-statement.js.map +1 -1
- package/dist/src/web/entry/student.js +80 -75
- package/dist/src/web/entry/student.js.map +1 -1
- package/dist/src/web/entry/teacher.js +63 -62
- package/dist/src/web/entry/teacher.js.map +1 -1
- package/package.json +13 -13
|
@@ -1,47 +1,47 @@
|
|
|
1
|
-
import { jsxs as
|
|
1
|
+
import { jsxs as o, jsx as e } from "react/jsx-runtime";
|
|
2
2
|
import { lazy as s } from "react";
|
|
3
|
-
import { Route as
|
|
3
|
+
import { Route as c, Redirect as m, Link as f, useParams as h, Switch as p } from "wouter";
|
|
4
4
|
import { AdminContext as u } from "./context.js";
|
|
5
5
|
import { AdminLayout as x } from "./layout.js";
|
|
6
|
-
import { SchoolTable as
|
|
6
|
+
import { SchoolTable as g } from "./school-table.js";
|
|
7
7
|
function A({
|
|
8
|
-
name:
|
|
9
|
-
contests:
|
|
10
|
-
setContest:
|
|
11
|
-
logout:
|
|
8
|
+
name: i,
|
|
9
|
+
contests: r,
|
|
10
|
+
setContest: d,
|
|
11
|
+
logout: l,
|
|
12
12
|
...n
|
|
13
13
|
}) {
|
|
14
|
-
return /* @__PURE__ */
|
|
15
|
-
/* @__PURE__ */
|
|
16
|
-
|
|
17
|
-
/* @__PURE__ */
|
|
18
|
-
/* @__PURE__ */
|
|
19
|
-
/* @__PURE__ */
|
|
14
|
+
return /* @__PURE__ */ o(x, { name: i, contests: r, logout: l, children: [
|
|
15
|
+
/* @__PURE__ */ o(c, { path: "/", children: [
|
|
16
|
+
r.length === 1 && /* @__PURE__ */ e(m, { to: `/${r[0].id}` }),
|
|
17
|
+
r.length === 0 ? /* @__PURE__ */ e("div", { className: "flex w-full grow flex-col items-center justify-center gap-4", children: /* @__PURE__ */ e("p", { className: "text-2xl", children: "Non sono state trovate gare" }) }) : /* @__PURE__ */ o("div", { className: "flex w-full grow flex-col items-center justify-center gap-4", children: [
|
|
18
|
+
/* @__PURE__ */ e("p", { className: "text-2xl", children: "Seleziona una gara" }),
|
|
19
|
+
/* @__PURE__ */ e("div", { className: "flex flex-wrap justify-center gap-2", children: r.map((a) => /* @__PURE__ */ e(f, { className: "btn btn-primary", href: `/${a.id}`, children: a.name }, a.id)) })
|
|
20
20
|
] })
|
|
21
21
|
] }),
|
|
22
|
-
/* @__PURE__ */
|
|
23
|
-
|
|
22
|
+
/* @__PURE__ */ e(c, { path: "/:contestId", nest: !0, children: /* @__PURE__ */ e(
|
|
23
|
+
N,
|
|
24
24
|
{
|
|
25
|
-
name:
|
|
26
|
-
contests:
|
|
27
|
-
setContest:
|
|
28
|
-
logout:
|
|
25
|
+
name: i,
|
|
26
|
+
contests: r,
|
|
27
|
+
setContest: d,
|
|
28
|
+
logout: l,
|
|
29
29
|
...n
|
|
30
30
|
}
|
|
31
31
|
) })
|
|
32
32
|
] });
|
|
33
33
|
}
|
|
34
|
-
const
|
|
35
|
-
function
|
|
36
|
-
const { contestId:
|
|
34
|
+
const v = s(() => import("./dashboard.js"));
|
|
35
|
+
function N({ contests: i, variants: r, ...d }) {
|
|
36
|
+
const { contestId: l } = h(), n = i.find((t) => t.id === l);
|
|
37
37
|
if (!n)
|
|
38
|
-
return /* @__PURE__ */
|
|
39
|
-
const
|
|
40
|
-
|
|
38
|
+
return /* @__PURE__ */ e(m, { to: "/" });
|
|
39
|
+
const a = Object.fromEntries(
|
|
40
|
+
r.filter((t) => t.contestId === n?.id).map((t) => [t.id, t])
|
|
41
41
|
);
|
|
42
|
-
return /* @__PURE__ */
|
|
43
|
-
/* @__PURE__ */
|
|
44
|
-
/* @__PURE__ */
|
|
42
|
+
return /* @__PURE__ */ e(u.Provider, { value: { ...d, variants: a, contest: n, contests: i }, children: /* @__PURE__ */ o(p, { children: [
|
|
43
|
+
/* @__PURE__ */ e(c, { path: "/", children: /* @__PURE__ */ e(v, {}) }),
|
|
44
|
+
/* @__PURE__ */ e(c, { path: "/schools", children: /* @__PURE__ */ e(g, {}) })
|
|
45
45
|
] }) });
|
|
46
46
|
}
|
|
47
47
|
export {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider.js","sources":["../../../../src/web/admin/provider.tsx"],"sourcesContent":["import { lazy } from \"react\";\n\nimport type { Contest, Variant } from \"@olinfo/quizms/models\";\nimport { Link, Redirect, Route, Switch, useParams } from \"wouter\";\n\nimport { AdminContext } from \"./context\";\nimport { AdminLayout } from \"./layout\";\nimport { SchoolTable } from \"./school-table\";\n\ntype AdminProviderProps = {\n name: string;\n contests: Contest[];\n variants: Variant[];\n setContest: (contest: Contest) => Promise<void>;\n logout: () => Promise<void>;\n};\n\nexport function AdminProvider({\n name,\n contests,\n setContest,\n logout,\n ...props\n}: AdminProviderProps) {\n return (\n <AdminLayout name={name} contests={contests} logout={logout}>\n <Route path=\"/\">\n {contests.length === 1 && <Redirect to={`/${contests[0].id}`} />}\n <div className=\"flex w-full grow flex-col items-center justify-center gap-4\">\n <p className=\"text-2xl\">Seleziona una gara</p>\n
|
|
1
|
+
{"version":3,"file":"provider.js","sources":["../../../../src/web/admin/provider.tsx"],"sourcesContent":["import { lazy } from \"react\";\n\nimport type { Contest, Variant } from \"@olinfo/quizms/models\";\nimport { Link, Redirect, Route, Switch, useParams } from \"wouter\";\n\nimport { AdminContext } from \"./context\";\nimport { AdminLayout } from \"./layout\";\nimport { SchoolTable } from \"./school-table\";\n\ntype AdminProviderProps = {\n name: string;\n contests: Contest[];\n variants: Variant[];\n setContest: (contest: Contest) => Promise<void>;\n logout: () => Promise<void>;\n};\n\nexport function AdminProvider({\n name,\n contests,\n setContest,\n logout,\n ...props\n}: AdminProviderProps) {\n return (\n <AdminLayout name={name} contests={contests} logout={logout}>\n <Route path=\"/\">\n {contests.length === 1 && <Redirect to={`/${contests[0].id}`} />}\n {contests.length === 0 ? (\n <div className=\"flex w-full grow flex-col items-center justify-center gap-4\">\n <p className=\"text-2xl\">Non sono state trovate gare</p>\n </div>\n ) : (\n <div className=\"flex w-full grow flex-col items-center justify-center gap-4\">\n <p className=\"text-2xl\">Seleziona una gara</p>\n <div className=\"flex flex-wrap justify-center gap-2\">\n {contests.map((c) => (\n <Link key={c.id} className=\"btn btn-primary\" href={`/${c.id}`}>\n {c.name}\n </Link>\n ))}\n </div>\n </div>\n )}\n </Route>\n <Route path=\"/:contestId\" nest>\n <ProviderInner\n name={name}\n contests={contests}\n setContest={setContest}\n logout={logout}\n {...props}\n />\n </Route>\n </AdminLayout>\n );\n}\n\nconst Dashboard = lazy(() => import(\"./dashboard\"));\n\nfunction ProviderInner({ contests, variants, ...props }: AdminProviderProps) {\n const { contestId } = useParams();\n\n const contest = contests.find((c) => c.id === contestId);\n if (!contest) {\n return <Redirect to=\"/\" />;\n }\n\n const contestVariants = Object.fromEntries(\n variants.filter((v) => v.contestId === contest?.id).map((v) => [v.id, v]),\n );\n\n return (\n <AdminContext.Provider value={{ ...props, variants: contestVariants, contest, contests }}>\n <Switch>\n <Route path=\"/\">\n <Dashboard />\n </Route>\n <Route path=\"/schools\">\n <SchoolTable />\n </Route>\n </Switch>\n </AdminContext.Provider>\n );\n}\n"],"names":["AdminProvider","name","contests","setContest","logout","props","jsxs","AdminLayout","Route","jsx","Redirect","c","Link","ProviderInner","Dashboard","lazy","variants","contestId","useParams","contest","contestVariants","v","AdminContext","Switch","SchoolTable"],"mappings":";;;;;;AAiBO,SAASA,EAAc;AAAA,EAC5B,MAAAC;AAAA,EACA,UAAAC;AAAA,EACA,YAAAC;AAAA,EACA,QAAAC;AAAA,EACA,GAAGC;AACL,GAAuB;AACrB,SACE,gBAAAC,EAACC,GAAA,EAAY,MAAAN,GAAY,UAAAC,GAAoB,QAAAE,GAC3C,UAAA;AAAA,IAAA,gBAAAE,EAACE,GAAA,EAAM,MAAK,KACT,UAAA;AAAA,MAAAN,EAAS,WAAW,KAAK,gBAAAO,EAACC,GAAA,EAAS,IAAI,IAAIR,EAAS,CAAC,EAAE,EAAE,GAAA,CAAI;AAAA,MAC7DA,EAAS,WAAW,IACnB,gBAAAO,EAAC,OAAA,EAAI,WAAU,+DACb,UAAA,gBAAAA,EAAC,KAAA,EAAE,WAAU,YAAW,UAAA,8BAAA,CAA2B,GACrD,IAEA,gBAAAH,EAAC,OAAA,EAAI,WAAU,+DACb,UAAA;AAAA,QAAA,gBAAAG,EAAC,KAAA,EAAE,WAAU,YAAW,UAAA,sBAAkB;AAAA,QAC1C,gBAAAA,EAAC,SAAI,WAAU,uCACZ,YAAS,IAAI,CAACE,MACb,gBAAAF,EAACG,GAAA,EAAgB,WAAU,mBAAkB,MAAM,IAAID,EAAE,EAAE,IACxD,YAAE,KAAA,GADMA,EAAE,EAEb,CACD,EAAA,CACH;AAAA,MAAA,EAAA,CACF;AAAA,IAAA,GAEJ;AAAA,IACA,gBAAAF,EAACD,GAAA,EAAM,MAAK,eAAc,MAAI,IAC5B,UAAA,gBAAAC;AAAA,MAACI;AAAA,MAAA;AAAA,QACC,MAAAZ;AAAA,QACA,UAAAC;AAAA,QACA,YAAAC;AAAA,QACA,QAAAC;AAAA,QACC,GAAGC;AAAA,MAAA;AAAA,IAAA,EACN,CACF;AAAA,EAAA,GACF;AAEJ;AAEA,MAAMS,IAAYC,EAAK,MAAM,OAAO,gBAAa,CAAC;AAElD,SAASF,EAAc,EAAE,UAAAX,GAAU,UAAAc,GAAU,GAAGX,KAA6B;AAC3E,QAAM,EAAE,WAAAY,EAAA,IAAcC,EAAA,GAEhBC,IAAUjB,EAAS,KAAK,CAACS,MAAMA,EAAE,OAAOM,CAAS;AACvD,MAAI,CAACE;AACH,WAAO,gBAAAV,EAACC,GAAA,EAAS,IAAG,IAAA,CAAI;AAG1B,QAAMU,IAAkB,OAAO;AAAA,IAC7BJ,EAAS,OAAO,CAACK,MAAMA,EAAE,cAAcF,GAAS,EAAE,EAAE,IAAI,CAACE,MAAM,CAACA,EAAE,IAAIA,CAAC,CAAC;AAAA,EAAA;AAG1E,SACE,gBAAAZ,EAACa,EAAa,UAAb,EAAsB,OAAO,EAAE,GAAGjB,GAAO,UAAUe,GAAiB,SAAAD,GAAS,UAAAjB,KAC5E,4BAACqB,GAAA,EACC,UAAA;AAAA,IAAA,gBAAAd,EAACD,GAAA,EAAM,MAAK,KACV,UAAA,gBAAAC,EAACK,KAAU,GACb;AAAA,sBACCN,GAAA,EAAM,MAAK,YACV,UAAA,gBAAAC,EAACe,KAAY,EAAA,CACf;AAAA,EAAA,EAAA,CACF,EAAA,CACF;AAEJ;"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as e } from "react/jsx-runtime";
|
|
2
2
|
import { useMemo as s, Suspense as o } from "react";
|
|
3
|
-
import { AgGrid as d, Loading as
|
|
4
|
-
import {
|
|
3
|
+
import { AgGrid as d, Loading as u } from "@olinfo/quizms/components";
|
|
4
|
+
import { venueConverter as f } from "../common/converters.js";
|
|
5
5
|
import "firebase/auth";
|
|
6
6
|
import "lodash-es";
|
|
7
7
|
import "react-error-boundary";
|
|
@@ -9,25 +9,21 @@ import "swr";
|
|
|
9
9
|
import "../common/base-login.js";
|
|
10
10
|
import { useCollection as m } from "../hooks/collection.js";
|
|
11
11
|
import "firebase/firestore";
|
|
12
|
-
import { useCount as
|
|
13
|
-
import { useAdmin as
|
|
14
|
-
function
|
|
15
|
-
const { contest:
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
constraints: { contestId: i.id }
|
|
20
|
-
}
|
|
21
|
-
), a = s(() => h(), []);
|
|
22
|
-
return /* @__PURE__ */ e(o, { fallback: /* @__PURE__ */ e(c, {}), children: /* @__PURE__ */ e("div", { className: "relative grow p-2", children: /* @__PURE__ */ e("div", { className: "absolute inset-0", children: /* @__PURE__ */ e(
|
|
12
|
+
import { useCount as c } from "../hooks/count.js";
|
|
13
|
+
import { useAdmin as p } from "./context.js";
|
|
14
|
+
function E() {
|
|
15
|
+
const { contest: t } = p(), [r, n] = m("venues", f, {
|
|
16
|
+
constraints: { contestId: t.id }
|
|
17
|
+
}), l = s(() => h(), []);
|
|
18
|
+
return /* @__PURE__ */ e(o, { fallback: /* @__PURE__ */ e(u, {}), children: /* @__PURE__ */ e("div", { className: "relative grow p-2", children: /* @__PURE__ */ e("div", { className: "absolute inset-0", children: /* @__PURE__ */ e(
|
|
23
19
|
d,
|
|
24
20
|
{
|
|
25
21
|
rowData: r,
|
|
26
|
-
getRowId: (
|
|
27
|
-
columnDefs:
|
|
28
|
-
onCellEditRequest: async (
|
|
29
|
-
const
|
|
30
|
-
|
|
22
|
+
getRowId: (i) => i.data.id,
|
|
23
|
+
columnDefs: l,
|
|
24
|
+
onCellEditRequest: async (i) => {
|
|
25
|
+
const a = i.data;
|
|
26
|
+
i.colDef.field === "finalized" && await n({ ...a, finalized: i.newValue }), i.api.refreshCells({ force: !0 });
|
|
31
27
|
}
|
|
32
28
|
}
|
|
33
29
|
) }) }) });
|
|
@@ -52,9 +48,9 @@ function h() {
|
|
|
52
48
|
headerName: "Studenti",
|
|
53
49
|
width: 100,
|
|
54
50
|
sortable: !1,
|
|
55
|
-
cellRenderer: ({ data:
|
|
56
|
-
if (
|
|
57
|
-
return /* @__PURE__ */ e(o, { children: /* @__PURE__ */ e(w, {
|
|
51
|
+
cellRenderer: ({ data: t }) => {
|
|
52
|
+
if (t)
|
|
53
|
+
return /* @__PURE__ */ e(o, { children: /* @__PURE__ */ e(w, { venueId: t.id }) });
|
|
58
54
|
}
|
|
59
55
|
},
|
|
60
56
|
{
|
|
@@ -67,12 +63,12 @@ function h() {
|
|
|
67
63
|
}
|
|
68
64
|
];
|
|
69
65
|
}
|
|
70
|
-
function w({
|
|
71
|
-
return
|
|
66
|
+
function w({ venueId: t }) {
|
|
67
|
+
return c(`venues/${t}/students`, {
|
|
72
68
|
constraints: { disabled: !1 }
|
|
73
69
|
});
|
|
74
70
|
}
|
|
75
71
|
export {
|
|
76
|
-
|
|
72
|
+
E as SchoolTable
|
|
77
73
|
};
|
|
78
74
|
//# sourceMappingURL=school-table.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"school-table.js","sources":["../../../../src/web/admin/school-table.tsx"],"sourcesContent":["import { Suspense, useMemo } from \"react\";\n\nimport { AgGrid, Loading } from \"@olinfo/quizms/components\";\nimport type {
|
|
1
|
+
{"version":3,"file":"school-table.js","sources":["../../../../src/web/admin/school-table.tsx"],"sourcesContent":["import { Suspense, useMemo } from \"react\";\n\nimport { AgGrid, Loading } from \"@olinfo/quizms/components\";\nimport type { Student, Venue } from \"@olinfo/quizms/models\";\nimport type { CellEditRequestEvent, ColDef, ICellRendererParams } from \"ag-grid-community\";\n\nimport { venueConverter } from \"~/web/common/converters\";\nimport { useCollection } from \"~/web/hooks\";\nimport { useCount } from \"~/web/hooks/count\";\n\nimport { useAdmin } from \"./context\";\n\nexport function SchoolTable() {\n const { contest } = useAdmin();\n\n const [venues, setVenue] = useCollection(\"venues\", venueConverter, {\n constraints: { contestId: contest.id },\n });\n\n const colDefs = useMemo(() => columnDefinition(), []);\n\n const onCellEditRequest = async (ev: CellEditRequestEvent) => {\n const venue = ev.data as Venue;\n if (ev.colDef.field === \"finalized\") {\n await setVenue({ ...venue, finalized: ev.newValue });\n }\n ev.api.refreshCells({ force: true });\n };\n\n return (\n <Suspense fallback={<Loading />}>\n <div className=\"relative grow p-2\">\n <div className=\"absolute inset-0\">\n <AgGrid\n rowData={venues}\n getRowId={(row) => (row.data as Venue).id}\n columnDefs={colDefs}\n onCellEditRequest={onCellEditRequest}\n />\n </div>\n </div>\n </Suspense>\n );\n}\n\nfunction columnDefinition(): ColDef[] {\n return [\n {\n field: \"schoolId\",\n headerName: \"ID\",\n width: 150,\n filter: true,\n },\n {\n field: \"name\",\n headerName: \"Nome\",\n minWidth: 200,\n flex: 1,\n filter: true,\n },\n {\n field: \"count\",\n headerName: \"Studenti\",\n width: 100,\n sortable: false,\n cellRenderer: ({ data }: ICellRendererParams<Venue>) => {\n if (!data) return;\n return (\n <Suspense>\n <Count venueId={data.id} />\n </Suspense>\n );\n },\n },\n {\n field: \"finalized\",\n headerName: \"Finalizzato\",\n width: 100,\n filter: true,\n cellDataType: \"boolean\",\n editable: true,\n },\n ];\n}\n\nfunction Count({ venueId }: { venueId: string }) {\n return useCount<Student>(`venues/${venueId}/students`, {\n constraints: { disabled: false },\n });\n}\n"],"names":["SchoolTable","contest","useAdmin","venues","setVenue","useCollection","venueConverter","colDefs","useMemo","columnDefinition","jsx","Suspense","Loading","AgGrid","row","ev","venue","data","Count","venueId","useCount"],"mappings":";;;;;;;;;;;;;AAYO,SAASA,IAAc;AAC5B,QAAM,EAAE,SAAAC,EAAA,IAAYC,EAAA,GAEd,CAACC,GAAQC,CAAQ,IAAIC,EAAc,UAAUC,GAAgB;AAAA,IACjE,aAAa,EAAE,WAAWL,EAAQ,GAAA;AAAA,EAAG,CACtC,GAEKM,IAAUC,EAAQ,MAAMC,EAAA,GAAoB,CAAA,CAAE;AAUpD,SACE,gBAAAC,EAACC,GAAA,EAAS,UAAU,gBAAAD,EAACE,GAAA,CAAA,CAAQ,GAC3B,UAAA,gBAAAF,EAAC,OAAA,EAAI,WAAU,qBACb,UAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,oBACb,UAAA,gBAAAA;AAAA,IAACG;AAAA,IAAA;AAAA,MACC,SAASV;AAAA,MACT,UAAU,CAACW,MAASA,EAAI,KAAe;AAAA,MACvC,YAAYP;AAAA,MACZ,mBAhBgB,OAAOQ,MAA6B;AAC5D,cAAMC,IAAQD,EAAG;AACjB,QAAIA,EAAG,OAAO,UAAU,eACtB,MAAMX,EAAS,EAAE,GAAGY,GAAO,WAAWD,EAAG,UAAU,GAErDA,EAAG,IAAI,aAAa,EAAE,OAAO,IAAM;AAAA,MACrC;AAAA,IAUU;AAAA,EAAA,EACF,CACF,GACF,GACF;AAEJ;AAEA,SAASN,IAA6B;AACpC,SAAO;AAAA,IACL;AAAA,MACE,OAAO;AAAA,MACP,YAAY;AAAA,MACZ,OAAO;AAAA,MACP,QAAQ;AAAA,IAAA;AAAA,IAEV;AAAA,MACE,OAAO;AAAA,MACP,YAAY;AAAA,MACZ,UAAU;AAAA,MACV,MAAM;AAAA,MACN,QAAQ;AAAA,IAAA;AAAA,IAEV;AAAA,MACE,OAAO;AAAA,MACP,YAAY;AAAA,MACZ,OAAO;AAAA,MACP,UAAU;AAAA,MACV,cAAc,CAAC,EAAE,MAAAQ,QAAuC;AACtD,YAAKA;AACL,mCACGN,GAAA,EACC,UAAA,gBAAAD,EAACQ,KAAM,SAASD,EAAK,IAAI,EAAA,CAC3B;AAAA,MAEJ;AAAA,IAAA;AAAA,IAEF;AAAA,MACE,OAAO;AAAA,MACP,YAAY;AAAA,MACZ,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,cAAc;AAAA,MACd,UAAU;AAAA,IAAA;AAAA,EACZ;AAEJ;AAEA,SAASC,EAAM,EAAE,SAAAC,KAAgC;AAC/C,SAAOC,EAAkB,UAAUD,CAAO,aAAa;AAAA,IACrD,aAAa,EAAE,UAAU,GAAA;AAAA,EAAM,CAChC;AACH;"}
|
|
@@ -1,44 +1,44 @@
|
|
|
1
|
-
import { createTRPCClient as
|
|
2
|
-
import { getIdToken as
|
|
3
|
-
import
|
|
4
|
-
const
|
|
1
|
+
import { createTRPCClient as o, httpLink as r } from "@trpc/client";
|
|
2
|
+
import { getIdToken as i } from "firebase/auth";
|
|
3
|
+
import a from "superjson";
|
|
4
|
+
const e = o({
|
|
5
5
|
links: [
|
|
6
|
-
|
|
6
|
+
r({
|
|
7
7
|
url: "/api",
|
|
8
|
-
transformer:
|
|
8
|
+
transformer: a,
|
|
9
9
|
async headers({ op: t }) {
|
|
10
10
|
const n = t.context?.user;
|
|
11
11
|
return n ? {
|
|
12
|
-
Authorization: `Bearer ${await
|
|
12
|
+
Authorization: `Bearer ${await i(n)}`
|
|
13
13
|
} : {};
|
|
14
14
|
}
|
|
15
15
|
})
|
|
16
16
|
]
|
|
17
17
|
});
|
|
18
|
-
function m(t) {
|
|
19
|
-
return i.teacherLogin.mutate(t);
|
|
20
|
-
}
|
|
21
18
|
function f(t) {
|
|
22
|
-
return
|
|
19
|
+
return e.teacherLogin.mutate(t);
|
|
23
20
|
}
|
|
24
|
-
function
|
|
25
|
-
return
|
|
21
|
+
function d(t) {
|
|
22
|
+
return e.adminLogin.mutate(t);
|
|
26
23
|
}
|
|
27
|
-
|
|
28
|
-
|
|
24
|
+
function p(t) {
|
|
25
|
+
return e.studentLogin.mutate(t);
|
|
29
26
|
}
|
|
30
|
-
async function
|
|
31
|
-
await
|
|
27
|
+
async function h(t, n) {
|
|
28
|
+
await e.teacherStartContestWindow.mutate({ venueId: n }, { context: { user: t } });
|
|
32
29
|
}
|
|
33
|
-
async function
|
|
34
|
-
await
|
|
30
|
+
async function w(t, n) {
|
|
31
|
+
await e.teacherStopContestWindow.mutate({ venueId: n }, { context: { user: t } });
|
|
32
|
+
}
|
|
33
|
+
async function g(t, n) {
|
|
34
|
+
await e.teacherFinalizeVenue.mutate({ venueId: n }, { context: { user: t } });
|
|
35
35
|
}
|
|
36
36
|
export {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
37
|
+
d as adminLogin,
|
|
38
|
+
g as finalizeVenue,
|
|
39
|
+
h as startContestWindow,
|
|
40
|
+
w as stopContestWindow,
|
|
41
|
+
p as studentLogin,
|
|
42
|
+
f as teacherLogin
|
|
43
43
|
};
|
|
44
44
|
//# sourceMappingURL=api.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","sources":["../../../../src/web/common/api.ts"],"sourcesContent":["import type { Student } from \"@olinfo/quizms/models\";\nimport { createTRPCClient, httpLink } from \"@trpc/client\";\nimport { getIdToken, type User } from \"firebase/auth\";\nimport superjson from \"superjson\";\n\nimport type { AppRouter } from \"~/functions/api\";\n\nconst trpc = createTRPCClient<AppRouter>({\n links: [\n httpLink({\n url: \"/api\",\n transformer: superjson,\n async headers({ op }) {\n const user = op.context?.user as User | undefined;\n if (user) {\n const token = await getIdToken(user);\n return {\n Authorization: `Bearer ${token}`,\n };\n }\n return {};\n },\n }),\n ],\n});\n\nexport function teacherLogin(body: { username: string; password: string }) {\n return trpc.teacherLogin.mutate(body);\n}\n\nexport function adminLogin(body: { username: string; password: string }) {\n return trpc.adminLogin.mutate(body);\n}\n\nexport function studentLogin(body: {\n contestId: string;\n token: string;\n userData: Required<NonNullable<Student[\"userData\"]>>;\n extraData: Record<string, any>;\n}) {\n return trpc.studentLogin.mutate(body);\n}\n\nexport async function
|
|
1
|
+
{"version":3,"file":"api.js","sources":["../../../../src/web/common/api.ts"],"sourcesContent":["import type { Student } from \"@olinfo/quizms/models\";\nimport { createTRPCClient, httpLink } from \"@trpc/client\";\nimport { getIdToken, type User } from \"firebase/auth\";\nimport superjson from \"superjson\";\n\nimport type { AppRouter } from \"~/functions/api\";\n\nconst trpc = createTRPCClient<AppRouter>({\n links: [\n httpLink({\n url: \"/api\",\n transformer: superjson,\n async headers({ op }) {\n const user = op.context?.user as User | undefined;\n if (user) {\n const token = await getIdToken(user);\n return {\n Authorization: `Bearer ${token}`,\n };\n }\n return {};\n },\n }),\n ],\n});\n\nexport function teacherLogin(body: { username: string; password: string }) {\n return trpc.teacherLogin.mutate(body);\n}\n\nexport function adminLogin(body: { username: string; password: string }) {\n return trpc.adminLogin.mutate(body);\n}\n\nexport function studentLogin(body: {\n contestId: string;\n token: string;\n userData: Required<NonNullable<Student[\"userData\"]>>;\n extraData: Record<string, any>;\n}) {\n return trpc.studentLogin.mutate(body);\n}\n\nexport async function startContestWindow(user: User, venueId: string) {\n await trpc.teacherStartContestWindow.mutate({ venueId }, { context: { user } });\n}\n\nexport async function stopContestWindow(user: User, venueId: string) {\n await trpc.teacherStopContestWindow.mutate({ venueId }, { context: { user } });\n}\n\nexport async function finalizeVenue(user: User, venueId: string) {\n await trpc.teacherFinalizeVenue.mutate({ venueId }, { context: { user } });\n}\n"],"names":["trpc","createTRPCClient","httpLink","superjson","op","user","getIdToken","teacherLogin","body","adminLogin","studentLogin","startContestWindow","venueId","stopContestWindow","finalizeVenue"],"mappings":";;;AAOA,MAAMA,IAAOC,EAA4B;AAAA,EACvC,OAAO;AAAA,IACLC,EAAS;AAAA,MACP,KAAK;AAAA,MACL,aAAaC;AAAA,MACb,MAAM,QAAQ,EAAE,IAAAC,KAAM;AACpB,cAAMC,IAAOD,EAAG,SAAS;AACzB,eAAIC,IAEK;AAAA,UACL,eAAe,UAFH,MAAMC,EAAWD,CAAI,CAEH;AAAA,QAAA,IAG3B,CAAA;AAAA,MACT;AAAA,IAAA,CACD;AAAA,EAAA;AAEL,CAAC;AAEM,SAASE,EAAaC,GAA8C;AACzE,SAAOR,EAAK,aAAa,OAAOQ,CAAI;AACtC;AAEO,SAASC,EAAWD,GAA8C;AACvE,SAAOR,EAAK,WAAW,OAAOQ,CAAI;AACpC;AAEO,SAASE,EAAaF,GAK1B;AACD,SAAOR,EAAK,aAAa,OAAOQ,CAAI;AACtC;AAEA,eAAsBG,EAAmBN,GAAYO,GAAiB;AACpE,QAAMZ,EAAK,0BAA0B,OAAO,EAAE,SAAAY,EAAA,GAAW,EAAE,SAAS,EAAE,MAAAP,EAAA,GAAQ;AAChF;AAEA,eAAsBQ,EAAkBR,GAAYO,GAAiB;AACnE,QAAMZ,EAAK,yBAAyB,OAAO,EAAE,SAAAY,EAAA,GAAW,EAAE,SAAS,EAAE,MAAAP,EAAA,GAAQ;AAC/E;AAEA,eAAsBS,EAAcT,GAAYO,GAAiB;AAC/D,QAAMZ,EAAK,qBAAqB,OAAO,EAAE,SAAAY,EAAA,GAAW,EAAE,SAAS,EAAE,MAAAP,EAAA,GAAQ;AAC3E;"}
|
|
@@ -1,57 +1,56 @@
|
|
|
1
|
-
import { contestSchema as
|
|
2
|
-
import { validate as
|
|
3
|
-
import { serverTimestamp as
|
|
4
|
-
import { cloneDeepWith as
|
|
5
|
-
import { websiteSchema as
|
|
6
|
-
function
|
|
7
|
-
return
|
|
8
|
-
if (
|
|
9
|
-
return
|
|
10
|
-
if (
|
|
11
|
-
return
|
|
12
|
-
if (t === void 0)
|
|
13
|
-
return null;
|
|
1
|
+
import { contestSchema as a, venueSchema as u, studentRestoreSchema as f, variantSchema as d, announcementSchema as v, studentSchema as p } from "@olinfo/quizms/models";
|
|
2
|
+
import { validate as F } from "@olinfo/quizms/utils";
|
|
3
|
+
import { serverTimestamp as i, Timestamp as s } from "firebase/firestore";
|
|
4
|
+
import { cloneDeepWith as m, omit as S, isDate as h, isString as C } from "lodash-es";
|
|
5
|
+
import { websiteSchema as D } from "../../models/website.js";
|
|
6
|
+
function o(t) {
|
|
7
|
+
return m(S(t, "id"), (e) => {
|
|
8
|
+
if (h(e))
|
|
9
|
+
return s.fromDate(e);
|
|
10
|
+
if (C(e))
|
|
11
|
+
return e.trim();
|
|
14
12
|
});
|
|
15
13
|
}
|
|
16
|
-
function
|
|
17
|
-
return
|
|
18
|
-
|
|
14
|
+
function T(t) {
|
|
15
|
+
return m(t, (e) => {
|
|
16
|
+
if (e instanceof s)
|
|
17
|
+
return e.toDate();
|
|
19
18
|
});
|
|
20
19
|
}
|
|
21
|
-
function
|
|
22
|
-
const
|
|
23
|
-
return
|
|
20
|
+
function n(t, e) {
|
|
21
|
+
const c = T({ ...e.data(), id: e.id });
|
|
22
|
+
return F(t, c);
|
|
24
23
|
}
|
|
25
|
-
function
|
|
24
|
+
function r(t) {
|
|
26
25
|
return {
|
|
27
|
-
toFirestore: (
|
|
28
|
-
fromFirestore: (
|
|
26
|
+
toFirestore: (e) => o(e),
|
|
27
|
+
fromFirestore: (e) => n(t, e)
|
|
29
28
|
};
|
|
30
29
|
}
|
|
31
|
-
const
|
|
32
|
-
toFirestore(
|
|
30
|
+
const x = r(a), W = r(u), j = r(f), k = r(d), q = r(D), y = {
|
|
31
|
+
toFirestore(t) {
|
|
33
32
|
return {
|
|
34
|
-
...
|
|
35
|
-
createdAt:
|
|
33
|
+
...o(t),
|
|
34
|
+
createdAt: i()
|
|
36
35
|
};
|
|
37
36
|
},
|
|
38
|
-
fromFirestore: (
|
|
39
|
-
},
|
|
40
|
-
toFirestore(
|
|
37
|
+
fromFirestore: (t) => n(v, t)
|
|
38
|
+
}, z = {
|
|
39
|
+
toFirestore(t) {
|
|
41
40
|
return {
|
|
42
|
-
...
|
|
43
|
-
updatedAt:
|
|
41
|
+
...o(t),
|
|
42
|
+
updatedAt: i()
|
|
44
43
|
};
|
|
45
44
|
},
|
|
46
|
-
fromFirestore: (
|
|
45
|
+
fromFirestore: (t) => n(p, t)
|
|
47
46
|
};
|
|
48
47
|
export {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
48
|
+
y as announcementConverter,
|
|
49
|
+
x as contestConverter,
|
|
50
|
+
z as studentConverter,
|
|
51
|
+
j as studentRestoreConvert,
|
|
52
|
+
k as variantConverter,
|
|
53
|
+
W as venueConverter,
|
|
54
|
+
q as websiteConverter
|
|
56
55
|
};
|
|
57
56
|
//# sourceMappingURL=converters.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"converters.js","sources":["../../../../src/web/common/converters.ts"],"sourcesContent":["import {\n type Announcement,\n announcementSchema,\n contestSchema,\n
|
|
1
|
+
{"version":3,"file":"converters.js","sources":["../../../../src/web/common/converters.ts"],"sourcesContent":["import {\n type Announcement,\n announcementSchema,\n contestSchema,\n type Student,\n studentRestoreSchema,\n studentSchema,\n variantSchema,\n venueSchema,\n} from \"@olinfo/quizms/models\";\nimport { validate } from \"@olinfo/quizms/utils\";\nimport {\n type DocumentSnapshot,\n type FirestoreDataConverter,\n serverTimestamp,\n Timestamp,\n} from \"firebase/firestore\";\nimport { cloneDeepWith, isDate, isString, omit } from \"lodash-es\";\nimport type z from \"zod\";\n\nimport { websiteSchema } from \"~/models/website\";\n\nfunction convertToFirestore(data: object) {\n return cloneDeepWith(omit(data, \"id\"), (value) => {\n if (isDate(value)) {\n return Timestamp.fromDate(value);\n }\n if (isString(value)) {\n return value.trim();\n }\n });\n}\n\nfunction convertFromFirestore(data: object) {\n return cloneDeepWith(data, (value) => {\n if (value instanceof Timestamp) {\n return value.toDate();\n }\n });\n}\n\nfunction parse<T>(schema: z.core.$ZodType<T>, snapshot: DocumentSnapshot): T {\n const data = convertFromFirestore({ ...snapshot.data(), id: snapshot.id });\n return validate(schema, data);\n}\n\nfunction converter<T extends object>(schema: z.core.$ZodType<T>): FirestoreDataConverter<T> {\n return {\n toFirestore: (data) => convertToFirestore(data),\n fromFirestore: (snapshot) => parse(schema, snapshot),\n };\n}\n\nexport const contestConverter = converter(contestSchema);\nexport const venueConverter = converter(venueSchema);\nexport const studentRestoreConvert = converter(studentRestoreSchema);\nexport const variantConverter = converter(variantSchema);\nexport const websiteConverter = converter(websiteSchema);\n\nexport const announcementConverter: FirestoreDataConverter<Announcement> = {\n toFirestore(data) {\n return {\n ...convertToFirestore(data),\n createdAt: serverTimestamp(),\n };\n },\n fromFirestore: (snapshot) => parse(announcementSchema, snapshot),\n};\n\nexport const studentConverter: FirestoreDataConverter<Student> = {\n toFirestore(data) {\n return {\n ...convertToFirestore(data),\n updatedAt: serverTimestamp(),\n };\n },\n fromFirestore: (snapshot) => parse(studentSchema, snapshot),\n};\n"],"names":["convertToFirestore","data","cloneDeepWith","omit","value","isDate","Timestamp","isString","convertFromFirestore","parse","schema","snapshot","validate","converter","contestConverter","contestSchema","venueConverter","venueSchema","studentRestoreConvert","studentRestoreSchema","variantConverter","variantSchema","websiteConverter","websiteSchema","announcementConverter","serverTimestamp","announcementSchema","studentConverter","studentSchema"],"mappings":";;;;;AAsBA,SAASA,EAAmBC,GAAc;AACxC,SAAOC,EAAcC,EAAKF,GAAM,IAAI,GAAG,CAACG,MAAU;AAChD,QAAIC,EAAOD,CAAK;AACd,aAAOE,EAAU,SAASF,CAAK;AAEjC,QAAIG,EAASH,CAAK;AAChB,aAAOA,EAAM,KAAA;AAAA,EAEjB,CAAC;AACH;AAEA,SAASI,EAAqBP,GAAc;AAC1C,SAAOC,EAAcD,GAAM,CAACG,MAAU;AACpC,QAAIA,aAAiBE;AACnB,aAAOF,EAAM,OAAA;AAAA,EAEjB,CAAC;AACH;AAEA,SAASK,EAASC,GAA4BC,GAA+B;AAC3E,QAAMV,IAAOO,EAAqB,EAAE,GAAGG,EAAS,QAAQ,IAAIA,EAAS,IAAI;AACzE,SAAOC,EAASF,GAAQT,CAAI;AAC9B;AAEA,SAASY,EAA4BH,GAAuD;AAC1F,SAAO;AAAA,IACL,aAAa,CAACT,MAASD,EAAmBC,CAAI;AAAA,IAC9C,eAAe,CAACU,MAAaF,EAAMC,GAAQC,CAAQ;AAAA,EAAA;AAEvD;AAEO,MAAMG,IAAmBD,EAAUE,CAAa,GAC1CC,IAAiBH,EAAUI,CAAW,GACtCC,IAAwBL,EAAUM,CAAoB,GACtDC,IAAmBP,EAAUQ,CAAa,GAC1CC,IAAmBT,EAAUU,CAAa,GAE1CC,IAA8D;AAAA,EACzE,YAAYvB,GAAM;AAChB,WAAO;AAAA,MACL,GAAGD,EAAmBC,CAAI;AAAA,MAC1B,WAAWwB,EAAA;AAAA,IAAgB;AAAA,EAE/B;AAAA,EACA,eAAe,CAACd,MAAaF,EAAMiB,GAAoBf,CAAQ;AACjE,GAEagB,IAAoD;AAAA,EAC/D,YAAY1B,GAAM;AAChB,WAAO;AAAA,MACL,GAAGD,EAAmBC,CAAI;AAAA,MAC1B,WAAWwB,EAAA;AAAA,IAAgB;AAAA,EAE/B;AAAA,EACA,eAAe,CAACd,MAAaF,EAAMmB,GAAejB,CAAQ;AAC5D;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"student-statement.js","sources":["../../../../src/web/entry/student-statement.tsx"],"sourcesContent":["import { useCallback } from \"react\";\n\nimport { RemoteStatement, useStudent } from \"@olinfo/quizms/student\";\nimport { getDownloadURL, getStorage, ref } from \"firebase/storage\";\n\nimport { useDb } from \"~/web/common/base-login\";\n\nexport function FirebaseStatement() {\n const db = useDb();\n const { student } = useStudent();\n\n const storage = getStorage(db.app);\n\n const getFileUrl = useCallback(\n (fileName: string) => {\n const statementRef = ref(\n storage,\n `statements/${student.contestId}/${student.
|
|
1
|
+
{"version":3,"file":"student-statement.js","sources":["../../../../src/web/entry/student-statement.tsx"],"sourcesContent":["import { useCallback } from \"react\";\n\nimport { RemoteStatement, useStudent } from \"@olinfo/quizms/student\";\nimport { getDownloadURL, getStorage, ref } from \"firebase/storage\";\n\nimport { useDb } from \"~/web/common/base-login\";\n\nexport function FirebaseStatement() {\n const db = useDb();\n const { student } = useStudent();\n\n const storage = getStorage(db.app);\n\n const getFileUrl = useCallback(\n (fileName: string) => {\n const statementRef = ref(\n storage,\n `statements/${student.contestId}/${student.variantId}/${fileName}`,\n );\n return getDownloadURL(statementRef);\n },\n [storage, student],\n );\n\n return (\n <RemoteStatement\n statementUrl={() => getFileUrl(\"statement.txt\")}\n // TODO\n // stylesheetUrl={() => getFileUrl(\"statement.css\")}\n moduleUrl={getFileUrl}\n />\n );\n}\n"],"names":["FirebaseStatement","db","useDb","student","useStudent","storage","getStorage","getFileUrl","useCallback","fileName","statementRef","ref","getDownloadURL","jsx","RemoteStatement"],"mappings":";;;;;AAOO,SAASA,IAAoB;AAClC,QAAMC,IAAKC,EAAA,GACL,EAAE,SAAAC,EAAA,IAAYC,EAAA,GAEdC,IAAUC,EAAWL,EAAG,GAAG,GAE3BM,IAAaC;AAAA,IACjB,CAACC,MAAqB;AACpB,YAAMC,IAAeC;AAAA,QACnBN;AAAA,QACA,cAAcF,EAAQ,SAAS,IAAIA,EAAQ,SAAS,IAAIM,CAAQ;AAAA,MAAA;AAElE,aAAOG,EAAeF,CAAY;AAAA,IACpC;AAAA,IACA,CAACL,GAASF,CAAO;AAAA,EAAA;AAGnB,SACE,gBAAAU;AAAA,IAACC;AAAA,IAAA;AAAA,MACC,cAAc,MAAMP,EAAW,eAAe;AAAA,MAG9C,WAAWA;AAAA,IAAA;AAAA,EAAA;AAGjB;"}
|