Issues git resolved

This commit is contained in:
2026-04-20 19:29:21 +02:00
parent 16498f564d
commit 16764fc335
37 changed files with 2340 additions and 715 deletions

View File

@@ -0,0 +1,81 @@
import { useState } from 'react';
type ContactFormStatus = 'idle' | 'submitting' | 'success' | 'error';
type ContactApiResponse = {
ok?: boolean;
error?: string;
};
const DEFAULT_ERROR_MESSAGE = 'Unable to send your message right now. Please try again or email us directly.';
function getValue(formData: FormData, key: string) {
return String(formData.get(key) || '').trim();
}
export function useContactForm() {
const [status, setStatus] = useState<ContactFormStatus>('idle');
const [errorMessage, setErrorMessage] = useState('');
const resetFeedback = () => {
if (status === 'idle') {
return;
}
setStatus('idle');
setErrorMessage('');
};
const submitContactForm = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
if (status === 'submitting') {
return;
}
const form = event.currentTarget;
const formData = new FormData(form);
const payload = {
name: getValue(formData, 'name'),
email: getValue(formData, 'email'),
phone: getValue(formData, 'phone'),
company: getValue(formData, 'company'),
message: getValue(formData, 'message'),
website: getValue(formData, 'website'),
};
setStatus('submitting');
setErrorMessage('');
try {
const response = await fetch('/api/contact', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(payload),
});
const data = (await response.json().catch(() => null)) as ContactApiResponse | null;
if (!response.ok || !data?.ok) {
throw new Error(data?.error || DEFAULT_ERROR_MESSAGE);
}
form.reset();
setStatus('success');
} catch (error) {
setStatus('error');
setErrorMessage(error instanceof Error ? error.message : DEFAULT_ERROR_MESSAGE);
}
};
return {
status,
errorMessage,
isSubmitting: status === 'submitting',
isSubmitted: status === 'success',
hasError: status === 'error',
resetFeedback,
submitContactForm,
};
}