import React, { useState } from 'react'; import { Send, AlertCircle } from 'lucide-react'; import { getCsrfToken } from '../utils/csrf'; import { rateLimiter } from '../utils/rateLimiting'; interface ContactFormProps { onSubmit: (data: FormData) => Promise; } const ContactForm: React.FC = ({ onSubmit }) => { const [name, setName] = useState(''); const [email, setEmail] = useState(''); const [message, setMessage] = useState(''); const [error, setError] = useState(null); const [success, setSuccess] = useState(false); const [loading, setLoading] = useState(false); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); setError(null); setLoading(true); try { // Check rate limiting const clientIp = '127.0.0.1'; // In production, get this from the request if (rateLimiter.isRateLimited(clientIp)) { const timeToReset = Math.ceil(rateLimiter.getTimeToReset(clientIp) / 1000 / 60); throw new Error(`Too many attempts. Please try again in ${timeToReset} minutes.`); } // Validate CSRF token const formData = new FormData(); formData.append('name', name); formData.append('email', email); formData.append('message', message); formData.append('csrf_token', getCsrfToken()); await onSubmit(formData); setSuccess(true); setName(''); setEmail(''); setMessage(''); } catch (err) { setError(err instanceof Error ? err.message : 'An error occurred'); } finally { setLoading(false); } }; return (
{error && (
{error}
)} {success && (
Message sent successfully!
)}
setName(e.target.value)} className="w-full bg-gray-900/50 border border-white/10 rounded-lg px-4 py-3 text-white placeholder-white/40 focus:outline-none focus:ring-2 focus:ring-orange-500" required />
setEmail(e.target.value)} className="w-full bg-gray-900/50 border border-white/10 rounded-lg px-4 py-3 text-white placeholder-white/40 focus:outline-none focus:ring-2 focus:ring-orange-500" required />
); }; export default ContactForm;