202 lines
6.2 KiB
TypeScript
202 lines
6.2 KiB
TypeScript
'use client';
|
|
|
|
import { Button } from '@/components/ui/Button';
|
|
import { Checkbox } from '@/components/ui/Checkbox';
|
|
import { Heading, Label, Text } from '@/components/ui/Typography';
|
|
import { useState } from 'react';
|
|
|
|
interface ContactFormProps {
|
|
title?: string;
|
|
subtitle?: string;
|
|
}
|
|
|
|
export function ContactForm({ title = 'Kontaktiraj nas', subtitle = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.' }: ContactFormProps) {
|
|
// Form state
|
|
const [formData, setFormData] = useState({
|
|
name: '',
|
|
email: '',
|
|
message: '',
|
|
acceptTerms: false
|
|
});
|
|
|
|
// Validation errors
|
|
const [errors, setErrors] = useState<Record<string, string>>({});
|
|
|
|
// Form submission status
|
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
const [isSubmitted, setIsSubmitted] = useState(false);
|
|
|
|
// Handle input changes
|
|
const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
|
|
const { name, value, type } = e.target;
|
|
|
|
// Handle checkbox
|
|
if (type === 'checkbox') {
|
|
const checked = (e.target as HTMLInputElement).checked;
|
|
setFormData(prev => ({ ...prev, [name]: checked }));
|
|
} else {
|
|
setFormData(prev => ({ ...prev, [name]: value }));
|
|
}
|
|
|
|
// Clear error when user starts typing
|
|
if (errors[name]) {
|
|
setErrors(prev => {
|
|
const newErrors = { ...prev };
|
|
delete newErrors[name];
|
|
return newErrors;
|
|
});
|
|
}
|
|
};
|
|
|
|
// Handle checkbox change specifically
|
|
const handleCheckboxChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
const { name, checked } = e.target;
|
|
setFormData(prev => ({ ...prev, [name]: checked }));
|
|
|
|
// Clear error when user changes checkbox
|
|
if (errors[name]) {
|
|
setErrors(prev => {
|
|
const newErrors = { ...prev };
|
|
delete newErrors[name];
|
|
return newErrors;
|
|
});
|
|
}
|
|
};
|
|
|
|
// Validate form
|
|
const validateForm = () => {
|
|
const newErrors: Record<string, string> = {};
|
|
|
|
// Name validation
|
|
if (!formData.name.trim()) {
|
|
newErrors.name = 'Molimo unesite vaše ime i prezime';
|
|
}
|
|
|
|
// Email validation
|
|
if (!formData.email.trim()) {
|
|
newErrors.email = 'Molimo unesite vašu email adresu';
|
|
} else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(formData.email)) {
|
|
newErrors.email = 'Molimo unesite ispravnu email adresu';
|
|
}
|
|
|
|
// Message validation
|
|
if (!formData.message.trim()) {
|
|
newErrors.message = 'Molimo unesite vašu poruku';
|
|
} else if (formData.message.trim().length < 10) {
|
|
newErrors.message = 'Vaša poruka mora sadržavati barem 10 znakova';
|
|
}
|
|
|
|
// Terms validation
|
|
if (!formData.acceptTerms) {
|
|
newErrors.acceptTerms = 'Molimo prihvatite uvjete korištenja';
|
|
}
|
|
|
|
setErrors(newErrors);
|
|
return Object.keys(newErrors).length === 0;
|
|
};
|
|
|
|
// Handle form submission
|
|
const handleSubmit = (e: React.FormEvent) => {
|
|
e.preventDefault();
|
|
|
|
if (validateForm()) {
|
|
setIsSubmitting(true);
|
|
|
|
// Simulate API call
|
|
setTimeout(() => {
|
|
setIsSubmitting(false);
|
|
setIsSubmitted(true);
|
|
|
|
// Reset form after submission
|
|
setFormData({
|
|
name: '',
|
|
email: '',
|
|
message: '',
|
|
acceptTerms: false
|
|
});
|
|
|
|
// Hide success message after 5 seconds
|
|
setTimeout(() => {
|
|
setIsSubmitted(false);
|
|
}, 5000);
|
|
}, 1000);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div>
|
|
<Heading level={2} className="mb-4">{title}</Heading>
|
|
<Text size="lg" className="mb-8">{subtitle}</Text>
|
|
|
|
{isSubmitted ? (
|
|
<div className="p-4 bg-green-50 border border-green-200 rounded-md mb-6">
|
|
<Text className="text-green-700 font-medium">Vaša poruka je uspješno poslana!</Text>
|
|
<Text className="text-green-600">Hvala vam na vašem upitu. Odgovorit ćemo vam u najkraćem mogućem roku.</Text>
|
|
</div>
|
|
) : null}
|
|
|
|
<form className="space-y-6" onSubmit={handleSubmit}>
|
|
<div>
|
|
<Label htmlFor="name" className="block mb-2 text-[16px] leading-[24px]">Ime i Prezime</Label>
|
|
<input
|
|
type="text"
|
|
id="name"
|
|
name="name"
|
|
value={formData.name}
|
|
onChange={handleChange}
|
|
className={`w-full p-3 border ${errors.name ? 'border-red-500' : 'border-gray-300'} rounded`}
|
|
/>
|
|
{errors.name && <Text size="sm" className="mt-1 text-red-500">{errors.name}</Text>}
|
|
</div>
|
|
|
|
<div>
|
|
<Label htmlFor="email" className="block mb-2 text-[16px] leading-[24px]">Email</Label>
|
|
<input
|
|
type="email"
|
|
id="email"
|
|
name="email"
|
|
value={formData.email}
|
|
onChange={handleChange}
|
|
className={`w-full p-3 border ${errors.email ? 'border-red-500' : 'border-gray-300'} rounded`}
|
|
/>
|
|
{errors.email && <Text size="sm" className="mt-1 text-red-500">{errors.email}</Text>}
|
|
</div>
|
|
|
|
<div>
|
|
<Label htmlFor="message" className="block mb-2 text-[16px] leading-[24px]">Poruka</Label>
|
|
<textarea
|
|
id="message"
|
|
name="message"
|
|
value={formData.message}
|
|
onChange={handleChange}
|
|
rows={5}
|
|
className={`w-full p-3 border ${errors.message ? 'border-red-500' : 'border-gray-300'} rounded`}
|
|
placeholder="Upišite vašu poruku..."
|
|
/>
|
|
{errors.message && <Text size="sm" className="mt-1 text-red-500">{errors.message}</Text>}
|
|
</div>
|
|
|
|
<div>
|
|
<Checkbox
|
|
id="acceptTerms"
|
|
name="acceptTerms"
|
|
checked={formData.acceptTerms}
|
|
onChange={handleCheckboxChange}
|
|
label="Prihvaćam uvjete korištenja"
|
|
className={errors.acceptTerms ? "ring-2 ring-red-500 rounded-sm" : ""}
|
|
/>
|
|
{errors.acceptTerms && <Text size="sm" className="mt-1 text-red-500">{errors.acceptTerms}</Text>}
|
|
</div>
|
|
|
|
<Button
|
|
type="submit"
|
|
variant="primary"
|
|
className="px-8 py-3 bg-black text-white"
|
|
disabled={isSubmitting}
|
|
>
|
|
{isSubmitting ? 'Slanje...' : 'Pošalji'}
|
|
</Button>
|
|
</form>
|
|
</div>
|
|
);
|
|
}
|