first commit

This commit is contained in:
Michaël
2026-01-29 14:13:11 -03:00
commit 2302748c87
105 changed files with 93301 additions and 0 deletions

View File

@@ -0,0 +1,158 @@
'use client';
import { useState } from 'react';
import { useLanguage } from '@/context/LanguageContext';
import { contactsApi } from '@/lib/api';
import Card from '@/components/ui/Card';
import Button from '@/components/ui/Button';
import Input from '@/components/ui/Input';
import { ChatBubbleLeftRightIcon } from '@heroicons/react/24/outline';
import { getSocialLinks, socialIcons, socialConfig } from '@/lib/socialLinks';
import toast from 'react-hot-toast';
export default function ContactPage() {
const { t } = useLanguage();
const [loading, setLoading] = useState(false);
const [formData, setFormData] = useState({
name: '',
email: '',
message: '',
});
const socialLinks = getSocialLinks();
const emailLink = socialLinks.find(l => l.type === 'email');
const otherLinks = socialLinks.filter(l => l.type !== 'email');
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setLoading(true);
try {
await contactsApi.submit(formData);
toast.success(t('contact.success'));
setFormData({ name: '', email: '', message: '' });
} catch (error) {
toast.error(t('contact.error'));
} finally {
setLoading(false);
}
};
return (
<div className="section-padding">
<div className="container-page">
<div className="text-center max-w-2xl mx-auto">
<h1 className="section-title">{t('contact.title')}</h1>
<p className="section-subtitle">{t('contact.subtitle')}</p>
</div>
<div className="mt-16 grid grid-cols-1 lg:grid-cols-2 gap-12 max-w-5xl mx-auto">
{/* Contact Form */}
<Card className="p-8">
<form onSubmit={handleSubmit} className="space-y-6">
<Input
id="name"
label={t('contact.form.name')}
value={formData.name}
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
required
/>
<Input
id="email"
label={t('contact.form.email')}
type="email"
value={formData.email}
onChange={(e) => setFormData({ ...formData, email: e.target.value })}
required
/>
<div>
<label
htmlFor="message"
className="block text-sm font-medium text-primary-dark mb-1.5"
>
{t('contact.form.message')}
</label>
<textarea
id="message"
rows={5}
value={formData.message}
onChange={(e) => setFormData({ ...formData, message: e.target.value })}
className="w-full px-4 py-3 rounded-btn border border-secondary-light-gray transition-colors duration-200 focus:outline-none focus:ring-2 focus:ring-primary-yellow focus:border-transparent placeholder:text-gray-400 resize-none"
required
minLength={10}
/>
</div>
<Button type="submit" className="w-full" size="lg" isLoading={loading}>
{t('contact.form.submit')}
</Button>
</form>
</Card>
{/* Contact Info */}
<div className="space-y-6">
{/* Email Card */}
{emailLink && (
<Card className="p-6">
<div className="flex items-start gap-4">
<div className="w-12 h-12 bg-primary-yellow/20 rounded-full flex items-center justify-center flex-shrink-0">
{socialIcons.email}
</div>
<div>
<h3 className="font-semibold text-lg">{t('contact.info.email')}</h3>
<a
href={emailLink.url}
className="text-secondary-blue hover:underline"
>
{emailLink.handle}
</a>
</div>
</div>
</Card>
)}
{/* Social Links Card */}
{otherLinks.length > 0 && (
<Card className="p-6">
<div className="flex items-start gap-4">
<div className="w-12 h-12 bg-primary-yellow/20 rounded-full flex items-center justify-center flex-shrink-0">
<ChatBubbleLeftRightIcon className="w-6 h-6 text-primary-dark" />
</div>
<div className="flex-1">
<h3 className="font-semibold text-lg">{t('contact.info.social')}</h3>
<div className="mt-3 space-y-3">
{otherLinks.map((link) => (
<a
key={link.type}
href={link.url}
target="_blank"
rel="noopener noreferrer"
className="flex items-center gap-3 text-secondary-blue hover:text-primary-dark transition-colors group"
>
<span className="w-8 h-8 flex items-center justify-center rounded-full bg-gray-100 group-hover:bg-primary-yellow/20 transition-colors">
{socialIcons[link.type]}
</span>
<span className="hover:underline">{link.handle || link.label}</span>
</a>
))}
</div>
</div>
</div>
</Card>
)}
{/* Map placeholder */}
<Card className="h-64 bg-gradient-to-br from-secondary-gray to-secondary-light-gray flex items-center justify-center">
<div className="text-center text-gray-400">
<div className="text-4xl mb-2">📍</div>
<p>Asunción, Paraguay</p>
</div>
</Card>
</div>
</div>
</div>
</div>
);
}