From 8912c1e0cfe9f318ea5a8213465b60bc29f9db66 Mon Sep 17 00:00:00 2001 From: Johan Grimsehl Date: Sun, 8 Dec 2024 11:28:10 +0100 Subject: [PATCH] Remove console logs, add Add component (#32) --- src/App.jsx | 1 - src/Vote.jsx | 3 +- src/admin/NewVote.jsx | 3 - src/admin/Students.tsx | 3 - src/admin/auth/Login.tsx | 4 +- src/admin/deprecated/AnswerList.jsx | 5 - src/admin/deprecated/AssignStudents.tsx | 4 - src/admin/deprecated/ListVotes.jsx | 1 - src/admin/index.jsx | 1 - src/admin/navigation/DrawerList.jsx | 9 +- src/admin/navigation/VoteDrawer.jsx | 6 + src/admin/vote/Add.tsx | 356 ++++++++++++++++++++++++ src/admin/vote/Answers.jsx | 1 - src/admin/vote/Assign.jsx | 4 - src/admin/vote/Edit.jsx | 12 +- src/admin/vote/Export.jsx | 1 - src/admin/vote/Match.tsx | 12 + src/admin/vote/Schedule.jsx | 1 - src/main.jsx | 6 + src/types.ts | 1 + 20 files changed, 387 insertions(+), 47 deletions(-) create mode 100644 src/admin/vote/Add.tsx diff --git a/src/App.jsx b/src/App.jsx index 65786a0..8753864 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -133,7 +133,6 @@ App.loader = async function loader() { votes.docs.map((e) => { let data = e.data(); - console.log(data, e.id); const now = moment().tz("Europe/Berlin"); const startTime = moment.unix(data.startTime.seconds).tz("Europe/Berlin"); diff --git a/src/Vote.jsx b/src/Vote.jsx index c29b2e4..b2d4e84 100644 --- a/src/Vote.jsx +++ b/src/Vote.jsx @@ -32,6 +32,8 @@ export default function Vote() { startTime, description, } = vote; + + const [firstName, setFirstName] = React.useState(); const [lastName, setLastName] = React.useState(); const [grade, setGrade] = React.useState(); @@ -118,7 +120,6 @@ export default function Vote() { }) .catch((error) => { setSending(false); - console.log(JSON.stringify(error)); if (error.code === "permission-denied") { alert( "Da hat etwas nicht geklappt. Sie sind nicht (mehr) berechtigt, Ihre Daten abzugeben. Bitte wenden Sie sich an den zuständigen Lehrer." diff --git a/src/admin/NewVote.jsx b/src/admin/NewVote.jsx index f049d49..db9792c 100644 --- a/src/admin/NewVote.jsx +++ b/src/admin/NewVote.jsx @@ -50,7 +50,6 @@ export default function NewVote() { } async function publish() { - console.log("Generating new vote with id: " + id); const berlinStartTime = moment.tz(startTime, "Europe/Berlin").toDate(); const berlinEndTime = moment.tz(endTime, "Europe/Berlin").toDate(); @@ -76,8 +75,6 @@ export default function NewVote() { await Promise.all(option); - console.log("Vote created successfully."); - snackbar({ message: "Wahl erfolgreich erstellt.", timeout: 5000, diff --git a/src/admin/Students.tsx b/src/admin/Students.tsx index 64d87ac..f551970 100644 --- a/src/admin/Students.tsx +++ b/src/admin/Students.tsx @@ -35,7 +35,6 @@ export default function Students() { const fileInputRef = useRef(null); function uploadStudents(event) { - console.log(event.target.files); const file = event.target.files[0]; const reader = new FileReader(); reader.onload = async (e) => { @@ -50,7 +49,6 @@ export default function Students() { } function updateStudents(event) { - console.log(event.target.files); const file = event.target.files[0]; const reader = new FileReader(); reader.onload = async (e) => { @@ -168,7 +166,6 @@ export default function Students() { onSubmit={(e) => { e.preventDefault(); if (classId) { - console.log(updatedStudents); updateClass(classId, { students: JSON.parse(updatedStudents), }).then(() => navigate(`/admin/students/${classId}`)); diff --git a/src/admin/auth/Login.tsx b/src/admin/auth/Login.tsx index 4498dd6..6a0dc71 100644 --- a/src/admin/auth/Login.tsx +++ b/src/admin/auth/Login.tsx @@ -12,9 +12,7 @@ export default function Login() { const handleLogin = () => { signInWithEmailAndPassword(auth, email, password) - .then((userCredential) => { - console.log(userCredential); - }) + .then((userCredential) => {}) .catch((error) => { snackbar({ message: error.message, diff --git a/src/admin/deprecated/AnswerList.jsx b/src/admin/deprecated/AnswerList.jsx index dcc05e1..80151fb 100644 --- a/src/admin/deprecated/AnswerList.jsx +++ b/src/admin/deprecated/AnswerList.jsx @@ -38,7 +38,6 @@ export default function AnswerList() { try { getDoc(doc(db, `/votes/${id}`)).then((e) => { let data = e.data(); - console.log(data); if (data === undefined) { alert("Document not found"); navigate("/admin"); @@ -119,17 +118,13 @@ for (const student of sortedStudentIds) { } setResult(options) -console.log(options) `); - console.log(optionsLet); - console.log(choicesLet); setLoading(false); }); }); } catch (error) { alert(error); AES(""); - console.log(enc); } }, [id]); diff --git a/src/admin/deprecated/AssignStudents.tsx b/src/admin/deprecated/AssignStudents.tsx index bb293c7..2cdc7ed 100644 --- a/src/admin/deprecated/AssignStudents.tsx +++ b/src/admin/deprecated/AssignStudents.tsx @@ -10,7 +10,6 @@ import React, { useState } from "react"; import { useLoaderData } from "react-router-dom"; import { db } from "../../firebase"; import { Choice, Option, Vote } from "../../types"; -import CSVFileUpload from "./FileUpload"; export default function AssignStudents() { const { vote, choices, options } = useLoaderData() as { @@ -40,8 +39,6 @@ export default function AssignStudents() { setAssignments(newAssignments); }, []); - console.log(assignments); - function deactivate() { if (prompt("Möchten Sie wirklich die Wahl beenden?") !== "Ja") return; updateDoc(doc(db, `/votes/${vote.id}`), { @@ -131,7 +128,6 @@ export default function AssignStudents() {
{vote.title}

- console.log(e)} />

