Obyek pembuatan:
Plugin WordPress Jadwal Sholat & Countdown Buka Puasa (Wilayah Banyumas) dengan bantuan AI Gemini (Canvas).
Berikut prompt yang digunakan:
Buatkan sebuah plugin WordPress khusus untuk menampilkan jadwal sholat dengan fokus utama pada waktu Maghrib (Buka Puasa) untuk wilayah Banyumas. Plugin ini harus memiliki fitur-fitur berikut:
-
Fungsionalitas Waktu:
-
Tampilkan list jadwal sholat lengkap, termasuk penambahan waktu Imsak.
-
Gunakan API jadwal sholat yang akurat atau perhitungan lokal untuk koordinat wilayah Banyumas.
-
-
Sistem Countdown Dinamis:
-
Buat fitur hitung mundur (countdown) menuju waktu berbuka puasa (Maghrib).
-
Logika Transisi: Setelah hitung mundur Maghrib selesai (mencapai nol), script membuat jeda 5 menit untuk menampilkan informasi Berbuka Puasa, kemudian dilanjutkan otomatis beralih (update) untuk menghitung mundur ke waktu sholat berikutnya secara berurutan.
-
-
Visual & UI:
-
Gunakan skema warna Hitam, Biru, dan Abu untuk bagian-bagiannya.
-
Tambahkan ikon yang relevan pada setiap nama waktu sholat (Imsak, Subuh, Dzuhur, Ashar, Maghrib, Isya).
-
-
Fitur Audio (Adzan):
-
Integrasikan script audio untuk memutar suara adzan secara otomatis tepat ketika hitung mundur Maghrib menyentuh waktu berbuka puasa.
-
-
Output Kode:
-
Berikan struktur file plugin standard (
.php), file CSS untuk styling hitam yang elegan, dan file JavaScript untuk logika countdown serta trigger audio.
-
Catatan:
-
Izin Browser: Browser modern (Chrome/Safari) biasanya memblokir autoplay audio sebelum ada interaksi user (klik) di halaman tersebut. Sehingga harus menambahkan script “Mute/Unmute”.
- API: Untuk wilayah Banyumas, biasanya paling stabil menggunakan API dari Kemenag atau aladhan.com.
- Hasil generate prompt mungkin bisa sedikit berbeda satu sama lain, perlu pengeditan agar sesuai kebutuhan.
File jadi dan siap pakai, berikut script hasil generate prompt (minor edit untuk penyesuaian tulisan):
<?php
/**
* Plugin Name: Jadwal Sholat, Imsak, Berbuka Banyumas
* Description: Menampilkan jadwal sholat harian, waktu Imsak, dan hitung mundur dinamis dengan suara adzan otomatis saat Maghrib khusus wilayah Banyumas.
* Version: 1.7
* Author: Banyumas WordPress
* Author URI: https://banyumaswordpress.com/
* License: GPLv2 or later
* License URI: http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*/
if (!defined('ABSPATH')) exit;
class BanyumasAdzanPlugin {
public function __construct() {
add_shortcode('adzan_banyumas', array($this, 'render_widget'));
add_action('wp_enqueue_scripts', array($this, 'enqueue_assets'));
}
public function enqueue_assets() {
?>
<style>
.adzan-container {
background: #f4f4f4;
border-radius: 12px;
padding: 20px;
text-align: center;
font-family: 'Tahoma', Lato;
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
max-width: 320px;
margin: 10px auto;
position: relative;
}
.adzan-title { font-weight: bold; color: #2c3e50; margin-bottom: 5px; }
.adzan-location { font-size: 0.9em; font-weight: bold; color: #2c3e50; margin-bottom: 15px; }
.next-event-timer {
background: #1a1a1a;
color: white;
padding: 12px;
border-radius: 8px;
font-size: 1.0em;
font-weight: bold;
margin-bottom: 15px;
transition: all 0.5s ease;
min-height: 50px;
display: flex;
align-items: center;
justify-content: center;
line-height: 1.2;
}
.sholat-list {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
font-size: 0.85em;
}
.sholat-item {
width: 48%;
background: white;
margin-bottom: 8px;
padding: 10px 5px;
border-radius: 8px;
border-bottom: 3px solid #22769d;
box-sizing: border-box;
display: flex;
flex-direction: column;
align-items: center;
gap: 5px;
transition: transform 0.2s;
}
.sholat-icon {
width: 20px;
height: 20px;
fill: #7f8c8d;
}
.sholat-name { font-weight: bold; color: #34495e; }
.sholat-time { color: #16a085; font-weight: bold; }
.highlight-next {
border-bottom-color: #1a1a1a;
background: #e0e0e0;
transform: scale(1.05);
}
.highlight-next .sholat-icon { fill: #1a1a1a; }
.highlight-imsak { border-bottom-color: #2980b9; }
.audio-control {
background: #22769d;
border: none;
border-radius: 10px;
padding: 10px 10px;
font-size: 12px;
color: white;
cursor: pointer;
margin-top: 15px;
display: inline-block;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
font-weight: bold;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.audio-control:active {
transform: scale(0.95);
}
.audio-control.active {
background: #27ae60;
box-shadow: 0 2px 8px rgba(39, 174, 96, 0.3);
}
.status-berbuka {
background: #27ae60 !important;
animation: pulse 2s infinite;
}
@keyframes pulse {
0% { opacity: 1; }
50% { opacity: 0.8; }
100% { opacity: 1; }
}
</style>
<?php
}
private function get_icon($name) {
$icons = [
'Imsak' => '<svg class="sholat-icon" viewBox="0 0 24 24"><path d="M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M12,4A8,8 0 0,1 20,12A8,8 0 0,1 12,20A8,8 0 0,1 4,12A8,8 0 0,1 12,4M12,6V12L16,14L16.8,12.7L13.5,10.8V6H12Z" /></svg>',
'Subuh' => '<svg class="sholat-icon" viewBox="0 0 24 24"><path d="M12,6.5L6,15H18L12,6.5M7.34,16.5C8,17.41 9.07,18 10.32,18H13.68C14.93,18 16,17.41 16.66,16.5H7.34M12,2L14.45,4.45H19.55V9.55L22,12L19.55,14.45V19.55H14.45L12,22L9.55,19.55H4.45V14.45L2,12L4.45,9.55V4.45H9.55L12,2Z" /></svg>',
'Dzuhur' => '<svg class="sholat-icon" viewBox="0 0 24 24"><path d="M12,7L14,11H10L12,7M12,2L14.83,4.83L19.17,4.83L19.17,9.17L22,12L19.17,14.83L19.17,19.17L14.83,19.17L12,22L9.17,19.17L4.83,19.17L4.83,14.83L2,12L4.83,9.17L4.83,4.83L9.17,4.83L12,2M12,18A6,6 0 0,0 18,12A6,6 0 0,0 12,6A6,6 0 0,0 6,12A6,6 0 0,0 12,18Z" /></svg>',
'Ashar' => '<svg class="sholat-icon" viewBox="0 0 24 24"><path d="M12,2L4.5,20.29L5.21,21L12,18L18.79,21L19.5,20.29L12,2Z" /></svg>',
'Maghrib' => '<svg class="sholat-icon" viewBox="0 0 24 24"><path d="M13,20H11V18H13V20M13,10H11V5H13V10M13,14H11V12H13V14M20,12C20,16.42 16.42,20 12,20C7.58,20 4,16.42 4,12C4,7.58 7.58,4 12,4C16.42,4 20,7.58 20,12M22,12C22,6.48 17.52,2 12,2C6.48,2 2,6.48 2,12C2,17.52 6.48,22 12,22C17.52,22 22,17.52 22,12Z" /></svg>',
'Isya' => '<svg class="sholat-icon" viewBox="0 0 24 24"><path d="M17.75,4.09L15.22,6.03L16.13,9.09L13.5,7.28L10.87,9.09L11.78,6.03L9.25,4.09L12.44,4.03L13.5,1L14.56,4.03L17.75,4.09M21.25,11L19.61,12.25L20.2,14.23L18.5,13.06L16.8,14.23L17.39,12.25L15.75,11L17.81,10.95L18.5,9L19.19,10.95L21.25,11M18.97,15.95C17.14,15.95 15.46,15.22 14.22,14.05C13.28,15.86 11.39,17.07 9.19,17.07C7.31,17.07 5.66,16.14 4.65,14.73C4.16,16.87 5.16,19.26 7.31,20.34C9.46,21.42 12.06,20.84 13.5,19.1C14.74,20.5 16.65,21.23 18.7,21.14C21.41,21.03 23.63,18.91 23.95,16.21C24,15.8 23.67,15.46 23.26,15.53C21.91,15.8 20.47,15.95 18.97,15.95Z" /></svg>'
];
return isset($icons[$name]) ? $icons[$name] : '';
}
private function get_adzan_data() {
$lat = -7.5133;
$lng = 109.2944;
$cache_key = 'adzan_banyumas_data_v17_' . date('Ymd');
$data = get_transient($cache_key);
if (false === $data) {
$url = "https://api.aladhan.com/v1/timings/" . time() . "?latitude=$lat&longitude=$lng&method=11";
$response = wp_remote_get($url);
if (is_wp_error($response)) return false;
$body = json_decode(wp_remote_retrieve_body($response), true);
if (isset($body['data']['timings'])) {
$data = $body['data']['timings'];
set_transient($cache_key, $data, HOUR_IN_SECONDS * 12);
} else {
return false;
}
}
return $data;
}
public function render_widget() {
$timings = $this->get_adzan_data();
if (!$timings) return "<p>Gagal memuat jadwal sholat.</p>";
ob_start();
?>
<div class="adzan-container">
<div class="adzan-title">Jadwal Sholat & Imsakiyah</div>
<div class="adzan-location">Kab. Banyumas & Sekitarnya</div>
<div class="next-event-timer" id="adzan-next-timer">
Memuat hitung mundur...
</div>
<div class="sholat-list">
<?php
$list = [
'Imsak' => $timings['Imsak'],
'Subuh' => $timings['Fajr'],
'Dzuhur' => $timings['Dhuhr'],
'Ashar' => $timings['Asr'],
'Maghrib' => $timings['Maghrib'],
'Isya' => $timings['Isha']
];
foreach ($list as $name => $time) :
$class = 'sholat-item';
if ($name == 'Imsak') $class .= ' highlight-imsak';
?>
<div class="<?php echo $class; ?>" id="item-<?php echo strtolower($name); ?>">
<?php echo $this->get_icon($name); ?>
<span class="sholat-name"><?php echo $name; ?></span>
<span class="sholat-time"><?php echo $time; ?></span>
</div>
<?php endforeach; ?>
</div>
<audio id="adzan-audio" preload="auto">
<source src="https://www.islamcan.com/audio/adhan/azan1.mp3" type="audio/mpeg">
</audio>
<div class="audio-control" id="enable-audio">Aktifkan Suara Adzan Maghrib</div>
</div>
<script>
(function() {
const timings = <?php echo json_encode($list); ?>;
const audio = document.getElementById('adzan-audio');
const audioBtn = document.getElementById('enable-audio');
let adzanPlayed = false;
audioBtn.addEventListener('click', function() {
audio.play().then(() => {
audio.pause();
audio.currentTime = 0;
audioBtn.innerHTML = "🔊 Suara Adzan Diaktifkan";
audioBtn.style.color = "#ffffff";
}).catch(e => console.log("Audio play blocked"));
});
function updateCountdown() {
const now = new Date();
let nextTime = null;
let nextName = "";
const schedule = Object.keys(timings).map(name => {
const [h, m] = timings[name].split(':');
const target = new Date();
target.setHours(parseInt(h), parseInt(m), 0, 0);
return { name, target };
});
// Cek apakah saat ini dalam masa "Selamat Berbuka" (5 menit setelah Maghrib)
const maghribItem = schedule.find(i => i.name === 'Maghrib');
const fiveMinutesAfterMaghrib = new Date(maghribItem.target.getTime() + 5 * 60000);
const display = document.getElementById('adzan-next-timer');
if (!display) return;
if (now >= maghribItem.target && now < fiveMinutesAfterMaghrib) {
// FASE 1: JEDA SELAMAT BERBUKA (5 Menit)
display.innerHTML = "Selamat Berbuka!<br>Segerakan Menikmati Hidangan";
display.classList.add('status-berbuka');
// Putar audio jika belum
if (!adzanPlayed) {
audio.play();
adzanPlayed = true;
}
// Tetap tunjukkan highlight pada Maghrib di list
updateHighlight('maghrib');
return;
}
// FASE 2: HITUNG MUNDUR NORMAL
display.classList.remove('status-berbuka');
// Cari jadwal berikutnya
schedule.sort((a, b) => a.target - b.target);
for (let item of schedule) {
if (item.target > now) {
nextTime = item.target;
nextName = item.name;
break;
}
}
// Reset flag jika sudah lewat masa berbuka agar bisa bunyi besok
if (now >= fiveMinutesAfterMaghrib) {
adzanPlayed = false;
}
if (!nextTime) {
const [h, m] = timings['Imsak'].split(':');
nextTime = new Date();
nextTime.setDate(nextTime.getDate() + 1);
nextTime.setHours(parseInt(h), parseInt(m), 0, 0);
nextName = "Imsak Besok";
}
const diff = nextTime - now;
const h = Math.floor(diff / 3600000);
const m = Math.floor((diff % 3600000) / 60000);
const s = Math.floor((diff % 60000) / 1000);
let label = (nextName === 'Maghrib') ? 'Buka Puasa' : nextName;
display.innerHTML = `Menuju ${label}: <br> ${h}jam ${m}menit ${s}detik`;
display.style.background = "#1a1a1a";
let searchName = nextName === "Imsak Besok" ? "imsak" : nextName.toLowerCase();
updateHighlight(searchName);
}
function updateHighlight(name) {
document.querySelectorAll('.sholat-item').forEach(el => {
el.classList.remove('highlight-next');
});
const currentId = 'item-' + name;
const currentItem = document.getElementById(currentId);
if (currentItem) {
currentItem.classList.add('highlight-next');
}
}
setInterval(updateCountdown, 1000);
updateCountdown();
})();
</script>
<?php
return ob_get_clean();
}
}
new BanyumasAdzanPlugin();
