Spaces:
Sleeping
Sleeping
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Type 1 Diabetes Dashboard</title> | |
<style> | |
body { | |
font-family: sans-serif; | |
margin: 20px; | |
} | |
.tab { | |
overflow: hidden; | |
border: 1px solid #ccc; | |
background-color: #f1f1f1; | |
} | |
.tab button { | |
background-color: inherit; | |
float: left; | |
border: none; | |
outline: none; | |
cursor: pointer; | |
padding: 14px 16px; | |
transition: 0.3s; | |
font-size: 17px; | |
} | |
.tab button:hover { | |
background-color: #ddd; | |
} | |
.tab button.active { | |
background-color: #ccc; | |
} | |
.tabcontent { | |
display: none; | |
padding: 6px 12px; | |
border: 1px solid #ccc; | |
border-top: none; | |
} | |
label { | |
display: block; | |
margin-bottom: 5px; | |
} | |
input[type="number"], input[type="range"], select, textarea { | |
width: 100%; | |
padding: 8px; | |
margin-bottom: 10px; | |
border: 1px solid #ccc; | |
border-radius: 4px; | |
box-sizing: border-box; | |
} | |
button { | |
background-color: #4CAF50; | |
color: white; | |
padding: 10px 15px; | |
border: none; | |
border-radius: 4px; | |
cursor: pointer; | |
} | |
button:hover { | |
background-color: #3e8e41; | |
} | |
#glucosePlot { | |
width: 100%; | |
height: 400px; /* Adjust as needed */ | |
border: 1px solid #ccc; | |
} | |
.error-message { | |
color: red; | |
} | |
</style> | |
</head> | |
<body> | |
<h1>Type 1 Diabetes Management Dashboard</h1> | |
<div class="tab"> | |
<button class="tablinks" onclick="openTab(event, 'GlucoseMeal')" id="defaultOpen">Glucose & Meal</button> | |
<button class="tablinks" onclick="openTab(event, 'Insulin')">Insulin</button> | |
<button class="tablinks" onclick="openTab(event, 'BasalSettings')">Basal Settings</button> | |
<button class="tablinks" onclick="openTab(event, 'OtherFactors')">Other Factors</button> | |
</div> | |
<div id="GlucoseMeal" class="tabcontent"> | |
<h3>Glucose & Meal</h3> | |
<label for="initialGlucose">Current Blood Glucose (mg/dL):</label> | |
<input type="number" id="initialGlucose" name="initialGlucose" value="120"> | |
<label for="foodImage">Food Image:</label> | |
<input type="file" id="foodImage" name="foodImage" accept="image/*"> | |
<label for="portionSize">Portion Size Multiplier:</label> | |
<input type="range" id="portionSize" name="portionSize" min="0.1" max="3" step="0.1" value="1.0"> | |
<span id="portionSizeValue">1.0</span> | |
</div> | |
<div id="Insulin" class="tabcontent"> | |
<h3>Insulin</h3> | |
<label for="insulinType">Insulin Type:</label> | |
<select id="insulinType" name="insulinType"> | |
<option value="Rapid-Acting">Rapid-Acting</option> | |
<option value="Long-Acting">Long-Acting</option> | |
</select> | |
<label for="overrideCorrectionDose">Override Correction Dose (Units):</label> | |
<input type="number" id="overrideCorrectionDose" name="overrideCorrectionDose"> | |
<label for="extendedBolusDuration">Extended Bolus Duration (Hours):</label> | |
<input type="number" id="extendedBolusDuration" name="extendedBolusDuration" value="0"> | |
</div> | |
<div id="BasalSettings" class="tabcontent"> | |
<h3>Basal Settings</h3> | |
<label for="basalRates">Basal Rates (JSON):</label> | |
<textarea id="basalRates" name="basalRates" rows="4">{"00:00-06:00": 0.8, "06:00-12:00": 1.0, "12:00-18:00": 0.9, "18:00-24:00": 0.7}</textarea> | |
</div> | |
<div id="OtherFactors" class="tabcontent"> | |
<h3>Other Factors</h3> | |
<label for="weight">Weight (kg):</label> | |
<input type="number" id="weight" name="weight" value="70"> | |
<label for="tdd">Total Daily Dose (TDD) of insulin (units):</label> | |
<input type="number" id="tdd" name="tdd" value="40"> | |
<label for="targetGlucose">Target Blood Glucose (mg/dL):</label> | |
<input type="number" id="targetGlucose" name="targetGlucose" value="100"> | |
<label for="stressLevel">Stress Level (1-10):</label> | |
<input type="range" id="stressLevel" name="stressLevel" min="1" max="10" step="1" value="1"> | |
<span id="stressLevelValue">1</span> | |
<label for="sleepHours">Sleep Hours:</label> | |
<input type="number" id="sleepHours" name="sleepHours" value="7"> | |
<label for="exerciseDuration">Exercise Duration (minutes):</label> | |
<input type="number" id="exerciseDuration" name="exerciseDuration" value="0"> | |
<label for="exerciseIntensity">Exercise Intensity (1-10):</label> | |
<input type="range" id="exerciseIntensity" name="exerciseIntensity" min="1" max="10" step="1" value="1"> | |
<span id="exerciseIntensityValue">1</span> | |
</div> | |
<label for="timeHours">Prediction Time (hours):</label> | |
<input type="range" id="timeHours" name="timeHours" min="1" max="24" step="1" value="6"> | |
<span id="timeHoursValue">6</span> | |
<button onclick="calculate()">Calculate</button> | |
<h2>Results</h2> | |
<div id="error" class="error-message"></div> | |
<label for="carbDetailsOutput">Carbohydrate Details:</label> | |
<textarea id="carbDetailsOutput" rows="5" readonly></textarea> | |
<label for="insulinDetailsOutput">Insulin Calculation Details:</label> | |
<textarea id="insulinDetailsOutput" rows="5" readonly></textarea> | |
<label for="basalDoseOutput">Basal Insulin Dose (units/day):</label> | |
<input type="number" id="basalDoseOutput" readonly> | |
<label for="bolusDoseOutput">Bolus Insulin Dose (units):</label> | |
<input type="number" id="bolusDoseOutput" readonly> | |
<label for="glucosePlot">Glucose Prediction:</label> | |
<div id="glucosePlot"></div> | |
<script> | |
// Tab functionality | |
function openTab(evt, tabName) { | |
var i, tabcontent, tablinks; | |
tabcontent = document.getElementsByClassName("tabcontent"); | |
for (i = 0; i < tabcontent.length; i++) { | |
tabcontent[i].style.display = "none"; | |
} | |
tablinks = document.getElementsByClassName("tablinks"); | |
for (i = 0; i < tablinks.length; i++) { | |
tablinks[i].className = tablinks[i].className.replace(" active", ""); | |
} | |
document.getElementById(tabName).style.display = "block"; | |
evt.currentTarget.className += " active"; | |
} | |
// Open default tab | |
document.getElementById("defaultOpen").click(); | |
// Range slider value display | |
document.getElementById("portionSize").addEventListener("input", function() { | |
document.getElementById("portionSizeValue").textContent = this.value; | |
}); | |
document.getElementById("stressLevel").addEventListener("input", function() { | |
document.getElementById("stressLevelValue").textContent = this.value; | |
}); | |
document.getElementById("exerciseIntensity").addEventListener("input", function() { | |
document.getElementById("exerciseIntensityValue").textContent = this.value; | |
}); | |
document.getElementById("timeHours").addEventListener("input", function() { | |
document.getElementById("timeHoursValue").textContent = this.value; | |
}); | |
// Main calculation function | |
async function calculate() { | |
const initialGlucose = parseFloat(document.getElementById("initialGlucose").value); | |
const foodImageInput = document.getElementById("foodImage"); | |
const portionSize = parseFloat(document.getElementById("portionSize").value); | |
const insulinType = document.getElementById("insulinType").value; | |
const overrideCorrectionDose = parseFloat(document.getElementById("overrideCorrectionDose").value) || null; | |
const extendedBolusDuration = parseFloat(document.getElementById("extendedBolusDuration").value); | |
const basalRates = document.getElementById("basalRates").value; | |
const weight = parseFloat(document.getElementById("weight").value); | |
const tdd = parseFloat(document.getElementById("tdd").value); | |
const targetGlucose = parseFloat(document.getElementById("targetGlucose").value); | |
const stressLevel = parseInt(document.getElementById("stressLevel").value); | |
const sleepHours = parseFloat(document.getElementById("sleepHours").value); | |
const exerciseDuration = parseFloat(document.getElementById("exerciseDuration").value); | |
const exerciseIntensity = parseInt(document.getElementById("exerciseIntensity").value); | |
const errorDiv = document.getElementById("error"); | |
errorDiv.textContent = ""; | |
let foodImage = null; | |
if (foodImageInput.files && foodImageInput.files[0]) { | |
foodImage = await toBase64(foodImageInput.files[0]); // Convert to base64 | |
} | |
const timeHours = parseInt(document.getElementById("timeHours").value); | |
// Prepare data for the backend | |
const data = { | |
initial_glucose: initialGlucose, | |
food_image: foodImage, | |
stress_level: stressLevel, | |
sleep_hours: sleepHours, | |
time_hours: timeHours, | |
weight: weight, | |
tdd: tdd, | |
target_glucose: targetGlucose, | |
exercise_duration: exerciseDuration, | |
exercise_intensity: exerciseIntensity, | |
portion_size: portionSize, | |
insulin_type: insulinType, | |
override_correction_dose: overrideCorrectionDose, | |
extended_bolus_duration: extendedBolusDuration, | |
basal_rates_input: basalRates | |
}; | |
// Send data to the backend (replace with your actual endpoint) | |
try { | |
const response = await fetch("YOUR_HUGGING_FACE_BACKEND_URL", { // <<<<< REPLACE WITH YOUR HUGGING FACE ENDPOINT | |
method: "POST", | |
headers: { | |
"Content-Type": "application/json", | |
}, | |
body: JSON.stringify(data), | |
}); | |
if (!response.ok) { | |
throw new Error(`HTTP error! Status: ${response.status}`); | |
} | |
const result = await response.json(); | |
// Update the UI with the results | |
document.getElementById("carbDetailsOutput").value = result.carb_details_output; | |
document.getElementById("insulinDetailsOutput").value = result.insulin_details_output; | |
document.getElementById("basalDoseOutput").value = result.basal_dose_output; | |
document.getElementById("bolusDoseOutput").value = result.bolus_dose_output; | |
// Render the plot (assuming the backend returns a base64 encoded image) | |
if (result.glucose_plot_output) { | |
const plotContainer = document.getElementById("glucosePlot"); | |
plotContainer.innerHTML = `<img src="data:image/png;base64,${result.glucose_plot_output}" alt="Glucose Prediction Plot">`; | |
} else { | |
document.getElementById("glucosePlot").textContent = "No plot available."; | |
} | |
} catch (error) { | |
console.error("Error:", error); | |
errorDiv.textContent = "An error occurred during calculation: " + error.message; | |
} | |
} | |
function toBase64(file) { | |
return new Promise((resolve, reject) => { | |
const reader = new FileReader(); | |
reader.readAsDataURL(file); | |
reader.onload = () => resolve(reader.result.split(',')[1]); // Remove the prefix | |
reader.onerror = error => reject(error); | |
}); | |
} | |
</script> | |
</body> | |
</html> |