React/Vite/shadcn-ui site for Gigafibre ISP. Address qualification via PostgreSQL (5.2M AQ addresses, pg_trgm fuzzy search). No Supabase dependency for address search. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
203 lines
6.8 KiB
TypeScript
203 lines
6.8 KiB
TypeScript
import { Phone, Mail, MapPin, Clock, Send } from "lucide-react";
|
||
import { Button } from "@/components/ui/button";
|
||
import { Input } from "@/components/ui/input";
|
||
import { Textarea } from "@/components/ui/textarea";
|
||
import { useState } from "react";
|
||
import { useToast } from "@/hooks/use-toast";
|
||
|
||
const contactInfo = [
|
||
{
|
||
icon: Phone,
|
||
label: "Téléphone",
|
||
value: "1-855-88-TARGO",
|
||
subValue: "514-448-0773",
|
||
},
|
||
{
|
||
icon: Mail,
|
||
label: "Courriel",
|
||
value: "support@targo.ca",
|
||
},
|
||
{
|
||
icon: MapPin,
|
||
label: "Adresse",
|
||
value: "1867 chemin de la rivière",
|
||
subValue: "Ste-Clotilde, Québec J0L 1W0",
|
||
},
|
||
{
|
||
icon: Clock,
|
||
label: "Heures d'ouverture",
|
||
value: "Lun-Ven: 8h00 – 20h00",
|
||
subValue: "Sam-Dim: 8h00 – 16h00",
|
||
},
|
||
];
|
||
|
||
const Contact = () => {
|
||
const { toast } = useToast();
|
||
const [formData, setFormData] = useState({
|
||
name: "",
|
||
address: "",
|
||
postalCode: "",
|
||
email: "",
|
||
phone: "",
|
||
message: "",
|
||
});
|
||
|
||
const handleSubmit = (e: React.FormEvent) => {
|
||
e.preventDefault();
|
||
toast({
|
||
title: "Message envoyé!",
|
||
description: "Nous vous répondrons dans les plus brefs délais.",
|
||
});
|
||
setFormData({
|
||
name: "",
|
||
address: "",
|
||
postalCode: "",
|
||
email: "",
|
||
phone: "",
|
||
message: "",
|
||
});
|
||
};
|
||
|
||
const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
|
||
setFormData((prev) => ({
|
||
...prev,
|
||
[e.target.name]: e.target.value,
|
||
}));
|
||
};
|
||
|
||
return (
|
||
<section id="contact" className="py-20 md:py-32 bg-secondary/30">
|
||
<div className="container">
|
||
<div className="text-center max-w-2xl mx-auto mb-16">
|
||
<span className="inline-block px-4 py-1 bg-primary/10 rounded-full text-primary font-medium text-sm mb-4">
|
||
Contactez-nous
|
||
</span>
|
||
<h2 className="font-display text-4xl md:text-5xl font-bold mb-4">
|
||
On aime <span className="text-gradient-targo">aider</span>
|
||
</h2>
|
||
<p className="text-muted-foreground text-lg">
|
||
Nous vous invitons à nous contacter pour bien évaluer votre situation
|
||
et vous faire profiter des meilleurs forfaits.
|
||
</p>
|
||
</div>
|
||
|
||
<div className="grid lg:grid-cols-5 gap-12">
|
||
{/* Contact form */}
|
||
<div className="lg:col-span-3">
|
||
<form onSubmit={handleSubmit} className="bg-card rounded-3xl p-8 shadow-lg border border-border">
|
||
<div className="grid sm:grid-cols-2 gap-6 mb-6">
|
||
<div className="space-y-2">
|
||
<label htmlFor="name" className="text-sm font-medium">Nom</label>
|
||
<Input
|
||
id="name"
|
||
name="name"
|
||
placeholder="Votre nom"
|
||
value={formData.name}
|
||
onChange={handleChange}
|
||
required
|
||
/>
|
||
</div>
|
||
<div className="space-y-2">
|
||
<label htmlFor="email" className="text-sm font-medium">Courriel</label>
|
||
<Input
|
||
id="email"
|
||
name="email"
|
||
type="email"
|
||
placeholder="votre@courriel.com"
|
||
value={formData.email}
|
||
onChange={handleChange}
|
||
required
|
||
/>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="grid sm:grid-cols-2 gap-6 mb-6">
|
||
<div className="space-y-2">
|
||
<label htmlFor="address" className="text-sm font-medium">Adresse (où le service est livré)</label>
|
||
<Input
|
||
id="address"
|
||
name="address"
|
||
placeholder="123 rue Principale"
|
||
value={formData.address}
|
||
onChange={handleChange}
|
||
required
|
||
/>
|
||
</div>
|
||
<div className="space-y-2">
|
||
<label htmlFor="postalCode" className="text-sm font-medium">Code postal</label>
|
||
<Input
|
||
id="postalCode"
|
||
name="postalCode"
|
||
placeholder="J0L 1W0"
|
||
value={formData.postalCode}
|
||
onChange={handleChange}
|
||
required
|
||
/>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="space-y-2 mb-6">
|
||
<label htmlFor="phone" className="text-sm font-medium">Téléphone</label>
|
||
<Input
|
||
id="phone"
|
||
name="phone"
|
||
type="tel"
|
||
placeholder="514-000-0000"
|
||
value={formData.phone}
|
||
onChange={handleChange}
|
||
/>
|
||
</div>
|
||
|
||
<div className="space-y-2 mb-6">
|
||
<label htmlFor="message" className="text-sm font-medium">Message</label>
|
||
<Textarea
|
||
id="message"
|
||
name="message"
|
||
placeholder="Comment pouvons-nous vous aider?"
|
||
rows={4}
|
||
value={formData.message}
|
||
onChange={handleChange}
|
||
required
|
||
/>
|
||
</div>
|
||
|
||
<Button type="submit" size="lg" className="w-full gradient-targo">
|
||
<Send className="w-5 h-5 mr-2" />
|
||
Envoyer
|
||
</Button>
|
||
</form>
|
||
</div>
|
||
|
||
{/* Contact info */}
|
||
<div className="lg:col-span-2 space-y-6">
|
||
{contactInfo.map((item) => (
|
||
<div key={item.label} className="flex gap-4 p-4 bg-card rounded-2xl border border-border">
|
||
<div className="w-12 h-12 rounded-xl gradient-targo flex items-center justify-center flex-shrink-0">
|
||
<item.icon className="w-6 h-6 text-primary-foreground" />
|
||
</div>
|
||
<div>
|
||
<div className="text-sm text-muted-foreground mb-1">{item.label}</div>
|
||
<div className="font-medium">{item.value}</div>
|
||
{item.subValue && (
|
||
<div className="text-sm text-muted-foreground">{item.subValue}</div>
|
||
)}
|
||
</div>
|
||
</div>
|
||
))}
|
||
|
||
<div className="p-6 bg-primary/10 rounded-2xl">
|
||
<div className="font-display font-semibold mb-2">Surveillance 24/7/365</div>
|
||
<p className="text-sm text-muted-foreground">
|
||
Notre équipe surveille le réseau et répond aux urgences 24 heures sur 24,
|
||
7 jours sur 7, toute l'année.
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
);
|
||
};
|
||
|
||
export default Contact;
|