870 lines
54 KiB
PHP
870 lines
54 KiB
PHP
<!DOCTYPE html>
|
|
<html lang="id">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<meta name="csrf-token" content="{{ csrf_token() }}">
|
|
<title>SiPakarTebu — Diagnosa Penyakit Tanaman Tebu</title>
|
|
<link href="https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400;0,700;1,400&family=DM+Sans:wght@300;400;500&display=swap" rel="stylesheet">
|
|
<style>
|
|
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
|
|
|
:root {
|
|
--green-deep: #1a3a2a;
|
|
--green-mid: #2d6a4f;
|
|
--green-bright: #40916c;
|
|
--green-light: #74c69d;
|
|
--green-pale: #b7e4c7;
|
|
--cream: #f8f4ee;
|
|
--cream-dark: #ede8df;
|
|
--brown: #8b5e3c;
|
|
--text-dark: #1a2e22;
|
|
--text-muted: #5a7a67;
|
|
}
|
|
|
|
html { scroll-behavior: smooth; }
|
|
body { font-family: 'DM Sans', sans-serif; background: var(--cream); color: var(--text-dark); overflow-x: hidden; }
|
|
|
|
nav {
|
|
position: fixed; top: 0; left: 0; right: 0; z-index: 100;
|
|
display: flex; align-items: center; justify-content: space-between;
|
|
padding: 1.25rem 3rem;
|
|
background: rgba(248, 244, 238, 0.92);
|
|
backdrop-filter: blur(14px);
|
|
border-bottom: 1px solid rgba(64,145,108,0.12);
|
|
gap: 1rem;
|
|
}
|
|
.nav-logo { display: flex; align-items: center; gap: .6rem; font-family: 'Playfair Display', serif; font-size: 1.4rem; font-weight: 700; color: var(--green-deep); text-decoration: none; flex-shrink: 0; }
|
|
.nav-links { display: flex; gap: .75rem; align-items: center; flex-shrink: 0; }
|
|
.btn-outline { padding: .5rem 1.4rem; border-radius: 50px; border: 1.5px solid var(--green-mid); color: var(--green-mid); background: transparent; font-family: 'DM Sans', sans-serif; font-size: .875rem; font-weight: 500; cursor: pointer; text-decoration: none; transition: all .25s ease; white-space: nowrap; }
|
|
.btn-outline:hover { background: var(--green-mid); color: white; }
|
|
.btn-solid { padding: .5rem 1.4rem; border-radius: 50px; background: var(--green-deep); color: white; font-family: 'DM Sans', sans-serif; font-size: .875rem; font-weight: 500; cursor: pointer; text-decoration: none; border: none; transition: all .25s ease; box-shadow: 0 4px 14px rgba(26,58,42,.25); white-space: nowrap; }
|
|
.btn-solid:hover { background: var(--green-mid); transform: translateY(-1px); box-shadow: 0 6px 20px rgba(26,58,42,.3); }
|
|
|
|
.hero { min-height: 100vh; display: grid; grid-template-columns: 1fr 1fr; align-items: center; padding: 7rem 3rem 4rem; position: relative; overflow: hidden; }
|
|
.hero::before { content: ''; position: absolute; top: -10%; right: -5%; width: 55%; height: 80%; background: radial-gradient(ellipse at 60% 40%, #b7e4c7 0%, #74c69d33 50%, transparent 75%); border-radius: 60% 40% 70% 30% / 50% 60% 40% 50%; animation: morph 12s ease-in-out infinite; z-index: 0; }
|
|
.hero::after { content: ''; position: absolute; bottom: -10%; left: 10%; width: 40%; height: 50%; background: radial-gradient(ellipse, #d8f3dc44 0%, transparent 70%); border-radius: 40% 60% 30% 70% / 60% 40% 70% 30%; animation: morph 16s ease-in-out infinite reverse; z-index: 0; }
|
|
@keyframes morph { 0%, 100% { border-radius: 60% 40% 70% 30% / 50% 60% 40% 50%; } 33% { border-radius: 40% 60% 30% 70% / 60% 40% 70% 30%; } 66% { border-radius: 70% 30% 50% 50% / 30% 70% 40% 60%; } }
|
|
|
|
.hero-content { position: relative; z-index: 1; padding-right: 2rem; }
|
|
.hero-badge { display: inline-flex; align-items: center; gap: .5rem; background: var(--green-pale); color: var(--green-deep); padding: .35rem 1rem; border-radius: 50px; font-size: .8rem; font-weight: 500; letter-spacing: .04em; margin-bottom: 1.5rem; animation: fadeUp .6s ease both; }
|
|
.hero-badge::before { content: '🌿'; font-size: .9rem; }
|
|
h1 { font-family: 'Playfair Display', serif; font-size: clamp(2.6rem, 4.5vw, 3.8rem); line-height: 1.1; color: var(--green-deep); margin-bottom: 1.25rem; animation: fadeUp .6s .1s ease both; }
|
|
h1 em { color: var(--green-bright); font-style: italic; }
|
|
.hero-desc { font-size: 1.05rem; line-height: 1.7; color: var(--text-muted); max-width: 460px; margin-bottom: 2.25rem; animation: fadeUp .6s .2s ease both; }
|
|
.hero-cta { display: flex; gap: 1rem; flex-wrap: wrap; animation: fadeUp .6s .3s ease both; }
|
|
.btn-hero { display: inline-flex; align-items: center; gap: .5rem; padding: .85rem 2rem; border-radius: 50px; font-family: 'DM Sans', sans-serif; font-size: .95rem; font-weight: 500; text-decoration: none; cursor: pointer; transition: all .3s ease; border: none; }
|
|
.btn-hero-primary { background: var(--green-deep); color: white; box-shadow: 0 6px 24px rgba(26,58,42,.3); }
|
|
.btn-hero-primary:hover { background: var(--green-mid); transform: translateY(-2px); }
|
|
.btn-hero-secondary { background: white; color: var(--green-deep); border: 1.5px solid var(--green-pale) !important; }
|
|
.btn-hero-secondary:hover { border-color: var(--green-bright) !important; background: var(--green-pale); }
|
|
.hero-stats { display: flex; gap: 2rem; margin-top: 3rem; animation: fadeUp .6s .4s ease both; }
|
|
.stat { display: flex; flex-direction: column; }
|
|
.stat-num { font-family: 'Playfair Display', serif; font-size: 1.8rem; color: var(--green-deep); font-weight: 700; }
|
|
.stat-label { font-size: .78rem; color: var(--text-muted); text-transform: uppercase; letter-spacing: .06em; }
|
|
.hero-visual { position: relative; z-index: 1; display: flex; justify-content: center; align-items: center; animation: fadeUp .6s .2s ease both; }
|
|
.plant-card { background: white; border-radius: 28px; padding: 2.5rem 2rem; box-shadow: 0 20px 60px rgba(26,58,42,.15), 0 4px 16px rgba(26,58,42,.08); width: 340px; position: relative; }
|
|
.plant-card::before { content: ''; position: absolute; top: -2px; left: -2px; right: -2px; bottom: -2px; background: linear-gradient(135deg, var(--green-light), var(--green-pale), var(--cream)); border-radius: 30px; z-index: -1; }
|
|
.plant-illustration { width: 100%; height: 200px; background: linear-gradient(160deg, #d8f3dc 0%, #b7e4c7 50%, #95d5b2 100%); border-radius: 18px; display: flex; align-items: center; justify-content: center; margin-bottom: 1.5rem; position: relative; overflow: hidden; }
|
|
.plant-illustration svg { width: 120px; height: 120px; }
|
|
.plant-illustration::before { content: ''; position: absolute; bottom: -20px; right: -20px; width: 100px; height: 100px; background: rgba(64,145,108,.2); border-radius: 50%; }
|
|
.plant-illustration::after { content: ''; position: absolute; top: -15px; left: -15px; width: 70px; height: 70px; background: rgba(116,198,157,.25); border-radius: 50%; }
|
|
.card-tag { display: inline-flex; align-items: center; gap: .4rem; background: #fff3cd; color: #8b5e3c; padding: .3rem .8rem; border-radius: 50px; font-size: .75rem; font-weight: 500; margin-bottom: .75rem; }
|
|
.card-title { font-family: 'Playfair Display', serif; font-size: 1.1rem; color: var(--green-deep); margin-bottom: .4rem; }
|
|
.card-subtitle { font-size: .85rem; color: var(--text-muted); margin-bottom: 1.25rem; }
|
|
.progress-wrap { margin-bottom: .5rem; }
|
|
.progress-label { display: flex; justify-content: space-between; font-size: .78rem; color: var(--text-muted); margin-bottom: .4rem; }
|
|
.progress-bar { height: 6px; background: var(--cream-dark); border-radius: 99px; overflow: hidden; }
|
|
.progress-fill { height: 100%; background: linear-gradient(90deg, var(--green-mid), var(--green-light)); border-radius: 99px; animation: grow 1.2s .8s ease both; }
|
|
@keyframes grow { from { width: 0 !important; } }
|
|
.floating-badge { position: absolute; top: -14px; right: 24px; background: var(--green-deep); color: white; padding: .35rem .85rem; border-radius: 50px; font-size: .75rem; font-weight: 500; box-shadow: 0 4px 12px rgba(26,58,42,.3); }
|
|
|
|
.features { padding: 6rem 3rem; background: var(--green-deep); position: relative; overflow: hidden; }
|
|
.features::before { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 120px; background: var(--cream); clip-path: ellipse(55% 100% at 50% 0%); }
|
|
.section-label { font-size: .78rem; text-transform: uppercase; letter-spacing: .12em; color: var(--green-light); margin-bottom: .75rem; }
|
|
.section-title { font-family: 'Playfair Display', serif; font-size: clamp(1.8rem, 3vw, 2.6rem); color: white; margin-bottom: 1rem; line-height: 1.2; }
|
|
.section-title em { color: var(--green-light); font-style: italic; }
|
|
.section-desc { color: rgba(255,255,255,.6); font-size: .95rem; line-height: 1.7; max-width: 500px; margin-bottom: 3.5rem; }
|
|
.features-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.5rem; }
|
|
.feature-card { background: rgba(255,255,255,.06); border: 1px solid rgba(255,255,255,.1); border-radius: 20px; padding: 2rem; transition: all .3s ease; position: relative; overflow: hidden; }
|
|
.feature-card::before { content: ''; position: absolute; inset: 0; background: linear-gradient(135deg, rgba(116,198,157,.08) 0%, transparent 100%); opacity: 0; transition: opacity .3s; }
|
|
.feature-card:hover { transform: translateY(-4px); border-color: rgba(116,198,157,.3); }
|
|
.feature-card:hover::before { opacity: 1; }
|
|
.feature-icon { width: 52px; height: 52px; border-radius: 14px; background: linear-gradient(135deg, var(--green-bright), var(--green-light)); display: flex; align-items: center; justify-content: center; font-size: 1.4rem; margin-bottom: 1.25rem; box-shadow: 0 6px 16px rgba(64,145,108,.35); }
|
|
.feature-title { font-family: 'Playfair Display', serif; font-size: 1.1rem; color: white; margin-bottom: .6rem; }
|
|
.feature-text { font-size: .875rem; color: rgba(255,255,255,.55); line-height: 1.65; }
|
|
|
|
.cta-section { padding: 6rem 3rem; text-align: center; background: linear-gradient(160deg, var(--green-deep) 0%, #0d2318 100%); position: relative; overflow: hidden; }
|
|
.cta-section::before { content: ''; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 600px; height: 600px; background: radial-gradient(circle, rgba(64,145,108,.2) 0%, transparent 65%); border-radius: 50%; }
|
|
.cta-label { color: var(--green-light); font-size: .78rem; text-transform: uppercase; letter-spacing: .12em; margin-bottom: .75rem; }
|
|
.cta-title { font-family: 'Playfair Display', serif; font-size: clamp(2rem, 3.5vw, 3rem); color: white; margin-bottom: 1rem; position: relative; }
|
|
.cta-title em { color: var(--green-light); font-style: italic; }
|
|
.cta-desc { color: rgba(255,255,255,.6); max-width: 440px; margin: 0 auto 2.5rem; line-height: 1.7; position: relative; }
|
|
.cta-buttons { display: flex; gap: 1rem; justify-content: center; flex-wrap: wrap; position: relative; }
|
|
|
|
footer { background: #0d2318; padding: 2rem 3rem; text-align: center; color: rgba(255,255,255,.35); font-size: .825rem; border-top: 1px solid rgba(255,255,255,.06); }
|
|
footer span { color: var(--green-light); }
|
|
|
|
@keyframes fadeUp { from { opacity: 0; transform: translateY(24px); } to { opacity: 1; transform: translateY(0); } }
|
|
|
|
/* ═══════════════════════════════════════════════════════
|
|
MODAL DIAGNOSIS GUEST
|
|
═══════════════════════════════════════════════════════ */
|
|
#guestModal {
|
|
display: none;
|
|
position: fixed; inset: 0; z-index: 9000;
|
|
background: rgba(15, 30, 20, 0.72);
|
|
backdrop-filter: blur(6px);
|
|
align-items: center; justify-content: center;
|
|
padding: 1rem;
|
|
}
|
|
#guestModal.open { display: flex; }
|
|
#guestModal.open .gm-box {
|
|
animation: gmSlideUp .35s cubic-bezier(.22,.97,.44,1) both;
|
|
}
|
|
@keyframes gmSlideUp { from { opacity:0; transform:translateY(32px) scale(.97); } to { opacity:1; transform:none; } }
|
|
|
|
.gm-box {
|
|
background: #fff;
|
|
border-radius: 24px;
|
|
width: 100%;
|
|
max-width: 540px;
|
|
max-height: 90vh;
|
|
overflow-y: auto;
|
|
box-shadow: 0 32px 80px rgba(10,25,15,.35);
|
|
position: relative;
|
|
}
|
|
.gm-box::-webkit-scrollbar { width: 4px; }
|
|
.gm-box::-webkit-scrollbar-track { background: transparent; }
|
|
.gm-box::-webkit-scrollbar-thumb { background: #b7ddc4; border-radius: 2px; }
|
|
|
|
.gm-header {
|
|
padding: 1.5rem 1.5rem 1rem;
|
|
border-bottom: 1px solid #ede8df;
|
|
position: sticky; top: 0; background: #fff; z-index: 2;
|
|
border-radius: 24px 24px 0 0;
|
|
}
|
|
.gm-close {
|
|
position: absolute; top: 1rem; right: 1rem;
|
|
width: 32px; height: 32px; border-radius: 50%;
|
|
background: #f0fdf4; border: none; cursor: pointer;
|
|
font-size: 1rem; color: #2d6a4f;
|
|
display: flex; align-items: center; justify-content: center;
|
|
transition: background .2s;
|
|
}
|
|
.gm-close:hover { background: #d8f3dc; }
|
|
|
|
.gm-progress-bar-wrap { height: 5px; background: #ede8df; border-radius: 99px; overflow: hidden; margin-top: .75rem; }
|
|
.gm-progress-fill { height: 100%; background: linear-gradient(90deg,#40916c,#74c69d); border-radius: 99px; transition: width .4s ease; }
|
|
|
|
.gm-body { padding: 1.5rem; }
|
|
|
|
/* Step panels */
|
|
.gm-step { display: none; }
|
|
.gm-step.active { display: block; }
|
|
|
|
/* Gejala list */
|
|
.gm-symptom-list { max-height: 300px; overflow-y: auto; display: flex; flex-direction: column; gap: 6px; margin-top: .75rem; }
|
|
.gm-symptom-list::-webkit-scrollbar { width: 4px; }
|
|
.gm-symptom-list::-webkit-scrollbar-thumb { background: #b7ddc4; border-radius: 2px; }
|
|
|
|
.gm-sym-item {
|
|
display: flex; align-items: center; gap: .75rem;
|
|
padding: .65rem 1rem; border-radius: 12px;
|
|
border: 1.5px solid #ede8df; background: white;
|
|
cursor: pointer; transition: all .18s;
|
|
}
|
|
.gm-sym-item:hover { border-color: #b7ddc4; background: #f8fffe; }
|
|
.gm-sym-item.checked { background: #f0fdf4; border-color: #b7ddc4; }
|
|
.gm-sym-item input[type=checkbox] { accent-color: #2d6a4f; width: 15px; height: 15px; flex-shrink: 0; }
|
|
.gm-sym-code { font-size: .68rem; font-weight: 700; padding: .2rem .5rem; border-radius: 6px; background: #d8f3dc; color: #2d6a4f; flex-shrink: 0; }
|
|
.gm-sym-name { font-size: .85rem; color: #1a3a2a; }
|
|
|
|
/* CF buttons */
|
|
.gm-cf-grid { display: grid; grid-template-columns: repeat(3,1fr); gap: 6px; margin-top: .5rem; }
|
|
.gm-cf-btn {
|
|
padding: .5rem .25rem; border-radius: 10px;
|
|
border: 1.5px solid #ede8df; background: white;
|
|
font-size: .75rem; font-weight: 600; color: #5a7a67;
|
|
cursor: pointer; text-align: center; transition: all .15s;
|
|
}
|
|
.gm-cf-btn:hover { border-color: #74c69d; background: #f0fdf4; }
|
|
.gm-cf-btn.active { border-color: #2d6a4f; background: #d8f3dc; color: #1a3a2a; }
|
|
|
|
/* Hasil ringkas */
|
|
.gm-result-card {
|
|
background: linear-gradient(135deg, #f0fdf4, #e8f7ee);
|
|
border: 1.5px solid #b7ddc4;
|
|
border-radius: 16px; padding: 1.25rem; margin-bottom: 1rem;
|
|
}
|
|
.gm-result-disease { font-family: 'Playfair Display', serif; font-size: 1.2rem; color: #1a3a2a; margin-bottom: .25rem; }
|
|
.gm-result-pct { font-size: 2rem; font-weight: 700; color: #2d6a4f; line-height: 1; }
|
|
.gm-result-level { font-size: .75rem; font-weight: 600; padding: .25rem .6rem; border-radius: 50px; display: inline-block; margin-top: .25rem; }
|
|
|
|
/* Lock overlay */
|
|
.gm-lock-wrap { position: relative; border-radius: 16px; overflow: hidden; margin-bottom: 1rem; }
|
|
.gm-lock-blur {
|
|
filter: blur(5px);
|
|
background: #f0fdf4;
|
|
border: 1.5px solid #b7ddc4;
|
|
border-radius: 16px; padding: 1.25rem;
|
|
user-select: none;
|
|
}
|
|
.gm-lock-overlay {
|
|
position: absolute; inset: 0;
|
|
display: flex; flex-direction: column;
|
|
align-items: center; justify-content: center;
|
|
background: rgba(248,254,250,.82);
|
|
backdrop-filter: blur(2px);
|
|
border-radius: 16px;
|
|
padding: 1rem; text-align: center;
|
|
}
|
|
.gm-lock-icon { font-size: 1.75rem; margin-bottom: .5rem; }
|
|
.gm-lock-title { font-family: 'Playfair Display', serif; font-size: .95rem; color: #1a3a2a; font-weight: 700; margin-bottom: .25rem; }
|
|
.gm-lock-desc { font-size: .78rem; color: #5a7a67; margin-bottom: .75rem; line-height: 1.5; }
|
|
|
|
/* Buttons di modal */
|
|
.gm-btn-primary {
|
|
width: 100%; padding: .85rem; border-radius: 12px;
|
|
background: #1a3a2a; color: white;
|
|
font-family: 'DM Sans', sans-serif; font-size: .9rem; font-weight: 600;
|
|
border: none; cursor: pointer; transition: background .2s;
|
|
}
|
|
.gm-btn-primary:hover { background: #2d6a4f; }
|
|
.gm-btn-secondary {
|
|
width: 100%; padding: .75rem; border-radius: 12px;
|
|
background: white; color: #2d6a4f;
|
|
font-family: 'DM Sans', sans-serif; font-size: .9rem; font-weight: 500;
|
|
border: 1.5px solid #b7ddc4; cursor: pointer; transition: all .2s;
|
|
}
|
|
.gm-btn-secondary:hover { background: #f0fdf4; }
|
|
.gm-btn-group { display: flex; gap: .75rem; }
|
|
.gm-btn-back { flex-shrink: 0; padding: .75rem 1.25rem; border-radius: 12px; background: white; color: #5a7a67; border: 1.5px solid #ede8df; cursor: pointer; font-size: .875rem; font-weight: 500; transition: background .2s; }
|
|
.gm-btn-back:hover { background: #f8f4ee; }
|
|
.gm-btn-next { flex: 1; padding: .85rem; border-radius: 12px; background: #1a3a2a; color: white; border: none; cursor: pointer; font-size: .9rem; font-weight: 600; transition: background .2s; }
|
|
.gm-btn-next:hover { background: #2d6a4f; }
|
|
|
|
/* Search */
|
|
.gm-search { width: 100%; padding: .65rem 1rem; border: 1.5px solid #ede8df; border-radius: 12px; font-size: .875rem; font-family: inherit; color: #1a3a2a; outline: none; margin-bottom: .75rem; transition: border-color .2s; }
|
|
.gm-search:focus { border-color: #74c69d; }
|
|
|
|
/* Loading spinner */
|
|
.gm-spinner { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 2.5rem 0; gap: 1rem; }
|
|
.gm-spin { width: 40px; height: 40px; border: 3px solid #d8f3dc; border-top-color: #2d6a4f; border-radius: 50%; animation: spin .8s linear infinite; }
|
|
@keyframes spin { to { transform: rotate(360deg); } }
|
|
|
|
/* Other results (ringkas) */
|
|
.gm-other-item { display: flex; align-items: center; justify-content: space-between; padding: .6rem .9rem; border-radius: 10px; background: #f8fffe; border: 1px solid #e0f0e6; margin-bottom: 5px; }
|
|
.gm-other-name { font-size: .82rem; color: #1a3a2a; font-weight: 500; }
|
|
.gm-other-pct { font-size: .82rem; font-weight: 700; color: #2d6a4f; }
|
|
|
|
/* Responsive */
|
|
@media (max-width: 900px) { .hero { grid-template-columns: 1fr; text-align: center; padding: 6rem 1.5rem 3rem; } .hero-desc { margin: 0 auto 2rem; } .hero-cta { justify-content: center; } .hero-stats { justify-content: center; } .hero-visual { margin-top: 3rem; } nav { padding: 1rem 1.5rem; } .features, .cta-section { padding: 4rem 1.5rem; } .features-grid { grid-template-columns: 1fr 1fr; } }
|
|
@media (max-width: 600px) { .features-grid { grid-template-columns: 1fr; } .plant-card { width: 290px; } }
|
|
@media (max-width: 640px) { .features { padding: 5rem 1.5rem 3rem; } .features::before { height: 80px; } .section-title { font-size: 1.8rem; } .artikel-desktop { display: none !important; } .artikel-mobile { display: block !important; } }
|
|
@media (max-width: 480px) { nav { padding: .75rem 1rem; gap: .5rem; } .nav-logo { font-size: .95rem; gap: .4rem; } .nav-links { gap: .4rem; } .btn-outline { padding: .4rem .75rem; font-size: .75rem; } .btn-solid { padding: .4rem .75rem; font-size: .75rem; } }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
|
|
<!-- NAV -->
|
|
<nav>
|
|
<a href="/" class="nav-logo">
|
|
<svg width="34" height="34" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
<ellipse cx="11" cy="15" rx="5" ry="11" fill="#d8f3dc" stroke="#2d6a4f" stroke-width="1.3" transform="rotate(-15 11 15)"/>
|
|
<line x1="11" y1="6" x2="10" y2="24" stroke="#2d6a4f" stroke-width="1" stroke-linecap="round" opacity="0.8" transform="rotate(-15 11 15)"/>
|
|
<line x1="10" y1="13" x2="7" y2="17" stroke="#2d6a4f" stroke-width="0.8" stroke-linecap="round" opacity="0.6"/>
|
|
<line x1="10" y1="17" x2="7.5" y2="21" stroke="#2d6a4f" stroke-width="0.8" stroke-linecap="round" opacity="0.6"/>
|
|
<path d="M19 7 C19 7 24 7 24 12 C24 17 20 18 20 22" stroke="#1a3a2a" stroke-width="1.5" stroke-linecap="round" fill="none"/>
|
|
<circle cx="20" cy="24.5" r="3" stroke="#1a3a2a" stroke-width="1.3" fill="#d8f3dc"/>
|
|
<line x1="18" y1="7" x2="21" y2="7" stroke="#1a3a2a" stroke-width="1.5" stroke-linecap="round"/>
|
|
</svg>
|
|
SiPakarTebu
|
|
</a>
|
|
<div class="nav-links">
|
|
<a href="{{ route('login') }}" class="btn-outline">Masuk</a>
|
|
<a href="{{ route('register') }}" class="btn-solid">Daftar Gratis</a>
|
|
</div>
|
|
</nav>
|
|
|
|
<!-- HERO -->
|
|
<section class="hero">
|
|
<div class="hero-content">
|
|
<div class="hero-badge">Didukung data oleh pakar</div>
|
|
<h1>Kenali Penyakit<br><em>Tanaman</em> Tebu<br>Lebih Cepat</h1>
|
|
<p class="hero-desc">
|
|
SiPakarTebu menggunakan kecerdasan buatan berbasis <em>Certainty Factor</em> untuk mendiagnosa penyakit tanaman secara akurat — cukup jawab beberapa pertanyaan gejala.
|
|
</p>
|
|
<div class="hero-cta">
|
|
{{-- Tombol utama: buka modal diagnosis guest --}}
|
|
<button onclick="gmOpen()" class="btn-hero btn-hero-primary">
|
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M8 2v12M2 8h12" stroke="white" stroke-width="2" stroke-linecap="round"/></svg>
|
|
Mulai Diagnosa
|
|
</button>
|
|
<a href="{{ route('login') }}" class="btn-hero btn-hero-secondary">
|
|
Sudah punya akun?
|
|
</a>
|
|
</div>
|
|
<div class="hero-stats">
|
|
<div class="stat">
|
|
<span class="stat-num">90%</span>
|
|
<span class="stat-label">Akurasi Rata-rata</span>
|
|
</div>
|
|
<div class="stat" style="border-left:1px solid var(--green-pale);padding-left:2rem">
|
|
<span class="stat-num">10</span>
|
|
<span class="stat-label">Jenis Penyakit</span>
|
|
</div>
|
|
<div class="stat" style="border-left:1px solid var(--green-pale);padding-left:2rem">
|
|
<span class="stat-num">1 mnt</span>
|
|
<span class="stat-label">Waktu Diagnosa</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="hero-visual">
|
|
<div class="plant-card">
|
|
<div class="floating-badge">✓ Diagnosa Selesai</div>
|
|
<div class="plant-illustration">
|
|
<svg viewBox="0 0 120 120" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
<ellipse cx="60" cy="55" rx="34" ry="44" fill="#52b788" opacity=".8"/>
|
|
<ellipse cx="60" cy="55" rx="34" ry="44" fill="none" stroke="#40916c" stroke-width="1.5"/>
|
|
<path d="M60 20 Q80 45 60 95" stroke="#1a3a2a" stroke-width="1.5" stroke-linecap="round" opacity=".5"/>
|
|
<path d="M60 40 Q48 45 42 58" stroke="#1a3a2a" stroke-width="1" stroke-linecap="round" opacity=".4"/>
|
|
<path d="M60 52 Q72 55 76 66" stroke="#1a3a2a" stroke-width="1" stroke-linecap="round" opacity=".4"/>
|
|
<ellipse cx="38" cy="72" rx="20" ry="28" fill="#74c69d" transform="rotate(-20 38 72)" opacity=".7"/>
|
|
<ellipse cx="86" cy="68" rx="18" ry="26" fill="#95d5b2" transform="rotate(15 86 68)" opacity=".6"/>
|
|
<rect x="54" y="90" width="12" height="22" rx="4" fill="#8b5e3c"/>
|
|
</svg>
|
|
</div>
|
|
<div class="card-tag">⚠️ Terdeteksi</div>
|
|
<div class="card-title">Luka Api (Leaf Scald)</div>
|
|
<div class="card-subtitle">Penyakit disebabkan bakteri Xanthomonas albilineans</div>
|
|
<div class="progress-wrap">
|
|
<div class="progress-label"><span>Tingkat Kepastian</span><span>78%</span></div>
|
|
<div class="progress-bar"><div class="progress-fill" style="width:78%"></div></div>
|
|
</div>
|
|
<div class="progress-wrap">
|
|
<div class="progress-label"><span>Kesesuaian Gejala</span><span>91%</span></div>
|
|
<div class="progress-bar"><div class="progress-fill" style="width:91%"></div></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- FEATURES -->
|
|
<section class="features">
|
|
<p class="section-label">Fitur Unggulan</p>
|
|
<h2 class="section-title">Teknologi Cermat untuk<br><em>Kebun Sehat</em> Kamu</h2>
|
|
<p class="section-desc">Sistem pakar kami menggabungkan pengetahuan ahli pertanian dengan teknologi untuk hasil diagnosa yang dapat dipercaya.</p>
|
|
<div class="features-grid">
|
|
<div class="feature-card"><div class="feature-icon">🔬</div><div class="feature-title">Diagnosa Akurat</div><p class="feature-text">Menggunakan metode Certainty Factor yang telah terbukti untuk mengidentifikasi penyakit tanaman dengan tingkat akurasi tinggi.</p></div>
|
|
<div class="feature-card"><div class="feature-icon">⚡</div><div class="feature-title">Hasil Instan</div><p class="feature-text">Dapatkan hasil diagnosa dalam hitungan menit. Cukup jawab pertanyaan gejala dan sistem kami akan menganalisis secara otomatis.</p></div>
|
|
<div class="feature-card"><div class="feature-icon">📋</div><div class="feature-title">Rekomendasi Penanganan</div><p class="feature-text">Setiap hasil diagnosa disertai panduan penanganan lengkap yang bisa langsung dipraktikkan di kebun kamu.</p></div>
|
|
<div class="feature-card"><div class="feature-icon">📊</div><div class="feature-title">Riwayat Diagnosa</div><p class="feature-text">Simpan dan pantau semua diagnosa sebelumnya. Lacak perkembangan kesehatan tanaman kamu dari waktu ke waktu.</p></div>
|
|
<div class="feature-card"><div class="feature-icon">🌱</div><div class="feature-title">Database Penyakit Lengkap</div><p class="feature-text">Mencakup lebih dari 5 jenis penyakit umum pada tanaman dengan gejala dan penanganan yang terperinci.</p></div>
|
|
<div class="feature-card"><div class="feature-icon">🛡️</div><div class="feature-title">Data Aman & Privat</div><p class="feature-text">Data diagnosa kamu tersimpan dengan aman. Hanya kamu yang bisa mengakses riwayat dan hasil diagnosa milik kamu.</p></div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- ARTIKEL -->
|
|
<section style="background:#f8f4ee;padding:5rem 1.5rem;">
|
|
<div style="max-width:1100px;margin:0 auto;">
|
|
<div style="text-align:center;margin-bottom:3rem;">
|
|
<p style="font-size:.78rem;font-weight:600;color:#2d6a4f;letter-spacing:.12em;text-transform:uppercase;margin-bottom:.75rem;">BERITA & RISET TERKINI</p>
|
|
<h2 style="font-family:'Playfair Display',serif;font-size:clamp(1.8rem,3vw,2.6rem);color:#1a3a2a;margin-bottom:1rem;line-height:1.2;">Dari Sumber <em style="color:#40916c;font-style:italic;">Terpercaya</em></h2>
|
|
<p style="color:#5a7a67;font-size:.95rem;max-width:480px;margin:0 auto;">Artikel terbaru seputar pertanian dan penyakit tanaman dari media & lembaga penelitian nasional</p>
|
|
</div>
|
|
@if(isset($articles) && count($articles) > 0)
|
|
<div class="artikel-desktop" style="display:grid;grid-template-columns:repeat(3,1fr);gap:1.5rem;">
|
|
@foreach($articles as $article)
|
|
<a href="{{ $article['link'] ?? '#' }}" target="_blank" rel="noopener"
|
|
style="display:flex;flex-direction:column;background:white;border-radius:20px;overflow:hidden;border:1px solid #ede8df;text-decoration:none;box-shadow:0 4px 16px rgba(26,58,42,.06);transition:transform .3s,box-shadow .3s;"
|
|
onmouseover="this.style.transform='translateY(-4px)';this.style.boxShadow='0 12px 32px rgba(26,58,42,.12)'"
|
|
onmouseout="this.style.transform='translateY(0)';this.style.boxShadow='0 4px 16px rgba(26,58,42,.06)'">
|
|
<div style="height:180px;overflow:hidden;background:#e8f5ec;position:relative;flex-shrink:0;">
|
|
@if(!empty($article['image']))
|
|
<img src="{{ $article['image'] }}" alt="{{ $article['title'] }}" style="width:100%;height:100%;object-fit:cover;" onerror="this.style.display='none';this.nextElementSibling.style.display='flex';">
|
|
<div style="display:none;width:100%;height:100%;align-items:center;justify-content:center;position:absolute;top:0;left:0;"><span style="font-size:3rem;">🌿</span></div>
|
|
@else
|
|
<div style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;"><span style="font-size:3rem;">🌿</span></div>
|
|
@endif
|
|
</div>
|
|
<div style="padding:1.25rem;display:flex;flex-direction:column;flex:1;">
|
|
<div style="display:flex;align-items:center;gap:.5rem;margin-bottom:.75rem;">
|
|
<span style="font-size:.7rem;font-weight:700;padding:.25rem .6rem;border-radius:.5rem;background:#d8f3dc;color:#2d6a4f;">{{ $article['source'] ?? 'SiPakarTebu' }}</span>
|
|
<span style="font-size:.7rem;color:#a0b4a8;">{{ $article['date'] ?? date('d M Y') }}</span>
|
|
</div>
|
|
<h3 style="font-family:'Playfair Display',serif;font-size:.95rem;color:#1a3a2a;line-height:1.5;margin-bottom:.6rem;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;">{{ $article['title'] ?? 'Artikel Pertanian' }}</h3>
|
|
<p style="font-size:.8rem;color:#8fa89a;line-height:1.6;margin-bottom:1rem;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;flex:1;">{{ $article['excerpt'] ?? '' }}</p>
|
|
<div style="font-size:.8rem;font-weight:600;color:#2d6a4f;margin-top:auto;">Baca Selengkapnya →</div>
|
|
</div>
|
|
</a>
|
|
@endforeach
|
|
</div>
|
|
<div class="artikel-mobile" style="display:none;">
|
|
@foreach($articles as $i => $article)
|
|
<div class="artikel-slide" style="display:{{ $i === 0 ? 'flex' : 'none' }};flex-direction:column;background:white;border-radius:20px;overflow:hidden;border:1px solid #ede8df;box-shadow:0 4px 16px rgba(26,58,42,.06);">
|
|
<a href="{{ $article['link'] ?? '#' }}" target="_blank" rel="noopener" style="text-decoration:none;display:flex;flex-direction:column;">
|
|
<div style="height:200px;overflow:hidden;background:#e8f5ec;position:relative;">
|
|
@if(!empty($article['image']))
|
|
<img src="{{ $article['image'] }}" alt="{{ $article['title'] }}" style="width:100%;height:100%;object-fit:cover;" onerror="this.style.display='none';this.nextElementSibling.style.display='flex';">
|
|
<div style="display:none;width:100%;height:100%;align-items:center;justify-content:center;position:absolute;top:0;left:0;"><span style="font-size:3rem;">🌿</span></div>
|
|
@else
|
|
<div style="width:100%;height:100%;display:flex;align-items:center;justify-content:center;"><span style="font-size:3rem;">🌿</span></div>
|
|
@endif
|
|
</div>
|
|
<div style="padding:1.5rem;">
|
|
<div style="display:flex;align-items:center;gap:.5rem;margin-bottom:.75rem;">
|
|
<span style="font-size:.7rem;font-weight:700;padding:.25rem .6rem;border-radius:.5rem;background:#d8f3dc;color:#2d6a4f;">{{ $article['source'] ?? 'SiPakarTebu' }}</span>
|
|
<span style="font-size:.7rem;color:#a0b4a8;">{{ $article['date'] ?? date('d M Y') }}</span>
|
|
</div>
|
|
<h3 style="font-family:'Playfair Display',serif;font-size:1.1rem;color:#1a3a2a;line-height:1.5;margin-bottom:.75rem;">{{ $article['title'] ?? 'Artikel Pertanian' }}</h3>
|
|
<p style="font-size:.875rem;color:#8fa89a;line-height:1.6;margin-bottom:1rem;">{{ $article['excerpt'] ?? '' }}</p>
|
|
<div style="font-size:.875rem;font-weight:600;color:#2d6a4f;">Baca Selengkapnya →</div>
|
|
</div>
|
|
</a>
|
|
</div>
|
|
@endforeach
|
|
<div style="display:flex;align-items:center;justify-content:space-between;margin-top:1.25rem;">
|
|
<button onclick="prevArtikel()" id="btn-prev" style="padding:.6rem 1.25rem;border-radius:50px;border:1.5px solid #b7ddc4;background:white;color:#2d6a4f;font-size:.875rem;font-weight:600;cursor:pointer;opacity:0.4;">← Sebelumnya</button>
|
|
<span id="artikel-counter" style="font-size:.8rem;color:#8fa89a;">1 / {{ count($articles) }}</span>
|
|
<button onclick="nextArtikel()" id="btn-next" style="padding:.6rem 1.25rem;border-radius:50px;border:none;background:#2d6a4f;color:white;font-size:.875rem;font-weight:600;cursor:pointer;">Selanjutnya →</button>
|
|
</div>
|
|
</div>
|
|
@else
|
|
<div style="text-align:center;padding:4rem 0;"><p style="color:#8fa89a;">Artikel sedang dimuat...</p></div>
|
|
@endif
|
|
</div>
|
|
</section>
|
|
|
|
<!-- CTA -->
|
|
<section class="cta-section">
|
|
<p class="cta-label">Mulai Sekarang</p>
|
|
<h2 class="cta-title">Jaga Tanaman Kamu<br>tetap <em>Sehat & Subur</em></h2>
|
|
<p class="cta-desc">Daftar gratis sekarang dan mulai diagnosa pertama kamu dalam hitungan menit. Tidak perlu kartu kredit.</p>
|
|
<div class="cta-buttons">
|
|
<a href="{{ route('register') }}" class="btn-hero btn-hero-primary" style="font-size:1rem;padding:1rem 2.25rem;">Daftar Gratis Sekarang</a>
|
|
<a href="{{ route('login') }}" class="btn-hero btn-hero-secondary" style="font-size:1rem;padding:1rem 2.25rem;background:rgba(255,255,255,.08);border-color:rgba(255,255,255,.2) !important;color:white;">Masuk ke Akun</a>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- FOOTER -->
|
|
<footer>
|
|
<p>© 2026 <span>SiPakarTebu</span> — Sistem Pakar Diagnosa Penyakit Tanaman. Dibuat dengan 🌿</p>
|
|
</footer>
|
|
|
|
<!-- ═══════════════════════════════════════════════════════════════
|
|
MODAL DIAGNOSIS GUEST
|
|
═══════════════════════════════════════════════════════════════ -->
|
|
<div id="guestModal">
|
|
<div class="gm-box">
|
|
|
|
<!-- Header sticky -->
|
|
<div class="gm-header">
|
|
<button class="gm-close" onclick="gmClose()">✕</button>
|
|
<div style="display:flex;align-items:center;gap:.5rem;margin-bottom:.2rem;">
|
|
<span style="font-size:.7rem;font-weight:700;color:#2d6a4f;text-transform:uppercase;letter-spacing:.08em;">
|
|
Coba Diagnosa
|
|
</span>
|
|
</div>
|
|
<div style="display:flex;justify-content:space-between;align-items:center;">
|
|
<span style="font-size:.8rem;color:#8fa89a;">
|
|
Step <span id="gm-step-num">1</span> dari 3 —
|
|
<span id="gm-step-label">Pilih Gejala</span>
|
|
</span>
|
|
</div>
|
|
<div class="gm-progress-bar-wrap">
|
|
<div class="gm-progress-fill" id="gm-prog" style="width:33%;"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Body -->
|
|
<div class="gm-body">
|
|
|
|
<!-- ── STEP 1: Pilih Gejala ─────────────────────── -->
|
|
<div class="gm-step active" id="gm-s1">
|
|
<h3 style="font-family:'Playfair Display',serif;color:#1a3a2a;font-size:1.1rem;margin-bottom:.25rem;">Pilih Gejala</h3>
|
|
<p style="font-size:.8rem;color:#8fa89a;margin-bottom:.75rem;">Pilih minimal 4 gejala yang tampak pada tanaman</p>
|
|
|
|
<input type="text" class="gm-search" id="gm-search" placeholder="Cari gejala..." oninput="gmFilterSearch(this.value)">
|
|
|
|
<div class="gm-symptom-list" id="gm-sym-list">
|
|
<div style="text-align:center;padding:2rem;color:#8fa89a;font-size:.875rem;">
|
|
⏳ Memuat daftar gejala...
|
|
</div>
|
|
</div>
|
|
|
|
<div style="margin-top:.75rem;display:flex;align-items:center;justify-content:space-between;">
|
|
<span style="font-size:.82rem;color:#5a7a67;">
|
|
Dipilih: <strong id="gm-count" style="color:#2d6a4f;">0</strong> gejala
|
|
<span id="gm-warn" style="color:#dc2626;font-size:.75rem;display:none;"> (min. 4)</span>
|
|
</span>
|
|
</div>
|
|
|
|
<div style="margin-top:1rem;">
|
|
<button class="gm-btn-next" style="width:100%;" onclick="gmNext()">Lanjut →</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- ── STEP 2: Tingkat Keyakinan ──────────────────── -->
|
|
<div class="gm-step" id="gm-s2">
|
|
<h3 style="font-family:'Playfair Display',serif;color:#1a3a2a;font-size:1.1rem;margin-bottom:.25rem;">Tingkat Keyakinan</h3>
|
|
<p style="font-size:.8rem;color:#8fa89a;margin-bottom:1rem;">Seberapa yakin kamu melihat gejala ini pada tanaman?</p>
|
|
|
|
<div id="gm-cf-container" style="display:flex;flex-direction:column;gap:12px;"></div>
|
|
|
|
<div class="gm-btn-group" style="margin-top:1.25rem;">
|
|
<button class="gm-btn-back" onclick="gmPrev()">← Kembali</button>
|
|
<button class="gm-btn-next" onclick="gmNext()">Lanjut →</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- ── STEP 3: Konfirmasi ──────────────────────────── -->
|
|
<div class="gm-step" id="gm-s3">
|
|
<h3 style="font-family:'Playfair Display',serif;color:#1a3a2a;font-size:1.1rem;margin-bottom:.25rem;">Konfirmasi</h3>
|
|
<p style="font-size:.8rem;color:#8fa89a;margin-bottom:1rem;">Periksa kembali sebelum diagnosa dimulai</p>
|
|
|
|
<div id="gm-summary" style="display:flex;flex-direction:column;gap:6px;margin-bottom:1.25rem;"></div>
|
|
|
|
<div class="gm-btn-group">
|
|
<button class="gm-btn-back" onclick="gmPrev()">← Kembali</button>
|
|
<button class="gm-btn-next" onclick="gmSubmit()">Diagnosa Sekarang</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- ── STEP 4: Loading ─────────────────────────────── -->
|
|
<div class="gm-step" id="gm-s4">
|
|
<div class="gm-spinner">
|
|
<div class="gm-spin"></div>
|
|
<p style="font-size:.9rem;color:#5a7a67;">Menganalisis gejala...</p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- ── STEP 5: Hasil ───────────────────────────────── -->
|
|
<div class="gm-step" id="gm-s5">
|
|
<h3 style="font-family:'Playfair Display',serif;color:#1a3a2a;font-size:1.1rem;margin-bottom:.25rem;">Hasil Diagnosa</h3>
|
|
<p style="font-size:.8rem;color:#8fa89a;margin-bottom:1rem;">Berdasarkan gejala yang kamu pilih</p>
|
|
|
|
<!-- Hasil utama (terlihat) -->
|
|
<div class="gm-result-card" id="gm-result-main"></div>
|
|
|
|
<!-- Hasil lain + penanganan (dikunci) -->
|
|
<div class="gm-lock-wrap">
|
|
<div class="gm-lock-blur" id="gm-result-blur">
|
|
<p style="font-size:.8rem;font-weight:600;color:#1a3a2a;margin-bottom:.5rem;">Penanganan yang Disarankan</p>
|
|
<p style="font-size:.8rem;color:#5a7a67;">• Semprot fungisida berbasis tembaga...</p>
|
|
<p style="font-size:.8rem;color:#5a7a67;">• Cabut dan musnahkan tanaman yang terinfeksi berat</p>
|
|
<p style="font-size:.8rem;color:#5a7a67;">• Lakukan rotasi tanaman minimal 2 musim</p>
|
|
<p style="font-size:.8rem;color:#5a7a67;margin-top:.75rem;font-weight:600;">Kemungkinan Penyakit Lain</p>
|
|
<p style="font-size:.8rem;color:#5a7a67;">• ██████████ (██%)</p>
|
|
<p style="font-size:.8rem;color:#5a7a67;">• ██████████ (██%)</p>
|
|
</div>
|
|
<div class="gm-lock-overlay">
|
|
<div class="gm-lock-icon">🔒</div>
|
|
<div class="gm-lock-title">Detail Lengkap Dikunci</div>
|
|
<div class="gm-lock-desc">Daftar atau masuk untuk melihat penanganan lengkap, kemungkinan penyakit lain, dan simpan riwayat diagnosa kamu.</div>
|
|
<a href="{{ route('register') }}"
|
|
style="display:block;width:100%;padding:.7rem;border-radius:10px;background:#1a3a2a;color:white;text-align:center;font-size:.85rem;font-weight:600;text-decoration:none;margin-bottom:.5rem;">
|
|
Daftar Gratis — Lihat Hasil Lengkap
|
|
</a>
|
|
<a href="{{ route('login') }}"
|
|
style="display:block;width:100%;padding:.6rem;border-radius:10px;border:1.5px solid #b7ddc4;color:#2d6a4f;text-align:center;font-size:.82rem;font-weight:500;text-decoration:none;background:white;">
|
|
Sudah punya akun? Masuk
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<button onclick="gmReset()" style="width:100%;padding:.65rem;border-radius:10px;background:white;border:1.5px solid #ede8df;color:#5a7a67;font-size:.85rem;cursor:pointer;margin-top:.75rem;font-family:inherit;">
|
|
↩ Ulangi Diagnosa
|
|
</button>
|
|
</div>
|
|
|
|
</div><!-- /gm-body -->
|
|
</div><!-- /gm-box -->
|
|
</div><!-- /guestModal -->
|
|
|
|
|
|
<script>
|
|
/* ═══════════════════════════════════════════════════════
|
|
ARTIKEL SLIDER (mobile)
|
|
═══════════════════════════════════════════════════════ */
|
|
const totalArtikel = {{ isset($articles) ? count($articles) : 0 }};
|
|
let currentArtikel = 0;
|
|
function showArtikel(index) {
|
|
document.querySelectorAll('.artikel-slide').forEach((el,i)=>{ el.style.display = i===index?'flex':'none'; });
|
|
document.getElementById('artikel-counter').textContent = (index+1)+' / '+totalArtikel;
|
|
document.getElementById('btn-prev').style.opacity = index===0?'0.4':'1';
|
|
document.getElementById('btn-next').style.opacity = index===totalArtikel-1?'0.4':'1';
|
|
}
|
|
function prevArtikel() { if(currentArtikel>0){currentArtikel--;showArtikel(currentArtikel);} }
|
|
function nextArtikel() { if(currentArtikel<totalArtikel-1){currentArtikel++;showArtikel(currentArtikel);} }
|
|
|
|
/* ═══════════════════════════════════════════════════════
|
|
GUEST MODAL — State
|
|
═══════════════════════════════════════════════════════ */
|
|
let gmStep = 1;
|
|
let gmSymptoms = []; // [{code, name}]
|
|
let gmChecked = []; // [code, ...]
|
|
let gmCFValues = {}; // {code: '0.8'}
|
|
|
|
const gmStepLabels = { 1:'Pilih Gejala', 2:'Tingkat Keyakinan', 3:'Konfirmasi' };
|
|
const gmProgWidth = { 1:'33%', 2:'66%', 3:'100%', 4:'100%', 5:'100%' };
|
|
const gmCFOpts = [
|
|
{val:'0.8', label:'Sangat Yakin'},
|
|
{val:'0.6', label:'Yakin'},
|
|
{val:'0.4', label:'Cukup Yakin'},
|
|
{val:'0.2', label:'Kurang Yakin'},
|
|
{val:'0.0', label:'Tidak Yakin'},
|
|
];
|
|
const gmCFMap = {'0.8':'Sangat Yakin','0.6':'Yakin','0.4':'Cukup Yakin','0.2':'Kurang Yakin','0.0':'Tidak Yakin'};
|
|
|
|
/* ── Buka/tutup modal ── */
|
|
function gmOpen() {
|
|
document.getElementById('guestModal').classList.add('open');
|
|
document.body.style.overflow = 'hidden';
|
|
if (gmSymptoms.length === 0) gmLoadSymptoms();
|
|
}
|
|
function gmClose() {
|
|
document.getElementById('guestModal').classList.remove('open');
|
|
document.body.style.overflow = '';
|
|
}
|
|
// Klik backdrop tutup modal
|
|
document.getElementById('guestModal').addEventListener('click', function(e) {
|
|
if (e.target === this) gmClose();
|
|
});
|
|
|
|
/* ── Load gejala dari server ── */
|
|
async function gmLoadSymptoms() {
|
|
try {
|
|
const res = await fetch('{{ route("guest.symptoms") }}');
|
|
gmSymptoms = await res.json();
|
|
gmRenderSymptoms(gmSymptoms);
|
|
} catch(e) {
|
|
document.getElementById('gm-sym-list').innerHTML =
|
|
'<div style="text-align:center;padding:2rem;color:#dc2626;font-size:.875rem;">Gagal memuat gejala. Refresh halaman.</div>';
|
|
}
|
|
}
|
|
|
|
/* ── Render daftar gejala ── */
|
|
function gmRenderSymptoms(list) {
|
|
const container = document.getElementById('gm-sym-list');
|
|
if (!list.length) {
|
|
container.innerHTML = '<div style="text-align:center;padding:2rem;color:#8fa89a;font-size:.875rem;">Tidak ada gejala ditemukan.</div>';
|
|
return;
|
|
}
|
|
container.innerHTML = list.map(s => `
|
|
<label class="gm-sym-item ${gmChecked.includes(s.code)?'checked':''}" id="gm-lbl-${s.code}">
|
|
<input type="checkbox" ${gmChecked.includes(s.code)?'checked':''}
|
|
onchange="gmToggle('${s.code}', this)"
|
|
style="accent-color:#2d6a4f;width:15px;height:15px;flex-shrink:0;">
|
|
<span class="gm-sym-code">${s.code}</span>
|
|
<span class="gm-sym-name">${s.name}</span>
|
|
</label>
|
|
`).join('');
|
|
gmUpdateCount();
|
|
}
|
|
|
|
/* ── Toggle gejala ── */
|
|
function gmToggle(code, cb) {
|
|
if (cb.checked) {
|
|
if (!gmChecked.includes(code)) gmChecked.push(code);
|
|
cb.closest('label').classList.add('checked');
|
|
} else {
|
|
gmChecked = gmChecked.filter(c => c !== code);
|
|
cb.closest('label').classList.remove('checked');
|
|
delete gmCFValues[code];
|
|
}
|
|
gmUpdateCount();
|
|
}
|
|
|
|
/* ── Update hitungan ── */
|
|
function gmUpdateCount() {
|
|
document.getElementById('gm-count').textContent = gmChecked.length;
|
|
document.getElementById('gm-warn').style.display = gmChecked.length < 4 ? 'inline' : 'none';
|
|
}
|
|
|
|
/* ── Filter search ── */
|
|
function gmFilterSearch(keyword) {
|
|
const kw = keyword.toLowerCase();
|
|
const filtered = gmSymptoms.filter(s =>
|
|
s.code.toLowerCase().includes(kw) || s.name.toLowerCase().includes(kw)
|
|
);
|
|
gmRenderSymptoms(filtered);
|
|
}
|
|
|
|
/* ── Navigasi step ── */
|
|
function gmShowStep(n) {
|
|
document.querySelectorAll('.gm-step').forEach(el => el.classList.remove('active'));
|
|
document.getElementById('gm-s' + n).classList.add('active');
|
|
gmStep = n;
|
|
if (n <= 3) {
|
|
document.getElementById('gm-step-num').textContent = n;
|
|
document.getElementById('gm-step-label').textContent = gmStepLabels[n] || '';
|
|
}
|
|
document.getElementById('gm-prog').style.width = gmProgWidth[n] || '100%';
|
|
}
|
|
|
|
function gmNext() {
|
|
if (gmStep === 1) {
|
|
if (gmChecked.length < 4) {
|
|
document.getElementById('gm-warn').style.display = 'inline';
|
|
return;
|
|
}
|
|
gmBuildCF();
|
|
gmShowStep(2);
|
|
} else if (gmStep === 2) {
|
|
gmBuildSummary();
|
|
gmShowStep(3);
|
|
}
|
|
}
|
|
|
|
function gmPrev() {
|
|
if (gmStep === 2) gmShowStep(1);
|
|
else if (gmStep === 3) gmShowStep(2);
|
|
}
|
|
|
|
/* ── Build CF step ── */
|
|
function gmBuildCF() {
|
|
const container = document.getElementById('gm-cf-container');
|
|
container.innerHTML = '';
|
|
|
|
gmChecked.forEach(code => {
|
|
const sym = gmSymptoms.find(s => s.code === code);
|
|
if (!sym) return;
|
|
// Default ke 0.8
|
|
if (!gmCFValues[code]) gmCFValues[code] = '0.8';
|
|
|
|
const btns = gmCFOpts.map(opt => `
|
|
<button type="button"
|
|
class="gm-cf-btn ${gmCFValues[code] === opt.val ? 'active' : ''}"
|
|
id="gmcfb-${code}-${opt.val.replace('.','_')}"
|
|
onclick="gmSelectCF('${code}', '${opt.val}')">
|
|
${opt.label}
|
|
</button>
|
|
`).join('');
|
|
|
|
container.innerHTML += `
|
|
<div style="padding:.9rem 1rem;border-radius:14px;border:1px solid #ede8df;background:#fafaf8;">
|
|
<p style="font-size:.82rem;font-weight:600;color:#1a3a2a;margin-bottom:.65rem;">
|
|
<span style="font-size:.68rem;font-weight:700;padding:.15rem .45rem;border-radius:5px;background:#d8f3dc;color:#2d6a4f;margin-right:.35rem;">${code}</span>
|
|
${sym.name}
|
|
</p>
|
|
<div class="gm-cf-grid">${btns}</div>
|
|
</div>
|
|
`;
|
|
});
|
|
}
|
|
|
|
function gmSelectCF(code, val) {
|
|
gmCFValues[code] = val;
|
|
gmCFOpts.forEach(opt => {
|
|
const btn = document.getElementById('gmcfb-' + code + '-' + opt.val.replace('.','_'));
|
|
if (btn) btn.classList.toggle('active', opt.val === val);
|
|
});
|
|
}
|
|
|
|
/* ── Build Summary ── */
|
|
function gmBuildSummary() {
|
|
const el = document.getElementById('gm-summary');
|
|
el.innerHTML = gmChecked.map(code => {
|
|
const sym = gmSymptoms.find(s => s.code === code);
|
|
const val = gmCFValues[code] || '0.8';
|
|
return `
|
|
<div style="display:flex;align-items:center;justify-content:space-between;padding:.6rem .9rem;border-radius:10px;background:#f0fdf4;border:1px solid #b7ddc4;">
|
|
<span style="font-size:.82rem;color:#1a3a2a;">
|
|
<span style="font-size:.68rem;font-weight:700;padding:.15rem .4rem;border-radius:5px;background:#d8f3dc;color:#2d6a4f;margin-right:.3rem;">${code}</span>
|
|
${sym ? sym.name : code}
|
|
</span>
|
|
<span style="font-size:.75rem;font-weight:600;padding:.2rem .6rem;border-radius:50px;background:#d8f3dc;color:#2d6a4f;flex-shrink:0;margin-left:.5rem;">${gmCFMap[val]||val}</span>
|
|
</div>
|
|
`;
|
|
}).join('');
|
|
}
|
|
|
|
/* ── Submit ke server ── */
|
|
async function gmSubmit() {
|
|
gmShowStep(4);
|
|
|
|
// Susun payload
|
|
const payload = { symptoms: {} };
|
|
gmChecked.forEach(code => { payload.symptoms[code] = gmCFValues[code] || '0.8'; });
|
|
|
|
try {
|
|
const res = await fetch('{{ route("guest.diagnosis") }}', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content,
|
|
'Accept': 'application/json',
|
|
},
|
|
body: JSON.stringify(payload),
|
|
});
|
|
|
|
const data = await res.json();
|
|
|
|
if (!res.ok) {
|
|
alert(data.error || 'Terjadi kesalahan. Coba lagi.');
|
|
gmShowStep(3);
|
|
return;
|
|
}
|
|
|
|
gmShowResult(data);
|
|
} catch(e) {
|
|
alert('Gagal terhubung ke server. Periksa koneksi internet kamu.');
|
|
gmShowStep(3);
|
|
}
|
|
}
|
|
|
|
/* ── Tampilkan hasil ── */
|
|
function gmShowResult(data) {
|
|
const pct = data.confidence;
|
|
const level = data.level;
|
|
|
|
// Warna badge level
|
|
const levelColors = {
|
|
'Sangat Tinggi': {bg:'#d8f3dc', color:'#2d6a4f'},
|
|
'Tinggi': {bg:'#dbeafe', color:'#1d4ed8'},
|
|
'Sedang': {bg:'#fef3c7', color:'#92400e'},
|
|
'Rendah': {bg:'#fee2e2', color:'#991b1b'},
|
|
'Sangat Rendah': {bg:'#f3f4f6', color:'#6b7280'},
|
|
'Tidak Terdeteksi': {bg:'#f3f4f6', color:'#6b7280'},
|
|
};
|
|
const lc = levelColors[level] || levelColors['Tidak Terdeteksi'];
|
|
|
|
document.getElementById('gm-result-main').innerHTML = `
|
|
<div style="display:flex;align-items:flex-start;justify-content:space-between;margin-bottom:.75rem;">
|
|
<div>
|
|
<p style="font-size:.7rem;font-weight:600;color:#5a7a67;text-transform:uppercase;letter-spacing:.06em;margin-bottom:.2rem;">Penyakit Terdeteksi</p>
|
|
<div class="gm-result-disease">${data.disease_name}</div>
|
|
</div>
|
|
<span class="gm-result-level" style="background:${lc.bg};color:${lc.color};">${level}</span>
|
|
</div>
|
|
<div style="margin-bottom:.5rem;">
|
|
<div style="display:flex;justify-content:space-between;font-size:.78rem;color:#5a7a67;margin-bottom:.35rem;">
|
|
<span>Tingkat Kepastian</span>
|
|
<span style="font-weight:700;color:#2d6a4f;">${pct}%</span>
|
|
</div>
|
|
<div style="height:8px;background:#d8f3dc;border-radius:99px;overflow:hidden;">
|
|
<div style="height:100%;width:${pct}%;background:linear-gradient(90deg,#2d6a4f,#74c69d);border-radius:99px;transition:width .8s ease;"></div>
|
|
</div>
|
|
</div>
|
|
<p style="font-size:.75rem;color:#8fa89a;margin-top:.5rem;">
|
|
🌿 Berdasarkan ${gmChecked.length} gejala yang dipilih
|
|
</p>
|
|
`;
|
|
|
|
gmShowStep(5);
|
|
}
|
|
|
|
/* ── Reset modal ── */
|
|
function gmReset() {
|
|
gmChecked = [];
|
|
gmCFValues = {};
|
|
gmShowStep(1);
|
|
gmRenderSymptoms(gmSymptoms);
|
|
document.getElementById('gm-search').value = '';
|
|
}
|
|
</script>
|
|
|
|
</body>
|
|
</html> |