diff --git a/src/Admin.css b/src/Admin.css index d7d329a..3c3c7eb 100644 --- a/src/Admin.css +++ b/src/Admin.css @@ -23,6 +23,31 @@ color: #ffffff; } +.header-buttons { + display: flex; + gap: 10px; +} + +.print-btn { + background-color: #28a745; + color: white; + border: none; + padding: 10px 20px; + border-radius: 5px; + cursor: pointer; + font-size: 16px; + transition: background-color 0.3s ease; +} + +.print-btn:hover { + background-color: #218838; +} + +.print-btn:active { + background-color: #1e7e34; + transform: scale(0.98); +} + .logout-btn { background-color: #dc3545; color: white; @@ -203,7 +228,176 @@ transform: scale(0.95); } -@media (max-width: 768px) { +.date-input { + padding: 12px 15px; + font-size: 14px; + background-color: rgba(97, 218, 251, 0.25); + border: 2px solid rgba(97, 218, 251, 0.5); + border-radius: 5px; + color: #ffffff; + transition: all 0.3s ease; + font-family: inherit; + max-width: 300px; +} + +.date-input:focus { + outline: none; + border-color: #61dafb; + background-color: rgba(97, 218, 251, 0.35); + box-shadow: 0 0 8px rgba(97, 218, 251, 0.4); +} + +.date-input::placeholder { + color: rgba(255, 255, 255, 0.5); +} + +.date-input-container { + max-width: 1200px; + margin: 20px auto 30px; + display: flex; + flex-direction: column; + align-items: center; + gap: 12px; +} + +.date-input-label { + color: #ffffff; + font-size: 14px; + margin-bottom: 8px; + opacity: 0.9; +} + +.date-input-group { + display: flex; + gap: 5px; + justify-content: center; + align-items: center; +} + +.date-save-btn { + background-color: #61dafb; + color: #000000; + border: none; + padding: 12px 25px; + border-radius: 5px; + cursor: pointer; + font-size: 14px; + font-weight: 600; + transition: all 0.3s ease; +} + +.date-save-btn:hover { + background-color: #4db8d9; + transform: translateY(-2px); + box-shadow: 0 4px 8px rgba(97, 218, 251, 0.3); +} + +.event-data-container { + background: rgba(0, 0, 0, 0.6); + backdrop-filter: blur(10px); + border-radius: 8px; + padding: 25px; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3); + max-width: 1200px; + margin: 20px auto 30px; + border: 1px solid rgba(97, 218, 251, 0.3); +} + +.event-data-container h3 { + margin-top: 0; + margin-bottom: 20px; + color: #ffffff; + font-size: 1.3em; + text-align: center; +} + +.event-data-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); + gap: 20px; + margin-bottom: 20px; +} + +.event-data-field { + display: flex; + flex-direction: column; + gap: 8px; +} + +.event-data-label { + color: #ffffff; + font-size: 14px; + font-weight: 600; + opacity: 0.9; +} + +.event-data-input { + padding: 12px 15px; + font-size: 14px; + background-color: rgba(97, 218, 251, 0.25); + border: 2px solid rgba(97, 218, 251, 0.5); + border-radius: 5px; + color: #ffffff; + transition: all 0.3s ease; + font-family: inherit; +} + +.event-data-input:focus { + outline: none; + border-color: #61dafb; + background-color: rgba(97, 218, 251, 0.35); + box-shadow: 0 0 8px rgba(97, 218, 251, 0.4); +} + +.event-data-input::placeholder { + color: rgba(255, 255, 255, 0.5); +} + +.checkbox-container { + display: flex; + align-items: center; + gap: 10px; + padding: 12px 15px; + background-color: rgba(97, 218, 251, 0.25); + border: 2px solid rgba(97, 218, 251, 0.5); + border-radius: 5px; +} + +.event-data-checkbox { + width: 18px; + height: 18px; + accent-color: #61dafb; +} + +.checkbox-container span { + color: #ffffff; + font-size: 14px; +} + +.event-save-btn { + background-color: #61dafb; + color: #000000; + border: none; + padding: 15px 30px; + border-radius: 5px; + cursor: pointer; + font-size: 16px; + font-weight: 600; + transition: all 0.3s ease; + display: block; + margin: 0 auto; +} + +.event-save-btn:hover { + background-color: #4db8d9; + transform: translateY(-2px); + box-shadow: 0 4px 8px rgba(97, 218, 251, 0.3); +} + +.event-save-btn:active { + background-color: #3a9bb6; + transform: translateY(0); +} .admin-header { flex-direction: column; gap: 15px; @@ -227,7 +421,11 @@ font-size: 36px; } - .admin-header h2 { - font-size: 24px; + .event-data-grid { + grid-template-columns: 1fr; + } + + .event-save-btn { + font-size: 14px; + padding: 12px 25px; } -} diff --git a/src/Admin.jsx b/src/Admin.jsx index e0e536f..0ae5e06 100644 --- a/src/Admin.jsx +++ b/src/Admin.jsx @@ -4,16 +4,29 @@ import { auth, db } from './firebase'; import { signOut } from 'firebase/auth'; import './Admin.css'; -export default function Admin() { +export default function Admin({ close }) { const [data, setData] = useState([]); + const [eventData, setEventData] = useState({ + time: "", + date: "", + price: "", + food: false, + endtime: "" + }); + useEffect(() => { let unsub = onSnapshot(collection(db, "forms"), (snapshot) => { let data = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() })); setData(data) }) + let unsub1 = onSnapshot(doc(db, "time", "time"), data => { + let parsedData = data.data() + setEventData(parsedData) + }) return () => { unsub(); + unsub1() }; }, []); @@ -33,6 +46,16 @@ export default function Admin() { } } + const saveEventData = async () => { + try { + await updateDoc(doc(db, "time", "time"), eventData) + alert("Event-Daten gespeichert") + } catch (error) { + alert("Irgendetwas ist schief gelaufen :(") + console.error(error) + } + } + const deletePerson = async (id, index) => { if (window.confirm("Möchtest du diese Person wirklich löschen?")) { try { @@ -52,13 +75,121 @@ export default function Admin() { } } + const resetEverything = () => { + if (!window.confirm("Wirklich alle Anmeldungen löschen? Dieser Vorgang kann nicht rückgängig gemacht werden.")) { + return; + } + data.forEach(async el => { + try { + await deleteDoc(doc(db, "forms", el.id)) + } catch (error) { + console.error(error) + alert("Irgendetwas ist schiefgelaufen :(") + } + }); + } + + const handlePrint = () => { + const allNames = data.flatMap(entry => entry.names || []); + const printContent = ` + + + Liste der angemeldeten Personen + + + +

