MIF_E31230266/resources/views/tampilanutama/prediksi.blade.php

496 lines
22 KiB
PHP

@extends('layouts.app')
@push('styles')
<link rel="stylesheet" href="{{ asset('css/prediksi.css') }}">
@endpush
@section('content')
<div class="bg-blob bg-blob-1"></div>
<div class="bg-blob bg-blob-2"></div>
<div class="page-wrap">
<!-- Header -->
<div class="form-header">
<p class="eyebrow">Pemeriksaan Awal</p>
<h2 class="form-main-title">Cek Kondisi Tubuh Anda</h2>
</div>
<!-- Step Progress -->
<div class="step-progress">
<div class="step-dot active" id="step-dot-1">
<div class="dot">1</div>
<span class="dot-label">Data Diri</span>
</div>
<div class="step-line" id="line-1-2"></div>
<div class="step-dot" id="step-dot-2">
<div class="dot">2</div>
<span class="dot-label">Gejala</span>
</div>
<div class="step-line" id="line-2-3"></div>
<div class="step-dot" id="step-dot-3">
<div class="dot">3</div>
<span class="dot-label">Gaya Hidup</span>
</div>
<div class="step-line" id="line-3-4"></div>
<div class="step-dot" id="step-dot-4">
<div class="dot">4</div>
<span class="dot-label">Hasil</span>
</div>
</div>
<!-- Card -->
<div class="form-card">
<form method="POST" action="{{ route('prediksi.proses') }}">
@csrf
<div class="slide-container">
{{-- ─── SLIDE 1: Data Diri ─── --}}
@if(!Auth::check())
<div class="prediction-slide active" id="slide-1">
<div class="slide-title">
<span class="icon">👤</span> Informasi Dasar
</div>
<div class="field-group">
<label for="nama">Nama Lengkap</label>
<input type="text" id="nama" name="nama" placeholder="cth. Budi Santoso" autocomplete="off">
<span class="field-error" id="err-nama">Nama tidak boleh kosong.</span>
</div>
<div class="field-group">
<label>Jenis Kelamin</label>
<div class="radio-group">
<div class="radio-option">
<input type="radio" name="jenis_kelamin" id="jk_l" value="L">
<label for="jk_l"> Laki-laki</label>
</div>
<div class="radio-option">
<input type="radio" name="jenis_kelamin" id="jk_p" value="P">
<label for="jk_p"> Perempuan</label>
</div>
</div>
<span class="field-error" id="err-jk">Pilih jenis kelamin.</span>
</div>
<div class="field-group">
<label for="umur">Umur</label>
<input type="number" id="umur" name="umur" placeholder="cth. 28" min="15" max="120">
<span class="field-error" id="err-umur"></span>
</div>
<div class="form-nav">
<button type="button" class="btn-prev" disabled> Kembali</button>
<button type="button" class="btn-next" onclick="nextSlide(1)">Lanjut </button>
</div>
</div>
@endif
{{-- ─── SLIDE 2: Gejala ─── --}}
<div class="prediction-slide {{ Auth::check() ? 'active' : '' }}" id="slide-2">
<div class="slide-title">
<span class="icon">🩺</span> Gejala yang Dirasakan
</div>
<div class="field-group">
<label>Pilih gejala yang sesuai</label>
<p class="field-hint" style="margin-bottom: 10px;">Pilih <strong>minimal 2 gejala</strong> yang paling sesuai dengan kondisi Anda saat ini.</p>
<div class="symptom-grid">
@php
$gejala = [
'g1' => 'Nyeri Ulu Hati (Perut Bagian Atas)',
'g2' => 'Kembung',
'g3' => 'Dada Terasa Terbakar (Heartburn)',
'g4' => 'BAB Berdarah',
'g5' => 'Nafsu Makan Turun',
'g6' => 'Penurunan Berat Badan Akibat Sering Muntah',
];
@endphp
@foreach($gejala as $id => $label)
<div class="symptom-item">
<input type="checkbox" id="{{ $id }}" name="gejala[]" value="{{ $id }}">
<label for="{{ $id }}">
<span class="check-box"></span>
{{ $label }}
</label>
</div>
@endforeach
</div>
<span class="field-error" id="err-gejala">Minimal pilih 2 gejala agar sistem dapat melakukan prediksi.</span>
</div>
<div class="form-nav">
<button type="button" class="btn-prev" onclick="prevSlide(2)"> Kembali</button>
<button type="button" class="btn-next" onclick="nextSlide(2)">Lanjut </button>
</div>
</div>
{{-- ─── SLIDE 3: Gaya Hidup ─── --}}
<div class="prediction-slide" id="slide-3">
<div class="slide-title">
<span class="icon">🌿</span> Faktor Gaya Hidup
</div>
<small class="slide-hint">Informasi gaya hidup akan membantu sistem memberikan prediksi yang lebih akurat.</small>
<div class="field-group">
<label>Mengalami Stres</label>
<small class="field-hint">Sering merasa cemas, tertekan, atau stres lebih dari 3-4 kali dalam seminggu</small>
<div class="radio-group">
<div class="radio-option">
<input type="radio" name="stres" id="stres_tidak" value="tidak">
<label for="stres_tidak">Tidak</label>
</div>
<div class="radio-option">
<input type="radio" name="stres" id="stres_ya" value="ya">
<label for="stres_ya">Ya</label>
</div>
</div>
<span class="field-error" id="err-stres">Silahkan pilih salah satu.</span>
</div>
<div class="field-group">
<label>Kebiasaan Merokok</label>
<small class="field-hint">Perokok aktif (≥10 batang/hari) atau perokok pasif</small>
<div class="radio-group">
<div class="radio-option">
<input type="radio" name="merokok" id="rokok_tidak" value="tidak">
<label for="rokok_tidak">Tidak</label>
</div>
<div class="radio-option">
<input type="radio" name="merokok" id="rokok_ya" value="ya">
<label for="rokok_ya">Ya</label>
</div>
</div>
<span class="field-error" id="err-merokok">Silahkan pilih salah satu.</span>
</div>
<div class="field-group">
<label>Konsumsi Alkohol</label>
<small class="field-hint">Sering konsumsi lebih dari 3-4 kali dalam seminggu</small>
<div class="radio-group">
<div class="radio-option">
<input type="radio" name="alkohol" id="alkohol_tidak" value="tidak">
<label for="alkohol_tidak">Tidak</label>
</div>
<div class="radio-option">
<input type="radio" name="alkohol" id="alkohol_ya" value="ya">
<label for="alkohol_ya">Ya</label>
</div>
</div>
<span class="field-error" id="err-alkohol">Silahkan pilih salah satu.</span>
</div>
<div class="field-group">
<label>Konsumsi Obat Anti Inflamasi</label>
<small class="field-hint">Rutin mengonsumsi obat anti-inflamasi (seperti paracetamol, ibuprofen, atau asam mefenamat) setiap hari selama ±2 bulan terakhir</small>
<div class="radio-group">
<div class="radio-option">
<input type="radio" name="obat" id="obat_tidak" value="tidak">
<label for="obat_tidak">Tidak</label>
</div>
<div class="radio-option">
<input type="radio" name="obat" id="obat_ya" value="ya">
<label for="obat_ya">Ya</label>
</div>
</div>
<span class="field-error" id="err-obat">Silahkan pilih salah satu.</span>
</div>
<div class="form-nav">
<button type="button" class="btn-prev" onclick="prevSlide(3)"> Kembali</button>
<button type="button" class="btn-next" onclick="nextSlide(3)">Lanjut </button>
</div>
</div>
{{-- ─── SLIDE 4: Hasil ─── --}}
<div class="prediction-slide" id="slide-4">
<div class="slide-title">
<span class="icon">📋</span> Hasil Pemeriksaan
</div>
@if(isset($hasil) && $hasil != "Tidak ada hasil")
<div class="result-box risk">
<div class="result-badge">
⚠️ Risiko Terdeteksi
</div>
<div class="disease-name">{{ $hasil }}</div>
<button type="button" class="btn-apa-itu" onclick="openDiseaseModal('{{ $hasil }}')">
Apa itu {{ $hasil }}?
</button>
@if(!empty($indikasi))
<div class="indikasi-box">
<div class="indikasi-label">Indikasi lain terdeteksi</div>
@foreach($indikasi as $ind)
<div class="indikasi-item">
<div>
<span class="indikasi-name">{{ $ind }}</span>
<div class="indikasi-sub">Disarankan untuk pemeriksaan lebih lanjut.</div>
</div>
<button type="button" class="btn-pelajari inline" onclick="openDiseaseModal('{{ $ind }}')">Pelajari</button>
</div>
@endforeach
</div>
@endif
<div class="result-divider"></div>
<div class="result-tips">
<div class="tips-label">💡 Saran</div>
<p class="tips-text">
@if($hasil == "Gastritis")
Makan secara teratur dan dalam porsi yang cukup, menghindari makanan pedas atau asam, tidak merokok dan tidak mengonsumsi alkohol, serta membatasi penggunaan obat anti inflamasi.
@elseif($hasil == "Gerd")
Hindari makanan yang berpotensi memicu gejala refluks seperti kopi, minuman bersoda, makanan pedas dan asam, serta makanan dengan kandungan lemak tinggi.
Selain itu, hindari merokok dan konsumsi alkohol.
@elseif($hasil == "Dispepsia")
Makan secara teratur, mengontrol stres, serta menghindari makanan pemicu seperti makanan pedas, asam, dan tinggi lemak.
@endif
</p>
</div>
<p class="result-desc">
Segera konsultasikan kondisi Anda ke dokter atau tenaga medis supaya mendapatkan penanganan yang tepat.
</p>
<div class="disclaimer-line"></div>
<div class="result-disclaimer">
<span class="disclaimer-icon">❗️</span>
<p>Prediksi ini dibuat oleh sistem berbasis machine learning dan <strong>tidak menggantikan</strong> diagnosis tenaga medis profesional.</p>
</div>
</div>
@else
<div class="result-placeholder">
<div class="result-icon">🌿</div>
<p>Sistem kami siap menganalisis kondisi Anda berdasarkan data yang telah diisi.</p>
<p style="margin-top:8px; font-size:12px;">
Klik <strong>Analisis</strong> untuk melihat hasil prediksi.
</p>
</div>
@endif
<div class="form-nav">
@if(isset($hasil))
<a href="{{ route('halaman.prediksi') }}" class="btn-prev">Cek Ulang</a>
<a href="{{ route('utama') }}" class="btn-next" style="text-decoration:none;">Selesai </a>
@else
<button type="button" class="btn-prev" onclick="prevSlide(4)"> Kembali</button>
<button type="submit" class="btn-next">Analisis </button>
@endif
</div>
</div>
</div>
</form>
</div>
{{-- Custom Alert Modal --}}
<div class="custom-alert-overlay" id="customAlertOverlay">
<div class="custom-alert-box">
<div class="custom-alert-icon">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none"
stroke="#e6a817" stroke-width="2.2"
stroke-linecap="round" stroke-linejoin="round">
<path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/>
<line x1="12" y1="9" x2="12" y2="13"/>
<line x1="12" y1="17" x2="12.01" y2="17"/>
</svg>
</div>
<p>Gejala yang dipilih masih terlalu umum. Tambahkan gejala lain agar sistem dapat melakukan prediksi yang lebih akurat.</p>
<button class="custom-alert-btn" onclick="closeCustomAlert()">Mengerti</button>
</div>
</div>
</div>
<div class="disease-modal-overlay" id="diseaseModalOverlay" onclick="closeDiseaseModal()">
<div class="disease-modal-box" onclick="event.stopPropagation()">
<button class="disease-modal-close" onclick="closeDiseaseModal()"></button>
<div class="disease-modal-icon">🩺</div>
<h3 class="disease-modal-title" id="diseaseModalTitle"></h3>
<p class="disease-modal-desc" id="diseaseModalDesc"></p>
</div>
</div>
@push('scripts')
<script>
let currentSlide = {{ Auth::check() ? 2 : 1 }};
const totalSlides = 4;
updateProgress();
const slideValidations = {
1: () => {
if ({{ Auth::check() ? 'true' : 'false' }}) return true;
let valid = true;
const nama = document.getElementById('nama');
const umur = document.getElementById('umur');
const jk = document.querySelector('input[name="jenis_kelamin"]:checked');
clearErrors();
if (!nama.value.trim()) { showError('nama', nama); valid = false; }
if (!jk) { showError('jk'); valid = false; }
if (!umur.value || umur.value < 15 || umur.value > 120) {
showError('umur', umur); valid = false;
}
return valid;
},
2: () => {
clearErrors();
const checked = document.querySelectorAll('input[name="gejala[]"]:checked');
if (checked.length < 2) {
showError('gejala');
return false;
}
return true;
},
3: () => {
clearErrors();
const stres = document.querySelector('input[name="stres"]:checked');
const merokok = document.querySelector('input[name="merokok"]:checked');
const alkohol = document.querySelector('input[name="alkohol"]:checked');
const obat = document.querySelector('input[name="obat"]:checked');
let valid = true;
if (!stres) {
showError('stres');
valid = false;
}
if (!merokok) {
showError('merokok');
valid = false;
}
if (!alkohol) {
showError('alkohol');
valid = false;
}
if (!obat) {
showError('obat');
valid = false;
}
return valid;
}
};
function validateSlide(slideNum) {
return slideValidations[slideNum] ? slideValidations[slideNum]() : true;
}
function showError(id, inputEl) {
document.getElementById('err-' + id)?.classList.add('show');
if (inputEl) inputEl.classList.add('error');
}
function clearErrors() {
document.querySelectorAll('.field-error').forEach(el => el.classList.remove('show'));
document.querySelectorAll('input.error, select.error').forEach(el => el.classList.remove('error'));
}
function nextSlide(from) {
if (!validateSlide(from)) return;
goToSlide(from + 1);
}
function prevSlide(from) {
goToSlide(from - 1);
}
function goToSlide(target) {
const current = document.getElementById('slide-' + currentSlide);
const next = document.getElementById('slide-' + target);
if (!next) return;
current.classList.add('exit-left');
setTimeout(() => {
current.classList.remove('active', 'exit-left');
next.classList.add('active');
currentSlide = target;
updateProgress();
}, 200);
}
function updateProgress() {
for (let i = 1; i <= totalSlides; i++) {
const dot = document.getElementById('step-dot-' + i);
dot.classList.remove('active', 'done');
if (i < currentSlide) dot.classList.add('done');
if (i === currentSlide) dot.classList.add('active');
}
document.getElementById('line-1-2').classList.toggle('filled', currentSlide >= 2);
document.getElementById('line-2-3').classList.toggle('filled', currentSlide >= 3);
document.getElementById('line-3-4').classList.toggle('filled', currentSlide >= 4);
}
function showCustomAlert() {
document.getElementById('customAlertOverlay').classList.add('show');
}
function closeCustomAlert() {
document.getElementById('customAlertOverlay').classList.remove('show');
}
document.querySelectorAll('input, select').forEach(el => {
el.addEventListener('input', () => el.classList.remove('error'));
});
document.getElementById('umur')?.addEventListener('input', function () {
const val = parseInt(this.value);
const errEl = document.getElementById('err-umur');
if (this.value && val < 15) {
this.classList.add('error');
errEl.textContent = 'Umur minimal 15 tahun.';
errEl.classList.add('show');
} else if (this.value && val > 120) {
this.classList.add('error');
errEl.textContent = 'Masukkan umur yang valid.';
errEl.classList.add('show');
} else {
this.classList.remove('error');
errEl.classList.remove('show');
}
});
@if(isset($hasil))
document.addEventListener("DOMContentLoaded", function () {
document.querySelectorAll('.prediction-slide').forEach(slide=>{
slide.classList.remove('active');
});
document.getElementById('slide-4').classList.add('active');
currentSlide = 4;
updateProgress();
});
@endif
const diseaseInfo = {
'Dispepsia': 'Dispepsia merupakan gangguan yang kompleks, mengacu pada kumpulan gejala seperti sensasi nyeri atau tak nyaman di perut bagian atas, terbakar, mual muntah, penuh dan kembung yang bersifat berulang.',
'Gerd': 'GERD merupakan suatu gangguan di mana isi lambung mengalami refluks secara berulang ke dalam esofagus, dan menyebabkan terjadinya gejala atau komplikasi yang mengganggu.',
'Gastritis': 'Gastritis adalah peradangan mukosa lambung yang dapat bersifat akut, kronik yang disebabkan rusaknya lapisan mukosa pelindung lambung.'
};
function openDiseaseModal(nama) {
const info = diseaseInfo[nama];
if (!info) return;
document.getElementById('diseaseModalTitle').textContent = nama;
document.getElementById('diseaseModalDesc').textContent = info;
document.getElementById('diseaseModalOverlay').classList.add('show');
}
function closeDiseaseModal() {
document.getElementById('diseaseModalOverlay').classList.remove('show');
}
</script>
@endpush
@endsection