This commit is contained in:
Philippe Torrel
2026-10-27 13:15:18 +01:00
parent 2efeba53f2
commit 75a26bda91
8 changed files with 4680 additions and 7 deletions
File diff suppressed because it is too large Load Diff
@@ -8,6 +8,9 @@
<title>React with Forms</title>
</head>
<body>
<noscript>
<p class="p-5">Die Seite benötigt JS.</p>
</noscript>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
File diff suppressed because it is too large Load Diff
@@ -1,13 +1,26 @@
import Navbar from './components/navs/Navbar.jsx';
import Router from './routes/Router.jsx';
import Navbar from './components/navs/Navbar';
import Router from './routes/Router';
import HeaderMain from './components/headers/HeaderMain';
import FooterMain from './components/footers/FooterMain';
import { Navigate, useNavigate } from 'react-router-dom';
import { useEffect } from 'react';
function App() {
// const navigate = useNavigate();
// useEffect(() => {
// navigate('/contact');
// }, []);
return (
<>
<HeaderMain />
<Navbar />
<Navigate to="/contact" />
<main id="main">
<Router />
</main>
<FooterMain />
</>
);
}
@@ -0,0 +1,91 @@
import validate from '../../utils/validators/validate';
import { useState } from 'react';
const FormContact = (props) => {
// const { } = props;
const FORM_DATA = {
firstname: '',
lastname: '',
email: '',
message: '',
};
const [formData, setFormData] = useState(FORM_DATA);
// EventHandlers
const handleSubmit = (e) => {
e.preventDefault();
const errors = validate(formData);
// AJAX/FETCH send to server
console.log('FormData: ', formData);
};
const handleChange = (e) => {
// console.log('Event: ', e);
const { name, value } = e.target;
setFormData((state) => ({ ...state, [name]: value }));
// console.log({ [e.target.name]: e.target.value });
// console.log('formData: ', formData);
};
return (
<form className="m-form-contact form-contact" noValidate={true} onSubmit={handleSubmit}>
<div className="row">
<div className="col-12 col-sm-6">
<div className="mb-3">
<label htmlFor="input-firstname" className="form-label">
Firstname
</label>
<input type="text" name="firstname" id="input-firstname" className="form-control" onChange={handleChange} />
</div>
</div>
<div className="col-12 col-sm-6">
<div className="mb-3">
<label htmlFor="input-lastname" className="form-label">
Lastname
</label>
<input type="text" name="lastname" id="input-lastname" className="form-control" onChange={handleChange} />
</div>
</div>
</div>
<div className="row">
<div className="col">
<div className="mb-3">
<label htmlFor="input-email" className="form-label">
Email
</label>
<input type="email" className="form-control" id="input-email" name="email" onChange={handleChange} />
</div>
</div>
</div>
<div className="row">
<div className="col">
<div className="mb-3">
<label htmlFor="textarea-message" className="form-label">
Message
</label>
<textarea
name="message"
id="textarea-message"
cols="30"
rows="5"
className="form-control"
onChange={handleChange}></textarea>
</div>
</div>
</div>
<div className="row">
<div className="col">
<button type="submit" className="btn btn-dark button-send-contact">
Send
</button>
</div>
</div>
</form>
);
};
export default FormContact;
@@ -1,9 +1,18 @@
import FormContact from '../components/forms/FormContact';
function ContactPage() {
return (
<div className="page-contact container py-5">
<h2>Kontakt</h2>
<p>Hast du Fragen? Schreib uns eine E-Mail:</p>
<a href="mailto:kontakt@example.com">kontakt@example.com</a>
<p>
Hast du Fragen? Schreib uns eine E-Mail:
<br />
<a href="mailto:kontakt@example.com">kontakt@example.com</a>
<br />
</p>
<hr />
<FormContact />
</div>
);
}
@@ -0,0 +1,23 @@
const validate = (formData) => {
const errors = {};
if (!formData.firstname) {
errors.firstname = 'Firstname is required';
}
if (!formData.lastname) {
errors.lastname = 'Lastname is required';
}
if (!formData.email) {
errors.email = 'Email is required';
} else if (!/\S+@\S+\.\S+/.test(formData.email)) {
errors.email = 'Email is invalid';
}
if (!formData.message) {
errors.message = 'Message is required';
}
return errors;
};
@@ -1,7 +1,15 @@
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import react from '@vitejs/plugin-react';
import { defineConfig } from 'vite';
// https://vite.dev/config/
export default defineConfig({
plugins: [react()],
})
css: {
preprocessorOptions: {
scss: {
quietDeps: true, // Unix
silenceDeprecations: ['color-functions', 'global-builtin', 'import', 'legacy-js-api', 'if-function'],
},
},
},
});