// KioskStaffScreens.jsx — Receptionist mode on the self check-in kiosk. // Flow: // 1. ScreenStaffScan – receptionist scans employee QR // 2. ScreenStaffMenu – quick actions + today's activity // 3. Sub-modals for the actions (handled inline by parent state) // // Style: matches brand kiosk aesthetic but with a distinct amber/gold treatment // to make "staff mode" visually unmistakable at a glance. Cyan is for guests. function ScreenStaffScan({ onBack, onSuccess }) { // Simulate a QR scan succeeding after ~2s React.useEffect(() => { const t = setTimeout(onSuccess, 2400); return () => clearTimeout(t); }, [onSuccess]); return ( {/* Amber overlay to distinguish staff mode */} {/* Staff mode badge */} OSEBJE · STAFF {'Skenirajte\nzaposleno QR kartico'} {/* Scanner square */} {[[0,0],[1,0],[0,1],[1,1]].map(([x,y],i)=>( ))} {/* Pulsing scan line */} SKENIRANJE… Samo pooblaščeno osebje hotela ); } function ScreenStaffMenu({ onExit, onAction, employee }) { const e = employee || { name:'Marko Horvat', role:'Receptor', shift:'Dnevna izmena · 07:00–15:00', id:'EMP-042' }; const actions = [ { k:'walkin', icon:'👤', title:'Walk-in prijava', sub:'Gost brez rezervacije' }, { k:'duplicate', icon:'🔑', title:'Podvojen ključ', sub:'Natisni dodaten ključ' }, { k:'override', icon:'✔︎', title:'Ročna prijava', sub:'Obidi samopostrežno' }, { k:'lookup', icon:'🔍', title:'Iskanje rezervacije', sub:'Po imenu ali št. sobe' }, { k:'maintenance',icon:'🛠', title:'Vzdrževanje', sub:'Zakleni kiosk za servis' }, { k:'closed', icon:'✕', title:'Zapri kiosk', sub:'Prikaži "Ni samoprijave"' }, ]; const today = [ { t:'14:32', title:'A. Novak · Walk-in', meta:'Soba 204 · 2 gostje', status:'active' }, { t:'13:18', title:'M. Horvat · Podvojen ključ',meta:'Soba 312', status:'done' }, { t:'11:05', title:'Kiosk · Samoprijava', meta:'3 gostje · Res-47219',status:'done' }, { t:'09:42', title:'Kiosk · Samoprijava', meta:'2 gosta · Res-47201', status:'done' }, ]; return ( {/* Staff mode tint */} {/* Staff mode badge + employee card */} OSEBJE · RECEPCIJA {e.name.split(' ').map(n=>n[0]).join('')} {e.name} {e.role} · {e.id} {`Živijo, ${e.name.split(' ')[0]}.`} {e.shift} {/* Action grid */} {actions.map(a => ( onAction(a.k)} /> ))} {/* Today's activity log */} Današnja aktivnost {today.map((it,i) => ( {it.t} {it.title} {it.meta} {it.status==='active' ? 'aktivno' : 'zaključeno'} ))} IZPIS / ODJAVA ); } function StaffActionCard({ icon, title, sub, onClick }) { const [h, setH] = React.useState(false); return ( setH(true)} onMouseLeave={()=>setH(false)} style={{ display:'flex', alignItems:'center', gap:20, padding:'28px 28px', borderRadius:20, textAlign:'left', background: h ? 'rgba(255,179,0,.15)' : 'rgba(255,255,255,.06)', border:`1.5px solid ${h ? 'rgba(255,179,0,.55)' : 'rgba(255,255,255,.12)'}`, color:'#fff', fontFamily:'inherit', cursor:'pointer', transition:'background 200ms, border-color 200ms, transform 80ms', transform: h ? 'translateY(-2px)' : 'none', }}> {icon} {title} {sub} → ); } function ScreenStaffConfirm({ action, onDone, onBack }) { const copy = { walkin: { title:'Walk-in prijava zagnana', sub:'Nadaljujte pri recepcijskem pultu', color:'#00BCD4' }, duplicate: { title:'Ključ natisnjen', sub:'Dvignite ključ iz avtomata', color:'#00BCD4' }, override: { title:'Prijava potrjena ročno', sub:'Gost lahko nadaljuje brez kioska', color:'#2DD164' }, lookup: { title:'Rezervacija najdena', sub:'RES-48210 · A. Novak · Soba 204', color:'#00BCD4' }, maintenance:{ title:'Kiosk v vzdrževanju', sub:'Na zaslonu je prikazano obvestilo', color:'#FFB300' }, closed: { title:'Kiosk zaklenjen', sub:'Prikazano: "Ni samoprijave"', color:'#E53935' }, }[action] || { title:'Dokončano', sub:'', color:'#00BCD4' }; return ( ✓ {copy.title} {copy.sub} NAZAJ NA MENI ); } Object.assign(window, { ScreenStaffScan, ScreenStaffMenu, ScreenStaffConfirm, StaffActionCard, });