This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -8,6 +8,9 @@
|
|||||||
<title>React with Forms</title>
|
<title>React with Forms</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<noscript>
|
||||||
|
<p class="p-5">Die Seite benötigt JS.</p>
|
||||||
|
</noscript>
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
<script type="module" src="/src/main.jsx"></script>
|
<script type="module" src="/src/main.jsx"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,13 +1,26 @@
|
|||||||
import Navbar from './components/navs/Navbar.jsx';
|
import Navbar from './components/navs/Navbar';
|
||||||
import Router from './routes/Router.jsx';
|
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() {
|
function App() {
|
||||||
|
// const navigate = useNavigate();
|
||||||
|
|
||||||
|
// useEffect(() => {
|
||||||
|
// navigate('/contact');
|
||||||
|
// }, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
<HeaderMain />
|
||||||
<Navbar />
|
<Navbar />
|
||||||
|
<Navigate to="/contact" />
|
||||||
<main id="main">
|
<main id="main">
|
||||||
<Router />
|
<Router />
|
||||||
</main>
|
</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() {
|
function ContactPage() {
|
||||||
return (
|
return (
|
||||||
<div className="page-contact container py-5">
|
<div className="page-contact container py-5">
|
||||||
<h2>Kontakt</h2>
|
<h2>Kontakt</h2>
|
||||||
<p>Hast du Fragen? Schreib uns eine E-Mail:</p>
|
<p>
|
||||||
<a href="mailto:kontakt@example.com">kontakt@example.com</a>
|
Hast du Fragen? Schreib uns eine E-Mail:
|
||||||
|
<br />
|
||||||
|
<a href="mailto:kontakt@example.com">kontakt@example.com</a>
|
||||||
|
<br />
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
<FormContact />
|
||||||
</div>
|
</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/
|
// https://vite.dev/config/
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [react()],
|
plugins: [react()],
|
||||||
})
|
css: {
|
||||||
|
preprocessorOptions: {
|
||||||
|
scss: {
|
||||||
|
quietDeps: true, // Unix
|
||||||
|
silenceDeprecations: ['color-functions', 'global-builtin', 'import', 'legacy-js-api', 'if-function'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user