Bootstrap
Bootstrap4
Dashboard
Admin
Responsive
Html
Template Bootstrap 4 d'administration avancée avec layouts complexes, navigation responsive et widgets dynamiques.
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>ArchitectUI Dashboard</title>
<link href="https://fonts.googleapis.com/css2?family=Sarabun:wght@300;400;500;600;700&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" />
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<style>
/* ─── RESET & BASE ─────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
:root {
--primary: #6770d2;
--primary-dark: #5560c2;
--primary-light:#8a91de;
--sidebar-bg: #252733;
--sidebar-hover:#2f3244;
--header-bg: #363740;
--page-bg: #f2f4f6;
--card-bg: #ffffff;
--text-dark: #1a1a2e;
--text-muted: #6c757d;
--text-light: #adb5bd;
--border: #e9ecef;
--success: #3ac47d;
--warning: #f7b731;
--danger: #e55353;
--info: #16aaff;
--sidebar-width:260px;
--header-height:60px;
}
html, body { height: 100%; }
body {
font-family: 'Sarabun', sans-serif;
background: var(--page-bg);
color: var(--text-dark);
font-size: 14px;
display: flex;
overflow: hidden;
}
/* ─── SIDEBAR ──────────────────────────────────── */
.sidebar {
width: var(--sidebar-width);
min-height: 100vh;
background: var(--sidebar-bg);
display: flex;
flex-direction: column;
flex-shrink: 0;
transition: width .3s ease;
z-index: 100;
}
.sidebar.collapsed { width: 64px; }
.sidebar-logo {
height: var(--header-height);
display: flex;
align-items: center;
padding: 0 20px;
border-bottom: 1px solid rgba(255,255,255,.07);
gap: 10px;
overflow: hidden;
white-space: nowrap;
}
.sidebar-logo .logo-icon {
width: 32px; height: 32px;
background: var(--primary);
border-radius: 8px;
display: flex; align-items: center; justify-content: center;
color: #fff;
font-size: 16px;
font-weight: 700;
flex-shrink: 0;
}
.sidebar-logo .logo-text {
color: #fff;
font-size: 16px;
font-weight: 700;
letter-spacing: .3px;
}
.sidebar-logo .logo-text span { color: var(--primary-light); }
.sidebar-nav { flex: 1; overflow-y: auto; padding: 12px 0; }
.sidebar-nav::-webkit-scrollbar { width: 4px; }
.sidebar-nav::-webkit-scrollbar-thumb { background: rgba(255,255,255,.1); border-radius: 4px; }
.nav-section-title {
font-size: 10px;
font-weight: 600;
letter-spacing: 1.2px;
text-transform: uppercase;
color: rgba(255,255,255,.3);
padding: 16px 20px 6px;
overflow: hidden;
white-space: nowrap;
}
.sidebar.collapsed .nav-section-title { visibility: hidden; }
.nav-item {
display: flex;
align-items: center;
gap: 12px;
padding: 10px 20px;
cursor: pointer;
color: rgba(255,255,255,.6);
border-radius: 0;
transition: background .2s, color .2s;
position: relative;
overflow: hidden;
white-space: nowrap;
}
.nav-item:hover { background: var(--sidebar-hover); color: rgba(255,255,255,.9); }
.nav-item.active {
background: rgba(103,112,210,.2);
color: #fff;
}
.nav-item.active::before {
content: '';
position: absolute;
left: 0; top: 0; bottom: 0;
width: 3px;
background: var(--primary);
}
.nav-item i { width: 20px; text-align: center; font-size: 15px; flex-shrink: 0; }
.nav-item .nav-label { font-size: 13.5px; font-weight: 500; }
.nav-item .badge {
margin-left: auto;
background: var(--primary);
color: #fff;
font-size: 10px;
padding: 2px 6px;
border-radius: 10px;
flex-shrink: 0;
}
.sidebar.collapsed .nav-label,
.sidebar.collapsed .badge { display: none; }
.sidebar-footer {
padding: 14px 20px;
border-top: 1px solid rgba(255,255,255,.07);
display: flex;
align-items: center;
gap: 10px;
overflow: hidden;
white-space: nowrap;
}
.sidebar-footer .avatar {
width: 34px; height: 34px;
border-radius: 50%;
background: var(--primary);
display: flex; align-items: center; justify-content: center;
color: #fff; font-weight: 700; font-size: 13px;
flex-shrink: 0;
}
.sidebar-footer .user-info { flex: 1; overflow: hidden; }
.sidebar-footer .user-name { color: #fff; font-size: 13px; font-weight: 600; }
.sidebar-footer .user-role { color: rgba(255,255,255,.4); font-size: 11px; }
.sidebar.collapsed .sidebar-footer .user-info { display: none; }
/* ─── MAIN WRAPPER ─────────────────────────────── */
.main-wrapper {
flex: 1;
display: flex;
flex-direction: column;
min-height: 100vh;
overflow: hidden;
}
/* ─── HEADER ───────────────────────────────────── */
.header {
height: var(--header-height);
background: var(--header-bg);
display: flex;
align-items: center;
padding: 0 24px;
gap: 16px;
flex-shrink: 0;
z-index: 50;
box-shadow: 0 2px 8px rgba(0,0,0,.2);
}
.header-toggle {
background: none; border: none;
color: rgba(255,255,255,.7);
font-size: 18px;
cursor: pointer;
padding: 6px;
border-radius: 6px;
transition: color .2s, background .2s;
}
.header-toggle:hover { color: #fff; background: rgba(255,255,255,.1); }
.header-search {
display: flex;
align-items: center;
background: rgba(255,255,255,.08);
border-radius: 8px;
padding: 6px 14px;
gap: 8px;
flex: 1;
max-width: 340px;
}
.header-search i { color: rgba(255,255,255,.4); }
.header-search input {
background: none;
border: none;
outline: none;
color: rgba(255,255,255,.8);
font-family: 'Sarabun', sans-serif;
font-size: 13px;
width: 100%;
}
.header-search input::placeholder { color: rgba(255,255,255,.35); }
.header-actions {
margin-left: auto;
display: flex;
align-items: center;
gap: 6px;
}
.header-btn {
background: none;
border: none;
color: rgba(255,255,255,.65);
font-size: 16px;
cursor: pointer;
padding: 8px;
border-radius: 8px;
position: relative;
transition: color .2s, background .2s;
}
.header-btn:hover { color: #fff; background: rgba(255,255,255,.1); }
.header-btn .dot {
position: absolute;
top: 5px; right: 5px;
width: 8px; height: 8px;
background: var(--danger);
border-radius: 50%;
border: 2px solid var(--header-bg);
}
.header-avatar {
width: 34px; height: 34px;
border-radius: 50%;
background: var(--primary);
display: flex; align-items: center; justify-content: center;
color: #fff; font-weight: 700; font-size: 13px;
cursor: pointer;
margin-left: 6px;
border: 2px solid rgba(255,255,255,.15);
transition: border-color .2s;
}
.header-avatar:hover { border-color: var(--primary-light); }
/* ─── PAGE CONTENT ─────────────────────────────── */
.page-content {
flex: 1;
overflow-y: auto;
padding: 28px 28px 40px;
}
.page-content::-webkit-scrollbar { width: 6px; }
.page-content::-webkit-scrollbar-thumb { background: #d0d5dd; border-radius: 4px; }
.page-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 24px;
}
.page-title { font-size: 20px; font-weight: 700; color: var(--text-dark); }
.breadcrumb {
display: flex;
align-items: center;
gap: 6px;
font-size: 12.5px;
color: var(--text-muted);
}
.breadcrumb span.sep { color: var(--text-light); }
.breadcrumb span.active { color: var(--primary); font-weight: 600; }
/* ─── STAT CARDS ───────────────────────────────── */
.stats-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 20px;
margin-bottom: 24px;
}
.stat-card {
background: var(--card-bg);
border-radius: 12px;
padding: 20px;
box-shadow: 0 2px 12px rgba(0,0,0,.06);
display: flex;
align-items: center;
gap: 16px;
transition: transform .2s, box-shadow .2s;
}
.stat-card:hover { transform: translateY(-2px); box-shadow: 0 6px 20px rgba(0,0,0,.1); }
.stat-icon {
width: 52px; height: 52px;
border-radius: 12px;
display: flex; align-items: center; justify-content: center;
font-size: 20px;
flex-shrink: 0;
}
.stat-icon.purple { background: rgba(103,112,210,.15); color: var(--primary); }
.stat-icon.green { background: rgba(58,196,125,.15); color: var(--success); }
.stat-icon.orange { background: rgba(247,183,49,.15); color: var(--warning); }
.stat-icon.red { background: rgba(229,83,83,.15); color: var(--danger); }
.stat-info { flex: 1; }
.stat-value { font-size: 24px; font-weight: 700; color: var(--text-dark); line-height: 1.2; }
.stat-label { font-size: 12.5px; color: var(--text-muted); margin-top: 3px; }
.stat-change {
font-size: 11.5px;
font-weight: 600;
margin-top: 6px;
display: flex;
align-items: center;
gap: 4px;
}
.stat-change.up { color: var(--success); }
.stat-change.down { color: var(--danger); }
/* ─── CHARTS ROW ───────────────────────────────── */
.charts-row {
display: grid;
grid-template-columns: 2fr 1fr;
gap: 20px;
margin-bottom: 24px;
}
.card {
background: var(--card-bg);
border-radius: 12px;
box-shadow: 0 2px 12px rgba(0,0,0,.06);
overflow: hidden;
}
.card-header {
padding: 18px 20px 14px;
display: flex;
align-items: center;
justify-content: space-between;
border-bottom: 1px solid var(--border);
}
.card-title { font-size: 15px; font-weight: 700; color: var(--text-dark); }
.card-subtitle { font-size: 12px; color: var(--text-muted); margin-top: 2px; }
.card-body { padding: 20px; }
.card-actions { display: flex; gap: 8px; align-items: center; }
.btn-xs {
font-size: 11.5px;
padding: 5px 12px;
border-radius: 6px;
border: none;
cursor: pointer;
font-family: 'Sarabun', sans-serif;
font-weight: 600;
transition: opacity .2s;
}
.btn-xs:hover { opacity: .85; }
.btn-primary { background: var(--primary); color: #fff; }
.btn-light { background: var(--page-bg); color: var(--text-muted); }
.chart-container { position: relative; }
/* ─── SECOND ROW ───────────────────────────────── */
.second-row {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 20px;
margin-bottom: 24px;
}
/* ─── TABLE CARD ───────────────────────────────── */
.table-card { margin-bottom: 24px; }
table { width: 100%; border-collapse: collapse; }
thead th {
text-align: left;
font-size: 11.5px;
font-weight: 600;
letter-spacing: .6px;
text-transform: uppercase;
color: var(--text-muted);
padding: 10px 14px;
background: #f8f9fa;
border-bottom: 1px solid var(--border);
}
tbody tr { transition: background .15s; }
tbody tr:hover { background: #fafbff; }
tbody td {
padding: 12px 14px;
border-bottom: 1px solid var(--border);
font-size: 13.5px;
color: var(--text-dark);
vertical-align: middle;
}
tbody tr:last-child td { border-bottom: none; }
.user-cell { display: flex; align-items: center; gap: 10px; }
.user-avatar {
width: 32px; height: 32px;
border-radius: 50%;
display: flex; align-items: center; justify-content: center;
color: #fff; font-size: 12px; font-weight: 700;
flex-shrink: 0;
}
.user-name-cell { font-weight: 600; font-size: 13.5px; }
.user-email-cell { font-size: 12px; color: var(--text-muted); }
.badge-status {
display: inline-block;
padding: 3px 10px;
border-radius: 20px;
font-size: 11.5px;
font-weight: 600;
}
.badge-success { background: rgba(58,196,125,.15); color: var(--success); }
.badge-warning { background: rgba(247,183,49,.15); color: #d4970f; }
.badge-danger { background: rgba(229,83,83,.15); color: var(--danger); }
.badge-info { background: rgba(22,170,255,.15); color: #0090d9; }
.progress-bar {
height: 6px;
background: var(--border);
border-radius: 4px;
overflow: hidden;
width: 100px;
}
.progress-fill {
height: 100%;
border-radius: 4px;
background: var(--primary);
transition: width .6s ease;
}
.progress-fill.green { background: var(--success); }
.progress-fill.orange { background: var(--warning); }
.progress-fill.red { background: var(--danger); }
/* ─── MINI WIDGETS ─────────────────────────────── */
.activity-list { display: flex; flex-direction: column; gap: 0; }
.activity-item {
display: flex;
align-items: flex-start;
gap: 12px;
padding: 12px 0;
border-bottom: 1px solid var(--border);
position: relative;
}
.activity-item:last-child { border-bottom: none; }
.activity-dot {
width: 10px; height: 10px;
border-radius: 50%;
margin-top: 4px;
flex-shrink: 0;
}
.activity-dot.purple { background: var(--primary); }
.activity-dot.green { background: var(--success); }
.activity-dot.orange { background: var(--warning); }
.activity-dot.red { background: var(--danger); }
.activity-dot.info { background: var(--info); }
.activity-text { flex: 1; font-size: 13px; line-height: 1.5; color: var(--text-dark); }
.activity-text strong { font-weight: 600; }
.activity-time { font-size: 11px; color: var(--text-muted); flex-shrink: 0; margin-top: 2px; }
/* ─── DONUT LEGEND ─────────────────────────────── */
.donut-legend { display: flex; flex-direction: column; gap: 10px; margin-top: 16px; }
.legend-item {
display: flex;
align-items: center;
justify-content: space-between;
font-size: 12.5px;
}
.legend-dot-label { display: flex; align-items: center; gap: 8px; }
.legend-dot {
width: 10px; height: 10px;
border-radius: 50%;
flex-shrink: 0;
}
.legend-pct { font-weight: 700; font-size: 13px; }
/* ─── SPARKLINE ROW ────────────────────────────── */
.metric-cards-row {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 20px;
margin-bottom: 24px;
}
.metric-card {
background: var(--card-bg);
border-radius: 12px;
padding: 18px 20px 12px;
box-shadow: 0 2px 12px rgba(0,0,0,.06);
}
.metric-top { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; }
.metric-label { font-size: 12.5px; color: var(--text-muted); font-weight: 500; }
.metric-badge {
font-size: 11px;
font-weight: 700;
padding: 2px 8px;
border-radius: 20px;
}
.metric-badge.up { background: rgba(58,196,125,.15); color: var(--success); }
.metric-badge.dn { background: rgba(229,83,83,.15); color: var(--danger); }
.metric-value { font-size: 22px; font-weight: 700; color: var(--text-dark); margin-bottom: 8px; }
.sparkline { height: 40px; }
/* ─── BOTTOM GRID ──────────────────────────────── */
.bottom-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
margin-bottom: 24px;
}
/* ─── CALENDAR WIDGET ──────────────────────────── */
.calendar-widget { }
.cal-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 14px;
}
.cal-month { font-size: 14px; font-weight: 700; }
.cal-nav { display: flex; gap: 6px; }
.cal-nav-btn {
width: 28px; height: 28px;
border: 1px solid var(--border);
background: none;
border-radius: 6px;
cursor: pointer;
display: flex; align-items: center; justify-content: center;
color: var(--text-muted);
font-size: 12px;
transition: all .2s;
}
.cal-nav-btn:hover { border-color: var(--primary); color: var(--primary); }
.cal-grid {
display: grid;
grid-template-columns: repeat(7, 1fr);
gap: 3px;
}
.cal-day-name {
text-align: center;
font-size: 11px;
font-weight: 600;
color: var(--text-muted);
padding: 4px 0;
}
.cal-day {
text-align: center;
font-size: 12.5px;
padding: 7px 0;
border-radius: 6px;
cursor: pointer;
color: var(--text-dark);
transition: all .2s;
}
.cal-day:hover { background: rgba(103,112,210,.1); color: var(--primary); }
.cal-day.today { background: var(--primary); color: #fff; font-weight: 700; }
.cal-day.other-month { color: var(--text-light); }
.cal-day.has-event { position: relative; font-weight: 600; }
.cal-day.has-event::after {
content: '';
position: absolute;
bottom: 2px; left: 50%;
transform: translateX(-50%);
width: 4px; height: 4px;
background: var(--success);
border-radius: 50%;
}
.cal-day.today.has-event::after { background: rgba(255,255,255,.8); }
/* ─── TASK LIST ────────────────────────────────── */
.task-list { display: flex; flex-direction: column; gap: 0; }
.task-item {
display: flex;
align-items: center;
gap: 12px;
padding: 11px 0;
border-bottom: 1px solid var(--border);
}
.task-item:last-child { border-bottom: none; }
.task-check {
width: 18px; height: 18px;
border-radius: 4px;
border: 2px solid var(--border);
display: flex; align-items: center; justify-content: center;
cursor: pointer;
transition: all .2s;
flex-shrink: 0;
font-size: 10px;
color: #fff;
}
.task-check.checked { background: var(--success); border-color: var(--success); }
.task-text { flex: 1; font-size: 13.5px; }
.task-text.done { text-decoration: line-through; color: var(--text-muted); }
.task-priority {
font-size: 11px;
font-weight: 600;
padding: 2px 8px;
border-radius: 4px;
}
.priority-high { background: rgba(229,83,83,.12); color: var(--danger); }
.priority-med { background: rgba(247,183,49,.12); color: #d4970f; }
.priority-low { background: rgba(58,196,125,.12); color: var(--success); }
/* ─── RESPONSIVE ───────────────────────────────── */
@media (max-width: 1200px) {
.stats-grid { grid-template-columns: repeat(2, 1fr); }
.charts-row { grid-template-columns: 1fr; }
.second-row { grid-template-columns: 1fr 1fr; }
.metric-cards-row { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 768px) {
.sidebar { position: fixed; transform: translateX(-100%); }
.sidebar.open { transform: translateX(0); }
.stats-grid { grid-template-columns: 1fr 1fr; }
.second-row { grid-template-columns: 1fr; }
.bottom-grid { grid-template-columns: 1fr; }
.metric-cards-row { grid-template-columns: repeat(2, 1fr); }
.header-search { display: none; }
}
@media (max-width: 480px) {
.stats-grid { grid-template-columns: 1fr; }
.metric-cards-row { grid-template-columns: 1fr 1fr; }
.page-content { padding: 16px; }
}
</style>
</head>
<body>
<!-- ═══════════════ SIDEBAR ═══════════════ -->
<aside class="sidebar" id="sidebar">
<div class="sidebar-logo">
<div class="logo-icon">A</div>
<span class="logo-text">Architect<span>UI</span></span>
</div>
<nav class="sidebar-nav">
<div class="nav-section-title">Dashboard</div>
<div class="nav-item active">
<i class="fas fa-th-large"></i>
<span class="nav-label">Overview</span>
</div>
<div class="nav-item">
<i class="fas fa-chart-line"></i>
<span class="nav-label">Analytics</span>
</div>
<div class="nav-item">
<i class="fas fa-chart-bar"></i>
<span class="nav-label">Reports</span>
<span class="badge">3</span>
</div>
<div class="nav-section-title">Management</div>
<div class="nav-item">
<i class="fas fa-users"></i>
<span class="nav-label">Users</span>
</div>
<div class="nav-item">
<i class="fas fa-shopping-cart"></i>
<span class="nav-label">Orders</span>
<span class="badge">12</span>
</div>
<div class="nav-item">
<i class="fas fa-box"></i>
<span class="nav-label">Products</span>
</div>
<div class="nav-item">
<i class="fas fa-tags"></i>
<span class="nav-label">Categories</span>
</div>
<div class="nav-section-title">System</div>
<div class="nav-item">
<i class="fas fa-bell"></i>
<span class="nav-label">Notifications</span>
<span class="badge">5</span>
</div>
<div class="nav-item">
<i class="fas fa-shield-alt"></i>
<span class="nav-label">Security</span>
</div>
<div class="nav-item">
<i class="fas fa-plug"></i>
<span class="nav-label">Integrations</span>
</div>
<div class="nav-item">
<i class="fas fa-cog"></i>
<span class="nav-label">Settings</span>
</div>
</nav>
<div class="sidebar-footer">
<div class="avatar">JD</div>
<div class="user-info">
<div class="user-name">John Doe</div>
<div class="user-role">Administrator</div>
</div>
</div>
</aside>
<!-- ═══════════════ MAIN ═══════════════ -->
<div class="main-wrapper">
<!-- HEADER -->
<header class="header">
<button class="header-toggle" id="toggleBtn">
<i class="fas fa-bars"></i>
</button>
<div class="header-search">
<i class="fas fa-search"></i>
<input type="text" placeholder="Search anything..." />
</div>
<div class="header-actions">
<button class="header-btn">
<i class="fas fa-bell"></i>
<span class="dot"></span>
</button>
<button class="header-btn">
<i class="fas fa-envelope"></i>
<span class="dot"></span>
</button>
<button class="header-btn">
<i class="fas fa-question-circle"></i>
</button>
<div class="header-avatar">JD</div>
</div>
</header>
<!-- PAGE CONTENT -->
<main class="page-content">
<!-- Page Header -->
<div class="page-header">
<div>
<div class="page-title">Dashboard Overview</div>
</div>
<div class="breadcrumb">
<span>Home</span>
<span class="sep">/</span>
<span>Dashboard</span>
<span class="sep">/</span>
<span class="active">Overview</span>
</div>
</div>
<!-- ── STAT CARDS ── -->
<div class="stats-grid">
<div class="stat-card">
<div class="stat-icon purple"><i class="fas fa-users"></i></div>
<div class="stat-info">
<div class="stat-value">24,521</div>
<div class="stat-label">Total Users</div>
<div class="stat-change up"><i class="fas fa-arrow-up"></i> 12.4% this month</div>
</div>
</div>
<div class="stat-card">
<div class="stat-icon green"><i class="fas fa-dollar-sign"></i></div>
<div class="stat-info">
<div class="stat-value">$84,200</div>
<div class="stat-label">Total Revenue</div>
<div class="stat-change up"><i class="fas fa-arrow-up"></i> 8.7% this month</div>
</div>
</div>
<div class="stat-card">
<div class="stat-icon orange"><i class="fas fa-shopping-bag"></i></div>
<div class="stat-info">
<div class="stat-value">1,340</div>
<div class="stat-label">Total Orders</div>
<div class="stat-change down"><i class="fas fa-arrow-down"></i> 3.2% this month</div>
</div>
</div>
<div class="stat-card">
<div class="stat-icon red"><i class="fas fa-ticket-alt"></i></div>
<div class="stat-info">
<div class="stat-value">238</div>
<div class="stat-label">Open Tickets</div>
<div class="stat-change down"><i class="fas fa-arrow-down"></i> 5.1% this month</div>
</div>
</div>
</div>
<!-- ── SPARKLINE METRICS ── -->
<div class="metric-cards-row">
<div class="metric-card">
<div class="metric-top">
<span class="metric-label">Page Views</span>
<span class="metric-badge up">+18%</span>
</div>
<div class="metric-value">128,450</div>
<canvas class="sparkline" id="spark1"></canvas>
</div>
<div class="metric-card">
<div class="metric-top">
<span class="metric-label">Bounce Rate</span>
<span class="metric-badge dn">-4%</span>
</div>
<div class="metric-value">34.6%</div>
<canvas class="sparkline" id="spark2"></canvas>
</div>
<div class="metric-card">
<div class="metric-top">
<span class="metric-label">Avg. Session</span>
<span class="metric-badge up">+9%</span>
</div>
<div class="metric-value">4m 38s</div>
<canvas class="sparkline" id="spark3"></canvas>
</div>
<div class="metric-card">
<div class="metric-top">
<span class="metric-label">Conversion</span>
<span class="metric-badge up">+2.1%</span>
</div>
<div class="metric-value">3.24%</div>
<canvas class="sparkline" id="spark4"></canvas>
</div>
</div>
<!-- ── MAIN CHARTS ── -->
<div class="charts-row">
<div class="card">
<div class="card-header">
<div>
<div class="card-title">Revenue Overview</div>
<div class="card-subtitle">Monthly performance — 2024</div>
</div>
<div class="card-actions">
<button class="btn-xs btn-light">Weekly</button>
<button class="btn-xs btn-primary">Monthly</button>
<button class="btn-xs btn-light">Yearly</button>
</div>
</div>
<div class="card-body">
<div class="chart-container"><canvas id="revenueChart" height="240"></canvas></div>
</div>
</div>
<div class="card">
<div class="card-header">
<div>
<div class="card-title">Traffic Sources</div>
<div class="card-subtitle">Last 30 days</div>
</div>
</div>
<div class="card-body">
<canvas id="donutChart" height="180"></canvas>
<div class="donut-legend">
<div class="legend-item">
<div class="legend-dot-label">
<div class="legend-dot" style="background:#6770d2"></div>
<span>Organic Search</span>
</div>
<span class="legend-pct" style="color:#6770d2">42%</span>
</div>
<div class="legend-item">
<div class="legend-dot-label">
<div class="legend-dot" style="background:#3ac47d"></div>
<span>Direct</span>
</div>
<span class="legend-pct" style="color:#3ac47d">28%</span>
</div>
<div class="legend-item">
<div class="legend-dot-label">
<div class="legend-dot" style="background:#16aaff"></div>
<span>Social Media</span>
</div>
<span class="legend-pct" style="color:#16aaff">18%</span>
</div>
<div class="legend-item">
<div class="legend-dot-label">
<div class="legend-dot" style="background:#f7b731"></div>
<span>Referral</span>
</div>
<span class="legend-pct" style="color:#d4970f">12%</span>
</div>
</div>
</div>
</div>
</div>
<!-- ── SECOND ROW CHARTS ── -->
<div class="second-row">
<div class="card">
<div class="card-header">
<div>
<div class="card-title">New Users</div>
<div class="card-subtitle">Daily registrations</div>
</div>
</div>
<div class="card-body">
<canvas id="barChart" height="200"></canvas>
</div>
</div>
<div class="card">
<div class="card-header">
<div>
<div class="card-title">Recent Activity</div>
<div class="card-subtitle">Last 24 hours</div>
</div>
</div>
<div class="card-body" style="padding:8px 20px">
<div class="activity-list">
<div class="activity-item">
<div class="activity-dot purple"></div>
<div class="activity-text"><strong>Alice Martin</strong> placed a new order #4521</div>
<div class="activity-time">2m ago</div>
</div>
<div class="activity-item">
<div class="activity-dot green"></div>
<div class="activity-text">Payment of <strong>$240.00</strong> received</div>
<div class="activity-time">14m ago</div>
</div>
<div class="activity-item">
<div class="activity-dot info"></div>
<div class="activity-text"><strong>Bob Chen</strong> submitted a support ticket</div>
<div class="activity-time">1h ago</div>
</div>
<div class="activity-item">
<div class="activity-dot orange"></div>
<div class="activity-text">Server CPU usage exceeded <strong>80%</strong></div>
<div class="activity-time">2h ago</div>
</div>
<div class="activity-item">
<div class="activity-dot red"></div>
<div class="activity-text">Failed login attempt from <strong>IP 192.168.1.45</strong></div>
<div class="activity-time">3h ago</div>
</div>
<div class="activity-item">
<div class="activity-dot green"></div>
<div class="activity-text">New user <strong>Sara Kim</strong> registered</div>
<div class="activity-time">5h ago</div>
</div>
</div>
</div>
</div>
<div class="card">
<div class="card-header">
<div>
<div class="card-title">Sales by Category</div>
<div class="card-subtitle">Top categories</div>
</div>
</div>
<div class="card-body">
<canvas id="polarChart" height="200"></canvas>
</div>
</div>
</div>
<!-- ── ORDERS TABLE ── -->
<div class="card table-card">
<div class="card-header">
<div>
<div class="card-title">Recent Orders</div>
<div class="card-subtitle">Latest 6 transactions</div>
</div>
<div class="card-actions">
<button class="btn-xs btn-primary">View All</button>
</div>
</div>
<table>
<thead>
<tr>
<th>#</th>
<th>Customer</th>
<th>Product</th>
<th>Amount</th>
<th>Status</th>
<th>Progress</th>
<th>Date</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>#4521</strong></td>
<td>
<div class="user-cell">
<div class="user-avatar" style="background:#6770d2">AM</div>
<div>
<div class="user-name-cell">Alice Martin</div>
<div class="user-email-cell">alice@example.com</div>
</div>
</div>
</td>
<td>MacBook Pro 16"</td>
<td><strong>$2,499</strong></td>
<td><span class="badge-status badge-success">Delivered</span></td>
<td>
<div style="display:flex;align-items:center;gap:8px">
<div class="progress-bar"><div class="progress-fill green" style="width:100%"></div></div>
<span style="font-size:12px;color:var(--text-muted)">100%</span>
</div>
</td>
<td style="color:var(--text-muted)">Apr 4, 2026</td>
</tr>
<tr>
<td><strong>#4520</strong></td>
<td>
<div class="user-cell">
<div class="user-avatar" style="background:#3ac47d">BC</div>
<div>
<div class="user-name-cell">Bob Chen</div>
<div class="user-email-cell">bob@example.com</div>
</div>
</div>
</td>
<td>iPhone 15 Pro</td>
<td><strong>$1,199</strong></td>
<td><span class="badge-status badge-info">Shipped</span></td>
<td>
<div style="display:flex;align-items:center;gap:8px">
<div class="progress-bar"><div class="progress-fill" style="width:65%"></div></div>
<span style="font-size:12px;color:var(--text-muted)">65%</span>
</div>
</td>
<td style="color:var(--text-muted)">Apr 3, 2026</td>
</tr>
<tr>
<td><strong>#4519</strong></td>
<td>
<div class="user-cell">
<div class="user-avatar" style="background:#f7b731">SK</div>
<div>
<div class="user-name-cell">Sara Kim</div>
<div class="user-email-cell">sara@example.com</div>
</div>
</div>
</td>
<td>Sony WH-1000XM5</td>
<td><strong>$349</strong></td>
<td><span class="badge-status badge-warning">Processing</span></td>
<td>
<div style="display:flex;align-items:center;gap:8px">
<div class="progress-bar"><div class="progress-fill orange" style="width:40%"></div></div>
<span style="font-size:12px;color:var(--text-muted)">40%</span>
</div>
</td>
<td style="color:var(--text-muted)">Apr 3, 2026</td>
</tr>
<tr>
<td><strong>#4518</strong></td>
<td>
<div class="user-cell">
<div class="user-avatar" style="background:#e55353">MR</div>
<div>
<div class="user-name-cell">Marc Roux</div>
<div class="user-email-cell">marc@example.com</div>
</div>
</div>
</td>
<td>Dell 4K Monitor</td>
<td><strong>$799</strong></td>
<td><span class="badge-status badge-danger">Cancelled</span></td>
<td>
<div style="display:flex;align-items:center;gap:8px">
<div class="progress-bar"><div class="progress-fill red" style="width:15%"></div></div>
<span style="font-size:12px;color:var(--text-muted)">15%</span>
</div>
</td>
<td style="color:var(--text-muted)">Apr 2, 2026</td>
</tr>
<tr>
<td><strong>#4517</strong></td>
<td>
<div class="user-cell">
<div class="user-avatar" style="background:#16aaff">NL</div>
<div>
<div class="user-name-cell">Nina López</div>
<div class="user-email-cell">nina@example.com</div>
</div>
</div>
</td>
<td>iPad Air 5th Gen</td>
<td><strong>$749</strong></td>
<td><span class="badge-status badge-success">Delivered</span></td>
<td>
<div style="display:flex;align-items:center;gap:8px">
<div class="progress-bar"><div class="progress-fill green" style="width:100%"></div></div>
<span style="font-size:12px;color:var(--text-muted)">100%</span>
</div>
</td>
<td style="color:var(--text-muted)">Apr 1, 2026</td>
</tr>
<tr>
<td><strong>#4516</strong></td>
<td>
<div class="user-cell">
<div class="user-avatar" style="background:#8a91de">TD</div>
<div>
<div class="user-name-cell">Tom Dupont</div>
<div class="user-email-cell">tom@example.com</div>
</div>
</div>
</td>
<td>Samsung Galaxy S24</td>
<td><strong>$999</strong></td>
<td><span class="badge-status badge-info">Shipped</span></td>
<td>
<div style="display:flex;align-items:center;gap:8px">
<div class="progress-bar"><div class="progress-fill" style="width:80%"></div></div>
<span style="font-size:12px;color:var(--text-muted)">80%</span>
</div>
</td>
<td style="color:var(--text-muted)">Apr 1, 2026</td>
</tr>
</tbody>
</table>
</div>
<!-- ── BOTTOM GRID ── -->
<div class="bottom-grid">
<!-- Calendar -->
<div class="card">
<div class="card-header">
<div class="card-title">Calendar</div>
</div>
<div class="card-body">
<div class="cal-header">
<span class="cal-month">April 2026</span>
<div class="cal-nav">
<button class="cal-nav-btn"><i class="fas fa-chevron-left"></i></button>
<button class="cal-nav-btn"><i class="fas fa-chevron-right"></i></button>
</div>
</div>
<div class="cal-grid">
<div class="cal-day-name">Sun</div>
<div class="cal-day-name">Mon</div>
<div class="cal-day-name">Tue</div>
<div class="cal-day-name">Wed</div>
<div class="cal-day-name">Thu</div>
<div class="cal-day-name">Fri</div>
<div class="cal-day-name">Sat</div>
<!-- Row 1 -->
<div class="cal-day other-month">30</div>
<div class="cal-day other-month">31</div>
<div class="cal-day has-event">1</div>
<div class="cal-day">2</div>
<div class="cal-day has-event">3</div>
<div class="cal-day has-event">4</div>
<div class="cal-day">5</div>
<!-- Row 2 -->
<div class="cal-day">6</div>
<div class="cal-day has-event">7</div>
<div class="cal-day">8</div>
<div class="cal-day">9</div>
<div class="cal-day has-event">10</div>
<div class="cal-day">11</div>
<div class="cal-day">12</div>
<!-- Row 3 -->
<div class="cal-day">13</div>
<div class="cal-day">14</div>
<div class="cal-day has-event">15</div>
<div class="cal-day">16</div>
<div class="cal-day">17</div>
<div class="cal-day has-event">18</div>
<div class="cal-day">19</div>
<!-- Row 4 -->
<div class="cal-day">20</div>
<div class="cal-day has-event">21</div>
<div class="cal-day">22</div>
<div class="cal-day">23</div>
<div class="cal-day">24</div>
<div class="cal-day today has-event">5</div>
<div class="cal-day">26</div>
<!-- Row 5 -->
<div class="cal-day">27</div>
<div class="cal-day has-event">28</div>
<div class="cal-day">29</div>
<div class="cal-day">30</div>
<div class="cal-day other-month">1</div>
<div class="cal-day other-month">2</div>
<div class="cal-day other-month">3</div>
</div>
</div>
</div>
<!-- Task List -->
<div class="card">
<div class="card-header">
<div class="card-title">Task List</div>
<button class="btn-xs btn-primary">+ Add Task</button>
</div>
<div class="card-body" style="padding:8px 20px">
<div class="task-list">
<div class="task-item">
<div class="task-check checked" onclick="toggleTask(this)"><i class="fas fa-check"></i></div>
<div class="task-text done">Design new landing page mockup</div>
<span class="task-priority priority-high">High</span>
</div>
<div class="task-item">
<div class="task-check checked" onclick="toggleTask(this)"><i class="fas fa-check"></i></div>
<div class="task-text done">Update user authentication flow</div>
<span class="task-priority priority-med">Med</span>
</div>
<div class="task-item">
<div class="task-check" onclick="toggleTask(this)"></div>
<div class="task-text">Write API documentation v2.1</div>
<span class="task-priority priority-high">High</span>
</div>
<div class="task-item">
<div class="task-check" onclick="toggleTask(this)"></div>
<div class="task-text">Set up CI/CD pipeline for staging</div>
<span class="task-priority priority-med">Med</span>
</div>
<div class="task-item">
<div class="task-check" onclick="toggleTask(this)"></div>
<div class="task-text">Review pull requests from team</div>
<span class="task-priority priority-low">Low</span>
</div>
<div class="task-item">
<div class="task-check" onclick="toggleTask(this)"></div>
<div class="task-text">Optimize database query performance</div>
<span class="task-priority priority-high">High</span>
</div>
<div class="task-item">
<div class="task-check" onclick="toggleTask(this)"></div>
<div class="task-text">Prepare monthly analytics report</div>
<span class="task-priority priority-low">Low</span>
</div>
</div>
</div>
</div>
</div>
</main>
</div><!-- /main-wrapper -->
<!-- ═══════════════ SCRIPTS ═══════════════ -->
<script>
// ── Sidebar toggle ──────────────────────────
const sidebar = document.getElementById('sidebar');
const toggleBtn = document.getElementById('toggleBtn');
toggleBtn.addEventListener('click', () => {
sidebar.classList.toggle('collapsed');
});
// Nav items
document.querySelectorAll('.nav-item').forEach(item => {
item.addEventListener('click', () => {
document.querySelectorAll('.nav-item').forEach(i => i.classList.remove('active'));
item.classList.add('active');
});
});
// ── Task check toggle ───────────────────────
function toggleTask(el) {
el.classList.toggle('checked');
const txt = el.nextElementSibling;
if (el.classList.contains('checked')) {
el.innerHTML = '<i class="fas fa-check"></i>';
txt.classList.add('done');
} else {
el.innerHTML = '';
txt.classList.remove('done');
}
}
// ── Chart defaults ──────────────────────────
Chart.defaults.font.family = "'Sarabun', sans-serif";
Chart.defaults.font.size = 12;
Chart.defaults.color = '#6c757d';
// ── Revenue Line Chart ──────────────────────
new Chart(document.getElementById('revenueChart'), {
type: 'line',
data: {
labels: ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'],
datasets: [
{
label: 'Revenue',
data: [38000,42000,35000,52000,49000,63000,58000,71000,66000,80000,74000,84200],
borderColor: '#6770d2',
backgroundColor: 'rgba(103,112,210,.08)',
fill: true,
tension: .4,
borderWidth: 2.5,
pointBackgroundColor: '#6770d2',
pointRadius: 4,
pointHoverRadius: 6
},
{
label: 'Expenses',
data: [22000,25000,21000,30000,28000,36000,33000,40000,37000,44000,41000,46000],
borderColor: '#3ac47d',
backgroundColor: 'rgba(58,196,125,.06)',
fill: true,
tension: .4,
borderWidth: 2.5,
borderDash: [5,4],
pointBackgroundColor: '#3ac47d',
pointRadius: 4,
pointHoverRadius: 6
}
]
},
options: {
responsive: true,
interaction: { mode: 'index', intersect: false },
plugins: {
legend: { position: 'top', labels: { boxWidth: 12, padding: 16 } },
tooltip: { backgroundColor: '#363740', titleColor: '#fff', bodyColor: '#adb5bd', padding: 10, cornerRadius: 8 }
},
scales: {
x: { grid: { display: false }, border: { display: false } },
y: {
grid: { color: 'rgba(0,0,0,.05)', drawBorder: false },
border: { display: false },
ticks: { callback: v => '$' + (v/1000).toFixed(0) + 'k' }
}
}
}
});
// ── Donut Chart ─────────────────────────────
new Chart(document.getElementById('donutChart'), {
type: 'doughnut',
data: {
labels: ['Organic','Direct','Social','Referral'],
datasets: [{
data: [42, 28, 18, 12],
backgroundColor: ['#6770d2','#3ac47d','#16aaff','#f7b731'],
borderWidth: 0,
hoverOffset: 6
}]
},
options: {
responsive: true,
cutout: '70%',
plugins: {
legend: { display: false },
tooltip: { backgroundColor: '#363740', titleColor: '#fff', bodyColor: '#adb5bd', padding: 10, cornerRadius: 8 }
}
}
});
// ── Bar Chart ───────────────────────────────
new Chart(document.getElementById('barChart'), {
type: 'bar',
data: {
labels: ['Mon','Tue','Wed','Thu','Fri','Sat','Sun'],
datasets: [{
label: 'New Users',
data: [145, 210, 178, 264, 198, 88, 72],
backgroundColor: 'rgba(103,112,210,.8)',
borderRadius: 6,
borderSkipped: false,
hoverBackgroundColor: '#6770d2'
}]
},
options: {
responsive: true,
plugins: {
legend: { display: false },
tooltip: { backgroundColor: '#363740', titleColor: '#fff', bodyColor: '#adb5bd', padding: 10, cornerRadius: 8 }
},
scales: {
x: { grid: { display: false }, border: { display: false } },
y: { grid: { color: 'rgba(0,0,0,.05)' }, border: { display: false } }
}
}
});
// ── Polar Area Chart ────────────────────────
new Chart(document.getElementById('polarChart'), {
type: 'polarArea',
data: {
labels: ['Electronics','Clothing','Books','Sports','Home'],
datasets: [{
data: [35, 22, 14, 18, 11],
backgroundColor: [
'rgba(103,112,210,.75)',
'rgba(58,196,125,.75)',
'rgba(22,170,255,.75)',
'rgba(247,183,49,.75)',
'rgba(229,83,83,.75)'
],
borderWidth: 0
}]
},
options: {
responsive: true,
plugins: {
legend: { position: 'bottom', labels: { boxWidth: 10, padding: 12, font: { size: 11 } } },
tooltip: { backgroundColor: '#363740', titleColor: '#fff', bodyColor: '#adb5bd', padding: 10, cornerRadius: 8 }
},
scales: { r: { grid: { color: 'rgba(0,0,0,.06)' }, ticks: { display: false } } }
}
});
// ── Sparklines ──────────────────────────────
function makeSparkline(id, data, color) {
new Chart(document.getElementById(id), {
type: 'line',
data: {
labels: data.map((_, i) => i),
datasets: [{
data,
borderColor: color,
backgroundColor: color.replace(')', ', .12)').replace('rgb', 'rgba'),
fill: true,
tension: .4,
borderWidth: 2,
pointRadius: 0
}]
},
options: {
responsive: true,
plugins: { legend: { display: false }, tooltip: { enabled: false } },
scales: { x: { display: false }, y: { display: false } },
elements: { line: { borderCapStyle: 'round' } }
}
});
}
makeSparkline('spark1', [60,72,68,80,74,90,88,95,100,112,108,128], 'rgb(103,112,210)');
makeSparkline('spark2', [42,38,44,40,36,38,35,34,37,33,36,34], 'rgb(229,83,83)');
makeSparkline('spark3', [3.2,3.5,3.8,4.0,3.9,4.2,4.4,4.1,4.5,4.3,4.6,4.6], 'rgb(58,196,125)');
makeSparkline('spark4', [2.1,2.4,2.3,2.6,2.8,2.7,3.0,2.9,3.1,3.2,3.1,3.2], 'rgb(22,170,255)');
</script>
</body>
</html>