📐 Architecture Frontend
Configuration Vite
// vite.config.ts
export default defineConfig(({ mode }) => ({
server: { host: '::', port: 8080 },
plugins: [react(), mode === 'development' && componentTagger()].filter(Boolean),
resolve: { alias: { '@': path.resolve(__dirname, './src') } },
}));
- Alias
@/→./src/dans tous les imports - Plugin
lovable-taggeruniquement en mode développement - Port 8080 (IPv6 compatible avec
::)
TypeScript (permissif pour le MVP)
{
"compilerOptions": {
"allowJs": true,
"noImplicitAny": false,
"strictNullChecks": false,
"paths": { "@/*": ["./src/*"] }
}
}
⚠️ Configuration permissive intentionnelle pour le MVP. Migration vers strict prévue Q2 2026.
Design System
Fichier principal : src/index.css
Toutes les couleurs sont en variables CSS HSL. Le système définit 4 thèmes via des sélecteurs [data-theme="..."].
Tokens Rasta Classic (thème par défaut :root)
| Variable CSS | Valeur HSL | Rôle |
|---|---|---|
--background | 0 0% 8% | Fond principal (quasi-noir) |
--foreground | 0 0% 98% | Texte principal (blanc) |
--card | 0 0% 12% | Fond des cards |
--primary | 142 76% 36% | Vert rastafari |
--secondary | 54 100% 62% | Jaune rastafari |
--accent | 0 84% 60% | Rouge rastafari |
--success | 142 76% 36% | = primary |
--warning | 54 100% 62% | = secondary |
--danger | 0 84% 60% | = accent |
--border | 0 0% 20% | Bordures |
--radius | 0.75rem | Rayon coins |
4 thèmes disponibles
| Thème | data-theme | Description |
|---|---|---|
| Rasta Classic | "" (défaut) | Vert/jaune/rouge vifs, néon |
| Jamaica Night | "jamaica-night" | Teintes sombres subtiles |
| Roots Earth | "roots-earth" | Tons terreux organiques |
| Digital Rasta | "digital-rasta" | Cyberpunk néon haute saturation |
Persistance : localStorage['rasta-theme'] → document.documentElement.setAttribute('data-theme', value)
Classes utilitaires néon
.neon-text-green /* texte + text-shadow vert */
.neon-text-yellow /* texte + text-shadow jaune */
.neon-text-red /* texte + text-shadow rouge */
.hover-glow-green /* box-shadow néon au hover */
.bg-gradient-rasta /* dégradé vert→jaune→rouge */
.pulse-neon /* animation pulse luminosité */
Pages (React Router)
// App.tsx
<Routes>
<Route path="/" element={<Home />} />
<Route path="/analyzer" element={<Analyzer />} />
<Route path="/dashboard" element={<Dashboard />} />
<Route path="/phone-checker" element={<PhoneChecker />} />
<Route path="/sms-dashboard" element={<SmsDashboard />} />
<Route path="/export" element={<Export />} />
<Route path="/settings" element={<Settings />} />
<Route path="/aide" element={<Aide />} />
<Route path="/auth" element={<Auth />} />
<Route path="*" element={<NotFound />} />
</Routes>
Composants métier
AppNavbar.tsx
Navigation sticky (z-50) avec backdrop-blur.
- Desktop : dropdowns
DropdownMenupour BlocMail (3 items) et BlocNumEtSMS (2 items) - Mobile : menu hamburger avec groupes labellisés
- Indicateur actif basé sur
useLocation()
AppBreadcrumb.tsx
Fil d'Ariane contextuel. Masqué sur /.
Mapping statique : /analyzer → BlocMail, /phone-checker → BlocNumEtSMS
EmailHeaderAnalyzer.tsx
Composant d'analyse SSE streaming.
- Auto-démarre via
useEffectau montage - Consomme les events SSE via
TextDecoder+ buffer - Met à jour
steps[]etprogressen temps réel - Appelle
onComplete(results)au stepcomplete
SpamAnalysisCard.tsx
Affichage résultats analyze-spam :
- Barre de progression score (0-100)
- Badge sévérité coloré + badge SPAM/SÛR
- Liste patterns déclenchés (icône par type, score, raisons)
- Règles headers déclenchées avec malus
- Timestamp Europe/Zurich
ExportModule.tsx
Gère 6 exports avec statuts individuels :
- JSON, XML, CSV, ICS → Blob + download link
- Slack → POST webhook (blocks API)
- n8n →
supabase.functions.invoke('trigger-n8n-export')
ThemeSelector.tsx
Aperçu gradient pour chaque thème. Persiste dans localStorage.
Hooks personnalisés
useEmailAnalyses.ts
CRUD analyses email avec dual mode :
// Si authentifié → Supabase
const { data } = await supabase.from('email_analyses').select('*').order('timestamp', { ascending: false }).limit(200);
// Si non-auth → localStorage fallback
const stored = localStorage.getItem('emailAnalyses');
Méthodes : analyses, addAnalysis(), toggleSpam(), deleteAnalysis(), clearAll(), refetch()
usePhoneChecks.ts
Similaire à useEmailAnalyses. Méthodes supplémentaires :
toggleManualBlock(id)— UPDATEmanually_blockedtoggleCommunityReport(id)— UPDATE + UPSERTcommunity_reports
useCommunityReports.ts
Read-only avec abonnement Realtime Supabase (postgres_changes).
reports— liste max 500 signalementsisReported(type, identifier)— booleangetReportCount(type, identifier)— number
useSpamAnalysis.ts
Mutation TanStack Query → supabase.functions.invoke('analyze-spam').
onSuccess: sauvegarde localStorage + invalidate queries + toastonError: toast d'erreur
use-toast.ts
Système toast via reducer + état global (pas de Context React).
TOAST_LIMIT = 1(1 toast simultané max)- Délai suppression : 1 000 000ms (toast persistant)
use-mobile.tsx
Détection breakpoint mobile = 768px via window.matchMedia.
localStorage — Clés
| Clé | Contenu | Géré par |
|---|---|---|
dailyCredits | { count, date } | src/lib/credits.ts |
emailAnalyses | Array analyses (fallback) | useEmailAnalyses |
phoneCheckResults | Array vérifications | usePhoneChecks |
spamAnalyses | Array résultats spam | useSpamAnalysis |
apiConfig | Keys + enabled IPQS/AbuseIPDB/VT | Settings.tsx |
apiCounters | Compteurs appels APIs | EmailHeaderAnalyzer.tsx |
n8nWebhookUrl | URL webhook n8n | Settings.tsx |
makeWebhookUrl | URL webhook Make.com | Settings.tsx |
blocNumSettings | Config BlocNum switches + code | Settings.tsx |
rasta-theme | Thème actif | ThemeSelector.tsx |
Bibliothèques UI (shadcn/ui)
40+ composants Radix UI dans src/components/ui/ :
accordion · alert · alert-dialog · avatar · badge · breadcrumb · button · calendar · card · chart · checkbox · command · dialog · drawer · dropdown-menu · form · input · label · navigation-menu · popover · progress · radio-group · scroll-area · select · separator · sheet · sidebar · skeleton · slider · switch · table · tabs · textarea · toast · toggle · tooltip
Variantes Button personnalisées
variant: {
neon: "border-2 border-success text-success hover:shadow-neon-green",
neonYellow: "border-2 border-warning text-warning hover:shadow-neon-yellow",
neonRed: "border-2 border-danger text-danger hover:shadow-neon-red",
success: "bg-success hover:shadow-neon-green",
warning: "bg-warning hover:shadow-neon-yellow",
danger: "bg-danger hover:shadow-neon-red",
}
Gestion des crédits (src/lib/credits.ts)
const MAX_DAILY_CREDITS = 5;
// Stockage : localStorage['dailyCredits'] = { count: number, date: string }
// Reset automatique si date ISO différente d'aujourd'hui (minuit UTC)
canUseCredit(): boolean // count < 5
consumeCredit(): boolean // décrémente + sauvegarde
getRemaining(): number // 5 - count
Les crédits sont partagés entre Mail Analyseur et BlocNum Analyseur.