82 lines
2.0 KiB
TypeScript
82 lines
2.0 KiB
TypeScript
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,
|
|
};
|
|
}
|