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> |