undefined / iot-dashboard.html
Codechief's picture
add "add device" button
ebf3198 verified
<!DOCTYPE html>
<html lang="en" class="light">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>IoT Dashboard | AuthPortal Pro</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
<script src="https://unpkg.com/feather-icons"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
tailwind.config = {
darkMode: 'class',
theme: {
extend: {
colors: {
primary: {
500: '#3B82F6',
600: '#2563EB',
},
secondary: {
500: '#6366F1',
600: '#4F46E5',
}
}
}
}
}
</script>
<style>
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
html {
font-family: 'Inter', sans-serif;
}
.card {
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
}
.dark .card {
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.2);
}
</style>
</head>
<body class="bg-gray-50 dark:bg-gray-900 transition-colors duration-200 min-h-screen flex flex-col">
<!-- Navigation Bar -->
<nav class="bg-white dark:bg-gray-800 shadow-sm py-4 px-6">
<div class="max-w-7xl mx-auto flex justify-between items-center">
<div class="flex items-center space-x-4">
<div class="flex items-center">
<i data-feather="wifi" class="text-primary-500 dark:text-primary-400 w-6 h-6"></i>
<span class="ml-2 font-semibold text-gray-800 dark:text-white">IoT Dashboard</span>
</div>
<div class="hidden md:flex space-x-1">
<a href="#" class="px-3 py-2 text-sm font-medium rounded-md text-primary-500 dark:text-primary-400 bg-primary-50 dark:bg-primary-900/30">Dashboard</a>
<a href="#" class="px-3 py-2 text-sm font-medium rounded-md text-gray-600 dark:text-gray-300 hover:text-gray-900 dark:hover:text-white">Devices</a>
<a href="#" class="px-3 py-2 text-sm font-medium rounded-md text-gray-600 dark:text-gray-300 hover:text-gray-900 dark:hover:text-white">Alerts</a>
<a href="#" class="px-3 py-2 text-sm font-medium rounded-md text-gray-600 dark:text-gray-300 hover:text-gray-900 dark:hover:text-white">Settings</a>
</div>
</div>
<div class="flex items-center space-x-4">
<!-- Language Selector -->
<div class="relative">
<select class="appearance-none bg-transparent border border-gray-300 dark:border-gray-600 rounded px-3 py-1 pr-8 text-sm text-gray-700 dark:text-gray-100 focus:outline-none focus:ring-1 focus:ring-primary-500 dark:bg-gray-700">
<option value="en" class="dark:bg-gray-700 dark:text-gray-100">English</option>
<option value="es" class="dark:bg-gray-700 dark:text-gray-100">Español</option>
<option value="fr" class="dark:bg-gray-700 dark:text-gray-100">Français</option>
<option value="de" class="dark:bg-gray-700 dark:text-gray-100">Deutsch</option>
<option value="ja" class="dark:bg-gray-700 dark:text-gray-100">日本語</option>
</select>
<div class="absolute inset-y-0 right-0 flex items-center pr-2 pointer-events-none">
<i data-feather="globe" class="h-4 w-4 text-gray-400 dark:text-gray-300"></i>
</div>
</div>
<!-- Dark Mode Toggle -->
<button id="theme-toggle" class="text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 focus:outline-none rounded-lg text-sm p-2">
<i id="theme-icon" data-feather="moon" class="w-5 h-5"></i>
</button>
<!-- User Profile -->
<div class="relative">
<button class="flex items-center space-x-2 focus:outline-none">
<div class="h-8 w-8 rounded-full bg-primary-100 dark:bg-primary-900/30 flex items-center justify-center">
<i data-feather="user" class="h-4 w-4 text-primary-500 dark:text-primary-400"></i>
</div>
<span class="hidden md:inline text-sm font-medium text-gray-700 dark:text-gray-300">Admin</span>
</button>
</div>
</div>
</div>
</nav>
<!-- Main Content -->
<main class="flex-grow p-6">
<div class="max-w-7xl mx-auto">
<!-- Header -->
<div class="flex flex-col md:flex-row md:items-center md:justify-between mb-6">
<h1 class="text-2xl font-bold text-gray-900 dark:text-white">Device Dashboard</h1>
<div class="flex space-x-2">
<button class="inline-flex items-center px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm text-sm font-medium text-gray-700 dark:text-gray-300 bg-white dark:bg-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600">
<i data-feather="refresh-cw" class="mr-2 h-4 w-4"></i>
Refresh
</button>
<button class="inline-flex items-center px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-primary-500 hover:bg-primary-600">
<i data-feather="plus" class="mr-2 h-4 w-4"></i>
Add Device
</button>
<button class="inline-flex items-center px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-green-500 hover:bg-green-600">
<i data-feather="upload" class="mr-2 h-4 w-4"></i>
Import
</button>
</div>
</div>
<!-- Stats Cards -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-6">
<!-- Active Devices -->
<div class="card bg-white dark:bg-gray-800 rounded-lg p-6">
<div class="flex items-center justify-between">
<div>
<p class="text-sm font-medium text-gray-500 dark:text-gray-400">Active Devices</p>
<p class="text-2xl font-bold text-gray-900 dark:text-white">24</p>
</div>
<div class="p-3 rounded-full bg-primary-100 dark:bg-primary-900/30">
<i data-feather="cpu" class="h-6 w-6 text-primary-500 dark:text-primary-400"></i>
</div>
</div>
<div class="mt-4">
<div class="flex items-center text-sm text-green-500">
<i data-feather="trending-up" class="h-4 w-4 mr-1"></i>
<span>12% from last week</span>
</div>
</div>
</div>
<!-- Temperature -->
<div class="card bg-white dark:bg-gray-800 rounded-lg p-6">
<div class="flex items-center justify-between">
<div>
<p class="text-sm font-medium text-gray-500 dark:text-gray-400">Avg Temperature</p>
<p class="text-2xl font-bold text-gray-900 dark:text-white">23.5°C</p>
</div>
<div class="p-3 rounded-full bg-red-100 dark:bg-red-900/30">
<i data-feather="thermometer" class="h-6 w-6 text-red-500 dark:text-red-400"></i>
</div>
</div>
<div class="mt-4">
<div class="flex items-center text-sm text-yellow-500">
<i data-feather="alert-circle" class="h-4 w-4 mr-1"></i>
<span>1.2°C above average</span>
</div>
</div>
</div>
<!-- Humidity -->
<div class="card bg-white dark:bg-gray-800 rounded-lg p-6">
<div class="flex items-center justify-between">
<div>
<p class="text-sm font-medium text-gray-500 dark:text-gray-400">Avg Humidity</p>
<p class="text-2xl font-bold text-gray-900 dark:text-white">65%</p>
</div>
<div class="p-3 rounded-full bg-blue-100 dark:bg-blue-900/30">
<i data-feather="droplet" class="h-6 w-6 text-blue-500 dark:text-blue-400"></i>
</div>
</div>
<div class="mt-4">
<div class="flex items-center text-sm text-green-500">
<i data-feather="check-circle" class="h-4 w-4 mr-1"></i>
<span>Within optimal range</span>
</div>
</div>
</div>
<!-- Alerts -->
<div class="card bg-white dark:bg-gray-800 rounded-lg p-6">
<div class="flex items-center justify-between">
<div>
<p class="text-sm font-medium text-gray-500 dark:text-gray-400">Active Alerts</p>
<p class="text-2xl font-bold text-gray-900 dark:text-white">3</p>
</div>
<div class="p-3 rounded-full bg-yellow-100 dark:bg-yellow-900/30">
<i data-feather="alert-triangle" class="h-6 w-6 text-yellow-500 dark:text-yellow-400"></i>
</div>
</div>
<div class="mt-4">
<div class="flex items-center text-sm text-red-500">
<i data-feather="arrow-up" class="h-4 w-4 mr-1"></i>
<span>2 new today</span>
</div>
</div>
</div>
</div>
<!-- Charts Row -->
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-6">
<!-- Temperature Chart -->
<div class="card bg-white dark:bg-gray-800 rounded-lg p-6">
<div class="flex items-center justify-between mb-4">
<h2 class="text-lg font-medium text-gray-900 dark:text-white">Temperature Trends</h2>
<div class="flex space-x-2">
<button class="text-xs px-2 py-1 rounded bg-gray-100 dark:bg-gray-700 text-gray-700 dark:text-gray-300">24h</button>
<button class="text-xs px-2 py-1 rounded text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700">7d</button>
<button class="text-xs px-2 py-1 rounded text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700">30d</button>
</div>
</div>
<canvas id="temperatureChart" height="250"></canvas>
</div>
<!-- Humidity Chart -->
<div class="card bg-white dark:bg-gray-800 rounded-lg p-6">
<div class="flex items-center justify-between mb-4">
<h2 class="text-lg font-medium text-gray-900 dark:text-white">Humidity Levels</h2>
<div class="flex space-x-2">
<button class="text-xs px-2 py-1 rounded bg-gray-100 dark:bg-gray-700 text-gray-700 dark:text-gray-300">24h</button>
<button class="text-xs px-2 py-1 rounded text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700">7d</button>
<button class="text-xs px-2 py-1 rounded text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700">30d</button>
</div>
</div>
<canvas id="humidityChart" height="250"></canvas>
</div>
</div>
<!-- Device Status Table -->
<div class="card bg-white dark:bg-gray-800 rounded-lg overflow-hidden">
<div class="px-6 py-4 border-b border-gray-200 dark:border-gray-700">
<h2 class="text-lg font-medium text-gray-900 dark:text-white">Connected Devices</h2>
</div>
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
<thead class="bg-gray-50 dark:bg-gray-700">
<tr>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">Device</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">Status</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">Temperature</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">Humidity</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">Last Active</th>
<th scope="col" class="px-6 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">Actions</th>
</tr>
</thead>
<tbody class="bg-white dark:bg-gray-800 divide-y divide-gray-200 dark:divide-gray-700">
<tr>
<td class="px-6 py-4 whitespace-nowrap">
<div class="flex items-center">
<div class="flex-shrink-0 h-10 w-10 rounded-full bg-blue-100 dark:bg-blue-900/30 flex items-center justify-center">
<i data-feather="thermometer" class="h-5 w-5 text-blue-500 dark:text-blue-400"></i>
</div>
<div class="ml-4">
<div class="text-sm font-medium text-gray-900 dark:text-white">Living Room Sensor</div>
<div class="text-sm text-gray-500 dark:text-gray-400">ID: SENS-001</div>
</div>
</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 dark:bg-green-900/30 text-green-800 dark:text-green-300">
Active
</span>
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-white">
22.4°C
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-white">
62%
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">
2 minutes ago
</td>
<td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
<button class="text-primary-500 dark:text-primary-400 hover:text-primary-600 dark:hover:text-primary-300 mr-3">
<i data-feather="settings" class="h-4 w-4"></i>
</button>
<button class="text-red-500 dark:text-red-400 hover:text-red-600 dark:hover:text-red-300">
<i data-feather="trash-2" class="h-4 w-4"></i>
</button>
</td>
</tr>
<tr>
<td class="px-6 py-4 whitespace-nowrap">
<div class="flex items-center">
<div class="flex-shrink-0 h-10 w-10 rounded-full bg-blue-100 dark:bg-blue-900/30 flex items-center justify-center">
<i data-feather="thermometer" class="h-5 w-5 text-blue-500 dark:text-blue-400"></i>
</div>
<div class="ml-4">
<div class="text-sm font-medium text-gray-900 dark:text-white">Kitchen Sensor</div>
<div class="text-sm text-gray-500 dark:text-gray-400">ID: SENS-002</div>
</div>
</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 dark:bg-green-900/30 text-green-800 dark:text-green-300">
Active
</span>
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-white">
24.1°C
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-white">
58%
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">
5 minutes ago
</td>
<td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
<button class="text-primary-500 dark:text-primary-400 hover:text-primary-600 dark:hover:text-primary-300 mr-3">
<i data-feather="settings" class="h-4 w-4"></i>
</button>
<button class="text-red-500 dark:text-red-400 hover:text-red-600 dark:hover:text-red-300">
<i data-feather="trash-2" class="h-4 w-4"></i>
</button>
</td>
</tr>
<tr>
<td class="px-6 py-4 whitespace-nowrap">
<div class="flex items-center">
<div class="flex-shrink-0 h-10 w-10 rounded-full bg-yellow-100 dark:bg-yellow-900/30 flex items-center justify-center">
<i data-feather="alert-triangle" class="h-5 w-5 text-yellow-500 dark:text-yellow-400"></i>
</div>
<div class="ml-4">
<div class="text-sm font-medium text-gray-900 dark:text-white">Bedroom Sensor</div>
<div class="text-sm text-gray-500 dark:text-gray-400">ID: SENS-003</div>
</div>
</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-yellow-100 dark:bg-yellow-900/30 text-yellow-800 dark:text-yellow-300">
Warning
</span>
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-white">
28.7°C
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-white">
45%
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">
15 minutes ago
</td>
<td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
<button class="text-primary-500 dark:text-primary-400 hover:text-primary-600 dark:hover:text-primary-300 mr-3">
<i data-feather="settings" class="h-4 w-4"></i>
</button>
<button class="text-red-500 dark:text-red-400 hover:text-red-600 dark:hover:text-red-300">
<i data-feather="trash-2" class="h-4 w-4"></i>
</button>
</td>
</tr>
</tbody>
</table>
</div>
<div class="px-6 py-4 border-t border-gray-200 dark:border-gray-700">
<div class="flex items-center justify-between">
<div class="text-sm text-gray-500 dark:text-gray-400">
Showing <span class="font-medium">1</span> to <span class="font-medium">3</span> of <span class="font-medium">24</span> devices
</div>
<div class="flex space-x-2">
<button class="px-3 py-1 rounded-md border border-gray-300 dark:border-gray-600 text-sm font-medium text-gray-700 dark:text-gray-300 bg-white dark:bg-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600">
Previous
</button>
<button class="px-3 py-1 rounded-md border border-gray-300 dark:border-gray-600 text-sm font-medium text-gray-700 dark:text-gray-300 bg-white dark:bg-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600">
Next
</button>
</div>
</div>
</div>
</div>
</div>
</main>
<script>
// Theme toggle functionality
const themeToggle = document.getElementById('theme-toggle');
const themeIcon = document.getElementById('theme-icon');
const html = document.documentElement;
// Check for saved theme preference or use preferred OS theme
if (localStorage.getItem('theme') === 'dark' || (!localStorage.getItem('theme') && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
html.classList.add('dark');
themeIcon.setAttribute('data-feather', 'sun');
} else {
html.classList.remove('dark');
themeIcon.setAttribute('data-feather', 'moon');
}
themeToggle.addEventListener('click', () => {
html.classList.toggle('dark');
localStorage.setItem('theme', html.classList.contains('dark') ? 'dark' : 'light');
if (html.classList.contains('dark')) {
themeIcon.setAttribute('data-feather', 'sun');
} else {
themeIcon.setAttribute('data-feather', 'moon');
}
feather.replace();
});
// Language change handler
document.querySelector('select').addEventListener('change', function() {
const lang = this.value;
console.log('Language changed to:', lang);
});
// Initialize charts
function initCharts() {
// Temperature Chart
const tempCtx = document.getElementById('temperatureChart').getContext('2d');
const tempChart = new Chart(tempCtx, {
type: 'line',
data: {
labels: Array.from({length: 24}, (_, i) => `${i}:00`),
datasets: [{
label: 'Temperature (°C)',
data: [22, 21, 20, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 19],
borderColor: '#EF4444',
backgroundColor: 'rgba(239, 68, 68, 0.1)',
borderWidth: 2,
tension: 0.3,
fill: true
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
labels: {
color: html.classList.contains('dark') ? '#F3F4F6' : '#111827'
}
}
},
scales: {
x: {
grid: {
color: html.classList.contains('dark') ? 'rgba(255, 255, 255, 0.1)' : 'rgba(0, 0, 0, 0.1)'
},
ticks: {
color: html.classList.contains('dark') ? '#9CA3AF' : '#6B7280'
}
},
y: {
grid: {
color: html.classList.contains('dark') ? 'rgba(255, 255, 255, 0.1)' : 'rgba(0, 0, 0, 0.1)'
},
ticks: {
color: html.classList.contains('dark') ? '#9CA3AF' : '#6B7280'
}
}
}
}
});
// Humidity Chart
const humidityCtx = document.getElementById('humidityChart').getContext('2d');
const humidityChart = new Chart(humidityCtx, {
type: 'line',
data: {
labels: Array.from({length: 24}, (_, i) => `${i}:00`),
datasets: [{
label: 'Humidity (%)',
data: [65, 64, 63, 62, 63, 64, 65, 66, 67, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 60, 61, 62, 63, 64],
borderColor: '#3B82F6',
backgroundColor: 'rgba(59, 130, 246, 0.1)',
borderWidth: 2,
tension: 0.3,
fill: true
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
labels: {
color: html.classList.contains('dark') ? '#F3F4F6' : '#111827'
}
}
},
scales: {
x: {
grid: {
color: html.classList.contains('dark') ? 'rgba(255, 255, 255, 0.1)' : 'rgba(0, 0, 0, 0.1)'
},
ticks: {
color: html.classList.contains('dark') ? '#9CA3AF' : '#6B7280'
}
},
y: {
grid: {
color: html.classList.contains('dark') ? 'rgba(255, 255, 255, 0.1)' : 'rgba(0, 0, 0, 0.1)'
},
ticks: {
color: html.classList.contains('dark') ? '#9CA3AF' : '#6B7280'
}
}
}
}
});
}
// Initialize feather icons and charts when DOM is loaded
document.addEventListener('DOMContentLoaded', function() {
feather.replace();
initCharts();
});
</script>
</body>
</html>