// rdv.jsx — Page Rendez-vous 2C ITECH
const { useState: useStateR, useEffect: useEffectR, useMemo: useMemoR } = React;
const PRIX_DIAG = 49;
function RdvPage() {
return (
<>
>
);
}
function BookingFlow({ prixDiag }) {
const params = new URLSearchParams(location.search);
const presetBesoin = params.get("besoin") || "";
const [step, setStep] = useStateR(1);
const [besoin, setBesoin] = useStateR(presetBesoin);
const [date, setDate] = useStateR(null);
const [slot, setSlot] = useStateR(null);
const [priority, setPriority] = useStateR(false);
const [info, setInfo] = useStateR({ nom: "", email: "", telephone: "", message: "" });
const [confirmed, setConfirmed] = useStateR(false);
const [submitting, setSubmitting] = useStateR(false);
const needsPayment = priority && !["depannage", "installation", "autre"].includes(besoin);
const submit = async (e) => {
e?.preventDefault();
setSubmitting(true);
try {
await fetch("/api/rdv", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
nom: info.nom,
email: info.email,
telephone: info.telephone,
message: info.message,
besoin,
date: date ? date.toISOString().split("T")[0] : null,
heure: slot,
prioritaire: priority,
}),
});
} catch (err) {
console.error("RDV submit error", err);
}
setSubmitting(false);
setConfirmed(true);
window.scrollTo({ top: 0, behavior: "smooth" });
};
if (confirmed) return ;
return (
Prise de rendez-vous
Choisissez votre créneau —
30 min, sans engagement.
1} onClick={() => setStep(1)} />
2} onClick={() => step > 1 && setStep(2)} />
step > 2 && setStep(3)} />
{step === 1 && setStep(2)} />}
{step === 2 && setStep(3)} prixDiag={prixDiag} />}
{step === 3 && }
);
}
function Step({ n, label, active, done, onClick }) {
return (
);
}
function StepBesoin({ besoin, setBesoin, onNext }) {
const opts = [
{ v: "facturation", t: "Facturation électronique 2026", d: "Diagnostic + plan de mise en conformité", icon: "📋", featured: true },
{ v: "ia", t: "Automatisation / IA", d: "Gagner du temps sur devis, factures, emails", icon: "⚡", featured: true },
{ v: "depannage", t: "Dépannage informatique", d: "PC, imprimante, réseau, virus, lenteurs", icon: "🔧" },
{ v: "maintenance", t: "Maintenance / abonnement", d: "Support illimité, sauvegarde, surveillance", icon: "🛡" },
{ v: "installation", t: "Installation matériel/logiciel", d: "Nouveau PC, NAS, suite Microsoft 365", icon: "📦" },
{ v: "autre", t: "Autre besoin", d: "Décrivez-nous votre situation", icon: "?" },
];
return (
<>
1. Quel est votre besoin ?
Pour préparer le rendez-vous au plus juste.
{opts.map(o => (
))}
>
);
}
const TZ_HOURS = ["10:00", "11:30", "14:00", "15:30", "17:00"];
function getNextDays(count = 8) {
const days = [];
let d = new Date();
d.setHours(0, 0, 0, 0);
while (days.length < count) {
d.setDate(d.getDate() + 1);
const day = d.getDay();
if (day === 2 || day === 3 || day === 4) days.push(new Date(d));
}
return days;
}
function remainingForDay(d) {
const seed = d.getDate() + d.getMonth();
return ((seed * 7) % 5) + 1;
}
function takenForDay(d) {
const seed = (d.getDate() * 13 + d.getMonth() * 7) % 5;
const idxs = [seed, (seed + 2) % 5];
return idxs.slice(0, 5 - remainingForDay(d));
}
function formatDateLong(d) { return d.toLocaleDateString("fr-FR", { weekday: "long", day: "numeric", month: "long" }); }
function StepSlot({ date, setDate, slot, setSlot, priority, setPriority, besoin, onNext, prixDiag }) {
const days = useMemoR(() => getNextDays(8), []);
const canPay = !["depannage", "installation", "autre"].includes(besoin);
return (
<>
2. Choisissez votre créneau
5 créneaux par jour — mardi, mercredi, jeudi.
{days.map((d, i) => {
const remaining = remainingForDay(d);
const sel = date && date.toDateString() === d.toDateString();
return (
);
})}
{date && (
{formatDateLong(date)}
{remainingForDay(date)} créneaux disponibles
{TZ_HOURS.map((h, i) => {
const taken = takenForDay(date).includes(i);
const sel = slot === h;
return (
);
})}
)}
{canPay && (
)}
>
);
}
function StepInfo({ info, setInfo, onSubmit, needsPayment, prixDiag, submitting }) {
return (
);
}
function ConfirmedScreen({ besoin, date, slot, info, priority }) {
return (
✓
C'est confirmé,
{info.nom?.split(" ")[0] || "merci"}.
Vous recevrez un email de confirmation sur {info.email} dans les minutes qui viennent.
Date{date && formatDateLong(date)}
Heure{slot}
Type{labelBesoin(besoin)}
Format{priority ? "Prioritaire 24h" : "Standard"}
LieuVisio + numéro envoyé par mail
);
}
function labelBesoin(b) {
return ({ facturation: "Facturation 2026", ia: "Automatisation / IA", depannage: "Dépannage", maintenance: "Maintenance / abonnement", installation: "Installation", autre: "Autre", conformite: "Pack Conformité", diagnostic: "Diagnostic Express", assistance: "Assistance à distance", sauvegarde: "Sauvegarde" })[b] || "";
}
Object.assign(window, { RdvPage });