Files
smart-city-digital-twin-mar…/smart-app-city/design/06-profil-blue.html
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

359 lines
14 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!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 — 06 Profil (Blue v2)</title>
<link rel="stylesheet" href="shared-blue.css">
<style>
.profil-header {
background: linear-gradient(160deg, var(--primary-700) 0%, var(--ocean-600) 50%, var(--ocean-500) 100%);
padding: 24px 20px 20px;
color: white; position: relative;
}
.profil-avatar-wrap {
display: flex; align-items: center; gap: 14px;
}
.profil-avatar {
width: 68px; height: 68px; border-radius: var(--radius-full);
background: rgba(255,255,255,0.2);
border: 3px solid rgba(255,255,255,0.4);
display: flex; align-items: center; justify-content: center;
font-size: 32px;
}
.profil-name { font-size: var(--text-lg); font-weight: 700; }
.profil-email { font-size: var(--text-sm); opacity: 0.75; }
.profil-level {
margin-top: 4px; font-size: 11px;
display: inline-flex; align-items: center; gap: 4px;
background: rgba(255,255,255,0.15);
padding: 3px 10px; border-radius: var(--radius-full);
}
.profil-stats {
display: grid; grid-template-columns: repeat(3, 1fr);
gap: 8px; padding: 0 16px;
margin-top: -20px; margin-bottom: 16px;
position: relative; z-index: 2;
}
.stat-card {
background: white; border-radius: var(--radius-lg);
padding: 14px 8px; text-align: center;
box-shadow: var(--shadow-md);
border: 1px solid var(--neutral-100);
}
.stat-value { font-size: var(--text-xl); font-weight: 700; }
.stat-label { font-size: 9px; color: var(--neutral-500); margin-top: 2px; }
.profil-section {
padding: 0 16px 16px;
}
.profil-section-title {
font-size: 12px; font-weight: 700;
color: var(--primary-500);
text-transform: uppercase;
letter-spacing: 0.5px;
margin-bottom: 8px; display: flex;
align-items: center; gap: 6px;
}
.profil-card {
background: white; border-radius: var(--radius-lg);
border: 1px solid var(--neutral-100);
overflow: hidden;
}
.profil-item {
display: flex; align-items: center; gap: 12px;
padding: 14px 16px;
border-bottom: 1px solid var(--neutral-100);
cursor: pointer; transition: background 0.15s;
}
.profil-item:last-child { border-bottom: none; }
.profil-item:hover { background: var(--neutral-50); }
.profil-item-icon {
width: 36px; height: 36px; border-radius: var(--radius-md);
display: flex; align-items: center; justify-content: center;
font-size: 18px; flex-shrink: 0;
}
.profil-item-text { flex: 1; }
.profil-item-title { font-size: var(--text-sm); font-weight: 600; }
.profil-item-sub { font-size: 11px; color: var(--neutral-500); }
.profil-item-right {
font-size: var(--text-sm); color: var(--neutral-500);
display: flex; align-items: center; gap: 4px;
}
.toggle-switch {
width: 44px; height: 24px; border-radius: 12px;
background: var(--neutral-300); position: relative;
cursor: pointer; transition: background 0.2s; flex-shrink: 0;
}
.toggle-switch.on { background: var(--primary-500); }
.toggle-switch::after {
content: ''; width: 20px; height: 20px;
border-radius: 50%; background: white;
position: absolute; top: 2px; left: 2px;
transition: transform 0.2s;
box-shadow: 0 1px 3px rgba(0,0,0,0.2);
}
.toggle-switch.on::after { transform: translateX(20px); }
.lang-grid {
display: grid; grid-template-columns: repeat(4, 1fr);
gap: 8px;
}
.lang-option {
padding: 10px; border-radius: var(--radius-md);
border: 2px solid var(--neutral-200);
background: white; text-align: center;
cursor: pointer; transition: all 0.2s;
}
.lang-option.active {
border-color: var(--primary-500);
background: var(--primary-50);
}
.lang-flag { font-size: 20px; }
.lang-code { font-size: 11px; font-weight: 600; margin-top: 2px; }
.section-divider { height: 8px; background: var(--neutral-50); }
.profil-badge {
display: inline-flex; align-items: center; gap: 3px;
padding: 2px 8px; border-radius: var(--radius-full);
font-size: 10px; font-weight: 600;
}
/* 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="profil-header">
<div style="display:flex;justify-content:flex-end;margin-bottom:8px;">
<svg class="icon-lg" style="cursor:pointer;" viewBox="0 0 24 24"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 00.33 1.82l.06.06a2 2 0 010 2.83 2 2 0 01-2.83 0l-.06-.06a1.65 1.65 0 00-1.82-.33 1.65 1.65 0 00-1 1.51V21a2 2 0 01-2 2 2 2 0 01-2-2v-.09A1.65 1.65 0 009 19.4a1.65 1.65 0 00-1.82.33l-.06.06a2 2 0 01-2.83 0 2 2 0 010-2.83l.06-.06a1.65 1.65 0 00.33-1.82 1.65 1.65 0 00-1.51-1H3a2 2 0 01-2-2 2 2 0 012-2h.09A1.65 1.65 0 004.6 9a1.65 1.65 0 00-.33-1.82l-.06-.06a2 2 0 010-2.83 2 2 0 012.83 0l.06.06a1.65 1.65 0 001.82.33H9a1.65 1.65 0 001-1.51V3a2 2 0 012-2 2 2 0 012 2v.09a1.65 1.65 0 001 1.51 1.65 1.65 0 001.82-.33l.06-.06a2 2 0 012.83 0 2 2 0 010 2.83l-.06.06a1.65 1.65 0 00-.33 1.82V9a1.65 1.65 0 001.51 1H21a2 2 0 012 2 2 2 0 01-2 2h-.09a1.65 1.65 0 00-1.51 1z"/></svg>
</div>
<div class="profil-avatar-wrap">
<div class="profil-avatar">👨🏻‍💻</div>
<div>
<div class="profil-name">Eric Ferdinand</div>
<div class="profil-email">eric@smartappcity.com</div>
<div class="profil-level">🏆 Contributeur · Niveau 5</div>
</div>
</div>
</div>
<!-- Content -->
<div class="content-area" style="background:var(--neutral-50);">
<!-- Stats -->
<div class="profil-stats">
<div class="stat-card">
<div class="stat-value" style="color:var(--primary-500)">27</div>
<div class="stat-label">Signalements</div>
</div>
<div class="stat-card">
<div class="stat-value" style="color:var(--ocean-500)">1,420</div>
<div class="stat-label">Points</div>
</div>
<div class="stat-card">
<div class="stat-value" style="color:var(--indigo-500)">84</div>
<div class="stat-label">Visites</div>
</div>
</div>
<!-- Langue -->
<div class="profil-section">
<div class="profil-section-title">🌐 Langue</div>
<div class="lang-grid">
<div class="lang-option active">
<div class="lang-flag">🇫🇷</div>
<div class="lang-code">FR</div>
</div>
<div class="lang-option">
<div class="lang-flag">🇬🇧</div>
<div class="lang-code">EN</div>
</div>
<div class="lang-option">
<div class="lang-flag">🇪🇸</div>
<div class="lang-code">ES</div>
</div>
<div class="lang-option">
<div class="lang-flag">🇩🇪</div>
<div class="lang-code">DE</div>
</div>
</div>
</div>
<div class="section-divider"></div>
<!-- Mon compte -->
<div class="profil-section">
<div class="profil-section-title">👤 Mon compte</div>
<div class="profil-card">
<div class="profil-item">
<div class="profil-item-icon" style="background:#E3F2FD;">✏️</div>
<div class="profil-item-text">
<div class="profil-item-title">Modifier le profil</div>
<div class="profil-item-sub">Nom, avatar, email</div>
</div>
<div class="profil-item-right"></div>
</div>
<div class="profil-item">
<div class="profil-item-icon" style="background:#FFF3E0;">🔑</div>
<div class="profil-item-text">
<div class="profil-item-title">Sécurité & mot de passe</div>
<div class="profil-item-sub">2FA, changement</div>
</div>
<div class="profil-item-right"></div>
</div>
<div class="profil-item">
<div class="profil-item-icon" style="background:#E8F5E9;">📋</div>
<div class="profil-item-text">
<div class="profil-item-title">Données personnelles</div>
<div class="profil-item-sub">RGPD, export</div>
</div>
<div class="profil-item-right"></div>
</div>
</div>
</div>
<div class="section-divider"></div>
<!-- Préférences -->
<div class="profil-section">
<div class="profil-section-title">⚙️ Préférences</div>
<div class="profil-card">
<div class="profil-item">
<div class="profil-item-icon" style="background:#E8EAF6;">🌙</div>
<div class="profil-item-text">
<div class="profil-item-title">Mode sombre</div>
<div class="profil-item-sub">Thème foncé</div>
</div>
<div class="toggle-switch on"></div>
</div>
<div class="profil-item">
<div class="profil-item-icon" style="background:#E3F2FD;">🔔</div>
<div class="profil-item-text">
<div class="profil-item-title">Notifications</div>
<div class="profil-item-sub">Push & alertes</div>
</div>
<div class="toggle-switch on"></div>
</div>
<div class="profil-item">
<div class="profil-item-icon" style="background:#E0F7FA;">📍</div>
<div class="profil-item-text">
<div class="profil-item-title">Géolocalisation</div>
<div class="profil-item-sub">Services proches</div>
</div>
<div class="toggle-switch on"></div>
</div>
</div>
</div>
<div class="section-divider"></div>
<!-- Paiements / DPI -->
<div class="profil-section">
<div class="profil-section-title">🔗 Paiements / DPI / OTN</div>
<div class="profil-card">
<div class="profil-item">
<div class="profil-item-icon" style="background:#1565C0;color:white;">💳</div>
<div class="profil-item-text">
<div class="profil-item-title">Portefeuille numérique</div>
<div class="profil-item-sub">Solde Wallet · Identité DPI</div>
</div>
<div class="profil-item-right"><span style="font-weight:700;color:var(--primary-500);">45,80 €</span></div>
</div>
<div class="profil-item">
<div class="profil-item-icon" style="background:#3949AB;color:white;">🛒</div>
<div class="profil-item-text">
<div class="profil-item-title">Mes commandes</div>
<div class="profil-item-sub">3 en cours · 12 terminées</div>
</div>
<div class="profil-item-right"><span class="badge" style="position:static;">3</span></div>
</div>
<div class="profil-item">
<div class="profil-item-icon" style="background:#00ACC1;color:white;">🪪</div>
<div class="profil-item-text">
<div class="profil-item-title">Identité DID</div>
<div class="profil-item-sub">did:smartcity:mq:0x8f2a...</div>
</div>
<div class="profil-item-right"><span class="profil-badge" style="background:#E8F5E9;color:#2E7D32;">✓ Vérifié</span></div>
</div>
</div>
</div>
<div class="section-divider"></div>
<!-- Signalements ODK -->
<div class="profil-section">
<div class="profil-section-title">📸 Signalements ODK</div>
<div class="profil-card">
<div class="profil-item">
<div class="profil-item-icon" style="background:#FFF3E0;">📋</div>
<div class="profil-item-text">
<div class="profil-item-title">Mes signalements</div>
<div class="profil-item-sub">27 soumis · 18 résolus</div>
</div>
<div class="profil-item-right"></div>
</div>
<div class="profil-item">
<div class="profil-item-icon" style="background:#E3F2FD;">📝</div>
<div class="profil-item-text">
<div class="profil-item-title">Formulaires ODK</div>
<div class="profil-item-sub">Saisie terrain hors-ligne</div>
</div>
<div class="profil-item-right"></div>
</div>
<div class="profil-item">
<div class="profil-item-icon" style="background:#E8F5E9;"></div>
<div class="profil-item-text">
<div class="profil-item-title">Validés</div>
<div class="profil-item-sub">Approuvés par la collectivité</div>
</div>
<div class="profil-item-right"><span class="profil-badge" style="background:#E8F5E9;color:#2E7D32;">18</span></div>
</div>
</div>
</div>
<div style="height:24px;"></div>
</div>
<!-- Bottom Nav -->
<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 class="page-label" style="position:absolute;bottom:88px;left:0;right:0;text-align:center;font-size:10px;color:var(--neutral-400);">06 — Profil Utilisateur · Blue v2</div>
</div>
</body>
</html>