| | <!DOCTYPE html> |
| | <html lang="en"> |
| | <head> |
| | <meta charset="UTF-8"> |
| | <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| | <title>PrivaMed - Medical Risk Prediction</title> |
| | <style> |
| | * { margin: 0; padding: 0; box-sizing: border-box; } |
| | body { font-family: 'Segoe UI', sans-serif; background: #0f172a; color: #e2e8f0; } |
| | header { background: #1e293b; padding: 20px 40px; border-bottom: 1px solid #334155; display: flex; justify-content: space-between; align-items: center; } |
| | header h1 { color: #38bdf8; font-size: 24px; } |
| | header a { color: #94a3b8; font-size: 14px; text-decoration: none; } |
| | header a:hover { color: #38bdf8; } |
| | .container { max-width: 700px; margin: 40px auto; padding: 0 20px; } |
| | h2 { font-size: 22px; margin-bottom: 8px; } |
| | .subtitle { color: #94a3b8; font-size: 14px; margin-bottom: 30px; } |
| | .diagnosis-select { background: #1e293b; border-radius: 12px; padding: 20px; border: 1px solid #334155; margin-bottom: 20px; } |
| | .diagnosis-select label { display: block; font-size: 13px; color: #94a3b8; margin-bottom: 8px; } |
| | .diagnosis-select select { width: 100%; background: #0f172a; border: 1px solid #334155; border-radius: 8px; padding: 12px 14px; color: #e2e8f0; font-size: 14px; } |
| | .diagnosis-select select:focus { outline: none; border-color: #38bdf8; } |
| | .form-box { background: #1e293b; border-radius: 12px; padding: 30px; border: 1px solid #334155; } |
| | .form-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 20px; } |
| | .field label { display: block; font-size: 13px; color: #94a3b8; margin-bottom: 6px; } |
| | .field input, .field select { width: 100%; background: #0f172a; border: 1px solid #334155; border-radius: 8px; padding: 10px 14px; color: #e2e8f0; font-size: 14px; } |
| | .field input:focus, .field select:focus { outline: none; border-color: #38bdf8; } |
| | .btn { width: 100%; margin-top: 24px; background: #38bdf8; color: #0f172a; border: none; padding: 14px; border-radius: 8px; font-size: 15px; font-weight: bold; cursor: pointer; } |
| | .btn:hover { background: #7dd3fc; } |
| | .result { margin-top: 30px; background: #1e293b; border-radius: 12px; padding: 30px; border: 1px solid #334155; text-align: center; display: none; } |
| | .result .risk { font-size: 36px; font-weight: bold; margin-bottom: 8px; } |
| | .result .risk.high { color: #f87171; } |
| | .result .risk.low { color: #34d399; } |
| | .result .prob { color: #94a3b8; font-size: 15px; } |
| | .result .confidence { font-size: 18px; margin-top: 8px; } |
| | .coming-soon { background: #1e293b; border-radius: 12px; padding: 60px 30px; border: 1px solid #334155; text-align: center; display: none; } |
| | .coming-soon h3 { font-size: 24px; color: #94a3b8; margin-bottom: 12px; } |
| | .coming-soon p { color: #64748b; font-size: 14px; } |
| | </style> |
| | </head> |
| | <body> |
| | <header> |
| | <h1>PrivaMed</h1> |
| | <a href="/dashboard">Back to Dashboard</a> |
| | </header> |
| |
|
| | <div class="container"> |
| | <h2>Medical Risk Prediction</h2> |
| | <p class="subtitle">Select diagnosis type and enter patient data to get an instant prediction.</p> |
| |
|
| | <div class="diagnosis-select"> |
| | <label>Select Diagnosis Type</label> |
| | <select id="diagnosisType" onchange="switchDiagnosis()"> |
| | <option value="diabetes">Diabetes Risk Assessment</option> |
| | <option value="heart">Heart Disease Risk Assessment</option> |
| | <option value="cancer">Cancer Screening (Coming Soon)</option> |
| | </select> |
| | </div> |
| |
|
| | <div class="form-box" id="diabetesForm"> |
| | <div class="form-grid"> |
| | <div class="field"> |
| | <label>Pregnancies</label> |
| | <input type="number" id="pregnancies" placeholder="e.g. 2" min="0"> |
| | </div> |
| | <div class="field"> |
| | <label>Glucose (mg/dL)</label> |
| | <input type="number" id="glucose" placeholder="e.g. 120" min="0"> |
| | </div> |
| | <div class="field"> |
| | <label>Blood Pressure (mmHg)</label> |
| | <input type="number" id="blood_pressure" placeholder="e.g. 70" min="0"> |
| | </div> |
| | <div class="field"> |
| | <label>Skin Thickness (mm)</label> |
| | <input type="number" id="skin_thickness" placeholder="e.g. 20" min="0"> |
| | </div> |
| | <div class="field"> |
| | <label>Insulin (μU/mL)</label> |
| | <input type="number" id="insulin" placeholder="e.g. 80" min="0"> |
| | </div> |
| | <div class="field"> |
| | <label>BMI</label> |
| | <input type="number" id="bmi" placeholder="e.g. 28.5" step="0.1" min="0"> |
| | </div> |
| | <div class="field"> |
| | <label>Diabetes Pedigree</label> |
| | <input type="number" id="diabetes_pedigree" placeholder="e.g. 0.5" step="0.01" min="0"> |
| | </div> |
| | <div class="field"> |
| | <label>Age</label> |
| | <input type="number" id="d_age" placeholder="e.g. 35" min="0"> |
| | </div> |
| | </div> |
| | <button class="btn" onclick="predict()">Predict Risk</button> |
| | </div> |
| |
|
| | <div class="form-box" id="heartForm" style="display:none;"> |
| | <div class="form-grid"> |
| | <div class="field"> |
| | <label>Age</label> |
| | <input type="number" id="h_age" placeholder="e.g. 55" min="0"> |
| | </div> |
| | <div class="field"> |
| | <label>Sex</label> |
| | <select id="sex"> |
| | <option value="1">Male</option> |
| | <option value="0">Female</option> |
| | </select> |
| | </div> |
| | <div class="field"> |
| | <label>Chest Pain Type (0-3)</label> |
| | <input type="number" id="cp" placeholder="0-3" min="0" max="3"> |
| | </div> |
| | <div class="field"> |
| | <label>Resting BP (mmHg)</label> |
| | <input type="number" id="trestbps" placeholder="e.g. 130" min="0"> |
| | </div> |
| | <div class="field"> |
| | <label>Cholesterol (mg/dL)</label> |
| | <input type="number" id="chol" placeholder="e.g. 250" min="0"> |
| | </div> |
| | <div class="field"> |
| | <label>Fasting Blood Sugar > 120</label> |
| | <select id="fbs"> |
| | <option value="0">No</option> |
| | <option value="1">Yes</option> |
| | </select> |
| | </div> |
| | <div class="field"> |
| | <label>Resting ECG (0-2)</label> |
| | <input type="number" id="restecg" placeholder="0-2" min="0" max="2"> |
| | </div> |
| | <div class="field"> |
| | <label>Max Heart Rate</label> |
| | <input type="number" id="thalach" placeholder="e.g. 150" min="0"> |
| | </div> |
| | <div class="field"> |
| | <label>Exercise Induced Angina</label> |
| | <select id="exang"> |
| | <option value="0">No</option> |
| | <option value="1">Yes</option> |
| | </select> |
| | </div> |
| | <div class="field"> |
| | <label>ST Depression</label> |
| | <input type="number" id="oldpeak" placeholder="e.g. 2.3" step="0.1" min="0"> |
| | </div> |
| | <div class="field"> |
| | <label>Slope (0-2)</label> |
| | <input type="number" id="slope" placeholder="0-2" min="0" max="2"> |
| | </div> |
| | <div class="field"> |
| | <label>Major Vessels (0-3)</label> |
| | <input type="number" id="ca" placeholder="0-3" min="0" max="3"> |
| | </div> |
| | <div class="field"> |
| | <label>Thalassemia (0-3)</label> |
| | <input type="number" id="thal" placeholder="0-3" min="0" max="3"> |
| | </div> |
| | </div> |
| | <button class="btn" onclick="predict()">Predict Risk</button> |
| | </div> |
| |
|
| | <div class="coming-soon" id="comingSoon"> |
| | <h3>Coming Soon</h3> |
| | <p>This diagnosis type will be available in future updates as we train more federated models.</p> |
| | </div> |
| |
|
| | <div class="result" id="result"> |
| | <div class="risk" id="riskLabel"></div> |
| | <div class="confidence" id="confidenceLabel"></div> |
| | <div class="prob" id="probLabel"></div> |
| | </div> |
| | </div> |
| |
|
| | <script> |
| | function switchDiagnosis() { |
| | const type = document.getElementById("diagnosisType").value; |
| | const diabetesForm = document.getElementById("diabetesForm"); |
| | const heartForm = document.getElementById("heartForm"); |
| | const comingSoon = document.getElementById("comingSoon"); |
| | const result = document.getElementById("result"); |
| | |
| | result.style.display = "none"; |
| | |
| | if (type === "diabetes") { |
| | diabetesForm.style.display = "block"; |
| | heartForm.style.display = "none"; |
| | comingSoon.style.display = "none"; |
| | } else if (type === "heart") { |
| | diabetesForm.style.display = "none"; |
| | heartForm.style.display = "block"; |
| | comingSoon.style.display = "none"; |
| | } else { |
| | diabetesForm.style.display = "none"; |
| | heartForm.style.display = "none"; |
| | comingSoon.style.display = "block"; |
| | } |
| | } |
| | |
| | function predict() { |
| | const diagnosisType = document.getElementById("diagnosisType").value; |
| | const data = new FormData(); |
| | data.append("diagnosis_type", diagnosisType); |
| | |
| | if (diagnosisType === "diabetes") { |
| | data.append("pregnancies", document.getElementById("pregnancies").value || 0); |
| | data.append("glucose", document.getElementById("glucose").value || 0); |
| | data.append("blood_pressure", document.getElementById("blood_pressure").value || 0); |
| | data.append("skin_thickness", document.getElementById("skin_thickness").value || 0); |
| | data.append("insulin", document.getElementById("insulin").value || 0); |
| | data.append("bmi", document.getElementById("bmi").value || 0); |
| | data.append("diabetes_pedigree", document.getElementById("diabetes_pedigree").value || 0); |
| | data.append("age", document.getElementById("d_age").value || 0); |
| | } else if (diagnosisType === "heart") { |
| | data.append("age", document.getElementById("h_age").value || 0); |
| | data.append("sex", document.getElementById("sex").value || 0); |
| | data.append("cp", document.getElementById("cp").value || 0); |
| | data.append("trestbps", document.getElementById("trestbps").value || 0); |
| | data.append("chol", document.getElementById("chol").value || 0); |
| | data.append("fbs", document.getElementById("fbs").value || 0); |
| | data.append("restecg", document.getElementById("restecg").value || 0); |
| | data.append("thalach", document.getElementById("thalach").value || 0); |
| | data.append("exang", document.getElementById("exang").value || 0); |
| | data.append("oldpeak", document.getElementById("oldpeak").value || 0); |
| | data.append("slope", document.getElementById("slope").value || 0); |
| | data.append("ca", document.getElementById("ca").value || 0); |
| | data.append("thal", document.getElementById("thal").value || 0); |
| | } |
| | |
| | fetch("/predict_result", { method: "POST", body: data }) |
| | .then(r => r.json()) |
| | .then(res => { |
| | const result = document.getElementById("result"); |
| | const riskLabel = document.getElementById("riskLabel"); |
| | const confidenceLabel = document.getElementById("confidenceLabel"); |
| | const probLabel = document.getElementById("probLabel"); |
| | |
| | riskLabel.textContent = res.risk; |
| | riskLabel.className = "risk " + (res.risk === "High Risk" ? "high" : "low"); |
| | confidenceLabel.textContent = "Confidence: " + res.confidence + "%"; |
| | probLabel.textContent = res.disease + " Probability: " + res.probability + "%"; |
| | result.style.display = "block"; |
| | }); |
| | } |
| | </script> |
| | </body> |
| | </html> |