mirror of
http://88.130.71.182:3000/BlitTech/badoHair_fe.git
synced 2026-06-12 23:23:22 +00:00
142 lines
5.9 KiB
TypeScript
142 lines
5.9 KiB
TypeScript
"use client";
|
|
|
|
import { useState } from "react";
|
|
import { Calendar } from "@/components/ui/calendar";
|
|
import { Button } from "@/components/ui/button";
|
|
import { Input } from "@/components/ui/input";
|
|
import { Label } from "@/components/ui/label";
|
|
import { useLanguage } from "@/contexts/LanguageContext";
|
|
import { services, generateTimeSlots } from "@/data/services";
|
|
import { Check, Clock, CalendarDays } from "lucide-react";
|
|
import { toast } from "sonner";
|
|
|
|
export default function Booking () {
|
|
const { t } = useLanguage();
|
|
const [selectedService, setSelectedService] = useState<string>("");
|
|
const [selectedDate, setSelectedDate] = useState<Date | undefined>();
|
|
const [selectedTime, setSelectedTime] = useState<string>("");
|
|
const [name, setName] = useState("");
|
|
const [email, setEmail] = useState("");
|
|
const [phone, setPhone] = useState("");
|
|
|
|
const timeSlots = generateTimeSlots();
|
|
const step = !selectedService ? 1 : !selectedDate ? 2 : !selectedTime ? 3 : 4;
|
|
|
|
const handleConfirm = () => {
|
|
toast.success(`${services.find((s) => s.id === selectedService)?.name} le ${selectedDate?.toLocaleDateString("fr-FR")} à ${selectedTime}`);
|
|
};
|
|
|
|
return (
|
|
<div className="min-h-screen py-8 lg:py-16">
|
|
<div className="container mx-auto px-4 lg:px-8 max-w-4xl">
|
|
<div className="text-center mb-12">
|
|
<CalendarDays className="h-10 w-10 mx-auto mb-4 text-primary" />
|
|
<h1 className="font-serif text-3xl lg:text-5xl mb-3">{t("booking.title")}</h1>
|
|
<p className="text-muted-foreground">{t("booking.subtitle")}</p>
|
|
</div>
|
|
|
|
{/* Progress steps */}
|
|
<div className="flex justify-center gap-2 mb-10">
|
|
{[1, 2, 3, 4].map((s) => (
|
|
<div key={s} className={`h-1.5 w-12 rounded-full transition-colors ${s <= step ? "bg-primary" : "bg-muted"}`} />
|
|
))}
|
|
</div>
|
|
|
|
{/* Step 1: Service */}
|
|
<div className="mb-10">
|
|
<h2 className="font-serif text-xl mb-4">{t("booking.select_service")}</h2>
|
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-3">
|
|
{services.map((service) => (
|
|
<button
|
|
key={service.id}
|
|
onClick={() => setSelectedService(service.id)}
|
|
className={`text-left p-4 rounded-lg border-2 transition-all cursor-pointer ${
|
|
selectedService === service.id ? "border-primary" : "border-border hover:border-primary/40"
|
|
}`}
|
|
>
|
|
<div className="flex justify-between items-start">
|
|
<div>
|
|
<h3 className="font-medium text-sm">{service.name}</h3>
|
|
<p className="text-xs text-muted-foreground mt-1">{service.description}</p>
|
|
<div className="flex items-center gap-1 mt-2 text-xs text-muted-foreground">
|
|
<Clock className="h-3 w-3" />
|
|
{service.duration}
|
|
</div>
|
|
</div>
|
|
<span className="text-sm font-semibold">
|
|
{service.price === 0 ? t("booking.free") : `${service.price} €`}
|
|
</span>
|
|
</div>
|
|
{selectedService === service.id && <Check className="h-4 w-4 text-primary mt-2" />}
|
|
</button>
|
|
))}
|
|
</div>
|
|
</div>
|
|
|
|
{/* Step 2: Date */}
|
|
{selectedService && (
|
|
<div className="mb-10">
|
|
<h2 className="font-serif text-xl mb-4">{t("booking.select_date")}</h2>
|
|
<div className="flex justify-center">
|
|
<Calendar
|
|
mode="single"
|
|
selected={selectedDate}
|
|
onSelect={setSelectedDate}
|
|
disabled={(date) => date < new Date() || date.getDay() === 0}
|
|
className="rounded-lg border border-border p-4"
|
|
/>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{/* Step 3: Time */}
|
|
{selectedDate && (
|
|
<div className="mb-10">
|
|
<h2 className="font-serif text-xl mb-4">{t("booking.select_time")}</h2>
|
|
<div className="grid grid-cols-4 md:grid-cols-7 gap-2">
|
|
{timeSlots.map((slot) => (
|
|
<button
|
|
key={slot.time}
|
|
onClick={() => slot.available && setSelectedTime(slot.time)}
|
|
disabled={!slot.available}
|
|
className={`py-2 px-3 rounded-md text-sm transition-colors cursor-pointer ${
|
|
selectedTime === slot.time
|
|
? "bg-primary text-primary-foreground"
|
|
: slot.available
|
|
? "bg-muted text-foreground hover:bg-accent"
|
|
: "bg-muted/50 text-muted-foreground/30 cursor-not-allowed"
|
|
}`}
|
|
>
|
|
{slot.time}
|
|
</button>
|
|
))}
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{/* Step 4: Contact info */}
|
|
{selectedTime && (
|
|
<div className="max-w-md mx-auto space-y-4">
|
|
<h2 className="font-serif text-xl mb-4 text-center">{t("booking.confirm")}</h2>
|
|
<div>
|
|
<Label htmlFor="name">{t("auth.name")}</Label>
|
|
<Input id="name" value={name} onChange={(e) => setName(e.target.value)} className="mt-1" />
|
|
</div>
|
|
<div>
|
|
<Label htmlFor="email">{t("auth.email")}</Label>
|
|
<Input id="email" type="email" value={email} onChange={(e) => setEmail(e.target.value)} className="mt-1" />
|
|
</div>
|
|
<div>
|
|
<Label htmlFor="phone">{t("booking.phone")}</Label>
|
|
<Input id="phone" type="tel" value={phone} onChange={(e) => setPhone(e.target.value)} className="mt-1" />
|
|
</div>
|
|
<Button className="w-full" size="lg" onClick={handleConfirm} disabled={!name || !email || !phone}>
|
|
{t("booking.confirm")}
|
|
</Button>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|