181 lines
5.6 KiB
JavaScript
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
|
|
}
|
|
}); |