Bootstrap
Bootstrap4
Dashboard
Admin
Statistiques
Html
Variante Bootstrap 4 de dashboard administrateur avec cartes de statistiques, graphiques et tableaux de données.
<!DOCTYPE html>
<html lang="fr" data-bs-theme="light">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Boitify — Dashboard v1 (ApexCharts)</title>
<!-- Bootstrap 5 -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" />
<!-- Bootstrap Icons -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css" rel="stylesheet" />
<!-- Google Fonts -->
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet" />
<!-- ApexCharts -->
<link href="https://cdn.jsdelivr.net/npm/apexcharts@3.49.0/dist/apexcharts.css" rel="stylesheet" />
<style>
:root {
--sidebar-width: 260px;
--sidebar-collapsed-width: 68px;
--topbar-height: 64px;
--primary: #6366f1;
--primary-light: #eef2ff;
--success: #22c55e;
--warning: #f59e0b;
--danger: #ef4444;
--info: #06b6d4;
--sidebar-bg: #0f172a;
--sidebar-text: #94a3b8;
--sidebar-active-bg: rgba(99,102,241,.15);
--sidebar-active-text: #6366f1;
--body-bg: #f1f5f9;
--card-bg: #ffffff;
--border-color: #e2e8f0;
--text-muted: #64748b;
--text-dark: #0f172a;
}
* { box-sizing: border-box; }
body {
font-family: 'Inter', sans-serif;
background: var(--body-bg);
color: var(--text-dark);
margin: 0;
overflow-x: hidden;
}
/* ── SIDEBAR ──────────────────────────────── */
#sidebar {
position: fixed;
top: 0; left: 0; bottom: 0;
width: var(--sidebar-width);
background: var(--sidebar-bg);
transition: width .25s ease;
z-index: 1040;
display: flex;
flex-direction: column;
overflow: hidden;
}
#sidebar.collapsed { width: var(--sidebar-collapsed-width); }
.sidebar-brand {
display: flex;
align-items: center;
gap: 12px;
padding: 20px 18px;
border-bottom: 1px solid rgba(255,255,255,.06);
min-height: var(--topbar-height);
text-decoration: none;
}
.sidebar-brand .brand-icon {
width: 36px; height: 36px;
border-radius: 10px;
background: var(--primary);
display: flex; align-items: center; justify-content: center;
flex-shrink: 0;
font-size: 18px; color: #fff;
}
.sidebar-brand .brand-name {
font-size: 18px; font-weight: 700;
color: #fff; white-space: nowrap;
transition: opacity .2s;
}
#sidebar.collapsed .brand-name { opacity: 0; pointer-events: none; }
.sidebar-scroll {
flex: 1;
overflow-y: auto;
overflow-x: hidden;
padding: 12px 0;
}
.sidebar-scroll::-webkit-scrollbar { width: 4px; }
.sidebar-scroll::-webkit-scrollbar-thumb { background: rgba(255,255,255,.1); border-radius: 4px; }
.nav-section-label {
font-size: 10px; font-weight: 600;
letter-spacing: .08em;
text-transform: uppercase;
color: #475569;
padding: 14px 18px 6px;
white-space: nowrap;
transition: opacity .2s;
}
#sidebar.collapsed .nav-section-label { opacity: 0; }
.nav-item-link {
display: flex;
align-items: center;
gap: 12px;
padding: 10px 18px;
text-decoration: none;
color: var(--sidebar-text);
border-radius: 0;
font-size: 13.5px;
font-weight: 500;
white-space: nowrap;
transition: background .15s, color .15s;
position: relative;
}
.nav-item-link .nav-icon {
font-size: 18px;
flex-shrink: 0;
width: 32px; height: 32px;
display: flex; align-items: center; justify-content: center;
}
.nav-item-link .nav-label { transition: opacity .2s; }
#sidebar.collapsed .nav-item-link .nav-label { opacity: 0; }
.nav-item-link .nav-badge {
margin-left: auto;
font-size: 10px; font-weight: 700;
background: var(--primary);
color: #fff;
padding: 2px 7px;
border-radius: 20px;
transition: opacity .2s;
}
#sidebar.collapsed .nav-badge { opacity: 0; }
.nav-item-link:hover { background: rgba(255,255,255,.05); color: #e2e8f0; }
.nav-item-link.active {
background: var(--sidebar-active-bg);
color: var(--sidebar-active-text);
}
.nav-item-link.active::before {
content: '';
position: absolute; left: 0; top: 6px; bottom: 6px;
width: 3px;
background: var(--primary);
border-radius: 0 3px 3px 0;
}
.sidebar-footer {
padding: 12px 10px;
border-top: 1px solid rgba(255,255,255,.06);
}
.sidebar-user {
display: flex; align-items: center; gap: 10px;
padding: 8px 8px;
border-radius: 10px;
text-decoration: none;
transition: background .15s;
}
.sidebar-user:hover { background: rgba(255,255,255,.06); }
.sidebar-user img {
width: 34px; height: 34px;
border-radius: 50%; flex-shrink: 0;
object-fit: cover; border: 2px solid rgba(255,255,255,.15);
}
.sidebar-user .user-info { min-width: 0; transition: opacity .2s; }
#sidebar.collapsed .user-info { opacity: 0; }
.sidebar-user .user-name { font-size: 13px; font-weight: 600; color: #e2e8f0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sidebar-user .user-role { font-size: 11px; color: #64748b; white-space: nowrap; }
/* ── TOPBAR ───────────────────────────────── */
#topbar {
position: fixed;
top: 0;
left: var(--sidebar-width);
right: 0;
height: var(--topbar-height);
background: var(--card-bg);
border-bottom: 1px solid var(--border-color);
display: flex;
align-items: center;
padding: 0 24px;
gap: 12px;
z-index: 1030;
transition: left .25s ease;
}
#sidebar.collapsed ~ #topbar { left: var(--sidebar-collapsed-width); }
.topbar-toggle {
background: none; border: none;
width: 36px; height: 36px;
border-radius: 8px;
display: flex; align-items: center; justify-content: center;
cursor: pointer; color: var(--text-muted);
font-size: 20px;
transition: background .15s;
}
.topbar-toggle:hover { background: var(--body-bg); }
.topbar-search {
flex: 1; max-width: 340px;
position: relative;
}
.topbar-search input {
width: 100%;
background: var(--body-bg);
border: 1px solid var(--border-color);
border-radius: 10px;
padding: 8px 14px 8px 38px;
font-size: 13.5px;
color: var(--text-dark);
outline: none;
transition: border-color .15s;
font-family: 'Inter', sans-serif;
}
.topbar-search input:focus { border-color: var(--primary); }
.topbar-search .search-icon {
position: absolute; left: 12px; top: 50%;
transform: translateY(-50%);
color: var(--text-muted); font-size: 15px;
}
.topbar-actions { margin-left: auto; display: flex; align-items: center; gap: 8px; }
.topbar-btn {
width: 38px; height: 38px;
border-radius: 10px;
background: var(--body-bg);
border: 1px solid var(--border-color);
display: flex; align-items: center; justify-content: center;
color: var(--text-muted);
cursor: pointer; font-size: 18px;
text-decoration: none;
position: relative;
transition: background .15s, border-color .15s;
}
.topbar-btn:hover { background: #e2e8f0; color: var(--text-dark); }
.topbar-btn .badge-dot {
position: absolute; top: 6px; right: 6px;
width: 8px; height: 8px;
border-radius: 50%;
background: var(--danger);
border: 2px solid var(--card-bg);
}
.topbar-avatar {
width: 38px; height: 38px;
border-radius: 10px;
overflow: hidden; cursor: pointer;
border: 2px solid var(--border-color);
}
.topbar-avatar img { width: 100%; height: 100%; object-fit: cover; }
/* ── MAIN CONTENT ─────────────────────────── */
.main-wrapper {
margin-left: var(--sidebar-width);
padding-top: var(--topbar-height);
transition: margin-left .25s ease;
}
#sidebar.collapsed ~ .main-wrapper { margin-left: var(--sidebar-collapsed-width); }
.page-content { padding: 28px 28px; }
/* ── PAGE HEADER ──────────────────────────── */
.page-title { font-size: 22px; font-weight: 700; margin: 0; }
.page-subtitle { font-size: 13px; color: var(--text-muted); margin-top: 3px; }
/* ── STAT CARDS ───────────────────────────── */
.stat-card {
background: var(--card-bg);
border-radius: 16px;
padding: 22px 22px;
border: 1px solid var(--border-color);
position: relative;
overflow: hidden;
}
.stat-card .stat-icon {
width: 48px; height: 48px;
border-radius: 12px;
display: flex; align-items: center; justify-content: center;
font-size: 22px;
margin-bottom: 14px;
}
.stat-card .stat-value { font-size: 26px; font-weight: 700; line-height: 1; }
.stat-card .stat-label { font-size: 13px; color: var(--text-muted); margin-top: 4px; }
.stat-card .stat-change {
display: inline-flex; align-items: center; gap: 3px;
font-size: 12px; font-weight: 600;
padding: 3px 8px; border-radius: 20px;
margin-top: 10px;
}
.stat-card .stat-change.up { background: #dcfce7; color: #16a34a; }
.stat-card .stat-change.down { background: #fee2e2; color: #dc2626; }
.stat-card .stat-sparkline { position: absolute; bottom: 0; right: 0; opacity: .6; }
/* ── DASH CARD ────────────────────────────── */
.dash-card {
background: var(--card-bg);
border-radius: 16px;
border: 1px solid var(--border-color);
overflow: hidden;
}
.dash-card .card-header-custom {
display: flex; align-items: center; justify-content: space-between;
padding: 18px 22px 0;
}
.dash-card .card-title-custom { font-size: 15px; font-weight: 700; }
.dash-card .card-subtitle-custom { font-size: 12px; color: var(--text-muted); margin-top: 2px; }
.dash-card .card-body-custom { padding: 18px 22px; }
/* ── TABLE ────────────────────────────────── */
.orders-table { font-size: 13.5px; }
.orders-table thead th {
font-size: 11px; font-weight: 600;
letter-spacing: .06em; text-transform: uppercase;
color: var(--text-muted);
padding: 12px 16px;
background: var(--body-bg);
border-bottom: 1px solid var(--border-color);
}
.orders-table tbody td {
padding: 13px 16px;
vertical-align: middle;
border-bottom: 1px solid var(--border-color);
}
.orders-table tbody tr:last-child td { border-bottom: none; }
.orders-table tbody tr:hover { background: #f8fafc; }
.order-product-img {
width: 40px; height: 40px;
border-radius: 10px;
background: var(--primary-light);
display: flex; align-items: center; justify-content: center;
color: var(--primary); font-size: 18px;
}
.badge-status {
font-size: 11px; font-weight: 600;
padding: 4px 10px;
border-radius: 20px;
display: inline-block;
}
.badge-status.delivered { background: #dcfce7; color: #16a34a; }
.badge-status.pending { background: #fef9c3; color: #a16207; }
.badge-status.processing { background: #dbeafe; color: #1d4ed8; }
.badge-status.cancelled { background: #fee2e2; color: #dc2626; }
/* ── PROGRESS ─────────────────────────────── */
.product-progress .pp-info { display: flex; justify-content: space-between; margin-bottom: 5px; font-size: 13px; }
.product-progress .pp-bar { height: 6px; border-radius: 99px; background: #e2e8f0; overflow: hidden; }
.product-progress .pp-fill { height: 100%; border-radius: 99px; }
/* ── ACTIVITY ─────────────────────────────── */
.activity-item {
display: flex; gap: 14px;
padding: 12px 0;
border-bottom: 1px solid var(--border-color);
}
.activity-item:last-child { border-bottom: none; }
.activity-avatar {
width: 38px; height: 38px;
border-radius: 10px;
flex-shrink: 0;
display: flex; align-items: center; justify-content: center;
font-size: 17px;
}
.activity-text { font-size: 13px; line-height: 1.5; }
.activity-time { font-size: 11px; color: var(--text-muted); margin-top: 2px; }
/* ── TRAFFIC ──────────────────────────────── */
.traffic-item { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; }
.traffic-item:last-child { margin-bottom: 0; }
.traffic-dot { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; }
.traffic-label { font-size: 13px; flex: 1; }
.traffic-value { font-size: 13px; font-weight: 600; }
.traffic-pct { font-size: 12px; color: var(--text-muted); width: 36px; text-align: right; }
/* ── DARK THEME ───────────────────────────── */
[data-bs-theme="dark"] {
--body-bg: #0d1117;
--card-bg: #161b22;
--border-color: #21262d;
--text-dark: #e6edf3;
--text-muted: #7d8590;
}
[data-bs-theme="dark"] .orders-table tbody tr:hover { background: #1c2128; }
[data-bs-theme="dark"] .orders-table thead th { background: #0d1117; }
[data-bs-theme="dark"] .topbar-search input { background: #0d1117; color: #e6edf3; }
[data-bs-theme="dark"] .topbar-btn { background: #0d1117; }
[data-bs-theme="dark"] .topbar-toggle:hover { background: #21262d; }
/* ── RESPONSIVE ───────────────────────────── */
@media (max-width: 991.98px) {
#sidebar { transform: translateX(-100%); width: var(--sidebar-width) !important; }
#sidebar.mobile-open { transform: translateX(0); }
.main-wrapper { margin-left: 0 !important; }
#topbar { left: 0 !important; }
.sidebar-overlay { display: block !important; }
}
.sidebar-overlay {
display: none;
position: fixed; inset: 0;
background: rgba(0,0,0,.5);
z-index: 1039;
}
.dropdown-menu { border: 1px solid var(--border-color); border-radius: 12px; box-shadow: 0 8px 24px rgba(0,0,0,.1); font-size: 13.5px; }
.dropdown-item { padding: 9px 16px; border-radius: 8px; }
/* version badge */
.version-badge {
position: fixed; bottom: 16px; right: 16px;
background: var(--primary); color: #fff;
font-size: 11px; font-weight: 700;
padding: 5px 12px; border-radius: 20px;
z-index: 9999;
box-shadow: 0 4px 12px rgba(99,102,241,.4);
}
</style>
</head>
<body>
<div class="version-badge"><i class="bi bi-stars me-1"></i>Version 1 — ApexCharts</div>
<div class="sidebar-overlay" id="sidebarOverlay" onclick="toggleSidebar()"></div>
<!-- ══ SIDEBAR ══ -->
<nav id="sidebar">
<a href="#" class="sidebar-brand">
<div class="brand-icon"><i class="bi bi-box-seam-fill"></i></div>
<span class="brand-name">Boitify</span>
</a>
<div class="sidebar-scroll">
<div class="nav-section-label">Principal</div>
<a href="#" class="nav-item-link active">
<span class="nav-icon"><i class="bi bi-grid-fill"></i></span>
<span class="nav-label">Tableau de bord</span>
</a>
<a href="#" class="nav-item-link">
<span class="nav-icon"><i class="bi bi-bar-chart-line-fill"></i></span>
<span class="nav-label">Analytiques</span>
</a>
<a href="#" class="nav-item-link">
<span class="nav-icon"><i class="bi bi-wallet2"></i></span>
<span class="nav-label">Revenus</span>
</a>
<div class="nav-section-label">Boutique</div>
<a href="#" class="nav-item-link">
<span class="nav-icon"><i class="bi bi-bag-fill"></i></span>
<span class="nav-label">Produits</span>
</a>
<a href="#" class="nav-item-link">
<span class="nav-icon"><i class="bi bi-receipt-cutoff"></i></span>
<span class="nav-label">Commandes</span>
<span class="nav-badge">12</span>
</a>
<a href="#" class="nav-item-link">
<span class="nav-icon"><i class="bi bi-people-fill"></i></span>
<span class="nav-label">Clients</span>
</a>
<a href="#" class="nav-item-link">
<span class="nav-icon"><i class="bi bi-truck"></i></span>
<span class="nav-label">Livraisons</span>
</a>
<a href="#" class="nav-item-link">
<span class="nav-icon"><i class="bi bi-percent"></i></span>
<span class="nav-label">Promotions</span>
</a>
<a href="#" class="nav-item-link">
<span class="nav-icon"><i class="bi bi-star-fill"></i></span>
<span class="nav-label">Avis clients</span>
<span class="nav-badge">5</span>
</a>
<div class="nav-section-label">Configuration</div>
<a href="#" class="nav-item-link">
<span class="nav-icon"><i class="bi bi-gear-fill"></i></span>
<span class="nav-label">Paramètres</span>
</a>
<a href="#" class="nav-item-link">
<span class="nav-icon"><i class="bi bi-shield-fill-check"></i></span>
<span class="nav-label">Sécurité</span>
</a>
<a href="#" class="nav-item-link">
<span class="nav-icon"><i class="bi bi-question-circle-fill"></i></span>
<span class="nav-label">Aide & Support</span>
</a>
</div>
<div class="sidebar-footer">
<a href="#" class="sidebar-user">
<img src="https://i.pravatar.cc/80?img=11" alt="user" />
<div class="user-info">
<div class="user-name">Mezga Admin</div>
<div class="user-role">Super Administrateur</div>
</div>
</a>
</div>
</nav>
<!-- ══ TOPBAR ══ -->
<header id="topbar">
<button class="topbar-toggle" onclick="toggleSidebar()">
<i class="bi bi-list"></i>
</button>
<div class="topbar-search d-none d-md-block">
<i class="bi bi-search search-icon"></i>
<input type="text" placeholder="Rechercher produits, commandes…" />
</div>
<div class="topbar-actions">
<button class="topbar-btn" id="themeToggle" title="Thème" onclick="toggleTheme()">
<i class="bi bi-moon-stars-fill"></i>
</button>
<div class="dropdown">
<button class="topbar-btn" data-bs-toggle="dropdown">
<i class="bi bi-bell-fill"></i>
<span class="badge-dot"></span>
</button>
<ul class="dropdown-menu dropdown-menu-end" style="width:320px;padding:8px;">
<li><h6 class="dropdown-header fw-bold" style="font-size:13px;">Notifications (4)</h6></li>
<li><hr class="dropdown-divider my-1"></li>
<li>
<a class="dropdown-item d-flex gap-2 align-items-start py-2" href="#">
<span style="width:36px;height:36px;border-radius:10px;background:#dbeafe;display:flex;align-items:center;justify-content:center;color:#1d4ed8;flex-shrink:0;font-size:16px;"><i class="bi bi-cart-check-fill"></i></span>
<div><div style="font-size:13px;font-weight:500;">Nouvelle commande #ORD-8821</div><div style="font-size:11.5px;color:var(--text-muted);">il y a 5 minutes</div></div>
</a>
</li>
<li>
<a class="dropdown-item d-flex gap-2 align-items-start py-2" href="#">
<span style="width:36px;height:36px;border-radius:10px;background:#dcfce7;display:flex;align-items:center;justify-content:center;color:#16a34a;flex-shrink:0;font-size:16px;"><i class="bi bi-person-plus-fill"></i></span>
<div><div style="font-size:13px;font-weight:500;">Nouveau client inscrit</div><div style="font-size:11.5px;color:var(--text-muted);">il y a 23 minutes</div></div>
</a>
</li>
<li>
<a class="dropdown-item d-flex gap-2 align-items-start py-2" href="#">
<span style="width:36px;height:36px;border-radius:10px;background:#fef3c7;display:flex;align-items:center;justify-content:center;color:#d97706;flex-shrink:0;font-size:16px;"><i class="bi bi-exclamation-triangle-fill"></i></span>
<div><div style="font-size:13px;font-weight:500;">Stock faible: T-shirt Premium</div><div style="font-size:11.5px;color:var(--text-muted);">il y a 1 heure</div></div>
</a>
</li>
<li><hr class="dropdown-divider my-1"></li>
<li><a class="dropdown-item text-center py-2" href="#" style="font-size:13px;color:var(--primary);">Voir toutes les notifications</a></li>
</ul>
</div>
<button class="topbar-btn"><i class="bi bi-chat-dots-fill"></i></button>
<div class="dropdown">
<div class="topbar-avatar" data-bs-toggle="dropdown">
<img src="https://i.pravatar.cc/80?img=11" alt="avatar" />
</div>
<ul class="dropdown-menu dropdown-menu-end" style="min-width:200px;padding:8px;">
<li>
<div class="px-3 py-2">
<div style="font-size:14px;font-weight:600;">Mezga Admin</div>
<div style="font-size:12px;color:var(--text-muted);">admin@boitify.com</div>
</div>
</li>
<li><hr class="dropdown-divider my-1"></li>
<li><a class="dropdown-item" href="#"><i class="bi bi-person me-2"></i>Mon profil</a></li>
<li><a class="dropdown-item" href="#"><i class="bi bi-gear me-2"></i>Paramètres</a></li>
<li><hr class="dropdown-divider my-1"></li>
<li><a class="dropdown-item text-danger" href="#"><i class="bi bi-box-arrow-right me-2"></i>Déconnexion</a></li>
</ul>
</div>
</div>
</header>
<!-- ══ MAIN CONTENT ══ -->
<div class="main-wrapper">
<div class="page-content">
<!-- Page Header -->
<div class="d-flex flex-wrap align-items-start justify-content-between gap-3 mb-4">
<div>
<h1 class="page-title">Tableau de bord</h1>
<p class="page-subtitle">Bienvenue, Mezga ! Voici un aperçu de votre boutique.</p>
</div>
<div class="d-flex gap-2">
<button class="btn btn-outline-secondary btn-sm d-flex align-items-center gap-2" style="border-radius:10px;font-size:13px;">
<i class="bi bi-calendar3"></i> Avr 2026
</button>
<button class="btn btn-sm d-flex align-items-center gap-2" style="border-radius:10px;font-size:13px;background:var(--primary);color:#fff;border:none;">
<i class="bi bi-download"></i> Rapport
</button>
</div>
</div>
<!-- STAT CARDS -->
<div class="row g-3 mb-4">
<div class="col-6 col-xl-3">
<div class="stat-card">
<div class="stat-icon" style="background:#eef2ff;color:#6366f1;"><i class="bi bi-bag-check-fill"></i></div>
<div class="stat-value">8 942</div>
<div class="stat-label">Total commandes</div>
<span class="stat-change up"><i class="bi bi-arrow-up-short"></i>+12.4%</span>
<div id="spark1" class="stat-sparkline"></div>
</div>
</div>
<div class="col-6 col-xl-3">
<div class="stat-card">
<div class="stat-icon" style="background:#dcfce7;color:#16a34a;"><i class="bi bi-currency-euro"></i></div>
<div class="stat-value">€142 K</div>
<div class="stat-label">Chiffre d'affaires</div>
<span class="stat-change up"><i class="bi bi-arrow-up-short"></i>+8.1%</span>
<div id="spark2" class="stat-sparkline"></div>
</div>
</div>
<div class="col-6 col-xl-3">
<div class="stat-card">
<div class="stat-icon" style="background:#fef3c7;color:#d97706;"><i class="bi bi-people-fill"></i></div>
<div class="stat-value">24 610</div>
<div class="stat-label">Clients actifs</div>
<span class="stat-change up"><i class="bi bi-arrow-up-short"></i>+5.3%</span>
<div id="spark3" class="stat-sparkline"></div>
</div>
</div>
<div class="col-6 col-xl-3">
<div class="stat-card">
<div class="stat-icon" style="background:#fee2e2;color:#ef4444;"><i class="bi bi-arrow-return-left"></i></div>
<div class="stat-value">1.8%</div>
<div class="stat-label">Taux de retour</div>
<span class="stat-change down"><i class="bi bi-arrow-down-short"></i>-0.4%</span>
<div id="spark4" class="stat-sparkline"></div>
</div>
</div>
</div>
<!-- CHART + TRAFFIC -->
<div class="row g-3 mb-3">
<div class="col-12 col-xl-8">
<div class="dash-card h-100">
<div class="card-header-custom">
<div>
<div class="card-title-custom">Évolution des ventes</div>
<div class="card-subtitle-custom">Revenus mensuels 2026</div>
</div>
<div class="d-flex gap-2">
<button class="btn btn-sm" id="btn-monthly" onclick="switchChart('monthly',this)"
style="border-radius:8px;font-size:12px;background:var(--primary);color:#fff;border:none;padding:5px 14px;">Mensuel</button>
<button class="btn btn-sm" id="btn-weekly" onclick="switchChart('weekly',this)"
style="border-radius:8px;font-size:12px;border:1px solid var(--border-color);padding:5px 14px;">Hebdo</button>
</div>
</div>
<div class="card-body-custom">
<div id="revenueChart"></div>
</div>
</div>
</div>
<div class="col-12 col-xl-4">
<div class="dash-card h-100">
<div class="card-header-custom">
<div>
<div class="card-title-custom">Sources de trafic</div>
<div class="card-subtitle-custom">Répartition des visiteurs</div>
</div>
</div>
<div class="card-body-custom">
<div id="donutChart" style="margin-top:-10px;"></div>
<div class="traffic-item mt-3">
<div class="traffic-dot" style="background:#6366f1;"></div>
<div class="traffic-label">Organique (SEO)</div>
<div class="traffic-value">38 240</div>
<div class="traffic-pct">42%</div>
</div>
<div class="traffic-item">
<div class="traffic-dot" style="background:#06b6d4;"></div>
<div class="traffic-label">Réseaux sociaux</div>
<div class="traffic-value">24 100</div>
<div class="traffic-pct">26%</div>
</div>
<div class="traffic-item">
<div class="traffic-dot" style="background:#f59e0b;"></div>
<div class="traffic-label">Publicités payantes</div>
<div class="traffic-value">18 500</div>
<div class="traffic-pct">20%</div>
</div>
<div class="traffic-item">
<div class="traffic-dot" style="background:#22c55e;"></div>
<div class="traffic-label">Référencement direct</div>
<div class="traffic-value">10 900</div>
<div class="traffic-pct">12%</div>
</div>
</div>
</div>
</div>
</div>
<!-- ORDERS + ACTIVITY -->
<div class="row g-3 mb-3">
<div class="col-12 col-xl-8">
<div class="dash-card">
<div class="card-header-custom pb-3">
<div>
<div class="card-title-custom">Commandes récentes</div>
<div class="card-subtitle-custom">12 nouvelles aujourd'hui</div>
</div>
<a href="#" class="btn btn-sm btn-outline-secondary" style="border-radius:8px;font-size:12px;">Voir tout</a>
</div>
<div class="table-responsive">
<table class="table orders-table mb-0">
<thead>
<tr>
<th>Produit</th>
<th>ID Commande</th>
<th>Client</th>
<th>Date</th>
<th>Montant</th>
<th>Statut</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div class="d-flex align-items-center gap-2">
<div class="order-product-img"><i class="bi bi-phone-fill"></i></div>
<span style="font-weight:600;">iPhone 16 Pro</span>
</div>
</td>
<td style="color:var(--text-muted);">#ORD-8821</td>
<td>Sarah K.</td>
<td style="color:var(--text-muted);">05 Avr 2026</td>
<td style="font-weight:700;">€1 299</td>
<td><span class="badge-status delivered">Livré</span></td>
<td><button class="btn btn-sm p-0" style="color:var(--text-muted);"><i class="bi bi-three-dots-vertical"></i></button></td>
</tr>
<tr>
<td>
<div class="d-flex align-items-center gap-2">
<div class="order-product-img" style="background:#fef3c7;color:#d97706;"><i class="bi bi-laptop-fill"></i></div>
<span style="font-weight:600;">MacBook Air M3</span>
</div>
</td>
<td style="color:var(--text-muted);">#ORD-8820</td>
<td>Ahmed B.</td>
<td style="color:var(--text-muted);">05 Avr 2026</td>
<td style="font-weight:700;">€1 499</td>
<td><span class="badge-status processing">En cours</span></td>
<td><button class="btn btn-sm p-0" style="color:var(--text-muted);"><i class="bi bi-three-dots-vertical"></i></button></td>
</tr>
<tr>
<td>
<div class="d-flex align-items-center gap-2">
<div class="order-product-img" style="background:#dcfce7;color:#16a34a;"><i class="bi bi-headphones"></i></div>
<span style="font-weight:600;">AirPods Pro 3</span>
</div>
</td>
<td style="color:var(--text-muted);">#ORD-8819</td>
<td>Marie L.</td>
<td style="color:var(--text-muted);">04 Avr 2026</td>
<td style="font-weight:700;">€279</td>
<td><span class="badge-status pending">En attente</span></td>
<td><button class="btn btn-sm p-0" style="color:var(--text-muted);"><i class="bi bi-three-dots-vertical"></i></button></td>
</tr>
<tr>
<td>
<div class="d-flex align-items-center gap-2">
<div class="order-product-img" style="background:#e0e7ff;color:#4338ca;"><i class="bi bi-watch"></i></div>
<span style="font-weight:600;">Apple Watch S10</span>
</div>
</td>
<td style="color:var(--text-muted);">#ORD-8818</td>
<td>Lucas M.</td>
<td style="color:var(--text-muted);">04 Avr 2026</td>
<td style="font-weight:700;">€449</td>
<td><span class="badge-status delivered">Livré</span></td>
<td><button class="btn btn-sm p-0" style="color:var(--text-muted);"><i class="bi bi-three-dots-vertical"></i></button></td>
</tr>
<tr>
<td>
<div class="d-flex align-items-center gap-2">
<div class="order-product-img" style="background:#fee2e2;color:#ef4444;"><i class="bi bi-camera-fill"></i></div>
<span style="font-weight:600;">Sony A7C II</span>
</div>
</td>
<td style="color:var(--text-muted);">#ORD-8817</td>
<td>Nina T.</td>
<td style="color:var(--text-muted);">03 Avr 2026</td>
<td style="font-weight:700;">€2 199</td>
<td><span class="badge-status cancelled">Annulé</span></td>
<td><button class="btn btn-sm p-0" style="color:var(--text-muted);"><i class="bi bi-three-dots-vertical"></i></button></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="col-12 col-xl-4">
<div class="dash-card h-100">
<div class="card-header-custom">
<div>
<div class="card-title-custom">Activité récente</div>
<div class="card-subtitle-custom">Dernières actions</div>
</div>
</div>
<div class="card-body-custom">
<div class="activity-item">
<div class="activity-avatar" style="background:#eef2ff;color:#6366f1;"><i class="bi bi-cart-plus-fill"></i></div>
<div>
<div class="activity-text"><strong>Commande #8821</strong> passée par Sarah K.</div>
<div class="activity-time"><i class="bi bi-clock me-1"></i>il y a 5 min</div>
</div>
</div>
<div class="activity-item">
<div class="activity-avatar" style="background:#dcfce7;color:#16a34a;"><i class="bi bi-person-check-fill"></i></div>
<div>
<div class="activity-text">Nouveau client <strong>Emma D.</strong> inscrit</div>
<div class="activity-time"><i class="bi bi-clock me-1"></i>il y a 22 min</div>
</div>
</div>
<div class="activity-item">
<div class="activity-avatar" style="background:#fef3c7;color:#d97706;"><i class="bi bi-star-fill"></i></div>
<div>
<div class="activity-text"><strong>Avis 5⭐</strong> pour iPhone 16 Pro</div>
<div class="activity-time"><i class="bi bi-clock me-1"></i>il y a 47 min</div>
</div>
</div>
<div class="activity-item">
<div class="activity-avatar" style="background:#fee2e2;color:#ef4444;"><i class="bi bi-exclamation-triangle-fill"></i></div>
<div>
<div class="activity-text">Stock bas : <strong>T-shirt Premium</strong> (3 restants)</div>
<div class="activity-time"><i class="bi bi-clock me-1"></i>il y a 1 h</div>
</div>
</div>
<div class="activity-item">
<div class="activity-avatar" style="background:#e0e7ff;color:#4338ca;"><i class="bi bi-truck"></i></div>
<div>
<div class="activity-text">Livraison expédiée pour <strong>#ORD-8812</strong></div>
<div class="activity-time"><i class="bi bi-clock me-1"></i>il y a 2 h</div>
</div>
</div>
<div class="activity-item">
<div class="activity-avatar" style="background:#f0fdf4;color:#15803d;"><i class="bi bi-tag-fill"></i></div>
<div>
<div class="activity-text">Promo <strong>SUMMER20</strong> activée (+120 usages)</div>
<div class="activity-time"><i class="bi bi-clock me-1"></i>il y a 3 h</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- TOP PRODUCTS + FUNNEL + SATISFACTION -->
<div class="row g-3">
<div class="col-12 col-md-6 col-xl-4">
<div class="dash-card h-100">
<div class="card-header-custom">
<div>
<div class="card-title-custom">Top produits</div>
<div class="card-subtitle-custom">Par volume de ventes</div>
</div>
</div>
<div class="card-body-custom d-flex flex-column gap-4">
<div class="product-progress">
<div class="pp-info"><span>iPhone 16 Pro</span><span style="font-weight:600;">842 ventes</span></div>
<div class="pp-bar"><div class="pp-fill" style="width:84%;background:#6366f1;"></div></div>
</div>
<div class="product-progress">
<div class="pp-info"><span>MacBook Air M3</span><span style="font-weight:600;">614 ventes</span></div>
<div class="pp-bar"><div class="pp-fill" style="width:61%;background:#06b6d4;"></div></div>
</div>
<div class="product-progress">
<div class="pp-info"><span>AirPods Pro 3</span><span style="font-weight:600;">529 ventes</span></div>
<div class="pp-bar"><div class="pp-fill" style="width:53%;background:#22c55e;"></div></div>
</div>
<div class="product-progress">
<div class="pp-info"><span>Apple Watch S10</span><span style="font-weight:600;">411 ventes</span></div>
<div class="pp-bar"><div class="pp-fill" style="width:41%;background:#f59e0b;"></div></div>
</div>
<div class="product-progress">
<div class="pp-info"><span>Sony A7C II</span><span style="font-weight:600;">298 ventes</span></div>
<div class="pp-bar"><div class="pp-fill" style="width:30%;background:#ef4444;"></div></div>
</div>
</div>
</div>
</div>
<div class="col-12 col-md-6 col-xl-4">
<div class="dash-card h-100">
<div class="card-header-custom">
<div>
<div class="card-title-custom">Entonnoir de conversion</div>
<div class="card-subtitle-custom">Parcours client</div>
</div>
</div>
<div class="card-body-custom">
<div id="funnelChart"></div>
</div>
</div>
</div>
<div class="col-12 col-xl-4">
<div class="dash-card h-100">
<div class="card-header-custom">
<div>
<div class="card-title-custom">Satisfaction client</div>
<div class="card-subtitle-custom">Note moyenne : 4.7 / 5</div>
</div>
</div>
<div class="card-body-custom">
<div class="text-center mb-4">
<div style="font-size:52px;font-weight:800;color:var(--primary);line-height:1;">4.7</div>
<div style="color:#f59e0b;font-size:20px;margin-top:4px;">★★★★★</div>
<div style="font-size:12px;color:var(--text-muted);margin-top:4px;">1 284 avis</div>
</div>
<div class="d-flex flex-column gap-2">
<div class="d-flex align-items-center gap-2" style="font-size:13px;">
<span style="width:14px;text-align:right;">5</span>
<i class="bi bi-star-fill" style="color:#f59e0b;font-size:11px;"></i>
<div class="flex-grow-1" style="background:#e2e8f0;border-radius:99px;height:8px;overflow:hidden;">
<div style="width:72%;height:100%;background:#f59e0b;border-radius:99px;"></div>
</div>
<span style="width:32px;text-align:right;color:var(--text-muted);">72%</span>
</div>
<div class="d-flex align-items-center gap-2" style="font-size:13px;">
<span style="width:14px;text-align:right;">4</span>
<i class="bi bi-star-fill" style="color:#f59e0b;font-size:11px;"></i>
<div class="flex-grow-1" style="background:#e2e8f0;border-radius:99px;height:8px;overflow:hidden;">
<div style="width:18%;height:100%;background:#f59e0b;border-radius:99px;"></div>
</div>
<span style="width:32px;text-align:right;color:var(--text-muted);">18%</span>
</div>
<div class="d-flex align-items-center gap-2" style="font-size:13px;">
<span style="width:14px;text-align:right;">3</span>
<i class="bi bi-star-fill" style="color:#f59e0b;font-size:11px;"></i>
<div class="flex-grow-1" style="background:#e2e8f0;border-radius:99px;height:8px;overflow:hidden;">
<div style="width:6%;height:100%;background:#f59e0b;border-radius:99px;"></div>
</div>
<span style="width:32px;text-align:right;color:var(--text-muted);">6%</span>
</div>
<div class="d-flex align-items-center gap-2" style="font-size:13px;">
<span style="width:14px;text-align:right;">2</span>
<i class="bi bi-star-fill" style="color:#f59e0b;font-size:11px;"></i>
<div class="flex-grow-1" style="background:#e2e8f0;border-radius:99px;height:8px;overflow:hidden;">
<div style="width:3%;height:100%;background:#f59e0b;border-radius:99px;"></div>
</div>
<span style="width:32px;text-align:right;color:var(--text-muted);">3%</span>
</div>
<div class="d-flex align-items-center gap-2" style="font-size:13px;">
<span style="width:14px;text-align:right;">1</span>
<i class="bi bi-star-fill" style="color:#f59e0b;font-size:11px;"></i>
<div class="flex-grow-1" style="background:#e2e8f0;border-radius:99px;height:8px;overflow:hidden;">
<div style="width:1%;height:100%;background:#f59e0b;border-radius:99px;"></div>
</div>
<span style="width:32px;text-align:right;color:var(--text-muted);">1%</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="mt-4 pt-3" style="border-top:1px solid var(--border-color);font-size:12px;color:var(--text-muted);text-align:center;">
© 2026 Boitify · Dashboard E-Commerce · Version 1 — ApexCharts
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/apexcharts@3.49.0/dist/apexcharts.min.js"></script>
<script>
/* ── SIDEBAR ── */
function toggleSidebar() {
const sidebar = document.getElementById('sidebar');
const overlay = document.getElementById('sidebarOverlay');
const isMobile = window.innerWidth < 992;
if (isMobile) {
sidebar.classList.toggle('mobile-open');
overlay.style.display = sidebar.classList.contains('mobile-open') ? 'block' : 'none';
} else {
sidebar.classList.toggle('collapsed');
}
}
/* ── DARK MODE ── */
function toggleTheme() {
const html = document.documentElement;
const btn = document.getElementById('themeToggle');
const isDark = html.getAttribute('data-bs-theme') === 'dark';
html.setAttribute('data-bs-theme', isDark ? 'light' : 'dark');
btn.innerHTML = isDark ? '<i class="bi bi-moon-stars-fill"></i>' : '<i class="bi bi-sun-fill"></i>';
Object.values(chartInstances).forEach(c => c && c.destroy());
buildCharts();
}
const chartInstances = {};
function getThemeColors() {
const dark = document.documentElement.getAttribute('data-bs-theme') === 'dark';
return {
text: dark ? '#7d8590' : '#94a3b8',
grid: dark ? '#21262d' : '#f1f5f9',
};
}
function buildCharts() {
const t = getThemeColors();
const sparkOpts = (color, data) => ({
series: [{ data }],
chart: { type: 'area', height: 50, width: 100, sparkline: { enabled: true } },
stroke: { curve: 'smooth', width: 2 },
fill: { type: 'gradient', gradient: { shadeIntensity: 1, opacityFrom: .3, opacityTo: 0 } },
colors: [color],
tooltip: { enabled: false },
});
['spark1','spark2','spark3','spark4'].forEach(id => { if (chartInstances[id]) chartInstances[id].destroy(); });
chartInstances.spark1 = new ApexCharts(document.getElementById('spark1'), sparkOpts('#6366f1', [30,45,28,60,42,75,58,80,65,90]));
chartInstances.spark2 = new ApexCharts(document.getElementById('spark2'), sparkOpts('#22c55e', [50,38,62,44,70,55,80,68,92,74]));
chartInstances.spark3 = new ApexCharts(document.getElementById('spark3'), sparkOpts('#f59e0b', [20,35,28,45,32,58,40,65,50,72]));
chartInstances.spark4 = new ApexCharts(document.getElementById('spark4'), sparkOpts('#ef4444', [10,14,8,12,6,9,5,8,4,3]));
chartInstances.spark1.render(); chartInstances.spark2.render();
chartInstances.spark3.render(); chartInstances.spark4.render();
if (chartInstances.revenue) chartInstances.revenue.destroy();
chartInstances.revenue = new ApexCharts(document.getElementById('revenueChart'), {
series: [
{ name: 'Revenus', data: [12400,18200,15800,22000,19500,28400,24200,31000,26500,34800,29900,38200] },
{ name: 'Dépenses', data: [8200,11500,9800,13400,11200,16800,14500,18200,15400,20100,17300,21800] },
],
chart: { type: 'area', height: 260, toolbar: { show: false }, fontFamily: 'Inter, sans-serif' },
colors: ['#6366f1','#06b6d4'],
stroke: { curve: 'smooth', width: 2.5 },
fill: { type: 'gradient', gradient: { shadeIntensity: 1, opacityFrom: .25, opacityTo: 0, stops: [0,100] } },
xaxis: { categories: ['Jan','Fév','Mar','Avr','Mai','Jun','Jul','Aoû','Sep','Oct','Nov','Déc'], labels: { style: { colors: t.text, fontSize: '12px' } }, axisBorder: { show: false }, axisTicks: { show: false } },
yaxis: { labels: { style: { colors: t.text, fontSize: '12px' }, formatter: v => '€'+Math.round(v/1000)+'k' } },
grid: { borderColor: t.grid, strokeDashArray: 4 },
legend: { position: 'top', horizontalAlign: 'right', labels: { colors: t.text } },
tooltip: { y: { formatter: v => '€' + v.toLocaleString('fr-FR') } },
dataLabels: { enabled: false },
});
chartInstances.revenue.render();
if (chartInstances.donut) chartInstances.donut.destroy();
chartInstances.donut = new ApexCharts(document.getElementById('donutChart'), {
series: [42,26,20,12],
chart: { type: 'donut', height: 200, fontFamily: 'Inter, sans-serif' },
colors: ['#6366f1','#06b6d4','#f59e0b','#22c55e'],
labels: ['SEO','Social','Ads','Direct'],
legend: { show: false },
dataLabels: { enabled: false },
plotOptions: { pie: { donut: { size: '70%', labels: { show: true, total: { show: true, label: 'Total', color: t.text, formatter: () => '91 740' } } } } },
stroke: { width: 0 },
tooltip: { y: { formatter: v => v + '%' } },
});
chartInstances.donut.render();
if (chartInstances.funnel) chartInstances.funnel.destroy();
chartInstances.funnel = new ApexCharts(document.getElementById('funnelChart'), {
series: [{ name: 'Visiteurs', data: [91740,62400,28300,11800,8942] }],
chart: { type: 'bar', height: 260, toolbar: { show: false }, fontFamily: 'Inter, sans-serif' },
plotOptions: { bar: { horizontal: true, distributed: true, borderRadius: 6, dataLabels: { position: 'bottom' } } },
colors: ['#6366f1','#818cf8','#a5b4fc','#c7d2fe','#e0e7ff'],
xaxis: { categories: ['Visites','Vues produit','Paniers','Paiements','Commandes'], labels: { style: { colors: t.text, fontSize: '12px' } } },
yaxis: { labels: { style: { colors: t.text, fontSize: '12px' } } },
grid: { borderColor: t.grid },
legend: { show: false },
dataLabels: { enabled: true, textAnchor: 'start', offsetX: 10, style: { fontSize: '12px' }, formatter: v => v.toLocaleString('fr-FR') },
tooltip: { y: { formatter: v => v.toLocaleString('fr-FR') } },
});
chartInstances.funnel.render();
}
const chartData = {
monthly: { labels: ['Jan','Fév','Mar','Avr','Mai','Jun','Jul','Aoû','Sep','Oct','Nov','Déc'], revenue: [12400,18200,15800,22000,19500,28400,24200,31000,26500,34800,29900,38200], expenses: [8200,11500,9800,13400,11200,16800,14500,18200,15400,20100,17300,21800] },
weekly: { labels: ['S1','S2','S3','S4','S5','S6','S7','S8','S9','S10','S11','S12'], revenue: [3100,4200,3800,5400,4900,7100,6100,7800,6600,8700,7500,9600], expenses: [2100,2900,2400,3400,2800,4200,3600,4600,3900,5000,4300,5500] },
};
function switchChart(type, btn) {
['btn-monthly','btn-weekly'].forEach(id => {
const b = document.getElementById(id);
b.style.background = 'transparent'; b.style.color = 'var(--text-dark)'; b.style.border = '1px solid var(--border-color)';
});
btn.style.background = 'var(--primary)'; btn.style.color = '#fff'; btn.style.border = 'none';
const d = chartData[type];
chartInstances.revenue.updateOptions({ xaxis: { categories: d.labels } });
chartInstances.revenue.updateSeries([{ name: 'Revenus', data: d.revenue }, { name: 'Dépenses', data: d.expenses }]);
}
document.addEventListener('DOMContentLoaded', buildCharts);
</script>
</body>
</html>