Files
Eric FELIXINE e30ae8ed09 feat(smart-app): implement complete mobile app MVP
- App.tsx: full navigation (Auth stack + Main tabs with 5 screens)
- Auth: LoginScreen, RegisterScreen, ForgotPasswordScreen
- HomeScreen: dashboard with IoT metrics, weather widget, alerts, quick actions, sensors
- MapScreen: interactive map with layer toggles (6 layers)
- MarketplaceScreen: categories (6), products (5), search
- ChatScreen: AI chat with quick prompts (4), bot responses
- ProfileScreen: user info, stats, menu (9 items), logout
- AlertsScreen: alert list with severity, acknowledge
- SensorsScreen: sensor list with type filters (6 types), search
- ZonesScreen: zone cards with stats
- SettingsScreen: language picker (FR/EN/ES/DE), privacy, about
- Stores: iotStore (sensors, zones, alerts), notificationStore, uiStore + i18n
- Hooks: useSensors, useAlerts, useNotifications, useLocation
- Components: Card, Button, LoadingSpinner, ErrorBoundary, Header
- Services: iotService, notificationService (with axios API client)
- Utils: formatters (temp, AQI, noise, dates), validators (email, password, IBAN)
- Theme: colors.ts with full design system (Blue Ocean palette)
- Ditto: fixed MongoDB connection, new JWT secrets, official gateway image
2026-06-01 18:00:35 -04:00

249 lines
9.4 KiB
HTML

