130 lines
6.7 KiB
TypeScript
130 lines
6.7 KiB
TypeScript
import React, { useState } from 'react';
|
|
import { Link } from 'react-router-dom';
|
|
import { motion } from 'framer-motion';
|
|
import { Mail, Phone, MapPin, Send, CheckCircle } from 'lucide-react';
|
|
|
|
const Contact = () => {
|
|
const [submitted, setSubmitted] = useState(false);
|
|
const [loading, setLoading] = useState(false);
|
|
|
|
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
|
|
e.preventDefault();
|
|
setLoading(true);
|
|
const formData = new FormData(e.currentTarget);
|
|
const data = Object.fromEntries(formData.entries());
|
|
|
|
try {
|
|
const response = await fetch('/api/contact', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(data),
|
|
});
|
|
if (response.ok) {
|
|
setSubmitted(true);
|
|
} else {
|
|
const err = await response.json();
|
|
alert(`Fehler: ${err.error || 'Es gab einen Fehler beim Senden Ihrer Nachricht.'}`);
|
|
}
|
|
} catch (error) {
|
|
alert('Es gab einen Fehler beim Senden Ihrer Nachricht.');
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className="container">
|
|
<section>
|
|
<div className="grid contact-grid" style={{ gridTemplateColumns: 'repeat(auto-fit, minmax(400px, 1fr))', gap: '4rem' }}>
|
|
<motion.div
|
|
initial={{ opacity: 0, y: 20 }}
|
|
animate={{ opacity: 1, y: 0 }}
|
|
>
|
|
<h1>Kontakt</h1>
|
|
<p style={{ fontSize: '1.1rem', color: 'var(--text-secondary)', marginBottom: '3rem' }}>
|
|
Haben Sie Fragen zu einem Projekt oder benötigen Sie technische Beratung? Wir freuen uns auf Ihre Nachricht.
|
|
</p>
|
|
|
|
<div style={{ display: 'flex', flexDirection: 'column', gap: '2rem' }}>
|
|
<div className="contact-info-item" style={{ display: 'flex', gap: '1.5rem', alignItems: 'flex-start' }}>
|
|
<div style={{ color: 'var(--accent-green)', background: 'white', padding: '1rem', border: '1px solid var(--secondary-bg)' }}><Mail size={24} /></div>
|
|
<div>
|
|
<h4 style={{ marginBottom: '0.25rem', fontSize: '1rem' }}>E-Mail</h4>
|
|
<a href="mailto:info@mb-grid-solutions.com" style={{ fontSize: '1.1rem', fontWeight: 500 }}>info@mb-grid-solutions.com</a>
|
|
</div>
|
|
</div>
|
|
<div className="contact-info-item" style={{ display: 'flex', gap: '1.5rem', alignItems: 'flex-start' }}>
|
|
<div style={{ color: 'var(--accent-green)', background: 'white', padding: '1rem', border: '1px solid var(--secondary-bg)' }}><Phone size={24} /></div>
|
|
<div>
|
|
<h4 style={{ marginBottom: '0.25rem', fontSize: '1rem' }}>Telefon</h4>
|
|
<a href="tel:+49123456789" style={{ fontSize: '1.1rem', fontWeight: 500 }}>+49 (0) 123 456789</a>
|
|
</div>
|
|
</div>
|
|
<div className="contact-info-item" style={{ display: 'flex', gap: '1.5rem', alignItems: 'flex-start' }}>
|
|
<div style={{ color: 'var(--accent-green)', background: 'white', padding: '1rem', border: '1px solid var(--secondary-bg)' }}><MapPin size={24} /></div>
|
|
<div>
|
|
<h4 style={{ marginBottom: '0.25rem', fontSize: '1rem' }}>Anschrift</h4>
|
|
<p style={{ fontSize: '1.1rem', fontWeight: 500, color: 'var(--primary-color)' }}>
|
|
MB Grid Solutions GmbH<br />
|
|
Raiffeisenstraße 22<br />
|
|
73630 Remshalden
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</motion.div>
|
|
|
|
<motion.div
|
|
initial={{ opacity: 0, y: 20 }}
|
|
animate={{ opacity: 1, y: 0 }}
|
|
transition={{ delay: 0.2 }}
|
|
className="card"
|
|
>
|
|
{submitted ? (
|
|
<div style={{ textAlign: 'center', padding: '3rem 0' }}>
|
|
<div style={{ color: 'var(--accent-green)', marginBottom: '1.5rem' }}><CheckCircle size={64} /></div>
|
|
<h3>Nachricht gesendet</h3>
|
|
<p style={{ color: 'var(--text-secondary)' }}>Vielen Dank für Ihre Anfrage. Wir werden uns in Kürze bei Ihnen melden.</p>
|
|
<button onClick={() => setSubmitted(false)} className="cta-button" style={{ marginTop: '2rem' }}>Weitere Nachricht</button>
|
|
</div>
|
|
) : (
|
|
<form onSubmit={handleSubmit} style={{ display: 'flex', flexDirection: 'column' }}>
|
|
<div className="grid contact-form-grid" style={{ gridTemplateColumns: '1fr 1fr', gap: '1rem' }}>
|
|
<div>
|
|
<label htmlFor="name" style={{ display: 'block', marginBottom: '0.5rem', fontSize: '0.9rem', fontWeight: 600 }}>Name *</label>
|
|
<input type="text" id="name" name="name" required minLength={2} maxLength={100} placeholder="Ihr Name" />
|
|
</div>
|
|
<div>
|
|
<label htmlFor="company" style={{ display: 'block', marginBottom: '0.5rem', fontSize: '0.9rem', fontWeight: 600 }}>Firma</label>
|
|
<input type="text" id="company" name="company" placeholder="Ihr Unternehmen" />
|
|
</div>
|
|
</div>
|
|
|
|
<label htmlFor="email" style={{ display: 'block', marginBottom: '0.5rem', fontSize: '0.9rem', fontWeight: 600 }}>E-Mail *</label>
|
|
<input type="email" id="email" name="email" required placeholder="ihre@email.de" />
|
|
|
|
<label htmlFor="message" style={{ display: 'block', marginBottom: '0.5rem', fontSize: '0.9rem', fontWeight: 600 }}>Nachricht *</label>
|
|
<textarea id="message" name="message" required minLength={20} maxLength={4000} rows={6} placeholder="Wie können wir Ihnen helfen?"></textarea>
|
|
|
|
<div className="visually-hidden">
|
|
<label htmlFor="website">Website (bitte leer lassen)</label>
|
|
<input type="text" id="website" name="website" tabIndex={-1} autoComplete="off" />
|
|
</div>
|
|
|
|
<button type="submit" disabled={loading} className="cta-button" style={{ alignSelf: 'flex-start' }}>
|
|
{loading ? 'Wird gesendet...' : 'Nachricht senden'} <Send size={18} />
|
|
</button>
|
|
<p style={{ fontSize: '0.75rem', marginTop: '1.5rem', color: 'var(--text-secondary)', lineHeight: 1.4 }}>
|
|
* Pflichtfelder. Mit dem Absenden erklären Sie sich mit unserer <Link to="/datenschutz" style={{ textDecoration: 'underline' }}>Datenschutzerklärung</Link> einverstanden.
|
|
</p>
|
|
</form>
|
|
)}
|
|
</motion.div>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default Contact;
|