feat: setup iniziale sistema controllo accessi Focolari

Struttura progetto:
- Backend mock Python (FastAPI) con API per gestione varchi
- Frontend React + TypeScript + Vite + Tailwind CSS
- Documentazione e piani di sviluppo

Backend (backend-mock/):
- API REST: /info-room, /login-validate, /anagrafica, /entry-request
- Dati mock: 7 utenti, validatore (999999/focolari)
- CORS abilitato, docs OpenAPI automatiche
- Configurazione pipenv per ambiente virtuale

Frontend (frontend/):
- State machine completa per flusso accesso varco
- Hook useRFIDScanner per lettura badge (pattern singolo)
- Componenti UI: Logo, Button, Input, Modal, UserCard, Timer
- Schermate: Loading, Login, ActiveGate, Success/Error Modal
- Design system con colori Focolari
- Ottimizzato per tablet touch

Documentazione (ai-prompts/):
- Welcome guide per futuri agenti
- Piano sviluppo backend e frontend con checklist

DA COMPLETARE:
- Hook RFID multi-pattern (US/IT/altri layout tastiera)
- Pagina /debug per diagnostica in loco
- Logging console strutturato
This commit is contained in:
2026-01-17 18:20:55 +01:00
commit 21b509c6ba
40 changed files with 7453 additions and 0 deletions

View File

@@ -0,0 +1,88 @@
/**
* Success Modal - Focolari Voting System
* Modal fullscreen per conferma ingresso
*/
import { Modal } from '../components';
interface SuccessModalProps {
isOpen: boolean;
onClose: () => void;
welcomeMessage: string;
userName?: string;
}
export function SuccessModal({
isOpen,
onClose,
welcomeMessage,
userName
}: SuccessModalProps) {
return (
<Modal
isOpen={isOpen}
onClose={onClose}
variant="success"
autoCloseMs={5000}
fullscreen
>
<div className="text-center text-white p-8">
{/* Success Icon */}
<div className="mb-8">
<div className="inline-flex items-center justify-center w-32 h-32 rounded-full bg-white/20 animate-pulse-glow">
<svg
className="w-20 h-20 text-white"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={3}
d="M5 13l4 4L19 7"
/>
</svg>
</div>
</div>
{/* User Name */}
{userName && (
<h2 className="text-4xl md:text-5xl font-bold mb-4 animate-slide-up">
{userName}
</h2>
)}
{/* Welcome Message */}
<h1 className="text-5xl md:text-7xl font-bold mb-8 animate-slide-up">
{welcomeMessage}
</h1>
{/* Sub text */}
<p className="text-2xl md:text-3xl opacity-80 animate-fade-in">
Ingresso registrato con successo
</p>
{/* Auto-close indicator */}
<div className="mt-12">
<div className="w-64 h-2 bg-white/30 rounded-full mx-auto overflow-hidden">
<div
className="h-full bg-white rounded-full"
style={{
animation: 'shrink 5s linear forwards',
}}
/>
</div>
<style>{`
@keyframes shrink {
from { width: 100%; }
to { width: 0%; }
}
`}</style>
</div>
</div>
</Modal>
);
}
export default SuccessModal;