@olinfo/quizms-firebase 4.0.0 → 4.1.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/functions.d.ts +2 -11
- package/dist/functions.js +2 -2
- package/dist/package.json.js +1 -1
- package/dist/src/cli/files/functions-index.js +4 -4
- package/dist/src/cli/files/functions-index.js.map +1 -1
- package/dist/src/cli/init.js +8 -8
- package/dist/src/cli/init.js.map +1 -1
- package/dist/src/cli/update-scores.js +21 -32
- package/dist/src/cli/update-scores.js.map +1 -1
- package/dist/src/cli/utils/collection.js +20 -18
- package/dist/src/cli/utils/collection.js.map +1 -1
- package/dist/src/cli/utils/converters-admin.js +31 -32
- package/dist/src/cli/utils/converters-admin.js.map +1 -1
- package/dist/src/cli/utils/region-finder.js +6 -5
- package/dist/src/cli/utils/region-finder.js.map +1 -1
- package/dist/src/cli/utils/storage.js +26 -35
- package/dist/src/cli/utils/storage.js.map +1 -1
- package/dist/src/cli/utils/users.js +13 -12
- package/dist/src/cli/utils/users.js.map +1 -1
- package/dist/src/functions/api/admin.js +28 -0
- package/dist/src/functions/api/admin.js.map +1 -0
- package/dist/src/functions/api/index.js +26 -34
- package/dist/src/functions/api/index.js.map +1 -1
- package/dist/src/functions/api/queries.js +5 -5
- package/dist/src/functions/api/student.js +62 -72
- package/dist/src/functions/api/student.js.map +1 -1
- package/dist/src/functions/api/teacher.js +104 -111
- package/dist/src/functions/api/teacher.js.map +1 -1
- package/dist/src/functions/api/trpc.js +18 -0
- package/dist/src/functions/api/trpc.js.map +1 -0
- package/dist/src/functions/submissions.js +1 -1
- package/dist/src/functions/submissions.js.map +1 -1
- package/dist/src/models/user.js +2 -2
- package/dist/src/models/user.js.map +1 -1
- package/dist/src/models/website.js +1 -1
- package/dist/src/models/website.js.map +1 -1
- package/dist/src/vite/preset.js +3 -4
- package/dist/src/vite/preset.js.map +1 -1
- package/dist/src/web/admin/announcements.js +9 -10
- package/dist/src/web/admin/announcements.js.map +1 -1
- package/dist/src/web/admin/school-table.js +7 -8
- package/dist/src/web/admin/school-table.js.map +1 -1
- package/dist/src/web/common/api.js +32 -35
- package/dist/src/web/common/api.js.map +1 -1
- package/dist/src/web/common/converters.js +35 -36
- package/dist/src/web/common/converters.js.map +1 -1
- package/dist/src/web/common/token-login.js +11 -11
- package/dist/src/web/common/token-login.js.map +1 -1
- package/dist/src/web/entry/admin.js +5 -7
- package/dist/src/web/entry/admin.js.map +1 -1
- package/dist/src/web/entry/student-restoring.js +18 -20
- package/dist/src/web/entry/student-restoring.js.map +1 -1
- package/dist/src/web/entry/student.js +70 -76
- package/dist/src/web/entry/student.js.map +1 -1
- package/dist/src/web/entry/teacher.js +68 -68
- package/dist/src/web/entry/teacher.js.map +1 -1
- package/dist/src/web/hooks/collection.js +29 -30
- package/dist/src/web/hooks/collection.js.map +1 -1
- package/dist/src/web/hooks/document.js +35 -36
- package/dist/src/web/hooks/document.js.map +1 -1
- package/dist/src/web/hooks/subscription.js +26 -22
- package/dist/src/web/hooks/subscription.js.map +1 -1
- package/package.json +23 -19
- package/dist/src/functions/api/schema.js +0 -42
- package/dist/src/functions/api/schema.js.map +0 -1
|
@@ -1,43 +1,40 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
return
|
|
1
|
+
import { createTRPCClient as a, httpLink as e } from "@trpc/client";
|
|
2
|
+
import { getIdToken as r } from "firebase/auth";
|
|
3
|
+
import o from "superjson";
|
|
4
|
+
const i = a({
|
|
5
|
+
links: [
|
|
6
|
+
e({
|
|
7
|
+
url: "/api",
|
|
8
|
+
transformer: o,
|
|
9
|
+
async headers({ op: t }) {
|
|
10
|
+
const n = t.context?.user;
|
|
11
|
+
return n ? {
|
|
12
|
+
Authorization: `Bearer ${await r(n)}`
|
|
13
|
+
} : {};
|
|
14
|
+
}
|
|
15
|
+
})
|
|
16
|
+
]
|
|
17
|
+
});
|
|
18
|
+
function m(t) {
|
|
19
|
+
return i.teacherLogin.mutate(t);
|
|
20
20
|
}
|
|
21
|
-
function
|
|
22
|
-
return
|
|
21
|
+
function f(t) {
|
|
22
|
+
return i.studentLogin.mutate(t);
|
|
23
23
|
}
|
|
24
|
-
function
|
|
25
|
-
|
|
24
|
+
async function h(t, n) {
|
|
25
|
+
await i.teacherStartParticipation.mutate({ participationId: n }, { context: { user: t } });
|
|
26
26
|
}
|
|
27
|
-
async function P(t,
|
|
28
|
-
await
|
|
27
|
+
async function P(t, n) {
|
|
28
|
+
await i.teacherStopParticipation.mutate({ participationId: n }, { context: { user: t } });
|
|
29
29
|
}
|
|
30
|
-
async function
|
|
31
|
-
await
|
|
32
|
-
}
|
|
33
|
-
async function j(t, i) {
|
|
34
|
-
await a(t, "teacherFinalizeParticipation", { participationId: i }, {});
|
|
30
|
+
async function g(t, n) {
|
|
31
|
+
await i.teacherFinalizeParticipation.mutate({ participationId: n }, { context: { user: t } });
|
|
35
32
|
}
|
|
36
33
|
export {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
P as
|
|
40
|
-
|
|
41
|
-
|
|
34
|
+
g as finalizeParticipation,
|
|
35
|
+
h as startParticipation,
|
|
36
|
+
P as stopParticipation,
|
|
37
|
+
f as studentLogin,
|
|
38
|
+
m as teacherLogin
|
|
42
39
|
};
|
|
43
40
|
//# 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 {
|
|
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 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 startParticipation(user: User, participationId: string) {\n await trpc.teacherStartParticipation.mutate({ participationId }, { context: { user } });\n}\n\nexport async function stopParticipation(user: User, participationId: string) {\n await trpc.teacherStopParticipation.mutate({ participationId }, { context: { user } });\n}\n\nexport async function finalizeParticipation(user: User, participationId: string) {\n await trpc.teacherFinalizeParticipation.mutate({ participationId }, { context: { user } });\n}\n"],"names":["trpc","createTRPCClient","httpLink","superjson","op","user","getIdToken","teacherLogin","body","studentLogin","startParticipation","participationId","stopParticipation","finalizeParticipation"],"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,EAAaD,GAK1B;AACD,SAAOR,EAAK,aAAa,OAAOQ,CAAI;AACtC;AAEA,eAAsBE,EAAmBL,GAAYM,GAAyB;AAC5E,QAAMX,EAAK,0BAA0B,OAAO,EAAE,iBAAAW,EAAA,GAAmB,EAAE,SAAS,EAAE,MAAAN,EAAA,GAAQ;AACxF;AAEA,eAAsBO,EAAkBP,GAAYM,GAAyB;AAC3E,QAAMX,EAAK,yBAAyB,OAAO,EAAE,iBAAAW,EAAA,GAAmB,EAAE,SAAS,EAAE,MAAAN,EAAA,GAAQ;AACvF;AAEA,eAAsBQ,EAAsBR,GAAYM,GAAyB;AAC/E,QAAMX,EAAK,6BAA6B,OAAO,EAAE,iBAAAW,EAAA,GAAmB,EAAE,SAAS,EAAE,MAAAN,EAAA,GAAQ;AAC3F;"}
|
|
@@ -1,59 +1,58 @@
|
|
|
1
|
-
import { announcementSchema as
|
|
2
|
-
import { validate as
|
|
3
|
-
import { serverTimestamp as
|
|
4
|
-
import { cloneDeepWith as
|
|
5
|
-
import
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
return s.fromDate(r);
|
|
1
|
+
import { announcementSchema as a, contestSchema as f, participationSchema as u, studentRestoreSchema as d, variantSchema as p, studentSchema as v } from "@olinfo/quizms/models";
|
|
2
|
+
import { validate as F } from "@olinfo/quizms/utils";
|
|
3
|
+
import { serverTimestamp as i, Timestamp as c } from "firebase/firestore";
|
|
4
|
+
import { cloneDeepWith as s, 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 s(S(t, "id"), (r) => {
|
|
8
|
+
if (h(r))
|
|
9
|
+
return c.fromDate(r);
|
|
11
10
|
if (C(r))
|
|
12
11
|
return r.trim();
|
|
13
12
|
if (r === void 0)
|
|
14
13
|
return null;
|
|
15
14
|
});
|
|
16
15
|
}
|
|
17
|
-
function
|
|
18
|
-
return
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
)
|
|
16
|
+
function T(t) {
|
|
17
|
+
return s(t, (r) => {
|
|
18
|
+
if (r instanceof c)
|
|
19
|
+
return r.toDate();
|
|
20
|
+
});
|
|
22
21
|
}
|
|
23
|
-
function
|
|
24
|
-
const
|
|
25
|
-
return
|
|
22
|
+
function n(t, r) {
|
|
23
|
+
const m = T({ ...r.data(), id: r.id });
|
|
24
|
+
return F(t, m);
|
|
26
25
|
}
|
|
27
|
-
function
|
|
26
|
+
function e(t) {
|
|
28
27
|
return {
|
|
29
|
-
toFirestore: (r) =>
|
|
30
|
-
fromFirestore: (r) =>
|
|
28
|
+
toFirestore: (r) => o(r),
|
|
29
|
+
fromFirestore: (r) => n(t, r)
|
|
31
30
|
};
|
|
32
31
|
}
|
|
33
|
-
const
|
|
32
|
+
const x = e(f), W = e(u), j = e(d), k = e(p), q = e(D), y = {
|
|
34
33
|
toFirestore(t) {
|
|
35
34
|
return {
|
|
36
|
-
...
|
|
37
|
-
createdAt:
|
|
35
|
+
...o(t),
|
|
36
|
+
createdAt: i()
|
|
38
37
|
};
|
|
39
38
|
},
|
|
40
|
-
fromFirestore: (t) => a
|
|
41
|
-
},
|
|
39
|
+
fromFirestore: (t) => n(a, t)
|
|
40
|
+
}, z = {
|
|
42
41
|
toFirestore(t) {
|
|
43
42
|
return {
|
|
44
|
-
...
|
|
45
|
-
updatedAt:
|
|
43
|
+
...o(t),
|
|
44
|
+
updatedAt: i()
|
|
46
45
|
};
|
|
47
46
|
},
|
|
48
|
-
fromFirestore: (t) =>
|
|
47
|
+
fromFirestore: (t) => n(v, t)
|
|
49
48
|
};
|
|
50
49
|
export {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
50
|
+
y as announcementConverter,
|
|
51
|
+
x as contestConverter,
|
|
52
|
+
W as participationConverter,
|
|
53
|
+
z as studentConverter,
|
|
54
|
+
j as studentRestoreConvert,
|
|
55
|
+
k as variantConverter,
|
|
56
|
+
q as websiteConverter
|
|
58
57
|
};
|
|
59
58
|
//# 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 participationSchema,\n type Student,\n studentRestoreSchema,\n studentSchema,\n variantSchema,\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,
|
|
1
|
+
{"version":3,"file":"converters.js","sources":["../../../../src/web/common/converters.ts"],"sourcesContent":["import {\n type Announcement,\n announcementSchema,\n contestSchema,\n participationSchema,\n type Student,\n studentRestoreSchema,\n studentSchema,\n variantSchema,\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 if (value === undefined) {\n return null;\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 participationConverter = converter(participationSchema);\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","participationConverter","participationSchema","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;AAEf,QAAIA,MAAU;AACZ,aAAO;AAAA,EAEX,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,IAAyBH,EAAUI,CAAmB,GACtDC,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,4 +1,4 @@
|
|
|
1
|
-
import { jsxs as
|
|
1
|
+
import { jsxs as a, Fragment as u, jsx as e } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect as f } from "react";
|
|
3
3
|
import { Title as p } from "@olinfo/quizms/components";
|
|
4
4
|
import { Navbar as h, NavbarBrand as b, Form as w, UsernameField as g, CurrentPasswordField as x, SubmitButton as N } from "@olinfo/react-components";
|
|
@@ -9,24 +9,24 @@ import "firebase/firestore";
|
|
|
9
9
|
import "lodash-es";
|
|
10
10
|
import "react-error-boundary";
|
|
11
11
|
import "swr";
|
|
12
|
-
import { useDb as
|
|
13
|
-
import {
|
|
14
|
-
function q({ allowedRole:
|
|
15
|
-
const
|
|
12
|
+
import { useDb as L } from "./base-login.js";
|
|
13
|
+
import { teacherLogin as P } from "./api.js";
|
|
14
|
+
function q({ allowedRole: s, children: n }) {
|
|
15
|
+
const i = L(), t = new URLSearchParams(A());
|
|
16
16
|
f(() => {
|
|
17
17
|
const r = new URL(window.location.href);
|
|
18
18
|
r.searchParams.delete("username"), r.searchParams.delete("password"), window.history.replaceState(void 0, "", r.href);
|
|
19
19
|
}, []);
|
|
20
20
|
const m = {
|
|
21
|
-
username:
|
|
22
|
-
password:
|
|
21
|
+
username: t.get("username") ?? "",
|
|
22
|
+
password: t.get("password") ?? ""
|
|
23
23
|
}, c = async (r) => {
|
|
24
|
-
const
|
|
24
|
+
const l = await P(r), d = S(i.app);
|
|
25
25
|
await v(d, l);
|
|
26
|
-
},
|
|
27
|
-
return
|
|
26
|
+
}, o = F(s);
|
|
27
|
+
return o ? n(o) : /* @__PURE__ */ a(u, { children: [
|
|
28
28
|
/* @__PURE__ */ e(h, { color: "bg-base-300 text-base-content", children: /* @__PURE__ */ e(b, { children: /* @__PURE__ */ e("div", { className: "flex items-center h-full font-bold", children: /* @__PURE__ */ e(p, {}) }) }) }),
|
|
29
|
-
/* @__PURE__ */
|
|
29
|
+
/* @__PURE__ */ a(w, { defaultValue: m, onSubmit: c, className: "p-4 pb-8", children: [
|
|
30
30
|
/* @__PURE__ */ e("h1", { className: "mb-2 text-xl font-bold", children: "Accedi alla gestione gara" }),
|
|
31
31
|
/* @__PURE__ */ e(g, { field: "username" }),
|
|
32
32
|
/* @__PURE__ */ e(x, { field: "password" }),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token-login.js","sources":["../../../../src/web/common/token-login.tsx"],"sourcesContent":["import { type ReactNode, useEffect } from \"react\";\n\nimport { Title } from \"@olinfo/quizms/components\";\nimport {\n CurrentPasswordField,\n Form,\n Navbar,\n NavbarBrand,\n SubmitButton,\n UsernameField,\n} from \"@olinfo/react-components\";\nimport { getAuth, signInWithCustomToken, type User } from \"firebase/auth\";\nimport { useSearch } from \"wouter\";\n\nimport { useAuth } from \"~/web/hooks\";\n\nimport {
|
|
1
|
+
{"version":3,"file":"token-login.js","sources":["../../../../src/web/common/token-login.tsx"],"sourcesContent":["import { type ReactNode, useEffect } from \"react\";\n\nimport { Title } from \"@olinfo/quizms/components\";\nimport {\n CurrentPasswordField,\n Form,\n Navbar,\n NavbarBrand,\n SubmitButton,\n UsernameField,\n} from \"@olinfo/react-components\";\nimport { getAuth, signInWithCustomToken, type User } from \"firebase/auth\";\nimport { useSearch } from \"wouter\";\n\nimport { useAuth } from \"~/web/hooks\";\n\nimport { teacherLogin } from \"./api\";\nimport { useDb } from \"./base-login\";\n\ntype Props = {\n allowedRole: \"teacher\" | \"admin\";\n children: (auth: { user: User; claims: Record<string, string> }) => ReactNode;\n};\n\nexport default function TokenLogin({ allowedRole, children }: Props) {\n const db = useDb();\n const params = new URLSearchParams(useSearch());\n\n useEffect(() => {\n const url = new URL(window.location.href);\n url.searchParams.delete(\"username\");\n url.searchParams.delete(\"password\");\n window.history.replaceState(undefined, \"\", url.href);\n }, []);\n\n const defaultCredential = {\n username: params.get(\"username\") ?? \"\",\n password: params.get(\"password\") ?? \"\",\n };\n\n const signIn = async (credential: { username: string; password: string }) => {\n const token = await teacherLogin(credential);\n\n const auth = getAuth(db.app);\n await signInWithCustomToken(auth, token);\n };\n\n const auth = useAuth(allowedRole);\n if (auth) {\n return children(auth);\n }\n\n return (\n <>\n <Navbar color=\"bg-base-300 text-base-content\">\n <NavbarBrand>\n <div className=\"flex items-center h-full font-bold\">\n <Title />\n </div>\n </NavbarBrand>\n </Navbar>\n <Form defaultValue={defaultCredential} onSubmit={signIn} className=\"p-4 pb-8\">\n <h1 className=\"mb-2 text-xl font-bold\">Accedi alla gestione gara</h1>\n <UsernameField field=\"username\" />\n <CurrentPasswordField field=\"password\" />\n <SubmitButton>Accedi</SubmitButton>\n </Form>\n </>\n );\n}\n"],"names":["TokenLogin","allowedRole","children","db","useDb","params","useSearch","useEffect","url","defaultCredential","signIn","credential","token","teacherLogin","auth","getAuth","signInWithCustomToken","useAuth","jsxs","Fragment","jsx","Navbar","NavbarBrand","Title","Form","UsernameField","CurrentPasswordField","SubmitButton"],"mappings":";;;;;;;;;;;;;AAwBA,SAAwBA,EAAW,EAAE,aAAAC,GAAa,UAAAC,KAAmB;AACnE,QAAMC,IAAKC,EAAA,GACLC,IAAS,IAAI,gBAAgBC,GAAW;AAE9C,EAAAC,EAAU,MAAM;AACd,UAAMC,IAAM,IAAI,IAAI,OAAO,SAAS,IAAI;AACxC,IAAAA,EAAI,aAAa,OAAO,UAAU,GAClCA,EAAI,aAAa,OAAO,UAAU,GAClC,OAAO,QAAQ,aAAa,QAAW,IAAIA,EAAI,IAAI;AAAA,EACrD,GAAG,CAAA,CAAE;AAEL,QAAMC,IAAoB;AAAA,IACxB,UAAUJ,EAAO,IAAI,UAAU,KAAK;AAAA,IACpC,UAAUA,EAAO,IAAI,UAAU,KAAK;AAAA,EAAA,GAGhCK,IAAS,OAAOC,MAAuD;AAC3E,UAAMC,IAAQ,MAAMC,EAAaF,CAAU,GAErCG,IAAOC,EAAQZ,EAAG,GAAG;AAC3B,UAAMa,EAAsBF,GAAMF,CAAK;AAAA,EACzC,GAEME,IAAOG,EAAQhB,CAAW;AAChC,SAAIa,IACKZ,EAASY,CAAI,IAIpB,gBAAAI,EAAAC,GAAA,EACE,UAAA;AAAA,IAAA,gBAAAC,EAACC,GAAA,EAAO,OAAM,iCACZ,UAAA,gBAAAD,EAACE,GAAA,EACC,UAAA,gBAAAF,EAAC,OAAA,EAAI,WAAU,sCACb,UAAA,gBAAAA,EAACG,GAAA,EAAM,EAAA,CACT,GACF,GACF;AAAA,sBACCC,GAAA,EAAK,cAAcf,GAAmB,UAAUC,GAAQ,WAAU,YACjE,UAAA;AAAA,MAAA,gBAAAU,EAAC,MAAA,EAAG,WAAU,0BAAyB,UAAA,6BAAyB;AAAA,MAChE,gBAAAA,EAACK,GAAA,EAAc,OAAM,WAAA,CAAW;AAAA,MAChC,gBAAAL,EAACM,GAAA,EAAqB,OAAM,WAAA,CAAW;AAAA,MACvC,gBAAAN,EAACO,KAAa,UAAA,SAAA,CAAM;AAAA,IAAA,EAAA,CACtB;AAAA,EAAA,GACF;AAEJ;"}
|
|
@@ -2,8 +2,8 @@ import { jsx as t } from "react/jsx-runtime";
|
|
|
2
2
|
import { useCallback as s } from "react";
|
|
3
3
|
import { signOut as a, getAuth as p } from "firebase/auth";
|
|
4
4
|
import { AdminProvider as c } from "../admin/provider.js";
|
|
5
|
-
import { useDb as
|
|
6
|
-
import { contestConverter as
|
|
5
|
+
import { useDb as l } from "../common/base-login.js";
|
|
6
|
+
import { contestConverter as u } from "../common/converters.js";
|
|
7
7
|
import d from "../common/token-login.js";
|
|
8
8
|
import "lodash-es";
|
|
9
9
|
import "react-error-boundary";
|
|
@@ -11,12 +11,10 @@ import "swr";
|
|
|
11
11
|
import { useCollection as f } from "../hooks/collection.js";
|
|
12
12
|
import "firebase/firestore";
|
|
13
13
|
function I() {
|
|
14
|
-
return /* @__PURE__ */ t(d, { allowedRole: "admin", children: (o) => /* @__PURE__ */ t(
|
|
14
|
+
return /* @__PURE__ */ t(d, { allowedRole: "admin", children: (o) => /* @__PURE__ */ t(g, { user: o.user }) });
|
|
15
15
|
}
|
|
16
|
-
function
|
|
17
|
-
const r =
|
|
18
|
-
subscribe: !0
|
|
19
|
-
}), m = s(async () => {
|
|
16
|
+
function g({ user: o }) {
|
|
17
|
+
const r = l(), n = o.displayName ?? "Utente anonimo", [e, i] = f("contests", u), m = s(async () => {
|
|
20
18
|
await a(p(r.app)), window.location.reload();
|
|
21
19
|
}, [r]);
|
|
22
20
|
return /* @__PURE__ */ t(c, { name: n, contests: e, setContest: i, logout: m });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin.js","sources":["../../../../src/web/entry/admin.tsx"],"sourcesContent":["import { useCallback } from \"react\";\n\nimport { getAuth, signOut, type User } from \"firebase/auth\";\n\nimport { AdminProvider } from \"~/web/admin/provider\";\nimport { useDb } from \"~/web/common/base-login\";\nimport { contestConverter } from \"~/web/common/converters\";\nimport TokenLogin from \"~/web/common/token-login\";\nimport { useCollection } from \"~/web/hooks\";\n\nexport default function AdminEntry() {\n return <TokenLogin allowedRole=\"admin\">{(auth) => <AdminInner user={auth.user} />}</TokenLogin>;\n}\n\nfunction AdminInner({ user }: { user: User }) {\n const db = useDb();\n const name = user.displayName ?? \"Utente anonimo\";\n\n const [contests, setContest] = useCollection(\"contests\", contestConverter
|
|
1
|
+
{"version":3,"file":"admin.js","sources":["../../../../src/web/entry/admin.tsx"],"sourcesContent":["import { useCallback } from \"react\";\n\nimport { getAuth, signOut, type User } from \"firebase/auth\";\n\nimport { AdminProvider } from \"~/web/admin/provider\";\nimport { useDb } from \"~/web/common/base-login\";\nimport { contestConverter } from \"~/web/common/converters\";\nimport TokenLogin from \"~/web/common/token-login\";\nimport { useCollection } from \"~/web/hooks\";\n\nexport default function AdminEntry() {\n return <TokenLogin allowedRole=\"admin\">{(auth) => <AdminInner user={auth.user} />}</TokenLogin>;\n}\n\nfunction AdminInner({ user }: { user: User }) {\n const db = useDb();\n const name = user.displayName ?? \"Utente anonimo\";\n\n const [contests, setContest] = useCollection(\"contests\", contestConverter);\n\n const logout = useCallback(async () => {\n await signOut(getAuth(db.app));\n window.location.reload();\n }, [db]);\n\n return <AdminProvider name={name} contests={contests} setContest={setContest} logout={logout} />;\n}\n"],"names":["AdminEntry","jsx","TokenLogin","auth","AdminInner","user","db","useDb","name","contests","setContest","useCollection","contestConverter","logout","useCallback","signOut","getAuth","AdminProvider"],"mappings":";;;;;;;;;;;;AAUA,SAAwBA,IAAa;AACnC,SAAO,gBAAAC,EAACC,GAAA,EAAW,aAAY,SAAS,UAAA,CAACC,MAAS,gBAAAF,EAACG,GAAA,EAAW,MAAMD,EAAK,KAAA,CAAM,EAAA,CAAG;AACpF;AAEA,SAASC,EAAW,EAAE,MAAAC,KAAwB;AAC5C,QAAMC,IAAKC,EAAA,GACLC,IAAOH,EAAK,eAAe,kBAE3B,CAACI,GAAUC,CAAU,IAAIC,EAAc,YAAYC,CAAgB,GAEnEC,IAASC,EAAY,YAAY;AACrC,UAAMC,EAAQC,EAAQV,EAAG,GAAG,CAAC,GAC7B,OAAO,SAAS,OAAA;AAAA,EAClB,GAAG,CAACA,CAAE,CAAC;AAEP,SAAO,gBAAAL,EAACgB,GAAA,EAAc,MAAAT,GAAY,UAAAC,GAAoB,YAAAC,GAAwB,QAAAG,GAAgB;AAChG;"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { jsx as e, jsxs as o, Fragment as
|
|
2
|
-
import { useEffect as
|
|
3
|
-
import { Loading as
|
|
4
|
-
import { Navbar as u, NavbarBrand as f, NavbarContent as
|
|
1
|
+
import { jsx as e, jsxs as o, Fragment as d } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect as l } from "react";
|
|
3
|
+
import { Loading as m, Title as p } from "@olinfo/quizms/components";
|
|
4
|
+
import { Navbar as u, NavbarBrand as f, NavbarContent as g, Dropdown as h, DropdownButton as v, DropdownMenu as x, DropdownItem as w } from "@olinfo/react-components";
|
|
5
5
|
import { signOut as s, getAuth as a } from "firebase/auth";
|
|
6
|
-
import { LogOut as
|
|
6
|
+
import { LogOut as b } from "lucide-react";
|
|
7
7
|
import { useDb as c } from "../common/base-login.js";
|
|
8
8
|
import { studentRestoreConvert as N } from "../common/converters.js";
|
|
9
9
|
import "lodash-es";
|
|
@@ -11,36 +11,34 @@ import "react-error-boundary";
|
|
|
11
11
|
import "swr";
|
|
12
12
|
import "firebase/firestore";
|
|
13
13
|
import { useDocumentOptional as D } from "../hooks/document.js";
|
|
14
|
-
function
|
|
15
|
-
const i = c(), [t] = D("studentRestores", r.uid, N
|
|
16
|
-
|
|
17
|
-
});
|
|
18
|
-
return d(() => {
|
|
14
|
+
function F({ user: r, children: n }) {
|
|
15
|
+
const i = c(), [t] = D("studentRestores", r.uid, N);
|
|
16
|
+
return l(() => {
|
|
19
17
|
t?.status === "revoked" && s(a(i.app)).then(() => window.location.reload());
|
|
20
|
-
}, [i, t]), !t || t.status === "approved" ? n : t.status === "revoked" ? /* @__PURE__ */ e(
|
|
18
|
+
}, [i, t]), !t || t.status === "approved" ? n : t.status === "revoked" ? /* @__PURE__ */ e(m, {}) : /* @__PURE__ */ o(d, { children: [
|
|
21
19
|
/* @__PURE__ */ o(u, { color: "bg-base-300 text-base-content", children: [
|
|
22
|
-
/* @__PURE__ */ e(f, { children: /* @__PURE__ */ e("div", { className: "flex items-center h-full font-bold", children: /* @__PURE__ */ e(
|
|
23
|
-
/* @__PURE__ */ e(
|
|
20
|
+
/* @__PURE__ */ e(f, { children: /* @__PURE__ */ e("div", { className: "flex items-center h-full font-bold", children: /* @__PURE__ */ e(p, {}) }) }),
|
|
21
|
+
/* @__PURE__ */ e(g, { children: /* @__PURE__ */ e(j, { name: `${t.name} ${t.surname}` }) })
|
|
24
22
|
] }),
|
|
25
23
|
/* @__PURE__ */ o("div", { className: "flex flex-col justify-center items-center grow text-center m-4", children: [
|
|
26
|
-
/* @__PURE__ */ e("p", { className: "text-lg max-w-3xl", children:
|
|
24
|
+
/* @__PURE__ */ e("p", { className: "text-lg max-w-3xl", children: `Il tuo account è già presente su un'altro dispositivo. Per trasferire l'accesso al dispositivo corrente comunica al tuo insegnante di inserire il codice seguente in fondo alla pagina di gestione gara, sezione "richieste di accesso":` }),
|
|
27
25
|
/* @__PURE__ */ e("div", { className: "flex justify-center pt-3", children: /* @__PURE__ */ e("span", { className: "pt-1 font-mono text-3xl", children: String(t?.approvalCode).padStart(3, "0") }) })
|
|
28
26
|
] })
|
|
29
27
|
] });
|
|
30
28
|
}
|
|
31
|
-
function
|
|
29
|
+
function j({ name: r }) {
|
|
32
30
|
const n = c();
|
|
33
|
-
return /* @__PURE__ */ o(
|
|
34
|
-
/* @__PURE__ */ e(
|
|
35
|
-
/* @__PURE__ */ e(
|
|
31
|
+
return /* @__PURE__ */ o(h, { className: "dropdown-end", children: [
|
|
32
|
+
/* @__PURE__ */ e(v, { children: /* @__PURE__ */ e("div", { className: "truncate uppercase", children: r }) }),
|
|
33
|
+
/* @__PURE__ */ e(x, { children: /* @__PURE__ */ e(w, { children: /* @__PURE__ */ o("button", { type: "button", className: "flex justify-between gap-4", onClick: async () => {
|
|
36
34
|
await s(a(n.app)), window.location.reload();
|
|
37
35
|
}, children: [
|
|
38
36
|
"Esci ",
|
|
39
|
-
/* @__PURE__ */ e(
|
|
37
|
+
/* @__PURE__ */ e(b, { size: 20 })
|
|
40
38
|
] }) }) })
|
|
41
39
|
] });
|
|
42
40
|
}
|
|
43
41
|
export {
|
|
44
|
-
|
|
42
|
+
F as StudentRestoring
|
|
45
43
|
};
|
|
46
44
|
//# sourceMappingURL=student-restoring.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"student-restoring.js","sources":["../../../../src/web/entry/student-restoring.tsx"],"sourcesContent":["import { type ReactNode, useEffect } from \"react\";\n\nimport { Loading, Title } from \"@olinfo/quizms/components\";\nimport {\n Dropdown,\n DropdownButton,\n DropdownItem,\n DropdownMenu,\n Navbar,\n NavbarBrand,\n NavbarContent,\n} from \"@olinfo/react-components\";\nimport { getAuth, signOut, type User } from \"firebase/auth\";\nimport { LogOut } from \"lucide-react\";\n\nimport { useDb } from \"~/web/common/base-login\";\nimport { studentRestoreConvert } from \"~/web/common/converters\";\nimport { useDocumentOptional } from \"~/web/hooks\";\n\nexport function StudentRestoring({ user, children }: { user: User; children: ReactNode }) {\n const db = useDb();\n\n const [studentRestore] = useDocumentOptional(\"studentRestores\", user.uid, studentRestoreConvert
|
|
1
|
+
{"version":3,"file":"student-restoring.js","sources":["../../../../src/web/entry/student-restoring.tsx"],"sourcesContent":["import { type ReactNode, useEffect } from \"react\";\n\nimport { Loading, Title } from \"@olinfo/quizms/components\";\nimport {\n Dropdown,\n DropdownButton,\n DropdownItem,\n DropdownMenu,\n Navbar,\n NavbarBrand,\n NavbarContent,\n} from \"@olinfo/react-components\";\nimport { getAuth, signOut, type User } from \"firebase/auth\";\nimport { LogOut } from \"lucide-react\";\n\nimport { useDb } from \"~/web/common/base-login\";\nimport { studentRestoreConvert } from \"~/web/common/converters\";\nimport { useDocumentOptional } from \"~/web/hooks\";\n\nexport function StudentRestoring({ user, children }: { user: User; children: ReactNode }) {\n const db = useDb();\n\n const [studentRestore] = useDocumentOptional(\"studentRestores\", user.uid, studentRestoreConvert);\n\n useEffect(() => {\n if (studentRestore?.status === \"revoked\") {\n void signOut(getAuth(db.app)).then(() => window.location.reload());\n }\n }, [db, studentRestore]);\n\n if (!studentRestore || studentRestore.status === \"approved\") {\n return children;\n }\n\n if (studentRestore.status === \"revoked\") {\n return <Loading />;\n }\n\n return (\n <>\n <Navbar color=\"bg-base-300 text-base-content\">\n <NavbarBrand>\n <div className=\"flex items-center h-full font-bold\">\n <Title />\n </div>\n </NavbarBrand>\n <NavbarContent>\n <UserDropdown name={`${studentRestore.name} ${studentRestore.surname}`} />\n </NavbarContent>\n </Navbar>\n <div className=\"flex flex-col justify-center items-center grow text-center m-4\">\n <p className=\"text-lg max-w-3xl\">\n Il tuo account è già presente su un'altro dispositivo. Per trasferire l'accesso\n al dispositivo corrente comunica al tuo insegnante di inserire il codice seguente in fondo\n alla pagina di gestione gara, sezione "richieste di accesso":\n </p>\n <div className=\"flex justify-center pt-3\">\n <span className=\"pt-1 font-mono text-3xl\">\n {String(studentRestore?.approvalCode).padStart(3, \"0\")}\n </span>\n </div>\n </div>\n </>\n );\n}\n\nfunction UserDropdown({ name }: { name: ReactNode }) {\n const db = useDb();\n\n const logout = async () => {\n await signOut(getAuth(db.app));\n window.location.reload();\n };\n\n return (\n <Dropdown className=\"dropdown-end\">\n <DropdownButton>\n <div className=\"truncate uppercase\">{name}</div>\n </DropdownButton>\n <DropdownMenu>\n <DropdownItem>\n <button type=\"button\" className=\"flex justify-between gap-4\" onClick={logout}>\n Esci <LogOut size={20} />\n </button>\n </DropdownItem>\n </DropdownMenu>\n </Dropdown>\n );\n}\n"],"names":["StudentRestoring","user","children","db","useDb","studentRestore","useDocumentOptional","studentRestoreConvert","useEffect","signOut","getAuth","Loading","jsxs","Fragment","Navbar","jsx","NavbarBrand","Title","NavbarContent","UserDropdown","name","Dropdown","DropdownButton","DropdownMenu","DropdownItem","LogOut"],"mappings":";;;;;;;;;;;;;AAmBO,SAASA,EAAiB,EAAE,MAAAC,GAAM,UAAAC,KAAiD;AACxF,QAAMC,IAAKC,EAAA,GAEL,CAACC,CAAc,IAAIC,EAAoB,mBAAmBL,EAAK,KAAKM,CAAqB;AAQ/F,SANAC,EAAU,MAAM;AACd,IAAIH,GAAgB,WAAW,aACxBI,EAAQC,EAAQP,EAAG,GAAG,CAAC,EAAE,KAAK,MAAM,OAAO,SAAS,QAAQ;AAAA,EAErE,GAAG,CAACA,GAAIE,CAAc,CAAC,GAEnB,CAACA,KAAkBA,EAAe,WAAW,aACxCH,IAGLG,EAAe,WAAW,8BACpBM,GAAA,EAAQ,IAIhB,gBAAAC,EAAAC,GAAA,EACE,UAAA;AAAA,IAAA,gBAAAD,EAACE,GAAA,EAAO,OAAM,iCACZ,UAAA;AAAA,MAAA,gBAAAC,EAACC,GAAA,EACC,4BAAC,OAAA,EAAI,WAAU,sCACb,UAAA,gBAAAD,EAACE,GAAA,CAAA,CAAM,GACT,EAAA,CACF;AAAA,MACA,gBAAAF,EAACG,GAAA,EACC,UAAA,gBAAAH,EAACI,GAAA,EAAa,MAAM,GAAGd,EAAe,IAAI,IAAIA,EAAe,OAAO,GAAA,CAAI,EAAA,CAC1E;AAAA,IAAA,GACF;AAAA,IACA,gBAAAO,EAAC,OAAA,EAAI,WAAU,kEACb,UAAA;AAAA,MAAA,gBAAAG,EAAC,KAAA,EAAE,WAAU,qBAAoB,UAAA,4OAIjC;AAAA,wBACC,OAAA,EAAI,WAAU,4BACb,UAAA,gBAAAA,EAAC,UAAK,WAAU,2BACb,UAAA,OAAOV,GAAgB,YAAY,EAAE,SAAS,GAAG,GAAG,GACvD,EAAA,CACF;AAAA,IAAA,EAAA,CACF;AAAA,EAAA,GACF;AAEJ;AAEA,SAASc,EAAa,EAAE,MAAAC,KAA6B;AACnD,QAAMjB,IAAKC,EAAA;AAOX,SACE,gBAAAQ,EAACS,GAAA,EAAS,WAAU,gBAClB,UAAA;AAAA,IAAA,gBAAAN,EAACO,KACC,UAAA,gBAAAP,EAAC,OAAA,EAAI,WAAU,sBAAsB,aAAK,EAAA,CAC5C;AAAA,IACA,gBAAAA,EAACQ,GAAA,EACC,UAAA,gBAAAR,EAACS,GAAA,EACC,UAAA,gBAAAZ,EAAC,UAAA,EAAO,MAAK,UAAS,WAAU,8BAA6B,SAZtD,YAAY;AACzB,YAAMH,EAAQC,EAAQP,EAAG,GAAG,CAAC,GAC7B,OAAO,SAAS,OAAA;AAAA,IAClB,GASsF,UAAA;AAAA,MAAA;AAAA,MACvE,gBAAAY,EAACU,GAAA,EAAO,MAAM,GAAA,CAAI;AAAA,IAAA,EAAA,CACzB,GACF,EAAA,CACF;AAAA,EAAA,GACF;AAEJ;"}
|