diff --git a/src/admin/vote/Answers.jsx b/src/admin/vote/Answers.jsx
index 82297c1..c785c1a 100644
--- a/src/admin/vote/Answers.jsx
+++ b/src/admin/vote/Answers.jsx
@@ -5,8 +5,9 @@ import {
getDoc,
getDocs,
onSnapshot,
+ setDoc,
} from "firebase/firestore";
-import { confirm, snackbar } from "mdui";
+import { confirm, prompt, snackbar } from "mdui";
import React from "react";
import { useLoaderData, useNavigate } from "react-router-dom";
import { db } from "../../firebase";
@@ -16,9 +17,14 @@ export default function Answers() {
const [loading, setLoading] = React.useState(true);
- const search = new URLSearchParams(window.location.search).get("search");
+ const searchParams = new URLSearchParams(window.location.search);
+ const search = searchParams.get("search");
+ const grade = searchParams.get("grade");
+ const listIndex = searchParams.get("listIndex");
- const [mode, setMode] = React.useState(search ? "by-name" : "by-option");
+ const [mode, setMode] = React.useState(
+ search || grade || listIndex ? "by-name" : "by-option"
+ );
const [answers, setAnswers] = React.useState([]);
const grades = [...new Set(answers.map((answer) => answer.grade))];
@@ -80,7 +86,43 @@ export default function Answers() {
searchField.value = search;
}
}
- }, [search, mode, answers, loading]);
+ if (grade && listIndex && mode === "by-name") {
+ const elements = document.querySelectorAll("tbody tr");
+ elements.forEach((element) => {
+ const gradeCell = element.querySelector("td:nth-child(2)").textContent;
+ const listIndexCell =
+ element.querySelector("td:nth-child(3)").textContent;
+ if (gradeCell == grade && listIndexCell == listIndex) {
+ element.style.display = "";
+ } else {
+ element.style.display = "none";
+ }
+ });
+ }
+ }, [search, mode, answers, loading, grade, listIndex]);
+
+ async function updateAnswer({ id, data }) {
+ try {
+ await setDoc(doc(db, `/votes/${vote.id}/choices/${id}`), data, {
+ merge: true,
+ });
+ snackbar({
+ message: "Antwort erfolgreich aktualisiert.",
+ timeout: 5000,
+ });
+ // update the answers
+ const newAnswers = answers.map((answer) =>
+ answer.id === id ? { ...answer, ...data } : answer
+ );
+ setAnswers(newAnswers);
+ } catch (error) {
+ snackbar({
+ message: "Fehler beim Aktualisieren der Antwort.",
+ timeout: 5000,
+ });
+ console.error(error);
+ }
+ }
if (loading) {
return
@@ -255,7 +300,17 @@ export default function Answers() {
.sort((a, b) => a.listIndex - b.listIndex)
.map((answer, i) => (
- ID + Antwort-Id | @@ -357,20 +420,73 @@ export default function Answers() { | { + let data = JSON.stringify(answer, null, 2); + prompt({ + placeholder: "JSON-2Daten", + confirmText: "Speichern", + cancelText: "Abbrechen", + headline: "Antwort bearbeiten", + description: + "Beachten Sie: bei fehlerhaften Daten kann diese Antwort unbrauchbar werden. Stellen Sie vor dem Speichern sicher, dass die Daten korrekt sind.", + onConfirm: (value) => { + try { + const data = JSON.parse(value); + console.log(data); + updateAnswer({ id: answer.id, data }); + } catch (error) { + snackbar("Ungültige JSON-Daten."); + } + }, + textFieldOptions: { + value: data, + oninput: (e) => { + data = e.target.value; + }, + autosize: true, + rows: 5, + }, + validator: (value) => { + try { + JSON.parse(value); + return true; + } catch (error) { + return false; + } + }, + }); + }} + > + Bearbeiten + | + {
confirm({
headline: "Löschen",
description:
"Sind Sie sicher, dass Sie diese Antwort löschen möchten?",
- }).then(() => {
- // Löschen
- deleteDoc(
- doc(db, `/votes/${vote.id}/choices/${answer.id}`)
- ).then(() => {
- window.location.reload();
- });
+ confirmText: "Löschen",
+ cancelText: "Abbrechen",
+ onConfirm: () => {
+ deleteDoc(
+ doc(
+ db,
+ `/votes/${vote.id}/choices/${answer.id}`
+ )
+ ).then(() => {
+ snackbar({
+ message: "Antwort erfolgreich gelöscht.",
+ timeout: 5000,
+ });
+ window.location.reload();
+ });
+ },
});
}}
>
@@ -383,6 +499,69 @@ export default function Answers() {
)}
+
+ {mode === "by-date" && (
+
+
+ )}
);
}
diff --git a/src/admin/vote/Match.tsx b/src/admin/vote/Match.tsx
index 77060c0..791aad4 100644
--- a/src/admin/vote/Match.tsx
+++ b/src/admin/vote/Match.tsx
@@ -54,14 +54,7 @@ export default function Match() {
+ Hinweis: Als Datenschutzmaßnahme wird die Uhrzeit vorerst nicht
+ angezeigt. Die Antworten sind nach der Uhrzeit sortiert. Erst beim
+ Klicken auf das Datum wird die Uhrzeit sichtbar. Diese Ansicht kann
+ Ihnen helfen, sich einen Überblick über die letzten Antworten zu
+ verschaffen.
+
+
+
+
| {s.listIndex} | - choice.listIndex === - s.listIndex.toString() && - choice.grade === c.grade.toString() - )[0]?.id - }`} + to={`../answers?grade=${c.grade}&listIndex=${s.listIndex}`} > { choices.filter( @@ -71,21 +64,21 @@ export default function Match() { choice.grade === c.grade.toString() )[0]?.name } + {choices.filter( + (choice) => + choice.listIndex === s.listIndex.toString() && + choice.grade === c.grade.toString() + ).length > 1 && + " + " + + (choices.filter( + (choice) => + choice.listIndex === + s.listIndex.toString() && + choice.grade === c.grade.toString() + ).length - + 1) + + " weitere"} - {choices.filter( - (choice) => - choice.listIndex === s.listIndex.toString() && - choice.grade === c.grade.toString() - ).length > 1 && - " + " + - (choices.filter( - (choice) => - choice.listIndex === - s.listIndex.toString() && - choice.grade === c.grade.toString() - ).length - - 1) + - " weitere"}{" "} {choices.filter( (choice) => choice.listIndex === s.listIndex.toString() && |
---|