nhatvy142 3327f9dcb3
feat: add three UI project examples (#174)
- SaaS landing page with social proof, pricing, testimonials
- Healthcare analytics dashboard with charts and KPIs
- Portfolio website with dark mode and project grid

All built using ui-ux-pro-max design system recommendations.

https://claude.ai/code/session_01E4rdBvf1LWqQ1XMTic7NrU

Co-authored-by: Claude <noreply@anthropic.com>
2026-06-29 23:59:34 +07:00

459 lines
23 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HealthView - Analytics Dashboard</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600;700&family=Fira+Sans:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<script>
tailwind.config = {
theme: {
extend: {
colors: {
primary: '#3B82F6',
secondary: '#60A5FA',
accent: '#F97316',
surface: '#F8FAFC',
text: '#1E293B',
success: '#10B981',
warning: '#F59E0B',
danger: '#EF4444',
},
fontFamily: {
heading: ['Fira Sans', 'sans-serif'],
body: ['Fira Sans', 'sans-serif'],
mono: ['Fira Code', 'monospace'],
}
}
}
}
</script>
<style>
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}
</style>
</head>
<body class="bg-slate-100 font-body text-text antialiased">
<div class="flex min-h-screen">
<!-- Sidebar -->
<aside class="w-64 bg-white border-r border-slate-200 fixed h-full">
<div class="p-6 border-b border-slate-100">
<h1 class="font-heading font-bold text-xl text-primary flex items-center gap-2">
<svg class="w-8 h-8" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"/>
</svg>
HealthView
</h1>
</div>
<nav class="p-4">
<ul class="space-y-1">
<li>
<a href="#" class="flex items-center gap-3 px-4 py-3 rounded-lg bg-primary/10 text-primary font-medium cursor-pointer">
<svg class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"/>
</svg>
Dashboard
</a>
</li>
<li>
<a href="#" class="flex items-center gap-3 px-4 py-3 rounded-lg text-slate-600 hover:bg-slate-50 transition-colors duration-200 cursor-pointer">
<svg class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"/>
</svg>
Patients
</a>
</li>
<li>
<a href="#" class="flex items-center gap-3 px-4 py-3 rounded-lg text-slate-600 hover:bg-slate-50 transition-colors duration-200 cursor-pointer">
<svg class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"/>
</svg>
Appointments
</a>
</li>
<li>
<a href="#" class="flex items-center gap-3 px-4 py-3 rounded-lg text-slate-600 hover:bg-slate-50 transition-colors duration-200 cursor-pointer">
<svg class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"/>
</svg>
Analytics
</a>
</li>
<li>
<a href="#" class="flex items-center gap-3 px-4 py-3 rounded-lg text-slate-600 hover:bg-slate-50 transition-colors duration-200 cursor-pointer">
<svg class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"/>
<path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>
</svg>
Settings
</a>
</li>
</ul>
</nav>
</aside>
<!-- Main Content -->
<main class="flex-1 ml-64 p-8">
<!-- Header -->
<header class="flex items-center justify-between mb-8">
<div>
<h2 class="font-heading text-2xl font-bold text-text">Healthcare Analytics</h2>
<p class="text-slate-500 text-sm">Overview of patient data and hospital metrics</p>
</div>
<div class="flex items-center gap-4">
<div class="relative">
<input type="text" placeholder="Search patients..." class="pl-10 pr-4 py-2.5 rounded-lg border border-slate-200 bg-white text-sm focus:outline-none focus:ring-2 focus:ring-primary/20 focus:border-primary w-64 transition-all duration-200" aria-label="Search patients">
<svg class="w-5 h-5 text-slate-400 absolute left-3 top-1/2 -translate-y-1/2" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"/>
</svg>
</div>
<button class="p-2.5 rounded-lg border border-slate-200 bg-white hover:bg-slate-50 transition-colors duration-200 cursor-pointer relative" aria-label="Notifications">
<svg class="w-5 h-5 text-slate-600" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9"/>
</svg>
<span class="absolute -top-1 -right-1 w-4 h-4 bg-danger rounded-full text-white text-xs flex items-center justify-center">3</span>
</button>
<div class="flex items-center gap-3 pl-4 border-l border-slate-200">
<div class="w-10 h-10 bg-primary/20 rounded-full flex items-center justify-center text-primary font-semibold">DR</div>
<div>
<div class="font-medium text-sm text-text">Dr. Roberts</div>
<div class="text-xs text-slate-400">Cardiologist</div>
</div>
</div>
</div>
</header>
<!-- KPI Cards -->
<div class="grid grid-cols-4 gap-6 mb-8">
<div class="bg-white p-6 rounded-xl border border-slate-100 hover:shadow-md transition-shadow duration-300 cursor-pointer">
<div class="flex items-center justify-between mb-4">
<div class="w-12 h-12 bg-primary/10 rounded-xl flex items-center justify-center">
<svg class="w-6 h-6 text-primary" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0z"/>
</svg>
</div>
<span class="text-success text-sm font-medium flex items-center gap-1">
<svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M5 10l7-7m0 0l7 7m-7-7v18"/></svg>
12%
</span>
</div>
<div class="font-mono text-3xl font-bold text-text mb-1">2,847</div>
<div class="text-slate-500 text-sm">Total Patients</div>
</div>
<div class="bg-white p-6 rounded-xl border border-slate-100 hover:shadow-md transition-shadow duration-300 cursor-pointer">
<div class="flex items-center justify-between mb-4">
<div class="w-12 h-12 bg-success/10 rounded-xl flex items-center justify-center">
<svg class="w-6 h-6 text-success" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
</div>
<span class="text-success text-sm font-medium flex items-center gap-1">
<svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M5 10l7-7m0 0l7 7m-7-7v18"/></svg>
8%
</span>
</div>
<div class="font-mono text-3xl font-bold text-text mb-1">94.2%</div>
<div class="text-slate-500 text-sm">Recovery Rate</div>
</div>
<div class="bg-white p-6 rounded-xl border border-slate-100 hover:shadow-md transition-shadow duration-300 cursor-pointer">
<div class="flex items-center justify-between mb-4">
<div class="w-12 h-12 bg-warning/10 rounded-xl flex items-center justify-center">
<svg class="w-6 h-6 text-warning" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
</div>
<span class="text-danger text-sm font-medium flex items-center gap-1">
<svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M19 14l-7 7m0 0l-7-7m7 7V3"/></svg>
3%
</span>
</div>
<div class="font-mono text-3xl font-bold text-text mb-1">24 min</div>
<div class="text-slate-500 text-sm">Avg. Wait Time</div>
</div>
<div class="bg-white p-6 rounded-xl border border-slate-100 hover:shadow-md transition-shadow duration-300 cursor-pointer">
<div class="flex items-center justify-between mb-4">
<div class="w-12 h-12 bg-accent/10 rounded-xl flex items-center justify-center">
<svg class="w-6 h-6 text-accent" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4"/>
</svg>
</div>
<span class="text-success text-sm font-medium flex items-center gap-1">
<svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M5 10l7-7m0 0l7 7m-7-7v18"/></svg>
5%
</span>
</div>
<div class="font-mono text-3xl font-bold text-text mb-1">142</div>
<div class="text-slate-500 text-sm">Beds Available</div>
</div>
</div>
<!-- Charts Row -->
<div class="grid grid-cols-3 gap-6 mb-8">
<!-- Patient Trend Chart -->
<div class="col-span-2 bg-white p-6 rounded-xl border border-slate-100">
<div class="flex items-center justify-between mb-6">
<h3 class="font-heading font-semibold text-lg text-text">Patient Admissions Trend</h3>
<div class="flex gap-2">
<button class="px-3 py-1.5 text-sm rounded-lg bg-primary text-white cursor-pointer">Weekly</button>
<button class="px-3 py-1.5 text-sm rounded-lg text-slate-500 hover:bg-slate-50 transition-colors duration-200 cursor-pointer">Monthly</button>
<button class="px-3 py-1.5 text-sm rounded-lg text-slate-500 hover:bg-slate-50 transition-colors duration-200 cursor-pointer">Yearly</button>
</div>
</div>
<div class="h-64">
<canvas id="admissionsChart"></canvas>
</div>
</div>
<!-- Department Distribution -->
<div class="bg-white p-6 rounded-xl border border-slate-100">
<h3 class="font-heading font-semibold text-lg text-text mb-6">Department Distribution</h3>
<div class="h-64">
<canvas id="departmentChart"></canvas>
</div>
</div>
</div>
<!-- Second Row -->
<div class="grid grid-cols-3 gap-6">
<!-- Recent Patients Table -->
<div class="col-span-2 bg-white rounded-xl border border-slate-100">
<div class="p-6 border-b border-slate-100 flex items-center justify-between">
<h3 class="font-heading font-semibold text-lg text-text">Recent Patients</h3>
<button class="text-primary text-sm font-medium hover:text-primary/80 transition-colors duration-200 cursor-pointer">View All</button>
</div>
<div class="overflow-x-auto">
<table class="w-full">
<thead>
<tr class="text-left text-sm text-slate-500 border-b border-slate-100">
<th class="px-6 py-4 font-medium">Patient</th>
<th class="px-6 py-4 font-medium">ID</th>
<th class="px-6 py-4 font-medium">Department</th>
<th class="px-6 py-4 font-medium">Status</th>
<th class="px-6 py-4 font-medium">Date</th>
</tr>
</thead>
<tbody>
<tr class="border-b border-slate-50 hover:bg-slate-50/50 transition-colors duration-200 cursor-pointer">
<td class="px-6 py-4">
<div class="flex items-center gap-3">
<div class="w-10 h-10 bg-primary/10 rounded-full flex items-center justify-center text-primary font-medium">JD</div>
<div>
<div class="font-medium text-text">John Doe</div>
<div class="text-sm text-slate-400">john.doe@email.com</div>
</div>
</div>
</td>
<td class="px-6 py-4 font-mono text-sm text-slate-600">#PT-2847</td>
<td class="px-6 py-4 text-slate-600">Cardiology</td>
<td class="px-6 py-4">
<span class="px-3 py-1 rounded-full bg-success/10 text-success text-sm font-medium">Recovered</span>
</td>
<td class="px-6 py-4 text-slate-500">Mar 8, 2026</td>
</tr>
<tr class="border-b border-slate-50 hover:bg-slate-50/50 transition-colors duration-200 cursor-pointer">
<td class="px-6 py-4">
<div class="flex items-center gap-3">
<div class="w-10 h-10 bg-secondary/10 rounded-full flex items-center justify-center text-secondary font-medium">SM</div>
<div>
<div class="font-medium text-text">Sarah Miller</div>
<div class="text-sm text-slate-400">sarah.m@email.com</div>
</div>
</div>
</td>
<td class="px-6 py-4 font-mono text-sm text-slate-600">#PT-2846</td>
<td class="px-6 py-4 text-slate-600">Neurology</td>
<td class="px-6 py-4">
<span class="px-3 py-1 rounded-full bg-warning/10 text-warning text-sm font-medium">In Treatment</span>
</td>
<td class="px-6 py-4 text-slate-500">Mar 7, 2026</td>
</tr>
<tr class="border-b border-slate-50 hover:bg-slate-50/50 transition-colors duration-200 cursor-pointer">
<td class="px-6 py-4">
<div class="flex items-center gap-3">
<div class="w-10 h-10 bg-accent/10 rounded-full flex items-center justify-center text-accent font-medium">RJ</div>
<div>
<div class="font-medium text-text">Robert Johnson</div>
<div class="text-sm text-slate-400">r.johnson@email.com</div>
</div>
</div>
</td>
<td class="px-6 py-4 font-mono text-sm text-slate-600">#PT-2845</td>
<td class="px-6 py-4 text-slate-600">Orthopedics</td>
<td class="px-6 py-4">
<span class="px-3 py-1 rounded-full bg-primary/10 text-primary text-sm font-medium">Scheduled</span>
</td>
<td class="px-6 py-4 text-slate-500">Mar 6, 2026</td>
</tr>
<tr class="hover:bg-slate-50/50 transition-colors duration-200 cursor-pointer">
<td class="px-6 py-4">
<div class="flex items-center gap-3">
<div class="w-10 h-10 bg-success/10 rounded-full flex items-center justify-center text-success font-medium">EW</div>
<div>
<div class="font-medium text-text">Emily Wilson</div>
<div class="text-sm text-slate-400">e.wilson@email.com</div>
</div>
</div>
</td>
<td class="px-6 py-4 font-mono text-sm text-slate-600">#PT-2844</td>
<td class="px-6 py-4 text-slate-600">Pediatrics</td>
<td class="px-6 py-4">
<span class="px-3 py-1 rounded-full bg-success/10 text-success text-sm font-medium">Recovered</span>
</td>
<td class="px-6 py-4 text-slate-500">Mar 5, 2026</td>
</tr>
</tbody>
</table>
</div>
</div>
<!-- Upcoming Appointments -->
<div class="bg-white rounded-xl border border-slate-100">
<div class="p-6 border-b border-slate-100">
<h3 class="font-heading font-semibold text-lg text-text">Upcoming Appointments</h3>
</div>
<div class="p-4 space-y-3">
<div class="p-4 rounded-lg bg-slate-50 hover:bg-slate-100 transition-colors duration-200 cursor-pointer">
<div class="flex items-center justify-between mb-2">
<span class="font-medium text-text">Checkup - Michael Brown</span>
<span class="text-xs px-2 py-1 rounded bg-primary/10 text-primary">9:00 AM</span>
</div>
<p class="text-sm text-slate-500">General Health Examination</p>
</div>
<div class="p-4 rounded-lg bg-slate-50 hover:bg-slate-100 transition-colors duration-200 cursor-pointer">
<div class="flex items-center justify-between mb-2">
<span class="font-medium text-text">Surgery - Lisa Anderson</span>
<span class="text-xs px-2 py-1 rounded bg-danger/10 text-danger">11:30 AM</span>
</div>
<p class="text-sm text-slate-500">Knee Replacement Procedure</p>
</div>
<div class="p-4 rounded-lg bg-slate-50 hover:bg-slate-100 transition-colors duration-200 cursor-pointer">
<div class="flex items-center justify-between mb-2">
<span class="font-medium text-text">Consultation - David Lee</span>
<span class="text-xs px-2 py-1 rounded bg-warning/10 text-warning">2:00 PM</span>
</div>
<p class="text-sm text-slate-500">Cardiac Follow-up</p>
</div>
<div class="p-4 rounded-lg bg-slate-50 hover:bg-slate-100 transition-colors duration-200 cursor-pointer">
<div class="flex items-center justify-between mb-2">
<span class="font-medium text-text">Lab Results - Jennifer Kim</span>
<span class="text-xs px-2 py-1 rounded bg-success/10 text-success">4:30 PM</span>
</div>
<p class="text-sm text-slate-500">Blood Work Review</p>
</div>
</div>
</div>
</div>
</main>
</div>
<script>
// Patient Admissions Line Chart
const admissionsCtx = document.getElementById('admissionsChart').getContext('2d');
new Chart(admissionsCtx, {
type: 'line',
data: {
labels: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
datasets: [{
label: 'Admissions',
data: [45, 52, 38, 65, 48, 32, 41],
borderColor: '#3B82F6',
backgroundColor: 'rgba(59, 130, 246, 0.1)',
tension: 0.4,
fill: true,
pointBackgroundColor: '#3B82F6',
pointBorderColor: '#fff',
pointBorderWidth: 2,
pointRadius: 5
}, {
label: 'Discharges',
data: [38, 45, 42, 58, 52, 28, 35],
borderColor: '#10B981',
backgroundColor: 'rgba(16, 185, 129, 0.1)',
tension: 0.4,
fill: true,
pointBackgroundColor: '#10B981',
pointBorderColor: '#fff',
pointBorderWidth: 2,
pointRadius: 5
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
position: 'bottom',
labels: {
usePointStyle: true,
padding: 20
}
}
},
scales: {
y: {
beginAtZero: true,
grid: {
color: 'rgba(0,0,0,0.05)'
}
},
x: {
grid: {
display: false
}
}
}
}
});
// Department Donut Chart
const departmentCtx = document.getElementById('departmentChart').getContext('2d');
new Chart(departmentCtx, {
type: 'doughnut',
data: {
labels: ['Cardiology', 'Neurology', 'Orthopedics', 'Pediatrics', 'Other'],
datasets: [{
data: [28, 22, 18, 15, 17],
backgroundColor: [
'#3B82F6',
'#10B981',
'#F97316',
'#8B5CF6',
'#94A3B8'
],
borderWidth: 0,
hoverOffset: 4
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
cutout: '65%',
plugins: {
legend: {
position: 'bottom',
labels: {
usePointStyle: true,
padding: 15,
font: {
size: 12
}
}
}
}
}
});
</script>
</body>
</html>