Liste der angemeldeten Personen

+ + + + `; + const printWindow = window.open('', '_blank'); + printWindow.document.write(printContent); + printWindow.document.close(); + printWindow.print(); + } + return (

Verwaltung Dashboard

- +
+ + + + +
+
+
+

Event-Daten bearbeiten

+
+
+ + setEventData({...eventData, time: e.target.value})} + className="event-data-input" + placeholder="z.B. 19:00 Uhr" + /> +
+
+ + setEventData({...eventData, date: e.target.value})} + className="event-data-input" + placeholder="z.B. 27. März 2026" + /> +
+
+ + setEventData({...eventData, price: e.target.value})} + className="event-data-input" + placeholder="z.B. 5" + /> +
+
+ + setEventData({...eventData, endtime: e.target.value})} + className="event-data-input" + /> +
+
+ +
+ setEventData({...eventData, food: e.target.checked})} + className="event-data-checkbox" + /> + Verpflegung ist gesorgt +
+
+
+
-

Gesamtzahl Anmeldungen

diff --git a/src/App.jsx b/src/App.jsx index adbac42..918d46f 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,6 +1,6 @@ import { useEffect, useRef, useState } from 'react'; import './App.css'; -import { addDoc, collection, doc, getDoc, onSnapshot } from 'firebase/firestore'; +import { addDoc, collection, doc, onSnapshot } from 'firebase/firestore'; import { auth, db } from './firebase'; import Admin from './Admin'; import { onAuthStateChanged, signInWithEmailAndPassword } from 'firebase/auth'; @@ -12,13 +12,24 @@ function App() { const [showManagement, setShowManagement] = useState(false); const [loginPassword, setLoginPassword] = useState(""); const [isLoggedIn, setisLoggedIn] = useState(false); + const [data, setData] = useState({ + time: "", + date: "", + price: "", + food: false, + endtime: "2026-03-27T17:30:00", + }); useEffect(() => { const unsub = onAuthStateChanged(auth, (user) => { setisLoggedIn(user ? true : false) }) + const unsub1 = onSnapshot(doc(db, "time", "time"), (data) => { + setData(data.data()) + }) return () => { unsub() + unsub1() }; }, []); @@ -126,7 +137,7 @@ function App() { - ) : } + ) : setShowManagement(false)} />}
) : ( <> @@ -135,7 +146,7 @@ function App() {
Zeit: - 18:00 + {data.time}
Ort: @@ -143,45 +154,46 @@ function App() {
Datum: - Fr. 27.03.2026 + {data.date}
Eintrittspreis: - 2€ + {data.price}€
Anmeldung spätestens bis: - 17:30 (online oder vor Ort) + { new Date(data.endtime).toLocaleDateString() } (online oder vor Ort)

{/* */} Ausschließlich für Schüler, Lehrer und Familienmitglieder.
-
+ { data.food &&
Für Verpflegung ist gesorgt. -
+
}
-
- - setEmail(e.target.value))} value={email}/> -
- - - { createPersonFields() } -
- -
+ { new Date() > new Date(data.endtime) ?

Die Anmeldefrist ist leider schon abgelaufen

: +
+ + setEmail(e.target.value))} value={email}/> +
+ + + { createPersonFields() } +
+ +
+ }
)}