diff --git a/package.json b/package.json index 087151d..311d7fa 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "beoanswer_react", "private": true, - "version": "0.0.0", + "version": "1.0.0", "type": "module", "scripts": { "dev": "vite", diff --git a/src/App.jsx b/src/App.jsx index 3fa29d0..ab0f8c5 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,5 +1,6 @@ import { useState, useEffect } from 'react' import { FormProvider, useFormData } from './FormContext' +import packageJson from '../package.json' import './App.css' import FandStattVer from './components/FandStattVer.jsx' import BesucherBar from './components/BesucherBar.jsx' @@ -16,16 +17,18 @@ function AppContent() { const [name, setName] = useState("") const [loading, setLoading] = useState(true) const [error, setError] = useState(null) + const [mitsend, setMitsend] = useState(false) + const [mitback, setMitback] = useState(false) - const version = "1.0.0" - const vdate = "2025-11-23" + const version = packageJson.version + const vdate = new Date().toLocaleDateString('de-DE') // States const [schritt, setSchritt] = useState(0) const [pfad, setPfad] = useState('') // Hole formData aus dem Context - const { formData } = useFormData() + const { formData, updateFormData } = useFormData() // URL-Parameter und Backend-Aufruf useEffect(() => { @@ -106,24 +109,76 @@ function AppContent() { // Callbacks: const handleFandStattVerNext = (auswahl) => { - setPfad(auswahl) - setSchritt(1) + auswahl && setPfad(auswahl) + handleNext() } const handleNext = () => { setSchritt((schritt) => schritt + 1) } + const handleBack = () => { + if (schritt > 0) { + const neuerSchritt = schritt - 1 + setSchritt(neuerSchritt) + + // Entsprechende FormData-Felder zurücksetzen je nach Schritt und Pfad + if (pfad === 'ja') { + // JA-Pfad rückwärts + if (schritt === 1) { + // Von Besucher zurück zu ja/nein → Pfad löschen + setPfad('') + updateFormData('stattgefunden', '') + } else if (schritt === 2) { + // Von Spende zurück zu Besucher → Besucher löschen + updateFormData('besucher', '') + } else if (schritt === 3) { + // Von Betrag/Bemerkungen zurück zu Spende → Spende löschen + updateFormData('spendenArt', '') + } else if (schritt === 4) { + // Von Bemerkungen zurück → Betrag löschen (bei Bar-Spende) + updateFormData('betrag', '') + } else if (schritt === 5) { + // Von Senden zurück → Bemerkungen löschen + updateFormData('bemerkungen', '') + } + } else if (pfad === 'nein') { + // NEIN-Pfad rückwärts + if (schritt === 1) { + // Von abgesagt/verschoben zurück zu ja/nein → Pfad löschen + setPfad('') + updateFormData('stattgefunden', '') + } else if (schritt === 2) { + // Von Datum/Senden zurück zu abgesagt/verschoben → abgesagt löschen + updateFormData('abgesagt', '') + } else if (schritt === 3) { + // Von Senden zurück → neues Datum löschen (bei verschoben) + updateFormData('neuesDatum', '') + } + } + } + } + + const setBackButton = () => { + setMitback(true) + } + // Welche Komponeneten werden angezeigt: const renderCoponents = () => { const components = [] // Schritt 0: ja/nein - Auswahl components.push( - 1} /> + 1} /> ) - if (schritt === 0) + if (schritt === 0) { + // Bei ja/nein Auswahl: Kein Zurück-Button, kein Senden-Button + components.push() return components + } // JA-Pfad: if (pfad === 'ja') { @@ -152,13 +207,6 @@ function AppContent() { ) } - // 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( - ) - } - } // NEIN - Pfad if (pfad === 'nein') { @@ -166,7 +214,10 @@ function AppContent() { // Schritt 1: abgesagt / verschoben if (schritt >= 1) { components.push( - 1} /> + 1} /> ) } @@ -176,14 +227,31 @@ function AppContent() { ) } - // Schritt 4 (bei verschoben) oder Schritt 3 (bei absage): unterste Buttons - const endeNeinSchritt = (formData.abgesagt === 'verschoben') ? 3 : 2 - if (schritt >= endeNeinSchritt) { - components.push( - ) - } - } + + // Zurück-Button nur anzeigen wenn nicht bei ja/nein Auswahl + const backVerfuegbar = schritt > 0 + + // LastButtons IMMER anzeigen, aber Senden-Button nur wenn bereit + const sendenBereit = () => { + if (pfad === 'ja') { + // JA-Pfad: vollständig wenn Bemerkungen-Schritt erreicht + const bemerkungsSchritt = (formData.spendenArt === 'bar') ? 4 : 3 + return schritt >= bemerkungsSchritt + } else if (pfad === 'nein') { + // NEIN-Pfad: vollständig wenn abgesagt ODER verschoben mit Datum + if (formData.abgesagt === 'abgesagt') { + return schritt >= 2 + } else if (formData.abgesagt === 'verschoben') { + return schritt >= 3 && formData.neuesDatum + } + } + return false + } + + // LastButtons immer anzeigen + components.push() + return components } diff --git a/src/FormContext.jsx b/src/FormContext.jsx index b88f337..4f35f29 100644 --- a/src/FormContext.jsx +++ b/src/FormContext.jsx @@ -6,7 +6,6 @@ import { createContext, useContext, useState } from 'react' const FormContext = createContext() export function FormProvider({ children }) { - console.log('🚀 FormProvider initialisiert') const [formData, setFormData] = useState({ stattgefunden: '', @@ -20,19 +19,16 @@ export function FormProvider({ children }) { }) const updateFormData = (field, value) => { - console.log('📝 FormContext UPDATE:', field, '=', value) setFormData(prev => { const newData = { ...prev, [field]: value } - console.log('📊 FormContext NEU:', newData) return newData }) } const resetFormData = () => { - console.log('🔄 FormContext RESET') setFormData({ stattgefunden: '', diff --git a/src/components/FandStattVer.jsx b/src/components/FandStattVer.jsx index ac536b1..99bb581 100644 --- a/src/components/FandStattVer.jsx +++ b/src/components/FandStattVer.jsx @@ -2,7 +2,7 @@ import { useState } from 'react' import { useFormData } from '../FormContext' import Modal from './Modal' -export default function FandStattVer({left, right, title, onNext, radioName = "fst"}) { +export default function FandStattVer({left, right, title, onNext, radioName = "fst", setbackButton}) { const { formData, updateFormData } = useFormData() // Bestimme das Feld basierend auf radioName @@ -11,9 +11,14 @@ export default function FandStattVer({left, right, title, onNext, radioName = "f const handleRadioChange = (e) => { const value = e.target.value - setAuswahl(value) updateFormData(fieldName, value) - onNext(value) + setbackButton(true) + if(radioName !== 'abgesagt') { + setAuswahl(value) + onNext(value) + } else { + onNext() + } } return ( diff --git a/src/components/LastButtons.jsx b/src/components/LastButtons.jsx index eb5f21f..d0ca694 100644 --- a/src/components/LastButtons.jsx +++ b/src/components/LastButtons.jsx @@ -3,51 +3,52 @@ import { useFormData } from '../FormContext' import Modal from './Modal' import ConfirmModal from './ConfirmModal' -export default function LastButtons() { - - const { formData } = useFormData() +export default function LastButtons({ mitSend, mitBack, handleBack}) { + + const { formData, resetFormData } = useFormData() const [isSending, setIsSending] = useState(false) const [showModal, setShowModal] = useState(false) const [modalMessage, setModalMessage] = useState('') const [modalType, setModalType] = useState('error') // 'error' oder 'success' const [showConfirmModal, setShowConfirmModal] = useState(false) - + const [isSuccessModal, setIsSuccessModal] = useState(false) + const handleSenden = async () => { console.log("Alle Formulardaten: ", formData) - + setIsSending(true) - + try { // API URL und Auth-Daten aus Environment const APIURL = import.meta.env.VITE_API_URL const username = import.meta.env.VITE_API_USERNAME const password = import.meta.env.VITE_API_PASSWORD - + if (!APIURL) { throw new Error('API URL nicht konfiguriert.') } - + // URL-Parameter für ID auslesen const urlParams = new URLSearchParams(window.location.search) const id = urlParams.get('id') - + if (!id) { throw new Error('Keine ID in der URL gefunden.') } - + // FormData für PHP Backend erstellen const backendData = new FormData() backendData.append('cmd', 'UPDATEAFTER') backendData.append('id', id) - + // Formulardaten zu Backend-Feldern mappen // Basis-Status if (formData.stattgefunden === 'ja') { backendData.append('stattgefunden', '1') - + // Spenden-Informationen if (formData.spendenArt) { - switch(formData.spendenArt) { + switch (formData.spendenArt) { case 'bar': backendData.append('bezahlt', `Kasse ${formData.betrag}€)`) break @@ -62,7 +63,7 @@ export default function LastButtons() { break } } - + } else if (formData.stattgefunden === 'nein') { backendData.append('stattgefunden', '0') backendData.append('bezahlt', 'keine') @@ -71,19 +72,19 @@ export default function LastButtons() { if (formData.abgesagt === 'abgesagt') { backendData.append('status', 3) } else if (formData.abgesagt === 'verschoben') { - backendData.append('wtermin', formData.neuesDatum || '1900-01-01 00:00:00') + backendData.append('wtermin', formData.neuesDatum || '1900-01-01 00:00:00') } } - + // Bemerkungen backendData.append('remark', formData.bemerkungen || '') // Besucher backendData.append('besucher', formData.besucher || '0') - + // // Bearbeitungsdatum setzen // const now = new Date().toISOString().slice(0, 19).replace('T', ' ') // backendData.append('bearbeitet_am', now) - + // Debug: FormData kann nicht direkt geloggt werden, deshalb iterieren console.log("=== FORM DATA DEBUG ===") console.log("Original formData aus Context:", formData) @@ -93,46 +94,60 @@ export default function LastButtons() { console.log(` ${key}: ${value}`) } console.log("========================") -/* + // HTTP Basic Authentication Header const headers = {} if (username && password) { const credentials = btoa(`${username}:${password}`) headers['Authorization'] = `Basic ${credentials}` } - + // Backend-Aufruf const response = await fetch(APIURL, { method: 'POST', headers: headers, body: backendData }) - + if (!response.ok) { throw new Error(`Server-Fehler: ${response.status}`) } - - const result = await response.json() - - if (result.success) { + + // Backend Response auslesen + const responseText = await response.text() + console.log('Backend Response (raw):', responseText) + + let result + try { + // Versuche JSON zu parsen + result = JSON.parse(responseText) + console.log('Backend Response (parsed):', result) + } catch (e) { + // Falls kein JSON, behandle als einfachen Text + console.log('Backend Response ist kein JSON, behandle als Text') + result = { success: responseText.trim() === 'true', raw: responseText } + } + + // Erfolg prüfen - sowohl JSON als auch Text-Format unterstützen + const isSuccess = result.success === true || + result.success === 'true' || + responseText.trim() === 'true' + + if (isSuccess) { setModalType('success') setModalMessage('✅ Daten erfolgreich gespeichert!') + setIsSuccessModal(true) setShowModal(true) - - // Nach erfolgreicher Speicherung könnte man zur Übersicht zurück - setTimeout(() => { - // Optional: Weiterleitung oder Formular zurücksetzen - console.log('Erfolgreich gespeichert:', result) - }, 2000) - + } else { - throw new Error(result.message || 'Unbekannter Fehler beim Speichern') + throw new Error(result.message || result.error || 'Unbekannter Fehler beim Speichern') } -*/ + } catch (error) { console.error('Fehler beim Speichern:', error) setModalType('error') setModalMessage(`❌ Fehler beim Speichern: ${error.message}`) + setIsSuccessModal(false) setShowModal(true) } finally { setIsSending(false) @@ -145,8 +160,17 @@ export default function LastButtons() { const confirmAbbruch = () => { setShowConfirmModal(false) - // Zurück zur vorherigen Seite oder Startseite - window.history.back() + + // Versuche das Browser-Fenster zu schließen (wie beim Speichern) + window.close() + + // Fallback: Falls window.close() nicht funktioniert + setTimeout(() => { + if (!window.closed) { + // Wenn das Fenster nicht geschlossen werden kann, zur vorherigen Seite + window.location.reload() + } + }, 100) } const cancelAbbruch = () => { @@ -176,10 +200,50 @@ export default function LastButtons() { } const closeModal = () => { - setShowModal(false) - setModalMessage('') + if (isSuccessModal) { + // Bei erfolgreichem Speichern: Browser-Fenster schließen + console.log('Schließe Browser-Fenster nach erfolgreichem Speichern...') + + // Formular zurücksetzen (für den Fall, dass das Schließen nicht funktioniert) + resetFormData() + + // Browser-Fenster schließen + window.close() + + // Fallback: Falls window.close() nicht funktioniert (z.B. bei direkt aufgerufenen URLs) + // Nach 100ms prüfen, ob das Fenster noch offen ist + setTimeout(() => { + // Wenn das Fenster noch offen ist, zur vorherigen Seite oder Neustart + if (!window.closed) { + console.log('Fenster konnte nicht geschlossen werden, führe Neustart durch...') + window.location.reload() + } + }, 100) + + } else { + // Normales Modal schließen + setShowModal(false) + setModalMessage('') + setIsSuccessModal(false) + } } + const sendeButton = mitSend ? + + : null + + const backButton = mitBack ? + + : null + return ( <>
@@ -189,23 +253,18 @@ export default function LastButtons() { - + {backButton} + {sendeButton}
- + {showModal && ( - )} - + {showConfirmModal && (