import React, { useState, useEffect, useRef } from 'react'; import { MapPin, Calendar, Clock, Info, Bell, Volume2 } from 'lucide-react'; // Konfigurasi Default const KOTA = 'Karawang'; const NEGARA = 'Indonesia'; const METODE_KEMENAG = 20; // Kode 20 di Aladhan API adalah standar Kemenag RI // Data Dummy untuk Slider const SLIDER_DATA = [ { type: 'image', url: 'https://images.unsplash.com/photo-1564683214965-3619addd900d?q=80&w=1920&auto=format&fit=crop', title: 'Kajian Rutin Ahad Pagi', desc: 'Tafsir Al-Quran bersama Ustadz Fulan. Bada Subuh - Selesai.' }, { type: 'text', title: 'Laporan Keuangan Masjid', desc: 'Pemasukan Infaq Jumat ini: Rp 5.500.000,- | Saldo Total: Rp 45.000.000,-. Terimakasih kepada para Jamaah.' }, { type: 'image', url: 'https://images.unsplash.com/photo-1584551246679-0daf3d275d0f?q=80&w=1920&auto=format&fit=crop', title: 'Mari Makmurkan Masjid', desc: 'Sholat berjamaah di masjid lebih utama 27 derajat dibandingkan sholat sendirian.' } ]; // Data Ayat/Hadits const AYAT_HARIAN = [ { text: "Sesungguhnya shalat itu adalah fardhu yang ditentukan waktunya atas orang-orang yang beriman.", surah: "QS. An-Nisa: 103" }, { text: "Barangsiapa yang menempuh suatu jalan untuk menuntut ilmu, maka Allah Swt akan memudahkan baginya jalan menuju surga.", surah: "HR. Muslim" }, { text: "Sebaik-baik kalian adalah orang yang belajar Al-Qur'an dan mengajarkannya.", surah: "HR. Bukhari" } ]; export default function App() { // States const [started, setStarted] = useState(false); // Untuk mengizinkan autoplay audio di browser const [currentTime, setCurrentTime] = useState(new Date()); const [prayerTimes, setPrayerTimes] = useState(null); const [hijriDate, setHijriDate] = useState(''); const [nextPrayer, setNextPrayer] = useState({ name: '-', time: '-', diffMs: 0 }); const [viewMode, setViewMode] = useState('CLOCK'); // 'CLOCK', 'COUNTDOWN', 'ADHAN', 'IQAMAH' const [iqamahCountdown, setIqamahCountdown] = useState(0); // dalam detik const [sliderIndex, setSliderIndex] = useState(0); const [ayatIndex, setAyatIndex] = useState(0); // Audio Refs (Menggunakan suara peringatan standar) const adhanAudio = useRef(new Audio('https://actions.google.com/sounds/v1/alarms/bugle_tune.ogg')); const beepAudio = useRef(new Audio('https://actions.google.com/sounds/v1/alarms/beep_short.ogg')); // Fetch Prayer Times useEffect(() => { const fetchTimings = async () => { try { const dateStr = `${currentTime.getDate()}-${currentTime.getMonth() + 1}-${currentTime.getFullYear()}`; const url = `https://api.aladhan.com/v1/timingsByCity/${dateStr}?city=${KOTA}&country=${NEGARA}&method=${METODE_KEMENAG}`; const res = await fetch(url); const data = await res.json(); if (data.code === 200) { const pt = data.data.timings; setPrayerTimes({ Imsak: pt.Imsak, Subuh: pt.Fajr, Terbit: pt.Sunrise, Dzuhur: pt.Dhuhr, Ashar: pt.Asr, Maghrib: pt.Maghrib, Isya: pt.Isha }); setHijriDate(`${data.data.date.hijri.day} ${data.data.date.hijri.month.en} ${data.data.date.hijri.year} H`); } } catch (error) { console.error('Gagal mengambil data jadwal sholat:', error); } }; fetchTimings(); // Refresh jadwal setiap hari jam 00:01 const interval = setInterval(fetchTimings, 24 * 60 * 60 * 1000); return () => clearInterval(interval); }, []); // Main Clock & Logic Loop (berjalan setiap detik) useEffect(() => { if (!started) return; const timer = setInterval(() => { const now = new Date(); setCurrentTime(now); if (!prayerTimes) return; // Logika Mencari Waktu Sholat Berikutnya const times = [ { name: 'Subuh', time: prayerTimes.Subuh }, { name: 'Dzuhur', time: prayerTimes.Dzuhur }, { name: 'Ashar', time: prayerTimes.Ashar }, { name: 'Maghrib', time: prayerTimes.Maghrib }, { name: 'Isya', time: prayerTimes.Isya } ]; let next = times[0]; let minDiff = Infinity; let isAdhanTimeNow = false; times.forEach(pt => { const [h, m] = pt.time.split(':'); const ptDate = new Date(now); ptDate.setHours(parseInt(h, 10), parseInt(m, 10), 0, 0); let diff = ptDate - now; // Jika sholat sudah lewat hari ini, hitung untuk besok if (diff < 0) { ptDate.setDate(ptDate.getDate() + 1); diff = ptDate - now; } if (diff < minDiff) { minDiff = diff; next = { name: pt.name, time: pt.time, diffMs: diff }; } // Cek jika SEKARANG adalah waktu adhan (HH:MM:00) if (now.getHours() === parseInt(h, 10) && now.getMinutes() === parseInt(m, 10) && now.getSeconds() === 0) { isAdhanTimeNow = true; } }); setNextPrayer(next); // STATE MACHINE: Mengatur View Mode Layar const seconds = now.getSeconds(); if (viewMode === 'CLOCK' || viewMode === 'COUNTDOWN') { if (isAdhanTimeNow) { // MASUK WAKTU SHOLAT -> MODE ADHAN setViewMode('ADHAN'); adhanAudio.current.play().catch(e => console.log('Audio play failed', e)); } else { // LOGIKA SWITCH JAM -> COUNTDOWN setiap 1 Menit (selama 15 detik) if (seconds === 0 && viewMode === 'CLOCK') { setViewMode('COUNTDOWN'); } else if (seconds === 15 && viewMode === 'COUNTDOWN') { setViewMode('CLOCK'); } } } else if (viewMode === 'ADHAN') { // Mode Adhan berlangsung misal 3 menit (180 detik), untuk demo kita buat 30 detik saja, lalu masuk Iqamah // (Di aplikasi real, bisa pakai tombol manual oleh marbot) if (seconds % 30 === 0 && now.getSeconds() !== 0) { // Demo: ganti setelah 30 detik setViewMode('IQAMAH'); setIqamahCountdown(10 * 60); // 10 Menit hitung mundur Iqamah } } else if (viewMode === 'IQAMAH') { setIqamahCountdown(prev => { if (prev <= 1) { beepAudio.current.play().catch(e => console.log(e)); setViewMode('CLOCK'); return 0; } return prev - 1; }); } }, 1000); return () => clearInterval(timer); }, [prayerTimes, viewMode, started]); // Slider & Ayat Interval useEffect(() => { const sliderInterval = setInterval(() => { setSliderIndex(prev => (prev + 1) % SLIDER_DATA.length); }, 10000); // Ganti slide setiap 10 detik const ayatInterval = setInterval(() => { setAyatIndex(prev => (prev + 1) % AYAT_HARIAN.length); }, 20000); // Ganti ayat setiap 20 detik return () => { clearInterval(sliderInterval); clearInterval(ayatInterval); } }, []); // Format Helpers const formatTimeHM = (date) => { const h = date.getHours().toString().padStart(2, '0'); const m = date.getMinutes().toString().padStart(2, '0'); return `${h}:${m}`; }; const formatCountdown = (ms) => { const totalSeconds = Math.floor(ms / 1000); const h = Math.floor(totalSeconds / 3600); const m = Math.floor((totalSeconds % 3600) / 60); const s = totalSeconds % 60; if (h > 0) return `${h}j ${m}m ${s}d`; return `${m}m ${s}d`; }; const formatIqamah = (seconds) => { const m = Math.floor(seconds / 60).toString().padStart(2, '0'); const s = (seconds % 60).toString().padStart(2, '0'); return `${m}:${s}`; }; const formatMasehi = (date) => { const days = ['Minggu', 'Senin', 'Selasa', 'Rabu', 'Kamis', 'Jumat', 'Sabtu']; const months = ['Januari', 'Februari', 'Maret', 'April', 'Mei', 'Juni', 'Juli', 'Agustus', 'September', 'Oktober', 'November', 'Desember']; return `${days[date.getDay()]}, ${date.getDate()} ${months[date.getMonth()]} ${date.getFullYear()}`; }; // Komponen Layar Mulai (Untuk mengaktifkan kebijakan Autoplay Audio Browser) if (!started) { return (
Klik / Tap dimana saja untuk memulai layar dan mengaktifkan audio
{time || '--:--'}
Informasi Waktu
{hijriDate || 'Memuat...'}
{formatMasehi(currentTime)}
{slide.desc}
{slide.desc}
Menuju Waktu {nextPrayer.name}
Telah Masuk
Iqamah Dalam
Luruskan & Rapatkan Shaf
"{AYAT_HARIAN[ayatIndex].text}"
- {AYAT_HARIAN[ayatIndex].surah}