/* @jsx React.createElement */
/* Method — 3-layer progress system (Level Journey + Skill Radar + Milestone Badges) */
const LEVELS = [
{ id: 0, short: 'Pre', long: 'Pre-Beginner', weeks: '1–4', desc: 'Adaptasi dulu. Posisi tangan, posture, suara pertama.' },
{ id: 1, short: 'B1', long: 'Beginner 1', weeks: '5–16', desc: 'Lagu asli mulai masuk. Chord, beat, melodi dasar.' },
{ id: 2, short: 'B2', long: 'Beginner 2', weeks: '17–36',desc: 'Udah bisa main. Teknik makin tight, kuping makin tajem.' },
{ id: 3, short: 'P1', long: 'Performance 1', weeks: '37–60',desc: 'Studio session pertama. Naik panggung beneran.' },
{ id: 4, short: 'P2', long: 'Performance 2', weeks: '60+', desc: 'Punya karakter sendiri. Improvisasi, theory deep-dive.' },
{ id: 5, short: 'P3', long: 'Performance 3', weeks: '∞', desc: 'Kamu ngajar sebanyak kamu belajar. Mentor track (optional).' },
];
function MethodSection() {
const [activeLevel, setActiveLevel] = React.useState(2);
const lvl = LEVELS[activeLevel];
return (
Metode IMS · A + B + C
Tiga cara liat progress kamu yang beneran.
Sekolah lain biasanya cuma bilang "good job" terus selesai. Kita bikin progress kelihatan —
tanpa bikin kayak ujian. Tiga lensa, satu arah.
A · Level
B · Radar
C · Badges
{/* A — Level Journey */}
{/* B — Skill Radar */}
{/* C — Milestone Badges */}
);
}
function Pill({ children }) {
return (
{children}
);
}
function SectionLabel({ n, title, desc, style = {} }) {
return (
);
}
/* ─── A — Level Journey (interactive line) ─── */
function LevelJourney({ levels, active, onSelect, current }) {
return (
{/* Rail */}
{/* Filled rail to active */}
{/* Nodes */}
{levels.map((l, i) => {
const isActive = i === active;
const isPast = i < active;
return (
);
})}
{/* Active level description */}
Lagi di
{current.long}
{current.desc}
Step {current.id + 1} / 6
);
}
/* ─── B — Skill Radar (animated chart) ─── */
const RADAR_DATA = {
guitar: { skills: ['Chord', 'Rhythm', 'Melody', 'Technique', 'Ear', 'Theory'], start: [1, 1, 1, 1, 1, 1], now: [4, 3.5, 3, 3.2, 2.8, 2.5] },
piano: { skills: ['L.Hand', 'R.Hand', 'Coord.', 'Rhythm', 'Ear', 'Theory'], start: [1, 1, 1, 1, 1, 1], now: [3.2, 4, 3.5, 3.5, 3, 2.8] },
drum: { skills: ['Power', 'Rhythm', 'Coord.', 'Tempo', 'Dynamics', 'Fills'], start: [1, 1, 1, 1, 1, 1], now: [4, 3.5, 3, 4, 2.8, 3.2] },
bass: { skills: ['Finger', 'Rhythm', 'Groove', 'Tech.', 'Ear', 'Theory'], start: [1, 1, 1, 1, 1, 1], now: [3.8, 3.5, 4, 3, 3.2, 2.5] },
vocal: { skills: ['Pitch', 'Breath', 'Tone', 'Rhythm', 'Express', 'Ear'], start: [1, 1, 1, 1, 1, 1], now: [3.5, 3.8, 3.2, 3, 4, 3] },
};
function SkillRadarBlock() {
const [inst, setInst] = React.useState('guitar');
const [showNow, setShowNow] = React.useState(false);
const data = RADAR_DATA[inst];
React.useEffect(() => {
setShowNow(false);
const t = setTimeout(() => setShowNow(true), 200);
return () => clearTimeout(t);
}, [inst]);
return (
{/* Radar chart */}
{Object.keys(RADAR_DATA).map(k => (
))}
Minggu 1
Minggu 32
{/* Right: explanation */}
);
}
function RadarPoint({ n, title, desc }) {
return (
);
}
function RadarSVG({ skills, start, now }) {
const size = 320;
const cx = size / 2, cy = size / 2;
const max = 5;
const radius = 110;
const n = skills.length;
const pointFor = (val, i) => {
const angle = (Math.PI * 2 * i) / n - Math.PI / 2;
const r = (val / max) * radius;
return [cx + Math.cos(angle) * r, cy + Math.sin(angle) * r];
};
const labelFor = (i) => {
const angle = (Math.PI * 2 * i) / n - Math.PI / 2;
const r = radius + 22;
return [cx + Math.cos(angle) * r, cy + Math.sin(angle) * r];
};
const polygon = (data) => data.map((v, i) => pointFor(v, i).join(',')).join(' ');
return (
);
}
/* ─── C — Milestone Badges (sample) ─── */
const SAMPLE_BADGES = [
{ id: 'first-chord', title: 'Chord pertama yang clean', unlock: 'Beginner 1', earned: true },
{ id: 'first-fill', title: 'Drum fill pertama', unlock: 'Beginner 1', earned: true },
{ id: 'song-end-to-end',title:'Satu lagu full, tanpa berhenti',unlock: 'Beginner 2', earned: true },
{ id: 'lock-in', title: 'Lock-in sama band', unlock: 'Beginner 2', earned: false, progress: 0.6 },
{ id: 'first-stage', title: 'Live performance pertama', unlock: 'Performance 1', earned: false, progress: 0.3 },
{ id: 'recording', title: 'Take rekaman studio', unlock: 'Performance 1', earned: false, progress: 0.1 },
{ id: 'arrange', title: 'Aransemen lagu sendiri', unlock: 'Performance 2', earned: false },
{ id: 'mentor', title: 'Mentor murid baru', unlock: 'Performance 3', earned: false },
];
function BadgesBlock() {
return (
{SAMPLE_BADGES.map(b => (
{b.title}
{b.unlock}
{!b.earned && b.progress !== undefined && (
)}
))}
);
}
Object.assign(window, { MethodSection });