make it in the light themed
Browse filesand
Air Quality Trends
CO₂ Level
0 ppm
Smoke Level
0 ppm
Air Quality Index
and themes component too
- components/air-quality-card.js +67 -0
- index.html +10 -8
- style.css +19 -19
components/air-quality-card.js
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
class AirQualityCard extends HTMLElement {
|
| 2 |
+
connectedCallback() {
|
| 3 |
+
this.attachShadow({ mode: 'open' });
|
| 4 |
+
this.shadowRoot.innerHTML = `
|
| 5 |
+
<style>
|
| 6 |
+
.air-quality-card {
|
| 7 |
+
background: white;
|
| 8 |
+
border-radius: 12px;
|
| 9 |
+
padding: 1.5rem;
|
| 10 |
+
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
|
| 11 |
+
border: 1px solid rgba(203, 213, 225, 0.3);
|
| 12 |
+
}
|
| 13 |
+
.card-title {
|
| 14 |
+
font-size: 1.25rem;
|
| 15 |
+
font-weight: 600;
|
| 16 |
+
margin-bottom: 1rem;
|
| 17 |
+
color: #1e293b;
|
| 18 |
+
display: flex;
|
| 19 |
+
align-items: center;
|
| 20 |
+
}
|
| 21 |
+
.card-title i {
|
| 22 |
+
margin-right: 0.5rem;
|
| 23 |
+
}
|
| 24 |
+
.metric {
|
| 25 |
+
margin-bottom: 1rem;
|
| 26 |
+
}
|
| 27 |
+
.metric-title {
|
| 28 |
+
font-size: 0.875rem;
|
| 29 |
+
color: #64748b;
|
| 30 |
+
margin-bottom: 0.25rem;
|
| 31 |
+
}
|
| 32 |
+
.metric-value {
|
| 33 |
+
font-size: 1.5rem;
|
| 34 |
+
font-weight: 600;
|
| 35 |
+
color: #1e293b;
|
| 36 |
+
font-family: 'Orbitron', sans-serif;
|
| 37 |
+
}
|
| 38 |
+
.metric-subtext {
|
| 39 |
+
font-size: 0.75rem;
|
| 40 |
+
color: #94a3b8;
|
| 41 |
+
}
|
| 42 |
+
</style>
|
| 43 |
+
<div class="air-quality-card">
|
| 44 |
+
<h3 class="card-title">
|
| 45 |
+
<i data-feather="wind"></i>
|
| 46 |
+
Air Quality Trends
|
| 47 |
+
</h3>
|
| 48 |
+
<div class="metric">
|
| 49 |
+
<p class="metric-title">CO₂ Level</p>
|
| 50 |
+
<p class="metric-value">0 ppm</p>
|
| 51 |
+
<p class="metric-subtext">Normal range: 400-1000ppm</p>
|
| 52 |
+
</div>
|
| 53 |
+
<div class="metric">
|
| 54 |
+
<p class="metric-title">Smoke Level</p>
|
| 55 |
+
<p class="metric-value">0 ppm</p>
|
| 56 |
+
<p class="metric-subtext">Detector sensitivity: 0.5ppm</p>
|
| 57 |
+
</div>
|
| 58 |
+
<div class="metric">
|
| 59 |
+
<p class="metric-title">Air Quality Index</p>
|
| 60 |
+
<p class="metric-value">0</p>
|
| 61 |
+
<p class="metric-subtext">Good</p>
|
| 62 |
+
</div>
|
| 63 |
+
</div>
|
| 64 |
+
`;
|
| 65 |
+
}
|
| 66 |
+
}
|
| 67 |
+
customElements.define('air-quality-card', AirQualityCard);
|
index.html
CHANGED
|
@@ -12,8 +12,8 @@
|
|
| 12 |
<script src="components/navbar.js"></script>
|
| 13 |
<script src="components/footer.js"></script>
|
| 14 |
</head>
|
| 15 |
-
<body class="bg-gray-
|
| 16 |
-
|
| 17 |
|
| 18 |
<main class="container mx-auto px-4 py-8 grid grid-cols-1 lg:grid-cols-12 gap-6">
|
| 19 |
<!-- Left Column -->
|
|
@@ -39,9 +39,9 @@
|
|
| 39 |
<span class="text-sm text-gray-400">Battery</span>
|
| 40 |
<span id="batteryPercent" class="text-sm">—%</span>
|
| 41 |
</div>
|
| 42 |
-
<div class="w-full bg-gray-
|
| 43 |
<div id="batteryLevelBar" class="h-2.5 rounded-full bg-gradient-to-r from-green-400 to-blue-500" style="width: 0%"></div>
|
| 44 |
-
|
| 45 |
<p id="hoursLeft" class="text-xs text-gray-400 mt-1">— hrs left</p>
|
| 46 |
</div>
|
| 47 |
|
|
@@ -131,11 +131,13 @@
|
|
| 131 |
</div>
|
| 132 |
</div>
|
| 133 |
</div>
|
| 134 |
-
|
| 135 |
<!-- Right Column -->
|
| 136 |
<div class="lg:col-span-3 space-y-6">
|
|
|
|
|
|
|
|
|
|
| 137 |
<!-- Connection Status -->
|
| 138 |
-
|
| 139 |
<h2 class="text-xl font-bold mb-4 flex items-center">
|
| 140 |
<i data-feather="wifi" class="mr-2"></i> Connection
|
| 141 |
</h2>
|
|
@@ -214,10 +216,10 @@
|
|
| 214 |
</div>
|
| 215 |
|
| 216 |
<custom-footer></custom-footer>
|
| 217 |
-
|
| 218 |
<script src="gauges.js"></script>
|
| 219 |
<script src="app.js"></script>
|
| 220 |
-
|
| 221 |
feather.replace();
|
| 222 |
document.addEventListener('DOMContentLoaded', () => {
|
| 223 |
// Initialize tooltips
|
|
|
|
| 12 |
<script src="components/navbar.js"></script>
|
| 13 |
<script src="components/footer.js"></script>
|
| 14 |
</head>
|
| 15 |
+
<body class="bg-gray-50 text-gray-900 font-sans">
|
| 16 |
+
<custom-navbar></custom-navbar>
|
| 17 |
|
| 18 |
<main class="container mx-auto px-4 py-8 grid grid-cols-1 lg:grid-cols-12 gap-6">
|
| 19 |
<!-- Left Column -->
|
|
|
|
| 39 |
<span class="text-sm text-gray-400">Battery</span>
|
| 40 |
<span id="batteryPercent" class="text-sm">—%</span>
|
| 41 |
</div>
|
| 42 |
+
<div class="w-full bg-gray-200 rounded-full h-2.5">
|
| 43 |
<div id="batteryLevelBar" class="h-2.5 rounded-full bg-gradient-to-r from-green-400 to-blue-500" style="width: 0%"></div>
|
| 44 |
+
</div>
|
| 45 |
<p id="hoursLeft" class="text-xs text-gray-400 mt-1">— hrs left</p>
|
| 46 |
</div>
|
| 47 |
|
|
|
|
| 131 |
</div>
|
| 132 |
</div>
|
| 133 |
</div>
|
|
|
|
| 134 |
<!-- Right Column -->
|
| 135 |
<div class="lg:col-span-3 space-y-6">
|
| 136 |
+
<!-- Air Quality Card -->
|
| 137 |
+
<air-quality-card></air-quality-card>
|
| 138 |
+
|
| 139 |
<!-- Connection Status -->
|
| 140 |
+
<div class="glass-card p-6 rounded-xl backdrop-blur-lg border border-opacity-20 border-white">
|
| 141 |
<h2 class="text-xl font-bold mb-4 flex items-center">
|
| 142 |
<i data-feather="wifi" class="mr-2"></i> Connection
|
| 143 |
</h2>
|
|
|
|
| 216 |
</div>
|
| 217 |
|
| 218 |
<custom-footer></custom-footer>
|
| 219 |
+
<script src="components/air-quality-card.js"></script>
|
| 220 |
<script src="gauges.js"></script>
|
| 221 |
<script src="app.js"></script>
|
| 222 |
+
<script>
|
| 223 |
feather.replace();
|
| 224 |
document.addEventListener('DOMContentLoaded', () => {
|
| 225 |
// Initialize tooltips
|
style.css
CHANGED
|
@@ -1,71 +1,71 @@
|
|
| 1 |
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600;700&family=Orbitron:wght@400;600&display=swap');
|
| 2 |
-
|
| 3 |
:root {
|
| 4 |
-
--primary: #
|
| 5 |
-
--primary-dark: #
|
| 6 |
--secondary: #10b981;
|
| 7 |
-
--danger: #
|
| 8 |
-
--warning: #
|
| 9 |
-
--success: #
|
| 10 |
-
--info: #
|
| 11 |
--dark: #1e293b;
|
| 12 |
-
--light: #
|
| 13 |
--muted: #64748b;
|
| 14 |
}
|
| 15 |
|
| 16 |
body {
|
| 17 |
font-family: 'Poppins', sans-serif;
|
| 18 |
-
background: linear-gradient(135deg, #
|
| 19 |
min-height: 100vh;
|
| 20 |
-
color:
|
| 21 |
}
|
| 22 |
|
| 23 |
.glass-card {
|
| 24 |
-
background: rgba(
|
| 25 |
backdrop-filter: blur(10px);
|
| 26 |
-webkit-backdrop-filter: blur(10px);
|
| 27 |
-
box-shadow: 0
|
| 28 |
transition: all 0.3s ease;
|
|
|
|
| 29 |
}
|
| 30 |
-
|
| 31 |
.glass-card:hover {
|
| 32 |
box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.2);
|
| 33 |
transform: translateY(-2px);
|
| 34 |
}
|
| 35 |
-
|
| 36 |
.led {
|
| 37 |
width: 24px;
|
| 38 |
height: 24px;
|
| 39 |
border-radius: 50%;
|
| 40 |
position: relative;
|
| 41 |
transition: all 0.3s ease;
|
| 42 |
-
box-shadow: 0 0 10px rgba(
|
| 43 |
}
|
| 44 |
|
| 45 |
.led-green {
|
| 46 |
background-color: #10b981;
|
|
|
|
| 47 |
}
|
| 48 |
|
| 49 |
.led-yellow {
|
| 50 |
background-color: #f59e0b;
|
|
|
|
| 51 |
}
|
| 52 |
|
| 53 |
.led-red {
|
| 54 |
background-color: #ef4444;
|
|
|
|
| 55 |
}
|
| 56 |
|
| 57 |
.led-active-green {
|
| 58 |
-
box-shadow: 0 0 15px
|
| 59 |
}
|
| 60 |
|
| 61 |
.led-active-yellow {
|
| 62 |
-
box-shadow: 0 0 15px
|
| 63 |
}
|
| 64 |
|
| 65 |
.led-active-red {
|
| 66 |
-
box-shadow: 0 0 15px
|
| 67 |
}
|
| 68 |
-
|
| 69 |
.led-pulse {
|
| 70 |
animation: pulse 1.5s infinite;
|
| 71 |
}
|
|
|
|
| 1 |
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600;700&family=Orbitron:wght@400;600&display=swap');
|
|
|
|
| 2 |
:root {
|
| 3 |
+
--primary: #4f46e5;
|
| 4 |
+
--primary-dark: #4338ca;
|
| 5 |
--secondary: #10b981;
|
| 6 |
+
--danger: #dc2626;
|
| 7 |
+
--warning: #d97706;
|
| 8 |
+
--success: #059669;
|
| 9 |
+
--info: #2563eb;
|
| 10 |
--dark: #1e293b;
|
| 11 |
+
--light: #ffffff;
|
| 12 |
--muted: #64748b;
|
| 13 |
}
|
| 14 |
|
| 15 |
body {
|
| 16 |
font-family: 'Poppins', sans-serif;
|
| 17 |
+
background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
|
| 18 |
min-height: 100vh;
|
| 19 |
+
color: #1e293b;
|
| 20 |
}
|
| 21 |
|
| 22 |
.glass-card {
|
| 23 |
+
background: rgba(255, 255, 255, 0.9);
|
| 24 |
backdrop-filter: blur(10px);
|
| 25 |
-webkit-backdrop-filter: blur(10px);
|
| 26 |
+
box-shadow: 0 4px 20px 0 rgba(0, 0, 0, 0.05);
|
| 27 |
transition: all 0.3s ease;
|
| 28 |
+
border: 1px solid rgba(203, 213, 225, 0.3);
|
| 29 |
}
|
|
|
|
| 30 |
.glass-card:hover {
|
| 31 |
box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.2);
|
| 32 |
transform: translateY(-2px);
|
| 33 |
}
|
|
|
|
| 34 |
.led {
|
| 35 |
width: 24px;
|
| 36 |
height: 24px;
|
| 37 |
border-radius: 50%;
|
| 38 |
position: relative;
|
| 39 |
transition: all 0.3s ease;
|
| 40 |
+
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
| 41 |
}
|
| 42 |
|
| 43 |
.led-green {
|
| 44 |
background-color: #10b981;
|
| 45 |
+
border: 1px solid #059669;
|
| 46 |
}
|
| 47 |
|
| 48 |
.led-yellow {
|
| 49 |
background-color: #f59e0b;
|
| 50 |
+
border: 1px solid #d97706;
|
| 51 |
}
|
| 52 |
|
| 53 |
.led-red {
|
| 54 |
background-color: #ef4444;
|
| 55 |
+
border: 1px solid #dc2626;
|
| 56 |
}
|
| 57 |
|
| 58 |
.led-active-green {
|
| 59 |
+
box-shadow: 0 0 15px rgba(16, 185, 129, 0.5);
|
| 60 |
}
|
| 61 |
|
| 62 |
.led-active-yellow {
|
| 63 |
+
box-shadow: 0 0 15px rgba(245, 158, 11, 0.5);
|
| 64 |
}
|
| 65 |
|
| 66 |
.led-active-red {
|
| 67 |
+
box-shadow: 0 0 15px rgba(239, 68, 68, 0.5);
|
| 68 |
}
|
|
|
|
| 69 |
.led-pulse {
|
| 70 |
animation: pulse 1.5s infinite;
|
| 71 |
}
|