<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Smart App City — 07 Notifications</title>
<link rel="stylesheet" href="shared.css">
<style>
.notif-header {
padding: 16px;
background: white;
border-bottom: 1px solid var(--neutral-200);
}
.notif-title {
font-size: var(--text-lg);
font-weight: var(--weight-bold);
margin-bottom: 4px;
}
.notif-sub {
font-size: var(--text-sm);
color: var(--neutral-500);
}
.notif-tabs {
display: flex; gap: 8px;
padding: 12px 16px;
background: white;
border-bottom: 1px solid var(--neutral-200);
}
.notif-tab {
padding: 8px 16px;
border-radius: var(--radius-full);
font-size: var(--text-sm);
font-weight: var(--weight-medium);
background: var(--neutral-100);
color: var(--neutral-600);
cursor: pointer;
transition: all 0.2s;
}
.notif-tab.active {
background: var(--primary-500);
color: white;
}
.notif-item {
display: flex; gap: 12px;
padding: 14px 16px;
background: white;
border-bottom: 1px solid var(--neutral-100);
cursor: pointer;
transition: background 0.15s;
}
.notif-item:hover { background: var(--neutral-50); }
.notif-item.unread { background: rgba(2,136,209,0.04); }
.notif-icon {
width: 44px; height: 44px;
border-radius: var(--radius-full);
display: flex; align-items: center; justify-content: center;
font-size: 20px;
flex-shrink: 0;
}
.notif-content { flex: 1; }
.notif-text {
font-size: var(--text-sm);
line-height: 1.4;
margin-bottom: 4px;
}
.notif-time {
font-size: var(--text-xs);
color: var(--neutral-400);
}
.notif-dot {
width: 8px; height: 8px;
border-radius: 50%;
background: var(--alert-info);
flex-shrink: 0;
margin-top: 6px;
}
.section-divider {
padding: 10px 16px;
font-size: var(--text-xs);
font-weight: var(--weight-semibold);
color: var(--neutral-400);
text-transform: uppercase;
letter-spacing: 0.5px;
background: var(--neutral-50);
}
/* Fixed viewport for PDF/iframe embedding */
html, body { width: 390px !important; height: 844px !important; overflow: hidden !important; margin: 0 !important; padding: 0 !important; }
</style>
<style>
/* Fixed viewport for PDF/iframe embedding */
html, body { width: 390px !important; height: 844px !important; overflow: hidden !important; margin: 0 !important; padding: 0 !important; }
</style>
</head>
<body>
<div class="mobile-frame">
<!-- Status Bar -->
<div class="status-bar">
<span>9:41</span>
<div style="display:flex;gap:4px;align-items:center;">
<svg width="16" height="12" viewBox="0 0 16 12"><rect x="0" y="4" width="3" height="8" rx="1" fill="#333"/><rect x="4.5" y="2.5" width="3" height="9.5" rx="1" fill="#333"/><rect x="9" y="0" width="3" height="12" rx="1" fill="#333"/><rect x="13.5" y="0" width="2.5" height="12" rx="1" fill="#ccc"/></svg>
</div>
</div>
<!-- Header -->
<div class="notif-header">
<div style="display:flex;justify-content:space-between;align-items:center;">
<div>
<div class="notif-title">Notifications</div>
<div class="notif-sub">3 non lues · Dernières 24h</div>
</div>
<div style="font-size:var(--text-sm);color:var(--primary-500);font-weight:500;cursor:pointer;">Tout marquer lu</div>
</div>
</div>
<!-- Tabs -->
<div class="notif-tabs">
<div class="notif-tab active">Tout</div>
<div class="notif-tab">🚨 Alertes</div>
<div class="notif-tab">📊 Données</div>
<div class="notif-tab">🏪 Marché</div>
<div class="notif-tab">🔄 Système</div>
</div>
<!-- Notifications list -->
<div class="content-area" style="top:152px;background:var(--neutral-50);">
<!-- Alert - Unread -->
<div class="section-divider">Aujourd'hui</div>
<div class="notif-item unread">
<div class="notif-icon" style="background:rgba(211,47,47,0.1);">🚨</div>
<div class="notif-content">
<div class="notif-text"><strong>Alerte qualité d'air</strong> — Secteur Centre-Ville FDF. Indice AQI élevé détecté (78). Restez vigilant.</div>
<div class="notif-time">Il y a 12 min · IoT Alert</div>
</div>
<div class="notif-dot"></div>
</div>
<div class="notif-item unread">
<div class="notif-icon" style="background:rgba(245,124,0,0.1);"></div>
<div class="notif-content">
<div class="notif-text"><strong>Consommation électrique anormale</strong> — Zone Schœlcher. +34% par rapport à la moyenne.</div>
<div class="notif-time">Il y a 28 min · Smart Grid</div>
</div>
<div class="notif-dot"></div>
</div>
<div class="notif-item unread">
<div class="notif-icon" style="background:rgba(2,136,209,0.1);">🚌</div>
<div class="notif-content">
<div class="notif-text"><strong>Retard ligne A1</strong> — 15 min de retard estimé entre FDF et Schœlcher.</div>
<div class="notif-time">Il y a 45 min · Transport</div>
</div>
<div class="notif-dot"></div>
</div>
<div class="notif-item">
<div class="notif-icon" style="background:rgba(46,125,50,0.1);">🌡️</div>
<div class="notif-content">
<div class="notif-text">Température stable à <strong>24.2°C</strong> dans votre zone. Tous les capteurs fonctionnent normalement.</div>
<div class="notif-time">Il y a 1h · IoT Update</div>
</div>
</div>
<div class="notif-item">
<div class="notif-icon" style="background:rgba(0,172,193,0.1);">💧</div>
<div class="notif-content">
<div class="notif-text"><strong>Pluie détectée</strong> — Secteur Nord. Prévision : 2h de précipitations modérées.</div>
<div class="notif-time">Il y a 2h · Météo</div>
</div>
</div>
<!-- Market notification -->
<div class="section-divider">Hier</div>
<div class="notif-item">
<div class="notif-icon" style="background:rgba(124,77,255,0.1);">🏪</div>
<div class="notif-content">
<div class="notif-text"><strong>Nouveau producteur</strong> — "Jardin Créole" a rejoint le marché. Potirons, christophines !</div>
<div class="notif-time">Hier · Marché Local</div>
</div>
</div>
<div class="notif-item">
<div class="notif-icon" style="background:rgba(211,47,47,0.1);">📸</div>
<div class="notif-content">
<div class="notif-text"><strong>Signalement traité</strong> — Votre signalement #008 "Nid de poule RN5" est en cours de traitement.</div>
<div class="notif-time">Hier · ODK</div>
</div>
</div>
<div class="notif-item">
<div class="notif-icon" style="background:rgba(2,136,209,0.1);">📊</div>
<div class="notif-content">
<div class="notif-text"><strong>Rapport hebdomadaire</strong> — Votre résumé Smart City de la semaine est disponible.</div>
<div class="notif-time">Hier · Analytics</div>
</div>
</div>
<div class="notif-item">
<div class="notif-icon" style="background:rgba(46,125,50,0.1);">🎉</div>
<div class="notif-content">
<div class="notif-text"><strong>Objectif atteint !</strong> — La ville a réduit ses émissions de CO₂ de 5% ce mois-ci.</div>
<div class="notif-time">2 jours · Environnement</div>
</div>
</div>
<div class="notif-item">
<div class="notif-icon" style="background:rgba(245,124,0,0.1);">🔧</div>
<div class="notif-content">
<div class="notif-text"><strong>Maintenance prévue</strong> — Capteurs zone Lamentin indisponibles le 30/05 de 2h à 4h.</div>
<div class="notif-time">2 jours · Système</div>
</div>
</div>
<div style="height:16px;"></div>
</div>
<!-- Bottom Nav -->
<!-- Bottom Nav (empty - accessed from bell icon) -->
<div class="bottom-nav">
<div class="bottom-nav-item">
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M3 9l9-7 9 7v11a2 2 0 01-2 2H5a2 2 0 01-2-2z"/><polyline points="9 22 9 12 15 12 15 22" fill="none" stroke="currentColor" stroke-width="2"/></svg>
<span>Accueil</span>
</div>
<div class="bottom-nav-item">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polygon points="1 6 1 22 8 18 16 22 23 18 23 2 16 6 8 2 1 6"/><line x1="8" y1="2" x2="8" y2="18"/><line x1="16" y1="6" x2="16" y2="22"/></svg>
<span>Carte</span>
</div>
<div class="bottom-nav-item">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><path d="M8 14s1.5 2 4 2 4-2 4-2"/><line x1="9" y1="9" x2="9.01" y2="9"/><line x1="15" y1="9" x2="15.01" y2="9"/></svg>
<span>AI Chat</span>
</div>
<div class="bottom-nav-item">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="2" y="3" width="20" height="14" rx="2"/><line x1="8" y1="21" x2="16" y2="21"/><line x1="12" y1="17" x2="12" y2="21"/></svg>
<span>Marché</span>
</div>
<div class="bottom-nav-item active">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M20 21v-2a4 4 0 00-4-4H8a4 4 0 00-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>
<span>Profil</span>
</div>
</div>
<div style="position:absolute;bottom:88px;left:0;right:0;text-align:center;font-size:10px;color:var(--neutral-400);">07 — Notifications & Alertes</div>
</div>
</body>
</html>