// Screen 3: WhatsApp on phone, proper mobile WhatsApp UI // Detailed convo: greeting → context → options → questions → decision → handoff to call const WA_MESSAGES = [ { from: 'system', text: 'Today', delay: 200, kind: 'day' }, { from: 'system', text: '🔒 Messages are end-to-end encrypted. Only Emirates and you can read them.', delay: 600, kind: 'enc' }, { from: 'aria', t: '09:16', text: 'Hi Sarah 👋', delay: 700 }, { from: 'aria', t: '09:16', text: "I'm Hala, the Emirates virtual assistant. I can see you've just received our update, EK202 to New York on 28 April has been cancelled.", delay: 1700 }, { from: 'aria', t: '09:16', text: "I'm sorry for the disruption. Your ticket is still valid and I can help you sort this out right now, no need to call.", delay: 1500 }, { from: 'aria', t: '09:16', text: "What would you like to do?", delay: 1100 }, { from: 'quick', delay: 600, options: ['Rebook me', 'I want a refund', 'Talk to someone'] }, { from: 'sarah', t: '09:17', text: "Rebook me. I have a meeting in Manhattan at 11am on the 29th.", delay: 2400 }, { from: 'aria', t: '09:17', text: "Got it, let me find you something that lands well before then.", delay: 1300 }, { from: 'aria', t: '09:17', text: "Give me one second…", delay: 900 }, { from: 'aria', t: '09:18', text: "Here are the two best options I can offer at no extra cost:", delay: 1100 }, { from: 'option', delay: 600, data: { tag: 'starred', tagText: 'Recommended', title: 'Same-day evening · direct', fromIata: 'DXB', toIata: 'JFK', flight: 'EK203', stops: 'Direct', dep: 'Tue 28 Apr · 22:40', arr: 'Wed 29 Apr · 04:55', seats: '12 seats', fare: 'No fare diff' }}, { from: 'option', delay: 700, data: { tag: 'alt', tagText: 'Earlier arrival', title: 'Via London (LHR)', fromIata: 'DXB', toIata: 'JFK', flight: 'EK205 + EK023', stops: '1 stop · 2h 30m layover', dep: 'Tue 28 Apr · 14:10', arr: 'Tue 28 Apr · 20:30', seats: '4 seats', fare: 'No fare diff', warn: true }}, { from: 'aria', t: '09:18', text: "Option 1 lands at JFK at 04:55 on the 29th, gives you several hours before your meeting.", delay: 1500 }, { from: 'aria', t: '09:18', text: "Option 2 gets you there the night before, but it's a connection through London with only 4 seats left.", delay: 1500 }, { from: 'sarah', t: '09:18', text: "Hmm. Will I be exhausted on Option 1? I land at 5am.", delay: 2200 }, { from: 'aria', t: '09:19', text: "It's a fair concern. Option 1 is an overnight flight (≈14h), most passengers sleep 5–7 hours. You'd have ~6 hours at your hotel before the meeting.", delay: 1900 }, { from: 'aria', t: '09:19', text: "Option 2 is two shorter flights and only 4 seats remain, risk if you arrive late at gate, you may not get the connection.", delay: 1700 }, { from: 'sarah', t: '09:19', text: "What about lounge access at JFK? I'm Skywards Silver.", delay: 2200 }, { from: 'aria', t: '09:19', text: "Yes, both options keep your Skywards Silver benefits, including priority check-in and lounge access at DXB before departure. JFK is arrival only, so no lounge there.", delay: 2000 }, { from: 'sarah', t: '09:20', text: "OK and seat 23A, I had that originally. Can I keep it?", delay: 2200 }, { from: 'aria', t: '09:20', text: "I'll do my best. 23A on EK203 is currently available, I can hold it for you when we finalise.", delay: 1700 }, { from: 'sarah', t: '09:20', text: "Honestly, can we just talk? I have a few more questions.", delay: 2400 }, { from: 'aria', t: '09:20', text: "Of course. 🙂", delay: 900 }, { from: 'aria', t: '09:20', text: "Tap 'Call Hala' on your Emirates app, I'll have everything we've discussed already loaded, so no need to repeat anything.", delay: 1700 }, { from: 'aria', t: '09:20', text: "Speak to you in a moment.", delay: 900 }, ]; function WhatsAppScreen({ onAdvance, autoAdvance }) { const [step, setStep] = React.useState(0); const [showTyping, setShowTyping] = React.useState(false); const scrollRef = React.useRef(null); React.useEffect(() => { if (step >= WA_MESSAGES.length) return; const msg = WA_MESSAGES[step]; let typingTimer, advanceTimer; if (msg.from === 'aria' || msg.from === 'sarah') { // Show typing for any live message bubble const showT = msg.delay > 700; if (showT) setShowTyping(true); typingTimer = setTimeout(() => { setShowTyping(false); advanceTimer = setTimeout(() => setStep(s => s + 1), 80); }, msg.delay); } else { setShowTyping(false); advanceTimer = setTimeout(() => setStep(s => s + 1), msg.delay); } return () => { clearTimeout(typingTimer); clearTimeout(advanceTimer); }; }, [step]); React.useEffect(() => { if (scrollRef.current) scrollRef.current.scrollTop = scrollRef.current.scrollHeight; }, [step, showTyping]); React.useEffect(() => { if (step >= WA_MESSAGES.length && autoAdvance) { const t = setTimeout(() => onAdvance && onAdvance(), 2500); return () => clearTimeout(t); } }, [step, autoAdvance]); const visible = WA_MESSAGES.slice(0, step); const nextMsg = WA_MESSAGES[step]; const showAriaTyping = showTyping && nextMsg && nextMsg.from === 'aria'; const showSarahTyping = showTyping && nextMsg && nextMsg.from === 'sarah'; return (
Emirates
Emirates
online
{visible.map((msg, i) => { if (msg.kind === 'day') return
TODAY
; if (msg.kind === 'enc') return
{msg.text}
; if (msg.kind === 'sys') return
{msg.text}
; if (msg.from === 'option') return ; if (msg.from === 'quick') return (
{msg.options.map((o, j) => )}
); const sent = msg.from === 'sarah'; return (
{msg.text} {msg.t}{sent && }
); })} {showAriaTyping && (
)} {showSarahTyping && (
)}
Message
); } function WAMOption({ data }) { return (
{data.tagText} {data.title}
{data.fromIata} {data.toIata} {data.flight}
Departs
{data.dep}
Arrives
{data.arr}
Connection
{data.stops}
Seats / Fare
{data.seats} · {data.fare}
Tap to select 09:18
); } window.WhatsAppScreen = WhatsAppScreen;