/* QUITOS — UI mockups */
const { useState, useEffect, useRef } = React;
/* ---------- Relance list — QUITOS Quote ---------- */
const RELANCE_ROWS = [
{ name: 'ACME SAS', ref: 'DEV-047', amount: '8 400 €', when: 'Envoyé il y a 3j' },
{ name: 'Tech Pulse', ref: 'DEV-048', amount: '3 200 €', when: 'Envoyé il y a 6j' },
{ name: 'Studio Kalon', ref: 'DEV-051', amount: '12 800 €', when: 'Envoyé il y a 1j' },
];
const STATUS_CYCLE = [
{ key: 'sent', label: 'Envoyée', color: '#A0A0A0' },
{ key: 'opened', label: 'Ouverte', color: '#E8892A' },
{ key: 'replied', label: 'Répondue', color: '#2D6A4F' },
];
function RelanceMockup() {
const [tick, setTick] = useState(0);
const notifRef = useRef(null);
/* Status cycling — each row has a different starting offset so they don't change simultaneously */
useEffect(() => {
const id = setInterval(() => setTick((t) => t + 1), 2500);
return () => clearInterval(id);
}, []);
/* Floating notification — GSAP pop-in with scale */
useEffect(() => {
const el = notifRef.current;
if (!el || !window.gsap) return;
gsap.set(el, { opacity: 0, y: 16, scale: 0.96 });
const showNotif = () => {
gsap.fromTo(el,
{ opacity: 0, y: 16, scale: 0.96 },
{ opacity: 1, y: 0, scale: 1, duration: 0.5, ease: 'power3.out',
onComplete: () => {
gsap.to(el, { opacity: 0, y: -8, scale: 0.97, duration: 0.4, delay: 3, ease: 'power2.in' });
},
}
);
};
const initial = setTimeout(showNotif, 800);
const id = setInterval(showNotif, 5000);
return () => { clearTimeout(initial); clearInterval(id); };
}, []);
return (
Relances devis en cours
{RELANCE_ROWS.map((row, i) => {
/* Each row starts at a different phase so they cycle independently */
const status = STATUS_CYCLE[(tick + i) % STATUS_CYCLE.length];
return (
{row.ref}
{row.amount}
{status.label}
);
})}
{/* Floating notification — GSAP animated, always in DOM */}
↑ 2 devis relancés ce matin ✓
);
}
/* ---------- Pay timeline — QUITOS Pay ---------- */
const PAY_STEPS = [
{ day: 'J+5', label: 'Email compréhensif' },
{ day: 'J+15', label: 'Rappel courtois' },
{ day: 'J+30', label: 'Mise en demeure' },
{ day: 'J+60', label: 'Recommandé électronique' },
];
function PayTimelineMockup() {
const [filled, setFilled] = useState(0);
const ref = useRef(null);
useEffect(() => {
const el = ref.current;
if (!el) return;
if (window.gsap && window.ScrollTrigger) {
/* GSAP ScrollTrigger approach */
const trigger = ScrollTrigger.create({
trigger: el,
start: 'top 75%',
onEnter: () => {
PAY_STEPS.forEach((_, i) => {
setTimeout(() => setFilled((f) => Math.max(f, i + 1)), i * 400);
});
/* Animate connector lines appearing */
const connectors = el.querySelectorAll(".pay-connector");
connectors.forEach((line, i) => {
gsap.fromTo(line,
{ opacity: 0 },
{ opacity: 1, duration: 0.4, delay: (i * 0.4) + 0.3, ease: 'power2.out' }
);
});
},
once: true,
});
return () => trigger.kill();
} else {
/* Fallback: IntersectionObserver */
const io = new IntersectionObserver(([entry]) => {
if (entry.isIntersecting) {
PAY_STEPS.forEach((_, i) => {
setTimeout(() => setFilled((f) => Math.max(f, i + 1)), i * 350);
});
io.disconnect();
}
}, { threshold: 0.4 });
io.observe(el);
return () => io.disconnect();
}
}, []);
const filledTarget = Math.min(filled, 2);
return (
Séquence de relance — QUITOS Pay
{PAY_STEPS.map((step, i) => {
const isFilled = i < filledTarget;
return (
{i < PAY_STEPS.length - 1 && (
)}
{step.day}
✓
{step.label}
);
})}
);
}
/* ---------- Monthly report mockup ---------- */
function ReportMockup() {
const rows = [
{ lbl: 'CA récupéré ce mois', val: '14 200 €', accent: true },
{ lbl: 'Devis relancés', val: '23' },
{ lbl: 'Taux de réponse', val: '34 %' },
{ lbl: 'DSO réduit de', val: '-8 jours' },
];
const top3 = [
{ name: 'Renault RH', amt: '12 800 €' },
{ name: 'Geodis Comms', amt: '8 400 €' },
{ name: 'Bouygues Tél.', amt: '6 200 €' },
];
return (
QUITOS — Rapport Mai 2026
{rows.map((r) => (
{r.lbl}
{r.val}
))}
Top 3 devis signés ce mois
{top3.map((t, i) => (
{t.name}
{t.amt}
✓
))}
);
}
/* ---------- Lifestyle photo — uses real image with overlay UI ---------- */
function LifestylePhoto() {
const imgSrc = 'assets/images/quitos-ambiance.png';
return (

{ e.target.style.display = 'none'; }}
/>
{/* Overlay UI — rapport mini (bottom-left) */}
Rapport QUITOS · Mai 2026
CA récupéré
14 200 € ↑
Devis traités
23
{/* Overlay UI — pill (bottom-right) */}
✓
3 relances envoyées
);
}
Object.assign(window, { RelanceMockup, PayTimelineMockup, ReportMockup, LifestylePhoto });