MIF_E31232094/public/js/tour.js

181 lines
5.6 KiB
JavaScript

// tour.js — SiPakarTebu Onboarding Tour
const tourSteps = [
{
title: "Selamat datang di SiPakarTebu! 🌱",
desc: "Ini adalah panduan singkat untuk membantu kamu memahami fitur-fitur utama aplikasi.",
target: null,
},
{
title: "Menu Navigasi",
desc: "Gunakan menu di sebelah kiri untuk berpindah antar halaman: Dashboard, Diagnosa, Riwayat, Kamus, dan Profil.",
target: "#sidebar",
pos: "right",
},
{
title: "Statistik Kamu",
desc: "Ringkasan total diagnosa yang sudah kamu lakukan dan akurasi rata-rata model.",
target: ".stat-cards",
pos: "bottom",
},
{
title: "Grafik Diagnosa",
desc: "Grafik ini menunjukkan aktivitas diagnosamu per bulan sepanjang tahun.",
target: ".chart-container",
pos: "top",
},
{
title: "Mulai Diagnosa Baru",
desc: "Klik menu Diagnosa untuk memulai diagnosa penyakit tebu. Unggah foto dan dapatkan hasilnya!",
target: "#nav-diagnosa",
pos: "right",
},
];
let tourCurrent = 0;
function createTourOverlay() {
const overlay = document.createElement("div");
overlay.id = "tour-overlay";
overlay.style.cssText = `
position: fixed; inset: 0; z-index: 9999;
pointer-events: none;
`;
document.body.appendChild(overlay);
return overlay;
}
function createTooltip() {
const el = document.createElement("div");
el.id = "tour-tooltip";
el.style.cssText = `
position: fixed; z-index: 10000;
background: #fff; border-radius: 14px;
padding: 20px 22px; width: 280px;
box-shadow: 0 8px 40px rgba(0,0,0,0.22);
pointer-events: auto;
font-family: inherit;
`;
document.body.appendChild(el);
return el;
}
function createHighlight() {
const el = document.createElement("div");
el.id = "tour-highlight";
el.style.cssText = `
position: fixed; z-index: 9998;
border: 2.5px solid #2e7d52;
border-radius: 10px;
pointer-events: none;
transition: all 0.35s ease;
box-shadow: 0 0 0 9999px rgba(0,0,0,0.50);
`;
document.body.appendChild(el);
return el;
}
function renderTourStep() {
const step = tourSteps[tourCurrent];
const total = tourSteps.length;
const highlight = document.getElementById("tour-highlight");
const tooltip = document.getElementById("tour-tooltip");
// Highlight target element
if (step.target) {
const target = document.querySelector(step.target);
if (target) {
const r = target.getBoundingClientRect();
const pad = 8;
highlight.style.display = "block";
highlight.style.top = (r.top - pad) + "px";
highlight.style.left = (r.left - pad) + "px";
highlight.style.width = (r.width + pad * 2) + "px";
highlight.style.height = (r.height + pad * 2) + "px";
// Position tooltip near target
if (step.pos === "right") {
tooltip.style.top = r.top + "px";
tooltip.style.left = (r.right + 16) + "px";
} else if (step.pos === "bottom") {
tooltip.style.top = (r.bottom + 16) + "px";
tooltip.style.left = Math.max(16, r.left) + "px";
} else if (step.pos === "top") {
tooltip.style.top = (r.top - 200) + "px";
tooltip.style.left = Math.max(16, r.left) + "px";
} else {
tooltip.style.top = "50%";
tooltip.style.left = "50%";
tooltip.style.transform = "translate(-50%, -50%)";
}
}
} else {
highlight.style.display = "none";
tooltip.style.top = "50%";
tooltip.style.left = "50%";
tooltip.style.transform = "translate(-50%, -50%)";
}
const dots = Array.from({ length: total }, (_, i) =>
`<div style="width:${i === tourCurrent ? 16 : 6}px;height:6px;border-radius:3px;
background:${i === tourCurrent ? "#2e7d52" : "#ddd"};
transition:all 0.3s;"></div>`
).join("");
tooltip.innerHTML = `
<div style="font-size:11px;color:#2e7d52;font-weight:600;text-transform:uppercase;
letter-spacing:0.8px;margin-bottom:6px;">
Langkah ${tourCurrent + 1} dari ${total}
</div>
<div style="font-size:15px;font-weight:600;color:#1a2f1a;margin-bottom:6px;">
${step.title}
</div>
<div style="font-size:13px;color:#555;line-height:1.6;margin-bottom:16px;">
${step.desc}
</div>
<div style="display:flex;align-items:center;justify-content:space-between;">
<div style="display:flex;gap:5px;align-items:center;">${dots}</div>
<div style="display:flex;gap:10px;align-items:center;">
<button onclick="endTour()" style="background:none;border:none;
font-size:12px;color:#999;cursor:pointer;">Lewati</button>
<button onclick="tourNext()" style="background:#2e7d52;color:#fff;border:none;
padding:8px 16px;border-radius:8px;font-size:13px;font-weight:500;cursor:pointer;">
${tourCurrent === total - 1 ? "Selesai ✓" : "Lanjut →"}
</button>
</div>
</div>
`;
}
function tourNext() {
tourCurrent++;
if (tourCurrent >= tourSteps.length) {
endTour();
return;
}
renderTourStep();
}
function endTour() {
["tour-overlay", "tour-tooltip", "tour-highlight"].forEach((id) => {
const el = document.getElementById(id);
if (el) el.remove();
});
// Tandai sudah pernah tour
localStorage.setItem("sipakartebu_tour_done", "1");
}
function startTour() {
tourCurrent = 0;
if (!document.getElementById("tour-overlay")) createTourOverlay();
if (!document.getElementById("tour-tooltip")) createTooltip();
if (!document.getElementById("tour-highlight")) createHighlight();
renderTourStep();
}
// Auto-start untuk pengguna baru
document.addEventListener("DOMContentLoaded", () => {
if (!localStorage.getItem("sipakartebu_tour_done")) {
setTimeout(startTour, 800); // delay sedikit biar halaman load dulu
}
});