add confirm site + add save JSON + add download JSON

This commit is contained in:
Michaela Grabke 2024-09-09 19:12:55 +02:00
parent 39d6b6f0bb
commit 3fce9ad750
11 changed files with 179 additions and 10 deletions

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavaScriptLibraryMappings">
<includedPredefinedLibrary name="Node.js Core" />
</component>
</project>

7
package-lock.json generated
View File

@ -16,6 +16,7 @@
"cors": "^2.8.5",
"express": "^4.19.2",
"formik": "^2.4.6",
"fs": "^0.0.1-security",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-scripts": "5.0.1",
@ -9535,6 +9536,12 @@
"node": ">= 0.6"
}
},
"node_modules/fs": {
"version": "0.0.1-security",
"resolved": "https://registry.npmjs.org/fs/-/fs-0.0.1-security.tgz",
"integrity": "sha512-3XY9e1pP0CVEUCdj5BmfIZxRBTSDycnbqhIOGec9QYtmVH2fbLpj86CFWkrNOkt/Fvty4KZG5lTglL9j/gJ87w==",
"license": "ISC"
},
"node_modules/fs-extra": {
"version": "10.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",

View File

@ -11,6 +11,7 @@
"cors": "^2.8.5",
"express": "^4.19.2",
"formik": "^2.4.6",
"fs": "^0.0.1-security",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-scripts": "5.0.1",

View File

@ -0,0 +1,8 @@
{
"kleidungsart": "jacke",
"krisengebiet": "syrien",
"lieferart": "Übergabe",
"abholadresse": "N/A",
"plz": "N/A",
"timestamp": "2024-09-09T16:52:56.753Z"
}

View File

@ -0,0 +1,8 @@
{
"kleidungsart": "tshirt",
"krisengebiet": "syrien",
"lieferart": "Übergabe",
"abholadresse": "N/A",
"plz": "N/A",
"timestamp": "2024-09-09T17:04:56.392Z"
}

View File

@ -0,0 +1,8 @@
{
"kleidungsart": "jacke",
"krisengebiet": "ukraine",
"lieferart": "Übergabe",
"abholadresse": "Teststrasse 4",
"plz": "24159",
"timestamp": "2024-09-09T16:48:30.248Z"
}

View File

@ -0,0 +1,8 @@
{
"kleidungsart": "hose",
"krisengebiet": "erdbeben",
"lieferart": "Abholung",
"abholadresse": "Teststrasse 44",
"plz": "24444",
"timestamp": "2024-09-09T17:05:45.685Z"
}

View File

@ -0,0 +1,51 @@
import React from 'react';
const ConfirmationPage = ({ spendenData }) => {
if (!spendenData) {
return <p>Lade Daten...</p>;
}
// Funktion zum Herunterladen der JSON-Datei
const downloadJSON = () => {
const jsonData = JSON.stringify(spendenData, null, 2); // Pretty-print JSON
const blob = new Blob([jsonData], { type: 'application/json' }); // Blob erstellen
const url = URL.createObjectURL(blob); // URL erstellen
// Link erstellen und den Download auslösen
const link = document.createElement('a');
link.href = url;
link.download = `spende_${spendenData.lieferart === 'Abholung' ? spendenData.abholadresse.replace(/\s+/g, '_') : 'uebergabe'}_${spendenData.timestamp}.json`;
link.click();
// URL-Objekt wieder freigeben
URL.revokeObjectURL(url);
};
return (
<div className="max-w-lg mx-auto p-6 bg-white shadow-lg rounded-lg">
<h2 className="text-2xl font-bold text-center mb-4">Spenden Bestätigung</h2>
<p><strong>Kleidungsart:</strong> {spendenData.kleidungsart}</p>
<p><strong>Krisengebiet:</strong> {spendenData.krisengebiet}</p>
<p><strong>Lieferart:</strong> {spendenData.lieferart}</p>
{spendenData.lieferart === 'Abholung' && (
<>
<p><strong>Abholadresse:</strong> {spendenData.abholadresse}</p>
<p><strong>PLZ:</strong> {spendenData.plz}</p>
</>
)}
<p><strong>Registrierungsdatum:</strong> {spendenData.timestamp}</p>
<p className="text-center mt-4"><strong>Vielen Dank für Ihre Spende!</strong></p>
<div className="text-center mt-6">
<button
onClick={downloadJSON}
className="bg-purple-600 text-white px-4 py-2 rounded-md hover:bg-purple-800 focus:outline-none focus:ring-2 focus:ring-purple-500"
>
Bestätigungs-Datei herunterladen
</button>
</div>
</div>
);
};
export default ConfirmationPage;

View File

@ -1,6 +1,7 @@
import React from "react";
import React, {useState} from "react";
import { Formik, Form, Field, ErrorMessage } from "formik";
import axios from "axios";
import ConfirmationPage from "./ConfimationPage";
// Manuelle Validierung
const validateForm = (values) => {
@ -34,17 +35,37 @@ const validateForm = (values) => {
};
const SpendenForm = () => {
const [isSubmitted, setIsSubmitted] = useState(false);
const [spendenData, setSpendenData] = useState(null);
const handleSubmit = (values) => {
axios
.post("http://localhost:5000/api/spenden", values)
.post("http://localhost:2000/api/spenden", values)
.then((response) => {
alert("Spende erfolgreich registriert!");
setSpendenData(response.data.data); // Speichere die Spenden-Daten
setIsSubmitted(true); // Zeige die Bestätigungsseite
})
.catch((error) => {
console.error("Es gab ein Problem bei der Registrierung:", error);
if (error.response) {
// Die Anfrage wurde gemacht und der Server hat eine Antwort mit Statuscode ungleich 2xx zurückgegeben
console.error("Serverantwort:", error.response.data);
console.error("Status:", error.response.status);
alert(`Fehler bei der Registrierung: ${error.response.data.error || 'Unbekannter Fehler'}`);
} else if (error.request) {
// Die Anfrage wurde gemacht, aber es gab keine Antwort
console.error("Keine Antwort vom Server:", error.request);
alert("Es gab keine Antwort vom Server.");
} else {
// Es gab ein Problem beim Aufbau der Anfrage
console.error("Fehler beim Erstellen der Anfrage:", error.message);
alert("Ein Fehler ist aufgetreten: " + error.message);
}
});
};
if (isSubmitted) {
return <ConfirmationPage spendenData={spendenData} />; // Bestätigungsseite anzeigen
}
return (
<div className="flex flex-col min-h-screen">
<header className="bg-purple-600 text-white p-4 text-center">
@ -60,7 +81,18 @@ const SpendenForm = () => {
abholadresse: "",
plz: "",
}}
validate={validateForm}
validate={values => {
const errors = {};
if (!values.kleidungsart) errors.kleidungsart = "Bitte wählen Sie eine Kleidungsart";
if (!values.krisengebiet) errors.krisengebiet = "Bitte wählen Sie ein Krisengebiet";
if (!values.lieferart) errors.lieferart = "Bitte wählen Sie eine Lieferart";
if (values.lieferart === "Abholung") {
if (!values.abholadresse) errors.abholadresse = "Bitte geben Sie Ihre Abholadresse an";
if (!values.plz) errors.plz = "Bitte geben Sie eine PLZ an";
else if (!/^\d{5}$/.test(values.plz)) errors.plz = "Die PLZ muss genau 5 Ziffern haben";
}
return errors;
}}
onSubmit={handleSubmit}
>
{({ values }) => (

View File

@ -1,27 +1,59 @@
const express = require('express');
const cors = require('cors');
const bodyParser = require('body-parser');
const fs = require('fs');
const app = express();
app.use(cors());
app.use(bodyParser.json());
const PLZ_GESCHAEFTSSTELLE = "10115"; // Beispiel-PLZ
const PLZ_GESCHAEFTSSTELLE = "24103"; // Beispiel-PLZ
app.post('/api/spenden', (req, res) => {
console.log("Anfrage-Daten:", req.body); // Überprüfe die gesendeten Daten
const { kleidungsart, krisengebiet, lieferart, abholadresse, plz } = req.body;
// PLZ-Validierung
if (lieferart === "Abholung" && plz.substring(0, 2) !== PLZ_GESCHAEFTSSTELLE.substring(0, 2)) {
return res.status(400).json({ error: "Die Abholadresse liegt nicht im gleichen PLZ-Gebiet." });
return res.status(400).json({ error: "Die Abholadresse liegt nicht im gleichen PLZ-Gebiet. (24***)" });
}
// Spende registrieren (Hier könnte man Daten in einer DB speichern)
console.log("Spende registriert:", req.body);
let filename;
if (lieferart === "Abholung") {
// Abholadresse als Dateiname verwenden
filename = `${abholadresse.replace(/\s+/g, '_')}.json`;
} else {
// Übergabe an Geschäftsstelle: Dateiname ist das aktuelle Datum im Format YYYYMMDD_HHmmss
const date = new Date();
const formattedDate = date.toISOString().replace(/:/g, '-').split('.')[0]; // Format: YYYY-MM-DDTHH-mm-ss
filename = `${formattedDate}.json`;
}
const spendenData = {
kleidungsart,
krisengebiet,
lieferart,
abholadresse: abholadresse || "N/A", // Falls keine Abholadresse vorhanden ist (Übergabe an Geschäftsstelle)
plz: plz || "N/A", // Falls keine PLZ vorhanden ist (Übergabe an Geschäftsstelle)
timestamp: new Date().toISOString(),
};
fs.writeFile(`./spenden/${filename}`, JSON.stringify(spendenData, null, 2), (err) => {
if (err) {
console.error("Fehler beim Erstellen der Datei:", err);
return res.status(500).json({ error: "Fehler beim Erstellen der Spenden-Datei." });
}
console.log(`Spende erfolgreich registriert und Datei ${filename} erstellt.`);
res.status(200).json({
message: "Spende erfolgreich registriert!",
data: req.body,
data: spendenData,
});
});
});

8
tailwind.config.js Normal file
View File

@ -0,0 +1,8 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ["./src/**/*.{js,jsx,ts,tsx}"],
theme: {
extend: {},
},
plugins: [],
}