<!DOCTYPE html>
<html lang="id" class="scroll-smooth">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>DevAcademy | Kursus Web Development</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://unpkg.com/lucide@latest"></script>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap" rel="stylesheet">
<style>
body { font-family: 'Plus Jakarta Sans', sans-serif; }
.gradient-text {
background: linear-gradient(90deg, #3b82f6, #10b981);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.view-transition { transition: all 0.3s ease-in-out; }
[v-cloak] { display: none; }
</style>
</head>
<body class="bg-slate-50 text-slate-900">
<!-- Navigation -->
<nav class="fixed w-full z-50 bg-white/80 backdrop-blur-md border-b border-slate-200">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex justify-between h-16 items-center">
<div class="flex items-center gap-2 cursor-pointer" onclick="showView('home')">
<div class="w-8 h-8 bg-blue-600 rounded-lg flex items-center justify-center">
<i data-lucide="code-2" class="text-white w-5 h-5"></i>
</div>
<span class="font-bold text-xl tracking-tight">Dev<span class="text-blue-600">Academy</span></span>
</div>
<div id="nav-links" class="hidden md:flex space-x-8 font-medium text-slate-600">
<a href="#kurikulum" class="hover:text-blue-600 transition">Kurikulum</a>
<a href="#keunggulan" class="hover:text-blue-600 transition">Keunggulan</a>
<a href="#harga" class="hover:text-blue-600 transition">Harga</a>
</div>
<div class="flex items-center gap-4">
<button onclick="showView('admin')" class="text-slate-500 hover:text-blue-600 font-medium text-sm flex items-center gap-1">
<i data-lucide="layout-dashboard" class="w-4 h-4"></i> Dashboard Admin
</button>
<a href="#daftar" id="nav-cta" class="bg-blue-600 text-white px-5 py-2.5 rounded-full font-semibold hover:bg-blue-700 transition shadow-lg shadow-blue-200 text-sm">Daftar</a>
</div>
</div>
</div>
</nav>
<!-- VIEWS CONTAINER -->
<main id="app-container">
<!-- HOME VIEW (Landing Page & Form) -->
<div id="view-home" class="view-content view-transition">
<!-- Hero Section -->
<section class="pt-32 pb-20 overflow-hidden">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="grid lg:grid-cols-2 gap-12 items-center">
<div class="space-y-8">
<div class="inline-flex items-center gap-2 px-3 py-1 rounded-full bg-blue-50 text-blue-700 text-sm font-semibold border border-blue-100">
<span class="flex h-2 w-2 rounded-full bg-blue-600 animate-pulse"></span>
Batch Mei: Sisa 5 Kursi Lagi!
</div>
<h1 class="text-5xl md:text-6xl font-extrabold leading-tight tracking-tight text-slate-900">
Kuasai Web Development dalam <span class="gradient-text">12 Minggu.</span>
</h1>
<p class="text-lg text-slate-600 leading-relaxed max-w-xl">
Bangun portofolio riil dari nol hingga siap kerja. Kurikulum berbasis industri dengan bimbingan mentor berpengalaman.
</p>
<div class="flex flex-col sm:flex-row gap-4 pt-4">
<a href="#daftar" class="bg-orange-500 text-white px-8 py-4 rounded-xl font-bold text-lg hover:bg-orange-600 transition shadow-xl shadow-orange-200 text-center">
Daftar Sekarang
</a>
<a href="#kurikulum" class="bg-white text-slate-700 border-2 border-slate-200 px-8 py-4 rounded-xl font-bold text-lg hover:border-blue-600 hover:text-blue-600 transition text-center flex items-center justify-center gap-2">
Lihat Silabus <i data-lucide="arrow-right" class="w-5 h-5"></i>
</a>
</div>
</div>
<div class="relative">
<div class="bg-white p-4 rounded-2xl shadow-2xl border border-slate-100 rotate-2">
<img src="https://images.unsplash.com/photo-1498050108023-c5249f4df085?auto=format&fit=crop&w=800&q=80" alt="Coding Showcase" class="rounded-xl">
</div>
</div>
</div>
</div>
</section>
<!-- Registration Form -->
<section id="daftar" class="py-24 bg-white border-t border-slate-100">
<div class="max-w-xl mx-auto px-4">
<div class="bg-white p-8 md:p-12 rounded-3xl shadow-2xl border border-slate-100">
<div class="text-center mb-8">
<h2 class="text-3xl font-bold mb-2">Mulai Perjalananmu</h2>
<p class="text-slate-500 italic">"Garansi uang kembali dalam 7 hari jika materi tidak sesuai."</p>
</div>
<form id="registrationForm" class="space-y-5">
<div>
<label class="block text-sm font-semibold text-slate-700 mb-2">Nama Lengkap</label>
<input type="text" name="nama" required class="w-full px-4 py-3 rounded-xl border border-slate-200 focus:outline-none focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 transition" placeholder="Contoh: Amir Santoso">
</div>
<div>
<label class="block text-sm font-semibold text-slate-700 mb-2">Alamat Email</label>
<input type="email" name="email" required class="w-full px-4 py-3 rounded-xl border border-slate-200 focus:outline-none focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 transition" placeholder="amir@email.com">
</div>
<div>
<label class="block text-sm font-semibold text-slate-700 mb-2">WhatsApp</label>
<input type="tel" name="whatsapp" required class="w-full px-4 py-3 rounded-xl border border-slate-200 focus:outline-none focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 transition" placeholder="0812xxxxxxxx">
</div>
<div>
<label class="block text-sm font-semibold text-slate-700 mb-2">Paket Pilihan</label>
<select name="paket" class="w-full px-4 py-3 rounded-xl border border-slate-200 focus:outline-none focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 transition">
<option value="basic">Basic Class - Rp 999rb</option>
<option value="pro" selected>Pro BootCamp - Rp 2.499rb</option>
</select>
</div>
<button type="submit" id="submitBtn" class="w-full py-4 bg-orange-600 text-white rounded-xl font-bold text-lg hover:bg-orange-700 transition shadow-xl shadow-orange-100 flex items-center justify-center gap-2">
<span>Konfirmasi Pendaftaran</span>
<i data-lucide="send" class="w-5 h-5"></i>
</button>
</form>
<div id="formFeedback" class="hidden mt-6 p-4 rounded-xl text-center font-medium"></div>
</div>
</div>
</section>
</div>
<!-- ADMIN VIEW (Dashboard) -->
<div id="view-admin" class="view-content view-transition hidden pt-24 pb-20">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex flex-col md:flex-row justify-between items-start md:items-end mb-8 gap-4">
<div>
<h1 class="text-3xl font-bold text-slate-900 tracking-tight">Dashboard Pendaftar</h1>
<p class="text-slate-500">Data pendaftar yang tersimpan di Google Sheets secara real-time.</p>
</div>
<div class="flex gap-3">
<button onclick="fetchAdminData()" class="flex items-center gap-2 bg-white border border-slate-200 px-4 py-2 rounded-xl text-sm font-semibold hover:bg-slate-50 transition shadow-sm">
<i data-lucide="refresh-cw" class="w-4 h-4" id="refresh-icon"></i> Segarkan Data
</button>
<button onclick="exportToCSV()" class="flex items-center gap-2 bg-blue-600 text-white px-4 py-2 rounded-xl text-sm font-semibold hover:bg-blue-700 transition">
<i data-lucide="download" class="w-4 h-4"></i> Export CSV
</button>
</div>
</div>
<div class="bg-white rounded-2xl shadow-sm border border-slate-200 overflow-hidden">
<div class="overflow-x-auto">
<table class="w-full text-left border-collapse" id="adminTable">
<thead>
<tr class="bg-slate-50 border-b border-slate-200">
<th class="px-6 py-4 text-xs font-bold text-slate-500 uppercase tracking-wider">Tanggal</th>
<th class="px-6 py-4 text-xs font-bold text-slate-500 uppercase tracking-wider">Nama</th>
<th class="px-6 py-4 text-xs font-bold text-slate-500 uppercase tracking-wider">Kontak</th>
<th class="px-6 py-4 text-xs font-bold text-slate-500 uppercase tracking-wider">Paket</th>
</tr>
</thead>
<tbody id="table-body" class="divide-y divide-slate-100">
<!-- Baris data akan diisi di sini -->
</tbody>
</table>
<div id="loading-state" class="py-20 text-center">
<div class="animate-spin w-8 h-8 border-4 border-blue-600 border-t-transparent rounded-full mx-auto mb-4"></div>
<p class="text-slate-500 font-medium">Memuat data...</p>
</div>
<div id="empty-state" class="hidden py-20 text-center">
<i data-lucide="inbox" class="w-12 h-12 mx-auto mb-4 text-slate-200"></i>
<p class="text-slate-500">Belum ada data pendaftar.</p>
</div>
</div>
</div>
</div>
</div>
</main>
<footer class="py-12 bg-slate-50 border-t border-slate-200">
<div class="max-w-7xl mx-auto px-4 text-center">
<p class="text-slate-500 text-sm">© 2024 DevAcademy. Powered by Google Apps Script & SPA Architecture.</p>
</div>
</footer>
<script>
// Inisialisasi Ikon Lucide
lucide.createIcons();
// GANTI URL INI DENGAN URL WEB APP ANDA
const SCRIPT_URL = 'URL_WEB_APP_ANDA_DISINI';
// 1. Logika Navigasi SPA
window.showView = (viewName) => {
document.querySelectorAll('.view-content').forEach(el => el.classList.add('hidden'));
document.getElementById(`view-${viewName}`).classList.remove('hidden');
if (viewName === 'admin') {
document.getElementById('nav-links').classList.add('invisible');
document.getElementById('nav-cta').classList.add('hidden');
fetchAdminData();
} else {
document.getElementById('nav-links').classList.remove('invisible');
document.getElementById('nav-cta').classList.remove('hidden');
}
window.scrollTo(0, 0);
};
// 2. Logika Formulir Pendaftaran (doPost)
const regForm = document.getElementById('registrationForm');
const feedback = document.getElementById('formFeedback');
const submitBtn = document.getElementById('submitBtn');
regForm.addEventListener('submit', async (e) => {
e.preventDefault();
if (SCRIPT_URL === 'URL_WEB_APP_ANDA_DISINI') {
alert("Kesalahan: SCRIPT_URL belum dikonfigurasi.");
return;
}
submitBtn.disabled = true;
const originalText = submitBtn.innerHTML;
submitBtn.innerHTML = 'Memproses...';
// Menggunakan format x-www-form-urlencoded untuk mode no-cors
const formData = new FormData(regForm);
const params = new URLSearchParams();
for (const [key, value] of formData.entries()) {
params.append(key, value);
}
try {
await fetch(SCRIPT_URL, {
method: 'POST',
mode: 'no-cors',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: params.toString()
});
// Tampilkan sukses (asumsi sukses pada mode no-cors jika tidak ada error jaringan)
feedback.textContent = "Pendaftaran Berhasil! Kami akan segera menghubungi Anda.";
feedback.className = "mt-6 p-4 rounded-xl text-center font-medium bg-emerald-100 text-emerald-700 block";
regForm.reset();
} catch (err) {
console.error("Gagal mengirim:", err);
feedback.textContent = "Gagal mengirim pendaftaran. Periksa koneksi Anda.";
feedback.className = "mt-6 p-4 rounded-xl text-center font-medium bg-red-100 text-red-700 block";
} finally {
submitBtn.disabled = false;
submitBtn.innerHTML = originalText;
lucide.createIcons();
}
});
// 3. Logika Dashboard Admin (doGet)
async function fetchAdminData() {
const body = document.getElementById('table-body');
const loader = document.getElementById('loading-state');
const empty = document.getElementById('empty-state');
const refreshIcon = document.getElementById('refresh-icon');
if(SCRIPT_URL === 'URL_WEB_APP_ANDA_DISINI') return;
refreshIcon.classList.add('animate-spin');
loader.classList.remove('hidden');
body.innerHTML = '';
empty.classList.add('hidden');
try {
const response = await fetch(SCRIPT_URL);
const data = await response.json();
if (data.length === 0) {
empty.classList.remove('hidden');
} else {
// Render Baris Tabel
data.reverse().forEach(item => {
const tr = document.createElement('tr');
tr.className = "hover:bg-slate-50 transition-colors";
tr.innerHTML = `
<td class="px-6 py-4 text-xs text-slate-500 whitespace-nowrap">${item.Timestamp || '-'}</td>
<td class="px-6 py-4">
<div class="font-bold text-slate-900">${item["Nama Lengkap"] || '-'}</div>
</td>
<td class="px-6 py-4">
<div class="text-sm font-medium text-slate-700">${item.Email || '-'}</div>
<div class="text-xs text-slate-400">${item.WhatsApp || '-'}</div>
</td>
<td class="px-6 py-4">
<span class="px-2 py-1 rounded-md text-[10px] font-bold uppercase ${item.Paket === 'pro' ? 'bg-blue-100 text-blue-700' : 'bg-orange-100 text-orange-700'}">
${item.Paket || '-'}
</span>
</td>
`;
body.appendChild(tr);
});
}
} catch (error) {
console.error('Fetch error:', error);
body.innerHTML = '<tr><td colspan="4" class="p-8 text-center text-red-500">Gagal memuat data. Periksa konfigurasi Apps Script.</td></tr>';
} finally {
loader.classList.add('hidden');
refreshIcon.classList.remove('animate-spin');
lucide.createIcons();
}
}
// 4. Ekspor ke CSV
window.exportToCSV = () => {
const rows = Array.from(document.querySelectorAll('#adminTable tr'));
let csvContent = "data:text/csv;charset=utf-8,Tanggal,Nama,Email,WhatsApp,Paket\n";
rows.slice(1).forEach(row => {
const cols = row.querySelectorAll('td');
const rowData = Array.from(cols).map(c => `"${c.innerText.replace(/\n/g, ' ')}"`).join(",");
csvContent += rowData + "\n";
});
const encodedUri = encodeURI(csvContent);
const link = document.createElement("a");
link.setAttribute("href", encodedUri);
link.setAttribute("download", "pendaftar_devacademy.csv");
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
};
</script>
</body>
</html>