/* ChatDemo — animowany agent AI obsługi klienta.
Odgrywa rozmowę krok po kroku: klient pisze -> bot "myśli" -> odpowiada.
Po ostatniej wiadomości pauza i restart (pętla). */
function CdBotIcon() {
return (
);
}
// scenariusz rozmowy (1:1 ze zrzutu)
const CD_MESSAGES = [
{ from: "user", time: "09:12", node: "Dzień dobry, gdzie jest moje zamówienie?" },
{
from: "bot", time: "09:12", think: 1700,
node: (
<>
Dzień dobry! Sprawdzę to dla Ciebie.
Twoje zamówienie nr 2026/05/12345 zostało wysłane dzisiaj o 08:47.
Aktualny status: W drodze
Przewidywana dostawa: jutro (24.05) przez InPost kurier
>
),
},
{ from: "user", time: "09:13", node: "Czy dotrze na pewno jutro?" },
{
from: "bot", time: "09:13", think: 1500,
node: (
<>
Tak, wszystko na to wskazuje 🙂
Przesyłki InPost doręczane są zazwyczaj w 24h. Otrzymasz SMS z dokładną godziną doręczenia.
>
),
},
{ from: "user", time: "09:14", node: "Czy to serum nadaje się do cery wrażliwej?" },
{
from: "bot", time: "09:14", think: 1600,
node: (
<>
Tak, nasze serum jest odpowiednie dla cery wrażliwej. Ma lekką formułę,
bez substancji zapachowych i zostało przebadane dermatologicznie.
>
),
},
];
function ChatDemo() {
const reduceMotion = typeof window !== "undefined" &&
window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
const [count, setCount] = React.useState(reduceMotion ? CD_MESSAGES.length : 0);
const [typing, setTyping] = React.useState(false);
const bodyRef = React.useRef(null);
// sterownik sekwencji
React.useEffect(() => {
if (reduceMotion) return;
let cancelled = false;
const timers = [];
const wait = (ms) => new Promise((res) => timers.push(setTimeout(res, ms)));
async function run() {
while (!cancelled) {
setCount(0); setTyping(false);
await wait(900);
for (let i = 0; i < CD_MESSAGES.length && !cancelled; i++) {
const m = CD_MESSAGES[i];
if (m.from === "bot") {
setTyping(true);
await wait(1500);
if (cancelled) break;
setTyping(false);
} else {
await wait(i === 0 ? 500 : 1100);
if (cancelled) break;
}
setCount(i + 1);
await wait(1700); // pauza na spokojne przeczytanie wiadomości (~3s/wiadomość)
if (cancelled) break;
}
await wait(4500); // pauza przed restartem
}
}
run();
return () => { cancelled = true; timers.forEach(clearTimeout); };
}, [reduceMotion]);
// auto-scroll do najnowszej wiadomości
React.useEffect(() => {
const el = bodyRef.current;
if (el) el.scrollTop = el.scrollHeight;
}, [count, typing]);
const shown = CD_MESSAGES.slice(0, count);
return (