Es geht jetzt mal grob

This commit is contained in:
rxf
2025-10-27 16:38:14 +01:00
parent 5a4b4a1db1
commit 14bc991a7b
11 changed files with 370 additions and 101 deletions

View File

@@ -7,7 +7,7 @@ import Spende from './components/Spende.jsx'
import LastLine from './components/LastLine.jsx'
import Bemerkungen from './components/Bemerkungen.jsx'
import LastButtons from './components/LastButtons.jsx'
import NeinPfad from './components/NeinPfad.jsx'
import Verschoben from './components/Verschoben.jsx'
function AppContent() {
@@ -41,7 +41,7 @@ function AppContent() {
// Schritt 0: ja/nein - Auswahl
components.push(
<FandStattVer key="fandstatt" left='ja' right='nein' onNext={handleFandStattVerNext} iscompleted={schritt > 1} />
<FandStattVer key="fandstatt" left='ja' right='nein' title='Fand die Führung statt?' onNext={handleFandStattVerNext} iscompleted={schritt > 1} />
)
if (schritt === 0)
return components
@@ -50,7 +50,7 @@ function AppContent() {
if (pfad === 'ja') {
// Schritt 1: Besucher-Anzahl
if (schritt >= 1) {
components.push(<BesucherBar key='besucher' title='Besucher-Anzahl:' eureo='' onNext={handleNext} isComplete={schritt > 1} />
components.push(<BesucherBar key='besucher' title='Besucher-Anzahl' euro='' onNext={handleNext} isCompleted={schritt > 1} />
)
}
@@ -62,18 +62,47 @@ function AppContent() {
// Schritt 3: Betrag der Spende (nur bei Bar-Spende)
if ((schritt >= 3) && (formData.spendenArt === 'bar')) {
components.push(<BesucherBar key='betrag' title='Höhe der Barspende:' euro='€' onNext={handleNext} isComplete={schritt > 3} />
components.push(<BesucherBar key='betrag' title='Höhe der Barspende' euro='€' onNext={handleNext} isCompleted={schritt > 3} />
)
}
// Schritt 3: Betrag der Spende (nur bei Bar-Spende)
if (schritt >= 4) {
components.push(<Bemerkungen key='bemerkungen' onNext={handleNext} isComplete={schritt > 4} />
// Schritt 4 (bei Bar-Spende) oder Schritt 3 (bei anderen Spenden): Bemerkungen
const bemerkungsSchritt = (formData.spendenArt === 'bar') ? 4 : 3
if (schritt >= bemerkungsSchritt) {
components.push(<Bemerkungen key='bemerkungen' onNext={handleNext} isCompleted={schritt > bemerkungsSchritt} />
)
}
// Schritt 5 (bei Bar-Spende) oder Schritt 4 (bei anderen Spenden): unterste Buttons
const endeSchritt = (formData.spendenArt === 'bar') ? 5 : 4
if (schritt >= endeSchritt) {
components.push(<LastButtons key='lastbutt' />
)
}
}
// NEIN - Pfad
if (pfad === 'nein') {
// Schritt 1: abgesagt / verschoben
if (schritt >= 1) {
components.push(
<FandStattVer key="abgesagt" left='abgesagt' right='verschoben' title='Die Führung wurde' radioName='abgesagt' onNext={handleNext} iscompleted={schritt > 1} />
)
}
// Schritt 2: Ende wenn abgesagt bzw. neues Datum bei verschoben
if (schritt >= 2 && formData.stattgefunden === 'verschoben') {
components.push(<Verschoben key='verschoben' onNext={handleNext} isCompleted={schritt > 2} />
)
}
// Schritt 4 (bei verschoben) oder Schritt 3 (bei absage): unterste Buttons
const endeNeinSchritt = (formData.stattgefunden === 'verschoben') ? 3 : 2
if (schritt >= endeNeinSchritt) {
components.push(<LastButtons key='lastbutt' />
)
}
}
return components
@@ -89,7 +118,6 @@ function AppContent() {
<h2 className="nachbearbeitung">Nachbearbeitung</h2>
</div>
{renderCoponents().map(component => component)}
<LastButtons />
<LastLine version={version} vdate={vdate} />
</div>
)

View File

@@ -14,7 +14,7 @@ export function FormProvider({ children }) {
spendenArt: '',
barspende: '',
bemerkungen: '',
neuertermin: '1900-01-01'
neuertermin: '1900-01-01T00:00',
// Weitere Felder können hier hinzugefügt werden
})
@@ -39,7 +39,7 @@ export function FormProvider({ children }) {
spendenArt: '',
barspende: '',
bemerkungen: '',
neuertermin: '1900-01-01'
neuertermin: '1900-01-01T00:00'
})
}

View File

@@ -1,11 +1,24 @@
export default function Bemerkungen() {
import { useState } from 'react'
import { useFormData } from '../FormContext'
return(
export default function Bemerkungen({ onNext, isCompleted }) {
const { formData, updateFormData } = useFormData()
const [wert, setWert] = useState(formData.bemerkungen || '')
const handleOK = () => {
updateFormData('bemerkungen', wert)
onNext()
}
return (
<section id="bemerkungen">
<h3>Bemerkungen (optional):</h3>
<div className="bemerkdiv">
<textarea className="beminfeld" />
<button className="okbutton">OK</button>
<textarea className="beminfeld" />
<button className="okbutton" onClick={handleOK}>OK</button>
</div>
</section>
)

View File

@@ -1,5 +1,6 @@
import { useState, useEffect } from 'react'
import { useState } from 'react'
import { useFormData } from '../FormContext'
import Modal from './Modal'
export default function BesucherBar({ title, euro, onNext, isCompleted }) {
@@ -8,45 +9,49 @@ export default function BesucherBar({ title, euro, onNext, isCompleted }) {
// Bestimme das Feld basierend auf dem Titel
const fieldName = title.includes('Barspende') ? 'barspende' : 'besucherAnzahl'
// DEBUG: Zeige formData beim Laden
console.log('🔍 BesucherBar geladen:', title)
console.log('📊 Aktuelles formData:', formData)
console.log('🔑 Verwende Feld:', fieldName)
console.log('💾 Gespeicherter Wert:', formData[fieldName])
const [wert, setWert] = useState(formData[fieldName] || '')
// DEBUG: Zeige State-Änderungen
useEffect(() => {
console.log('✏️ Wert geändert für', fieldName, ':', wert)
}, [wert, fieldName])
const [showModal, setShowModal] = useState(false)
const handleOK = () => {
if (wert) {
updateFormData(fieldName, wert)
console.log('✅ Gespeichert! Neues formData:', formData)
onNext()
} else {
alert('Bitte einen Wert eingeben')
setShowModal(true)
}
}
const handleKeyDown = (e) => {
if (e.key === 'Enter') {
handleOK()
}
}
const closeModal = () => {
setShowModal(false)
}
return (
<section id="besucherbar">
<h3>{title}:</h3>
<div className="besadiv">
<input type='number' value={wert} onChange={(e) => setWert(e.target.value)}
placeholder={euro ? 'Betrag in Euro' : 'Anzahl'} disabled={isCompleted}
/>
&nbsp;&nbsp;{euro}
<button className="okbutton" onClick={handleOK} disabled={!wert}>OK</button>
</div>
</section>
<>
<section id="besucherbar">
<h3>{title}:</h3>
<div className="besadiv">
<input type='number' value={wert} onChange={(e) => setWert(e.target.value)}
onKeyDown={handleKeyDown}
placeholder={euro ? 'Betrag in Euro' : 'Anzahl'} disabled={isCompleted}
/>
&nbsp;&nbsp;{euro}
<button className="okbutton" onClick={handleOK}>OK</button>
</div>
</section>
<Modal
isOpen={showModal}
onClose={closeModal}
title="Eingabe erforderlich"
>
<p>Bitte einen Wert eingeben</p>
</Modal>
</>
)
}

View File

@@ -1,34 +1,51 @@
import { useState } from 'react'
import { useFormData } from '../FormContext'
import Modal from './Modal'
export default function FandStattVer({left, right, onNext}) {
export default function FandStattVer({left, right, title, onNext, radioName = "fst"}) {
const { formData, updateFormData } = useFormData()
const [auswahl, setAuswahl] = useState(formData.stattgefunden || '')
const [showModal, setShowModal] = useState(false)
const handleOK = () => {
if(!auswahl) {
alert('Bitte ja/nein wählen')
setShowModal(true)
return
}
updateFormData('stattgefunden', auswahl)
onNext(auswahl)
}
const closeModal = () => {
setShowModal(false)
}
return (
<section>
<h3>Fand die Führung statt?</h3>
<div className="fstdiv">
<label className="fsLabel">
<input type="radio" name="fst" value={left} checked={auswahl === left}
onChange = {(e) => setAuswahl(e.target.value)} />
{left}
</label>
<label className="fsLabel">
<input type="radio" name="fst" value={right} checked={auswahl === right}
onChange = {(e) => setAuswahl(e.target.value)} />
{right}
</label>
<button className="okbutton" onClick={handleOK} disabled = {!auswahl}>OK</button>
</div>
</section>
<>
<section>
<h3>{title}</h3>
<div className="fstdiv">
<label className="fsLabel">
<input type="radio" name={radioName} value={left} checked={auswahl === left}
onChange = {(e) => setAuswahl(e.target.value)} />
{left}
</label>
<label className="fsLabel">
<input type="radio" name={radioName} value={right} checked={auswahl === right}
onChange = {(e) => setAuswahl(e.target.value)} />
{right}
</label>
<button className="okbutton" onClick={handleOK}>OK</button>
</div>
</section>
<Modal
isOpen={showModal}
onClose={closeModal}
title="Auswahl erforderlich"
>
<p>Bitte eine Option wählen</p>
</Modal>
</>
)
}

View File

@@ -1,9 +1,26 @@
import { useFormData } from '../FormContext'
export default function LastButtons() {
const { formData } = useFormData()
const handleSenden = () => {
console.log("Alle Formulardaten: ", formData)
}
const handleAbbruch = () => {
console.log("Abbruch")
}
const handleAnleitung = () => {
console.log("Zeige Anleitung")
}
return (
<div className="lastbuttons">
<button className="btnabbruch">Abbruch</button>
<button className="btnanleit">Anleitung</button>
<button className="btnsend">Senden</button>
<button className="btnabbruch" onClick = {handleAbbruch}>Abbruch</button>
<button className="btnanleit" onClick = {handleAnleitung}>Anleitung</button>
<button className="btnsend" onClick = {handleSenden}>Senden</button>
</div>
)

127
src/components/Modal.css Normal file
View File

@@ -0,0 +1,127 @@
/* Modal Overlay - covers the entire screen */
.modal-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.6);
display: flex;
justify-content: center;
align-items: center;
z-index: 1000;
backdrop-filter: blur(2px);
}
/* Modal Content Box */
.modal-content {
background: white;
border-radius: 12px;
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.3);
max-width: 400px;
width: 90%;
max-height: 90vh;
overflow: hidden;
animation: modalSlideIn 0.2s ease-out;
}
@keyframes modalSlideIn {
from {
transform: scale(0.9) translateY(-10px);
opacity: 0;
}
to {
transform: scale(1) translateY(0);
opacity: 1;
}
}
/* Modal Header */
.modal-header {
background: #f8f9fa;
padding: 16px 20px;
border-bottom: 1px solid #e9ecef;
display: flex;
justify-content: space-between;
align-items: center;
}
.modal-title {
margin: 0;
color: #333;
font-size: 1.2rem;
font-weight: 600;
}
.modal-close {
background: none;
border: none;
font-size: 24px;
cursor: pointer;
color: #666;
width: 30px;
height: 30px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
transition: all 0.2s ease;
}
.modal-close:hover {
background: #e9ecef;
color: #333;
}
/* Modal Body */
.modal-body {
padding: 20px;
color: #333;
line-height: 1.5;
text-align: center;
}
/* Modal Footer */
.modal-footer {
background: #f8f9fa;
padding: 16px 20px;
border-top: 1px solid #e9ecef;
display: flex;
justify-content: center;
}
.modal-button {
background: #007bff;
color: white;
border: none;
padding: 8px 24px;
border-radius: 6px;
cursor: pointer;
font-weight: 500;
transition: all 0.2s ease;
min-width: 80px;
}
.modal-button:hover {
background: #0056b3;
transform: translateY(-1px);
}
.modal-button:focus {
outline: 2px solid #80bdff;
outline-offset: 2px;
}
/* Responsive Design */
@media (max-width: 480px) {
.modal-content {
margin: 20px;
width: calc(100% - 40px);
}
.modal-header,
.modal-body,
.modal-footer {
padding: 12px 16px;
}
}

39
src/components/Modal.jsx Normal file
View File

@@ -0,0 +1,39 @@
import React from 'react'
// Import des CSS direkt hier
import './Modal.css'
export default function Modal({ isOpen, onClose, title, children }) {
if (!isOpen) return null
const handleOverlayClick = (e) => {
if (e.target === e.currentTarget) {
onClose()
}
}
const handleKeyDown = (e) => {
if (e.key === 'Escape') {
onClose()
}
if (e.key === 'Enter') {
onClose()
}
}
return (
<div className="modal-overlay" onClick={handleOverlayClick} onKeyDown={handleKeyDown} tabIndex={0}>
<div className="modal-content">
<div className="modal-header">
<h3 className="modal-title">{title}</h3>
<button className="modal-close" onClick={onClose}>&times;</button>
</div>
<div className="modal-body">
{children}
</div>
<div className="modal-footer">
<button className="modal-button" onClick={onClose} autoFocus>OK</button>
</div>
</div>
</div>
)
}

View File

@@ -1,21 +0,0 @@
import FandStattVer from "./FandStattVer.jsx";
import Verschoben from "./Verschoben.jsx";
export default function NeinPfad({ isNein }) {
let verschoben = true
let dt = null
if (verschoben) {
dt = <Verschoben />
}
if (isNein) {
return (
<>
<FandStattVer left='abgesagt' right='verschoben' />
{dt}
</>
)
} else {
return null
}
}

View File

@@ -11,9 +11,7 @@ export default function Spende({ onNext, isCompleted }) {
const art = e.target.value
setSpendenArt(art)
updateFormData('spendenArt', art)
if (art !== 'bar') {
onNext()
}
onNext()
}
return (

View File

@@ -1,16 +1,62 @@
import { useState } from 'react'
import { useFormData } from '../FormContext/'
import Modal from './Modal'
export default function Verschoben({onNext, isCompleted}) {
const { formData, updateFormData } = useFormData()
// State für das selektierte Datum
const [selectedDate, setSelectedDate] = useState(formData.neuertermin || '')
const [showModal, setShowModal] = useState(false)
const handleOK = () => {
if (selectedDate) {
updateFormData('neuertermin', selectedDate)
onNext()
} else {
setShowModal(true)
}
}
const handleKeyDown = (e) => {
if (e.key === 'Enter') {
handleOK()
}
}
const closeModal = () => {
setShowModal(false)
}
export default function Verschoben() {
let now = new Date()
now.setMinutes(now.getMinutes() - now.getTimezoneOffset());
return (
<section>
<h3>Verschoben auf:</h3>
<div className="verschoben">
<input type="datetime-local" id="datetime" min={now.toISOString().slice(0,16)} />
<button className="okbutton">OK</button>
<>
<section>
<h3>Verschoben auf:</h3>
<div className="verschoben">
<input
type="datetime-local"
id="datetime"
value={selectedDate}
onChange={(e) => setSelectedDate(e.target.value)}
onKeyDown={handleKeyDown}
min={now.toISOString().slice(0,16)}
disabled={isCompleted}
/>
<button className="okbutton" onClick={handleOK}>OK</button>
</div>
</section>
</div>
</section>
<Modal
isOpen={showModal}
onClose={closeModal}
title="Datum erforderlich"
>
<p>Bitte ein Datum auswählen</p>
</Modal>
</>
)
}