This commit is contained in:
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'],
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user