hema / index.html
Soundaryasos's picture
Add 3 files
bfea988 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Virus Fever Detection Using IoT</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="https://cdn.jsdelivr.net/npm/react@18/umd/react.development.js" crossorigin></script>
<script src="https://cdn.jsdelivr.net/npm/react-dom@18/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<style>
.chart-container {
position: relative;
height: 300px;
width: 100%;
max-width: 400px;
margin: 0 auto;
}
.alert-badge {
position: absolute;
top: 10px;
right: 10px;
width: 20px;
height: 20px;
border-radius: 50%;
background-color: #ef4444;
color: white;
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
font-size: 12px;
z-index: 10;
}
.threshold-line {
border-top: 2px dashed;
position: absolute;
width: 100%;
}
.threshold-label {
position: absolute;
right: 10px;
font-size: 12px;
background-color: rgba(255,255,255,0.8);
padding: 2px 5px;
border-radius: 3px;
}
.chart-toolbar {
display: flex;
gap: 10px;
margin-bottom: 15px;
flex-wrap: wrap;
}
.chart-wrapper {
background-color: #f8fafc;
border-radius: 0.5rem;
padding: 1rem;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
transition: all 0.3s ease;
}
.chart-wrapper:hover {
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
transform: translateY(-2px);
}
@media (max-width: 768px) {
.chart-grid {
grid-template-columns: 1fr;
}
}
</style>
</head>
<body class="bg-gray-50 font-sans">
<div id="root"></div>
<script type="text/babel">
const { useState, useEffect, useRef } = React;
function App() {
// Initial data points (first 20 seconds)
const initialTempData = [
{x: 0, y: 36.8}, {x: 2, y: 36.9}, {x: 4, y: 37.0},
{x: 6, y: 37.1}, {x: 8, y: 37.0}, {x: 10, y: 37.2},
{x: 12, y: 37.3}, {x: 14, y: 38.1}, {x: 16, y: 38.2},
{x: 18, y: 38.0}
];
const initialPulseData = [
{x: 0, y: 78}, {x: 2, y: 79}, {x: 4, y: 80},
{x: 6, y: 82}, {x: 8, y: 81}, {x: 10, y: 83},
{x: 12, y: 84}, {x: 14, y: 86}, {x: 16, y: 85},
{x: 18, y: 84}
];
const initialRespData = [
{x: 0, y: 14}, {x: 2, y: 15}, {x: 4, y: 15},
{x: 6, y: 14}, {x: 8, y: 15}, {x: 10, y: 16},
{x: 12, y: 15}, {x: 14, y: 16}, {x: 16, y: 15},
{x: 18, y: 14}
];
// State for data points
const [temperatureData, setTemperatureData] = useState([...initialTempData]);
const [pulseData, setPulseData] = useState([...initialPulseData]);
const [respirationData, setRespirationData] = useState([...initialRespData]);
const [isRunning, setIsRunning] = useState(false);
const [showTemperature, setShowTemperature] = useState(true);
const [showPulse, setShowPulse] = useState(true);
const [showRespiration, setShowRespiration] = useState(true);
const [currentTime, setCurrentTime] = useState(20); // Start at 20 seconds
const [isInitialized, setIsInitialized] = useState(false);
// Refs for chart instances
const tempChartRef = useRef(null);
const pulseChartRef = useRef(null);
const respChartRef = useRef(null);
const combinedChartRef = useRef(null);
// Initialize data with initial points
useEffect(() => {
if (!isInitialized) {
setIsInitialized(true);
}
}, []);
// Data simulation effect
useEffect(() => {
let interval;
if (isRunning) {
interval = setInterval(() => {
updateData();
setCurrentTime(prev => prev + 2);
}, 2000);
}
return () => clearInterval(interval);
}, [isRunning, temperatureData, pulseData, respirationData]);
// Initialize charts when component mounts
useEffect(() => {
initCharts();
return () => {
// Clean up charts when component unmounts
if (tempChartRef.current) tempChartRef.current.destroy();
if (pulseChartRef.current) pulseChartRef.current.destroy();
if (respChartRef.current) respChartRef.current.destroy();
if (combinedChartRef.current) combinedChartRef.current.destroy();
};
}, []);
// Update charts when data changes
useEffect(() => {
updateCharts();
}, [temperatureData, pulseData, respirationData, showTemperature, showPulse, showRespiration]);
const resetData = () => {
setTemperatureData([...initialTempData]);
setPulseData([...initialPulseData]);
setRespirationData([...initialRespData]);
setCurrentTime(20);
if (!isRunning) {
updateCharts();
}
};
const generateNewValue = (currentValue, min, max, maxChange) => {
const change = (Math.random() * 2 - 1) * maxChange;
let newValue = currentValue + change;
// Ensure the new value stays within bounds
newValue = Math.max(min, Math.min(max, newValue));
// Round to appropriate decimal places
if (maxChange < 1) {
return parseFloat(newValue.toFixed(1));
}
return Math.round(newValue);
};
const updateData = () => {
// Get last values or use defaults if no data
const lastTemp = temperatureData.length > 0 ? temperatureData[temperatureData.length - 1].y : 37.0;
const lastPulse = pulseData.length > 0 ? pulseData[pulseData.length - 1].y : 80;
const lastResp = respirationData.length > 0 ? respirationData[respirationData.length - 1].y : 15;
// Generate new values with realistic fluctuations
const newTemp = generateNewValue(lastTemp, 36.5, 38.5, 0.2);
const newPulse = generateNewValue(lastPulse, 70, 100, 5);
const newResp = generateNewValue(lastResp, 12, 18, 1);
// Update data arrays (sliding window of 30 points)
setTemperatureData(prev => {
const newData = [...prev.slice(1), { x: currentTime, y: newTemp }];
return newData;
});
setPulseData(prev => {
const newData = [...prev.slice(1), { x: currentTime, y: newPulse }];
return newData;
});
setRespirationData(prev => {
const newData = [...prev.slice(1), { x: currentTime, y: newResp }];
return newData;
});
};
const initCharts = () => {
// Temperature Chart
const tempCtx = document.getElementById('temperatureChart').getContext('2d');
tempChartRef.current = new Chart(tempCtx, {
type: 'line',
data: {
datasets: [{
label: 'Temperature (Β°C)',
data: temperatureData,
borderColor: '#ef4444',
backgroundColor: 'rgba(239, 68, 68, 0.1)',
borderWidth: 2,
tension: 0.4,
fill: true,
pointRadius: 0
}]
},
options: getChartOptions('Temperature (Β°C)', 'Β°C', 34, 42, false, [
{ value: 38, color: '#ef4444', label: 'Fever Threshold' }
])
});
// Pulse Chart
const pulseCtx = document.getElementById('pulseChart').getContext('2d');
pulseChartRef.current = new Chart(pulseCtx, {
type: 'line',
data: {
datasets: [{
label: 'Pulse Rate (bpm)',
data: pulseData,
borderColor: '#3b82f6',
backgroundColor: 'rgba(59, 130, 246, 0.1)',
borderWidth: 2,
tension: 0.4,
fill: true,
pointRadius: 0
}]
},
options: getChartOptions('Pulse Rate (bpm)', 'bpm', 50, 130, false, [
{ value: 100, color: '#f59e0b', label: 'High Pulse' }
])
});
// Respiration Chart
const respCtx = document.getElementById('respirationChart').getContext('2d');
respChartRef.current = new Chart(respCtx, {
type: 'line',
data: {
datasets: [{
label: 'Respiration Rate (rpm)',
data: respirationData,
borderColor: '#10b981',
backgroundColor: 'rgba(16, 185, 129, 0.1)',
borderWidth: 2,
tension: 0.4,
fill: true,
pointRadius: 0
}]
},
options: getChartOptions('Respiration Rate (rpm)', 'rpm', 8, 24, false, [
{ value: 20, color: '#f59e0b', label: 'High Respiration' }
])
});
// Combined Chart
const combinedCtx = document.getElementById('combinedChart').getContext('2d');
combinedChartRef.current = new Chart(combinedCtx, {
type: 'line',
data: {
datasets: [
{
label: 'Temperature (Β°C)',
data: temperatureData,
borderColor: '#ef4444',
backgroundColor: 'rgba(239, 68, 68, 0.1)',
borderWidth: 2,
tension: 0.4,
fill: false,
hidden: !showTemperature,
pointRadius: 0
},
{
label: 'Pulse Rate (bpm)',
data: pulseData,
borderColor: '#3b82f6',
backgroundColor: 'rgba(59, 130, 246, 0.1)',
borderWidth: 2,
tension: 0.4,
fill: false,
hidden: !showPulse,
pointRadius: 0
},
{
label: 'Respiration Rate (rpm)',
data: respirationData,
borderColor: '#10b981',
backgroundColor: 'rgba(16, 185, 129, 0.1)',
borderWidth: 2,
tension: 0.4,
fill: false,
hidden: !showRespiration,
pointRadius: 0
}
]
},
options: getChartOptions('Combined Health Metrics', 'Value', 30, 42, true, [
{ value: 38, color: '#ef4444', label: 'Fever' },
{ value: 100, color: '#f59e0b', label: 'High Pulse' },
{ value: 20, color: '#f59e0b', label: 'High Respiration' }
])
});
};
const updateCharts = () => {
if (tempChartRef.current) {
tempChartRef.current.data.datasets[0].data = temperatureData;
tempChartRef.current.update();
}
if (pulseChartRef.current) {
pulseChartRef.current.data.datasets[0].data = pulseData;
pulseChartRef.current.update();
}
if (respChartRef.current) {
respChartRef.current.data.datasets[0].data = respirationData;
respChartRef.current.update();
}
if (combinedChartRef.current) {
combinedChartRef.current.data.datasets[0].data = temperatureData;
combinedChartRef.current.data.datasets[0].hidden = !showTemperature;
combinedChartRef.current.data.datasets[1].data = pulseData;
combinedChartRef.current.data.datasets[1].hidden = !showPulse;
combinedChartRef.current.data.datasets[2].data = respirationData;
combinedChartRef.current.data.datasets[2].hidden = !showRespiration;
combinedChartRef.current.update();
}
};
const getChartOptions = (title, yLabel, minY, maxY, isCombined = false, thresholds = []) => {
const options = {
responsive: true,
maintainAspectRatio: false,
animation: {
duration: 0
},
plugins: {
title: {
display: true,
text: title,
font: {
size: 16,
weight: 'bold'
},
padding: {
top: 10,
bottom: 10
}
},
tooltip: {
mode: 'index',
intersect: false,
callbacks: {
label: function(context) {
return `${context.dataset.label}: ${context.parsed.y.toFixed(1)}`;
}
}
},
legend: {
display: isCombined,
position: 'top',
labels: {
boxWidth: 12,
padding: 20
}
},
zoom: {
pan: {
enabled: true,
mode: 'xy'
},
zoom: {
wheel: {
enabled: true,
},
pinch: {
enabled: true
},
mode: 'xy',
}
}
},
scales: {
x: {
type: 'linear',
position: 'bottom',
title: {
display: true,
text: 'Time (seconds)',
font: {
size: 12
}
},
min: Math.max(0, currentTime - 60),
max: currentTime,
ticks: {
stepSize: 10,
callback: function(value) {
return value + 's';
}
},
grid: {
color: 'rgba(0, 0, 0, 0.05)'
}
},
y: {
title: {
display: true,
text: yLabel,
font: {
size: 12
}
},
min: minY,
max: maxY,
ticks: {
// For more precise ticks on temperature
...(yLabel === 'Β°C' ? {
stepSize: 1,
callback: function(value) {
// Show minor ticks (0.2) as smaller ticks
if (value % 1 === 0) return value;
return '';
}
} : {}),
// For pulse and respiration
...(yLabel === 'bpm' ? { stepSize: 10 } : {}),
...(yLabel === 'rpm' ? { stepSize: 2 } : {})
},
grid: {
color: function(context) {
// For temperature chart, draw minor grid lines every 0.2Β°C
if (yLabel === 'Β°C' && context.tick.value % 1 !== 0) {
return 'rgba(0, 0, 0, 0.02)';
}
return 'rgba(0, 0, 0, 0.05)';
}
}
}
},
elements: {
point: {
radius: 0,
hoverRadius: 5
},
line: {
borderWidth: 2,
tension: 0.4
}
},
interaction: {
mode: 'nearest',
axis: 'x',
intersect: false
}
};
// Add threshold annotations
if (thresholds.length > 0) {
options.plugins.annotation = {
annotations: thresholds.map(threshold => ({
type: 'line',
yMin: threshold.value,
yMax: threshold.value,
borderColor: threshold.color,
borderWidth: 2,
borderDash: [6, 6],
label: {
content: threshold.label,
enabled: true,
position: 'right',
backgroundColor: 'rgba(255,255,255,0.8)',
color: threshold.color,
font: {
weight: 'bold',
size: 10
}
}
}))
};
}
return options;
};
const toggleSimulation = () => {
setIsRunning(!isRunning);
};
const handleReset = () => {
resetData();
if (!isRunning) {
updateCharts();
}
};
const getLatestValues = () => {
const temp = temperatureData.length > 0 ? temperatureData[temperatureData.length - 1].y : null;
const pulse = pulseData.length > 0 ? pulseData[pulseData.length - 1].y : null;
const resp = respirationData.length > 0 ? respirationData[respirationData.length - 1].y : null;
return {
temp: temp !== null ? temp.toFixed(1) : '--',
pulse: pulse !== null ? pulse.toFixed(0) : '--',
resp: resp !== null ? resp.toFixed(0) : '--',
time: currentTime + 's'
};
};
const getStatusColor = (value, thresholds) => {
if (value === null || value === undefined || value === '--') return 'gray';
const numValue = parseFloat(value);
if (numValue > thresholds.high) return 'red';
if (numValue > thresholds.warning) return 'yellow';
return 'green';
};
const latest = getLatestValues();
const tempStatus = getStatusColor(latest.temp, { warning: 37.5, high: 38 });
const pulseStatus = getStatusColor(latest.pulse, { warning: 90, high: 100 });
const respStatus = getStatusColor(latest.resp, { warning: 18, high: 20 });
return (
<div className="container mx-auto px-4 py-8 max-w-6xl">
{/* Header Section */}
<header className="text-center mb-8">
<h1 className="text-4xl md:text-5xl font-bold text-blue-800 mb-2">
Virus Fever Detection Using IoT
</h1>
<p className="text-gray-600 text-lg">
By Dhanashree (220301014), Harinee (220301027), Hema Rekha (220301030)
</p>
</header>
{/* Current Readings Section */}
<section className="mb-8 bg-white p-6 rounded-lg shadow-md">
<h2 className="text-2xl font-bold text-blue-700 mb-4">Current Health Readings</h2>
<div className="grid grid-cols-1 md:grid-cols-3 gap-4 mb-6">
<div className={`bg-${tempStatus}-100 border-${tempStatus}-500 border-l-4 p-4 rounded-lg`}>
<div className="flex justify-between items-center">
<h3 className="font-semibold text-gray-800">Temperature</h3>
{tempStatus === 'red' && <span className="bg-red-500 text-white text-xs px-2 py-1 rounded-full">ALERT</span>}
</div>
<p className="text-3xl font-bold mt-2">{latest.temp} <span className="text-xl">Β°C</span></p>
<p className="text-sm text-gray-600 mt-1">Last updated: {latest.time}</p>
</div>
<div className={`bg-${pulseStatus}-100 border-${pulseStatus}-500 border-l-4 p-4 rounded-lg`}>
<div className="flex justify-between items-center">
<h3 className="font-semibold text-gray-800">Pulse Rate</h3>
{pulseStatus === 'red' && <span className="bg-red-500 text-white text-xs px-2 py-1 rounded-full">ALERT</span>}
</div>
<p className="text-3xl font-bold mt-2">{latest.pulse} <span className="text-xl">bpm</span></p>
<p className="text-sm text-gray-600 mt-1">Last updated: {latest.time}</p>
</div>
<div className={`bg-${respStatus}-100 border-${respStatus}-500 border-l-4 p-4 rounded-lg`}>
<div className="flex justify-between items-center">
<h3 className="font-semibold text-gray-800">Respiration Rate</h3>
{respStatus === 'red' && <span className="bg-red-500 text-white text-xs px-2 py-1 rounded-full">ALERT</span>}
</div>
<p className="text-3xl font-bold mt-2">{latest.resp} <span className="text-xl">rpm</span></p>
<p className="text-sm text-gray-600 mt-1">Last updated: {latest.time}</p>
</div>
</div>
<div className="flex flex-wrap gap-4 mb-4">
<button
onClick={toggleSimulation}
className={`px-4 py-2 rounded-lg font-medium ${isRunning ? 'bg-red-500 hover:bg-red-600' : 'bg-blue-500 hover:bg-blue-600'} text-white transition-colors`}
>
{isRunning ? 'Stop Simulation' : 'Start Simulation'}
</button>
<button
onClick={handleReset}
className="px-4 py-2 rounded-lg font-medium bg-gray-500 hover:bg-gray-600 text-white transition-colors"
>
Reset Graphs
</button>
<div className="flex items-center ml-auto text-sm text-gray-600">
<span className="mr-2">Simulation Time:</span>
<span className="font-medium">{currentTime}s</span>
</div>
</div>
</section>
{/* Graph Visualization Section */}
<section className="mb-8 bg-white p-6 rounded-lg shadow-md">
<h2 className="text-2xl font-bold text-blue-700 mb-4">Real-time Health Monitoring</h2>
{/* Combined Graph Controls */}
<div className="mb-6 bg-gray-50 p-4 rounded-lg">
<h3 className="font-semibold text-lg mb-2">Graph Controls</h3>
<div className="flex flex-wrap gap-4">
<label className="inline-flex items-center">
<input
type="checkbox"
checked={showTemperature}
onChange={() => setShowTemperature(!showTemperature)}
className="form-checkbox h-5 w-5 text-red-500"
/>
<span className="ml-2 text-gray-700">Temperature</span>
</label>
<label className="inline-flex items-center">
<input
type="checkbox"
checked={showPulse}
onChange={() => setShowPulse(!showPulse)}
className="form-checkbox h-5 w-5 text-blue-500"
/>
<span className="ml-2 text-gray-700">Pulse Rate</span>
</label>
<label className="inline-flex items-center">
<input
type="checkbox"
checked={showRespiration}
onChange={() => setShowRespiration(!showRespiration)}
className="form-checkbox h-5 w-5 text-green-500"
/>
<span className="ml-2 text-gray-700">Respiration Rate</span>
</label>
</div>
</div>
{/* Combined Graph */}
<div className="mb-8">
<h3 className="font-semibold text-lg mb-2">Combined Metrics</h3>
<div className="chart-container">
<canvas id="combinedChart" aria-label="Combined health metrics graph"></canvas>
{(latest.temp > 38 || latest.pulse > 100 || latest.resp > 20) && (
<div className="alert-badge">!</div>
)}
</div>
</div>
{/* Individual Graphs */}
<h3 className="font-semibold text-lg mb-4">Individual Metrics</h3>
<div className="grid chart-grid gap-6 md:grid-cols-2 lg:grid-cols-3">
<div className="chart-wrapper">
<div className="chart-container">
<canvas id="temperatureChart" aria-label="Temperature graph"></canvas>
{latest.temp > 38 && (
<div className="alert-badge">!</div>
)}
</div>
</div>
<div className="chart-wrapper">
<div className="chart-container">
<canvas id="pulseChart" aria-label="Pulse rate graph"></canvas>
{latest.pulse > 100 && (
<div className="alert-badge">!</div>
)}
</div>
</div>
<div className="chart-wrapper">
<div className="chart-container">
<canvas id="respirationChart" aria-label="Respiration rate graph"></canvas>
{latest.resp > 20 && (
<div className="alert-badge">!</div>
)}
</div>
</div>
</div>
</section>
{/* Data Table for Accessibility */}
<section className="mb-8 bg-white p-6 rounded-lg shadow-md">
<h2 className="text-2xl font-bold text-blue-700 mb-4">Recent Data Points</h2>
<div className="overflow-x-auto">
<table className="min-w-full bg-white">
<thead>
<tr className="bg-gray-100">
<th className="py-2 px-4 border">Time (s)</th>
<th className="py-2 px-4 border">Temperature (Β°C)</th>
<th className="py-2 px-4 border">Pulse Rate (bpm)</th>
<th className="py-2 px-4 border">Respiration Rate (rpm)</th>
</tr>
</thead>
<tbody>
{temperatureData.slice(-5).map((data, index) => (
<tr key={index} className="border-t">
<td className="py-2 px-4 border">{data.x}</td>
<td className="py-2 px-4 border">{data.y?.toFixed(1) || '--'}</td>
<td className="py-2 px-4 border">{pulseData[index + temperatureData.length - 5]?.y?.toFixed(0) || '--'}</td>
<td className="py-2 px-4 border">{respirationData[index + temperatureData.length - 5]?.y?.toFixed(0) || '--'}</td>
</tr>
))}
</tbody>
</table>
</div>
</section>
{/* System Description Sections */}
<section className="mb-8 bg-white p-6 rounded-lg shadow-md">
<h2 className="text-2xl font-bold text-blue-700 mb-4">System Overview</h2>
<div className="grid md:grid-cols-2 gap-8">
{/* System Architecture */}
<div>
<h3 className="text-xl font-semibold text-blue-600 mb-3">System Architecture</h3>
<div className="bg-gray-50 p-4 rounded-lg">
<div className="flex flex-col items-center space-y-2">
<div className="bg-blue-100 p-3 rounded-lg w-full text-center font-medium">Sensors</div>
<div className="text-2xl text-gray-500">↓</div>
<div className="bg-purple-100 p-3 rounded-lg w-full text-center font-medium">Microcontroller</div>
<div className="text-2xl text-gray-500">↓</div>
<div className="bg-green-100 p-3 rounded-lg w-full text-center font-medium">Wi-Fi Module</div>
<div className="text-2xl text-gray-500">↓</div>
<div className="bg-yellow-100 p-3 rounded-lg w-full text-center font-medium">Cloud & Mobile App</div>
</div>
</div>
</div>
{/* Hardware Components */}
<div>
<h3 className="text-xl font-semibold text-blue-600 mb-3">Hardware Components</h3>
<ul className="space-y-2">
<li className="flex items-start">
<span className="bg-blue-100 text-blue-800 rounded-full p-1 mr-2">πŸ”˜</span>
<span><strong>Temperature Sensor:</strong> LM35/DS18B20 (Β±0.5Β°C accuracy)</span>
</li>
<li className="flex items-start">
<span className="bg-blue-100 text-blue-800 rounded-full p-1 mr-2">πŸ”˜</span>
<span><strong>Pulse Sensor:</strong> Photoplethysmography (PPG) based</span>
</li>
<li className="flex items-start">
<span className="bg-blue-100 text-blue-800 rounded-full p-1 mr-2">πŸ”˜</span>
<span><strong>Respiration Sensor:</strong> Chest movement detection</span>
</li>
<li className="flex items-start">
<span className="bg-blue-100 text-blue-800 rounded-full p-1 mr-2">πŸ”˜</span>
<span><strong>Microcontroller:</strong> NodeMCU (ESP8266)</span>
</li>
<li className="flex items-start">
<span className="bg-blue-100 text-blue-800 rounded-full p-1 mr-2">πŸ”˜</span>
<span><strong>Power Supply:</strong> 5V USB or battery</span>
</li>
</ul>
</div>
</div>
</section>
{/* Advantages Section */}
<section className="mb-8 bg-white p-6 rounded-lg shadow-md">
<h2 className="text-2xl font-bold text-blue-700 mb-4">Advantages</h2>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
{[
"Contactless monitoring reduces infection risk",
"Real-time health data visualization",
"Early fever detection alerts",
"Cost-effective IoT solution",
"Cloud connectivity for remote access",
"User-friendly dashboard interface",
"Scalable for multiple locations",
"Continuous health monitoring",
"Reduces healthcare worker exposure"
].map((advantage, index) => (
<div key={index} className="bg-green-50 p-4 rounded-lg border border-green-200 flex items-start">
<span className="text-green-600 mr-2">βœ“</span>
<span>{advantage}</span>
</div>
))}
</div>
</section>
{/* Conclusion Section */}
<section className="bg-white p-6 rounded-lg shadow-md">
<h2 className="text-2xl font-bold text-blue-700 mb-4">Conclusion</h2>
<p className="text-gray-700 mb-4">
The IoT-based Virus Fever Detection system provides an innovative, contactless solution for
early fever detection in public spaces, healthcare facilities, and homes. By integrating
multiple health parameters with real-time cloud monitoring, the system enables timely
interventions while minimizing infection risks.
</p>
<p className="text-gray-700">
This project demonstrates the potential of IoT in transforming healthcare monitoring,
offering a scalable and cost-effective approach to pandemic response and general health
surveillance. Future enhancements could include AI-based predictive analytics and integration
with hospital EHR systems for comprehensive patient care.
</p>
</section>
</div>
);
}
ReactDOM.render(<App />, document.getElementById('root'));
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Soundaryasos/hema" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>