{ data.docs.map((e) => { let data = e.data(); - console.log(data.version > 1); if (data.active) { setActiveVotes((activeVotes) => [ ...activeVotes, diff --git a/src/admin/index.jsx b/src/admin/index.jsx index be0ec53..d98f78e 100644 --- a/src/admin/index.jsx +++ b/src/admin/index.jsx @@ -22,7 +22,6 @@ export default function Admin(props) { const listen = onAuthStateChanged(auth, (user) => { if (user) { setAuthUser(user); - console.log(user); setLoading(false); } else { setAuthUser(false); diff --git a/src/admin/navigation/DrawerList.jsx b/src/admin/navigation/DrawerList.jsx index feab210..c109e14 100644 --- a/src/admin/navigation/DrawerList.jsx +++ b/src/admin/navigation/DrawerList.jsx @@ -26,7 +26,6 @@ export default function DrawerList() { .then((data) => { data.docs.map((e) => { let data = e.data(); - console.log(data.version > 1); if (data.active && data.endTime.seconds * 1000 > Date.now()) { if (data.startTime.seconds * 1000 > Date.now()) { setScheduledVotes((scheduledVotes) => [ @@ -80,8 +79,6 @@ export default function DrawerList() { setActive(location.pathname.split("/")[2]); }, [location]); - console.log(active, pages.includes(active)); - if (!pages.includes(active)) { return ; } @@ -120,11 +117,7 @@ export default function DrawerList() { onCLick={() => navigate("/admin")} /> - console.log(e)} - value="active-votes" - > + navigate(`/admin/${id}/match`)} /> + navigate(`/admin/${id}/add`)} + /> ([]); + + React.useEffect(() => { + const newSuggestedStudents: { + name: string; + grade: number; + listIndex: string; + }[] = []; + for (const c of classes) { + for (const s of c.students) { + if ( + choices.find( + (choice) => + choice.listIndex == s.listIndex && choice.grade == c.grade + ) === undefined + ) { + newSuggestedStudents.push({ + name: s.name, + grade: c.grade, + listIndex: s.listIndex, + }); + } + } + } + + setSuggestedStudents(newSuggestedStudents); + + // read url params + const urlParams = new URLSearchParams(window.location.search); + const name = urlParams.get("name"); + const grade = urlParams.get("grade"); + const listIndex = urlParams.get("listIndex"); + + if (name && grade && listIndex) { + setName(name); + setGrade(grade); + setListIndex(Number(listIndex)); + } + }, []); + + const [showSuggestions, setShowSuggestions] = React.useState(false); + + const [name, setName] = React.useState(""); + const [grade, setGrade] = React.useState(""); + const [listIndex, setListIndex] = React.useState(0); + + const [selected, setSelected] = React.useState( + Array.from({ length: vote.selectCount }, () => "null") + ); + + const [saving, setSaving] = React.useState(false); + + interface EditStudentParams { + grade: number; + listIndex: number; + name: string; + } + + function editStudent({ grade, listIndex, name }: EditStudentParams): void { + setName(name); + setGrade(grade.toString()); + setListIndex(listIndex); + setShowSuggestions(false); + } + + async function saveChoice() { + setSaving(true); + addDoc(collection(db, `/votes/${vote.id}/choices`), { + name, + grade, + listIndex, + selected, + extraFields: [], + version: 2, + timestamp: serverTimestamp(), + }) + .then((e) => { + setName(""); + setGrade(""); + setListIndex(0); + setSelected(Array.from({ length: vote.selectCount }, () => "null")); + + snackbar({ + message: "Wahl hinzugefügt", + }); + setSaving(false); + }) + .catch((error) => { + snackbar({ + message: error.message, + }); + setSaving(false); + }); + } + + const submitDisabled = + name === "" || grade === "" || listIndex === 0 || selected.includes("null"); + + return ( +
+

Hinzufügen

+

+ {suggestedStudents.length < 1 ? ( + +

+
+
+

Alle Schüler aus der Datenbank haben gewählt

+ +
+
+
+ + ) : ( +
+ +
setShowSuggestions(!showSuggestions)} + > +

Vorschläge anzeigen

+ {showSuggestions ? ( + + ) : ( + + )} +
+ + {showSuggestions && ( + a.grade - b.grade)[0].id} + > + {classes + .sort((a, b) => a.grade - b.grade) + .map((c) => ( + + Klasse {c.grade} + + { + suggestedStudents.filter((s) => s.grade == c.grade) + .length + } + + + ))} +

+ {classes + .sort((a, b) => a.grade - b.grade) + .map((c) => ( + +

+ {suggestedStudents + .filter((s) => s.grade == c.grade) + .map((s) => ( + { + editStudent({ + grade: s.grade, + listIndex: parseInt(s.listIndex), + name: s.name, + }); + }} + > +
+
+ {s.name} +
+
+
+ ))} +
+ + ))} +
+ )} +
+
+ )} +

+ +

+ setName((e.target as HTMLInputElement).value)} + label="Name" + placeholder="Max M." + variant="outlined" + > + setGrade((e.target as HTMLInputElement).value)} + label="Klasse" + placeholder="10" + variant="outlined" + > + + setListIndex(Number((e.target as HTMLInputElement).value)) + } + label="Klassenlistennr." + placeholder="9" + variant="outlined" + > +
+

+

+ {Array.from({ length: vote.selectCount }).map((_, i) => ( + + Keine + {options.map((o) => ( + { + const newSelected = selected.slice(); + newSelected[i] = o.id; + setSelected(newSelected); + }} + value={o.id} + > + {o.title} + + ))} + + ))} +
+

+ +

+ {saving ? ( + + Speichern + + ) : submitDisabled ? ( + + Speichern + + ) : ( + + Speichern + + )} + +

+ ); +} + +Add.loader = async function loader({ params }) { + const { id } = params; + const vote = await getDoc(doc(db, `/votes/${id}`)); + if (!vote.exists()) { + throw new Response("Vote not found", { status: 404 }); + } + const voteData = { id: vote.id, ...vote.data() }; + + const choices = await getDocs(collection(db, `/votes/${id}/choices`)); + const choiceData = choices.docs.map((doc) => ({ id: doc.id, ...doc.data() })); + + const options = await getDocs(collection(db, `/votes/${id}/options`)); + const optionData = options.docs.map((doc) => ({ id: doc.id, ...doc.data() })); + + const results = await getDocs(collection(db, `/votes/${id}/results`)); + const resultData = results.docs.map((doc) => ({ id: doc.id, ...doc.data() })); + + // get student database + const classes = await getDocs(collection(db, `/class`)); + const classesData = classes.docs.map((doc) => ({ + id: doc.id, + ...doc.data(), + })); + + return { + vote: voteData, + choices: choiceData, + options: optionData, + results: resultData, + classes: classesData, + }; +}; diff --git a/src/admin/vote/Answers.jsx b/src/admin/vote/Answers.jsx index c2838ac..29e1922 100644 --- a/src/admin/vote/Answers.jsx +++ b/src/admin/vote/Answers.jsx @@ -40,7 +40,6 @@ export default function Answers() { const newAnswer = answerData.find( (newAns) => !answersLoad.some((oldAns) => oldAns.id === newAns.id) ); - console.log("New Answer:", newAnswer); snackbar({ message: `Neue Antwort von ${newAnswer.name} (${newAnswer.grade})`, timeout: 5000, diff --git a/src/admin/vote/Assign.jsx b/src/admin/vote/Assign.jsx index bb447bf..616dc52 100644 --- a/src/admin/vote/Assign.jsx +++ b/src/admin/vote/Assign.jsx @@ -73,13 +73,11 @@ export default function Assign() { } } - console.log(points); preferences[choice.id] = { selected: choice.selected, points: points, }; } - console.log(preferences); const requestObject = { token: authToken, @@ -99,11 +97,9 @@ export default function Assign() { const data = await response.json(); - console.log(data); setResults(data); if (window.location.hostname === "localhost") { - console.log("Running on localhost"); setLoading(false); } setTimeout(() => setLoading(false), 5000); diff --git a/src/admin/vote/Edit.jsx b/src/admin/vote/Edit.jsx index 7a34915..f569f11 100644 --- a/src/admin/vote/Edit.jsx +++ b/src/admin/vote/Edit.jsx @@ -64,8 +64,6 @@ export default function Edit() { async function update() { try { - console.log("Publishing vote with id: " + vote.id); - await setDoc( doc(db, "/votes", vote.id), { @@ -86,7 +84,6 @@ export default function Edit() { confirmText: "Trotzdem löschen", onConfirm: async () => { await deleteDoc(doc(db, `/votes/${vote.id}/options/${opt.id}`)); - console.log("Option deleted successfully."); }, }) ); @@ -101,8 +98,6 @@ export default function Edit() { await Promise.all([...optionsPromises]); - console.log("Vote created successfully."); - snackbar({ message: "Wahl erfolgreich aktualisiert.", timeout: 5000, @@ -141,8 +136,7 @@ export default function Edit() { if (!_.isEmpty(changes)) { // log the changes - console.log("Vote has changed", changes); - + console.info("Vote has changed", changes); return false; } @@ -168,7 +162,7 @@ export default function Edit() { if (!_.isEmpty(changes)) { // log the changes - console.log("Option has changed", changes); + console.info("Option has changed", changes); return false; } @@ -430,13 +424,11 @@ Edit.loader = async function loader({ params }) { } const voteData = { id, ...vote.data() }; - console.log("Loaded vote:", voteData); const options = await getDocs(collection(db, `/votes/${id}/options`)); const optionData = options.docs.map((doc) => ({ id: doc.id, ...doc.data(), })); - console.log("Loaded options:", optionData); return { vote: voteData, diff --git a/src/admin/vote/Export.jsx b/src/admin/vote/Export.jsx index fa0060a..0a51f18 100644 --- a/src/admin/vote/Export.jsx +++ b/src/admin/vote/Export.jsx @@ -34,7 +34,6 @@ export default function Export() { ) => { const workbook = XLSX.utils.book_new(); if (exportMeta) { - console.log(vote); const meta = XLSX.utils.json_to_sheet([ { title: vote.title, diff --git a/src/admin/vote/Match.tsx b/src/admin/vote/Match.tsx index 3f72e79..77060c0 100644 --- a/src/admin/vote/Match.tsx +++ b/src/admin/vote/Match.tsx @@ -86,6 +86,18 @@ export default function Match() { ).length - 1) + " weitere"}{" "} + {choices.filter( + (choice) => + choice.listIndex === s.listIndex.toString() && + choice.grade === c.grade.toString() + ).length < 1 && ( + + (Erstellen) + + )} ))} diff --git a/src/admin/vote/Schedule.jsx b/src/admin/vote/Schedule.jsx index 225e89d..1594e57 100644 --- a/src/admin/vote/Schedule.jsx +++ b/src/admin/vote/Schedule.jsx @@ -44,7 +44,6 @@ export default function Schedule() { endTime: Timestamp.fromDate(moment.tz(endTime, "Europe/Berlin").toDate()), }) .then(() => { - console.log("Saved"); snackbar({ message: "Einstellungen gespeichert." }); navigate(`/admin/${id}`); }) diff --git a/src/main.jsx b/src/main.jsx index eec4357..54d9860 100644 --- a/src/main.jsx +++ b/src/main.jsx @@ -24,6 +24,7 @@ import Overview from "./admin/Overview"; import ReleaseNotes from "./admin/ReleaseNotes"; import Settings from "./admin/Settings"; import Students from "./admin/Students"; +import Add from "./admin/vote/Add"; import Answers from "./admin/vote/Answers"; import Assign from "./admin/vote/Assign"; import Delete from "./admin/vote/Delete"; @@ -167,6 +168,11 @@ const routes = [ element: , loader: Results.loader, }, + { + path: "add", + element: , + loader: Add.loader, + }, ], }, ], diff --git a/src/types.ts b/src/types.ts index c662d21..45a4c31 100644 --- a/src/types.ts +++ b/src/types.ts @@ -12,6 +12,7 @@ export type Choice = { grade: number; selected: string[]; extraFields: any[]; + listIndex: string; }; export type Vote = {