batcave / index.html
Moatsim1471's picture
Add 3 files
ec16a1a verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Islamic Prayer Times - Waterford</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap');
body {
font-family: 'Poppins', sans-serif;
background: linear-gradient(135deg, #1e3a8a 0%, #0ea5e9 100%);
min-height: 100vh;
}
.prayer-card {
transition: all 0.3s ease;
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
}
.prayer-card:hover {
transform: translateY(-5px);
}
.active-prayer {
background: linear-gradient(135deg, #10b981 0%, #059669 100%);
color: white;
}
.loader {
border-top-color: #3b82f6;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.mosque-icon {
position: absolute;
bottom: -20px;
right: -20px;
opacity: 0.1;
font-size: 8rem;
transform: rotate(15deg);
}
.waterford-bg {
background-image: url('https://upload.wikimedia.org/wikipedia/commons/thumb/7/7f/Waterford_quays.jpg/1200px-Waterford_quays.jpg');
background-size: cover;
background-position: center;
background-blend-mode: overlay;
background-color: rgba(30, 58, 138, 0.7);
}
</style>
</head>
<body class="text-gray-100">
<div class="container mx-auto px-4 py-8 max-w-4xl">
<!-- Header -->
<header class="text-center mb-8">
<div class="flex justify-center items-center mb-4">
<i class="fas fa-mosque text-4xl mr-3 text-yellow-300"></i>
<h1 class="text-3xl md:text-4xl font-bold bg-gradient-to-r from-yellow-300 to-yellow-500 bg-clip-text text-transparent">
Prayer Times in Waterford
</h1>
</div>
<p class="text-gray-200">Accurate prayer times for Waterford, Ireland</p>
</header>
<!-- Main Content -->
<main>
<!-- Location and Date Info -->
<div class="waterford-bg bg-white/10 backdrop-blur-sm rounded-xl p-6 mb-8 relative overflow-hidden">
<div class="flex flex-col md:flex-row justify-between items-start md:items-center mb-4">
<div>
<h2 class="text-xl font-semibold mb-1">Waterford, Ireland</h2>
<p class="text-gray-300" id="hijri-date"></p>
</div>
<div class="text-right mt-2 md:mt-0">
<p class="text-2xl font-bold" id="gregorian-date"></p>
<p class="text-gray-300" id="gregorian-day"></p>
</div>
</div>
<i class="fas fa-mosque mosque-icon"></i>
</div>
<!-- Prayer Times Cards -->
<div id="prayer-times-container" class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 mb-8">
<!-- Loading state -->
<div class="col-span-full flex justify-center py-12">
<div class="loader h-12 w-12 rounded-full border-4 border-t-4 border-gray-200"></div>
</div>
</div>
<!-- Calculation Method Selector -->
<div class="bg-white/10 backdrop-blur-sm rounded-xl p-6 mb-8">
<h3 class="text-lg font-semibold mb-4">Calculation Method</h3>
<div class="grid grid-cols-2 md:grid-cols-4 gap-3">
<button onclick="updateMethod('MWL')" class="method-btn bg-blue-600 hover:bg-blue-700 px-4 py-2 rounded-lg transition">Muslim World League</button>
<button onclick="updateMethod('ISNA')" class="method-btn bg-blue-600 hover:bg-blue-700 px-4 py-2 rounded-lg transition">Islamic Society of North America</button>
<button onclick="updateMethod('Egypt')" class="method-btn bg-blue-600 hover:bg-blue-700 px-4 py-2 rounded-lg transition">Egyptian General Authority</button>
<button onclick="updateMethod('Makkah')" class="method-btn bg-blue-600 hover:bg-blue-700 px-4 py-2 rounded-lg transition">Umm al-Qura, Makkah</button>
</div>
</div>
<!-- Next Prayer Notification -->
<div id="next-prayer-notification" class="hidden bg-green-600/90 backdrop-blur-sm rounded-xl p-4 mb-8 flex items-center">
<i class="fas fa-bell text-2xl mr-4"></i>
<div>
<p class="font-semibold">Next Prayer: <span id="next-prayer-name"></span> at <span id="next-prayer-time"></span></p>
<p class="text-sm opacity-90" id="time-remaining"></p>
</div>
</div>
<!-- Time Zone Info -->
<div class="bg-white/10 backdrop-blur-sm rounded-xl p-6 text-center">
<p><i class="fas fa-clock mr-2"></i> All times are in <strong>Irish Standard Time (IST)</strong> or <strong>Greenwich Mean Time (GMT)</strong> depending on season</p>
</div>
</main>
<!-- Footer -->
<footer class="text-center text-gray-300 text-sm mt-12">
<p>Made with <i class="fas fa-heart text-red-400"></i> for the Muslim community in Waterford</p>
<p class="mt-1">Data provided by <a href="https://aladhan.com" class="text-blue-300 hover:underline" target="_blank">AlAdhan API</a></p>
</footer>
</div>
<script>
// Global variables
const waterfordLocation = {
lat: 52.2583, // Waterford latitude
long: -7.1119, // Waterford longitude
timezone: "Europe/Dublin" // Waterford timezone
};
let prayerTimes = {};
let currentMethod = 'MWL';
let nextPrayerTimer = null;
// DOM Elements
const hijriDateElement = document.getElementById('hijri-date');
const gregorianDateElement = document.getElementById('gregorian-date');
const gregorianDayElement = document.getElementById('gregorian-day');
const prayerTimesContainer = document.getElementById('prayer-times-container');
const nextPrayerNotification = document.getElementById('next-prayer-notification');
const nextPrayerNameElement = document.getElementById('next-prayer-name');
const nextPrayerTimeElement = document.getElementById('next-prayer-time');
const timeRemainingElement = document.getElementById('time-remaining');
// Prayer names with icons
const prayerNames = {
Fajr: { name: 'Fajr', icon: 'sun', color: 'bg-blue-600' },
Sunrise: { name: 'Sunrise', icon: 'sun', color: 'bg-yellow-500' },
Dhuhr: { name: 'Dhuhr', icon: 'sun', color: 'bg-orange-500' },
Asr: { name: 'Asr', icon: 'sun', color: 'bg-red-500' },
Maghrib: { name: 'Maghrib', icon: 'moon', color: 'bg-purple-600' },
Isha: { name: 'Isha', icon: 'moon', color: 'bg-indigo-700' }
};
// Initialize the app
document.addEventListener('DOMContentLoaded', () => {
updateDates();
fetchPrayerTimes();
// Update prayer times every hour
setInterval(fetchPrayerTimes, 3600000);
});
// Fetch prayer times from API for Waterford
async function fetchPrayerTimes() {
try {
const today = new Date();
const dateStr = `${today.getDate()}-${today.getMonth() + 1}-${today.getFullYear()}`;
// Include timezone parameter for accurate time conversion
const response = await fetch(
`https://api.aladhan.com/v1/timings/${dateStr}?latitude=${waterfordLocation.lat}&longitude=${waterfordLocation.long}&method=${currentMethod}&timezonestring=${waterfordLocation.timezone}`
);
const data = await response.json();
if (data.code === 200) {
prayerTimes = data.data.timings;
displayPrayerTimes();
updateNextPrayerNotification();
} else {
throw new Error(data.data);
}
} catch (error) {
console.error("Error fetching prayer times:", error);
prayerTimesContainer.innerHTML = `
<div class="col-span-full bg-red-500/20 p-4 rounded-lg text-center">
<i class="fas fa-exclamation-triangle mr-2"></i>
Failed to load prayer times. Please try again later.
</div>
`;
}
}
// Display prayer times in cards
function displayPrayerTimes() {
let html = '';
for (const [key, value] of Object.entries(prayerTimes)) {
if (prayerNames[key]) {
const prayer = prayerNames[key];
const time = formatTime(value);
html += `
<div class="prayer-card ${prayer.color} rounded-xl p-5 text-white relative overflow-hidden">
<div class="flex items-center mb-3">
<i class="fas fa-${prayer.icon} text-xl mr-3"></i>
<h3 class="text-xl font-semibold">${prayer.name}</h3>
</div>
<p class="text-3xl font-bold mb-2">${time}</p>
<p class="text-sm opacity-90">${getPrayerDescription(key)}</p>
<i class="fas fa-${prayer.icon} mosque-icon"></i>
</div>
`;
}
}
prayerTimesContainer.innerHTML = html;
highlightCurrentPrayer();
}
// Format time to 12-hour format with AM/PM
function formatTime(timeStr) {
const [hours, minutes] = timeStr.split(':').map(Number);
const period = hours >= 12 ? 'PM' : 'AM';
const displayHours = hours % 12 || 12;
return `${displayHours}:${minutes.toString().padStart(2, '0')} ${period}`;
}
// Get prayer description
function getPrayerDescription(prayerName) {
const descriptions = {
Fajr: 'The dawn prayer before sunrise',
Sunrise: 'The time when the sun rises',
Dhuhr: 'The midday prayer after the sun passes its zenith',
Asr: 'The afternoon prayer',
Maghrib: 'The prayer just after sunset',
Isha: 'The night prayer'
};
return descriptions[prayerName] || '';
}
// Highlight current prayer
function highlightCurrentPrayer() {
const now = new Date();
const currentTime = now.getHours() * 60 + now.getMinutes();
// Convert prayer times to minutes since midnight for comparison
const prayerTimesInMinutes = {};
for (const [key, value] of Object.entries(prayerTimes)) {
if (prayerNames[key]) {
const [hours, minutes] = value.split(':').map(Number);
prayerTimesInMinutes[key] = hours * 60 + minutes;
}
}
// Determine which prayer is currently active
let activePrayer = null;
const prayerOrder = ['Fajr', 'Sunrise', 'Dhuhr', 'Asr', 'Maghrib', 'Isha'];
for (let i = 0; i < prayerOrder.length; i++) {
const prayer = prayerOrder[i];
if (currentTime < prayerTimesInMinutes[prayer]) {
if (i > 0) {
activePrayer = prayerOrder[i - 1];
}
break;
}
}
// If no prayer found (after Isha), then it's before Fajr next day
if (!activePrayer && currentTime > prayerTimesInMinutes['Isha']) {
activePrayer = 'Isha';
}
// Highlight the active prayer card
const prayerCards = document.querySelectorAll('.prayer-card');
prayerCards.forEach(card => {
card.classList.remove('active-prayer');
const prayerName = card.querySelector('h3').textContent;
if (prayerName === activePrayer) {
card.classList.add('active-prayer');
}
});
}
// Update next prayer notification
function updateNextPrayerNotification() {
clearTimeout(nextPrayerTimer);
const now = new Date();
const currentTime = now.getHours() * 60 + now.getMinutes();
// Convert prayer times to minutes since midnight for comparison
const prayerTimesInMinutes = {};
for (const [key, value] of Object.entries(prayerTimes)) {
if (prayerNames[key]) {
const [hours, minutes] = value.split(':').map(Number);
prayerTimesInMinutes[key] = hours * 60 + minutes;
}
}
// Find the next prayer
const prayerOrder = ['Fajr', 'Sunrise', 'Dhuhr', 'Asr', 'Maghrib', 'Isha'];
let nextPrayer = null;
let nextPrayerTime = null;
for (const prayer of prayerOrder) {
if (currentTime < prayerTimesInMinutes[prayer]) {
nextPrayer = prayer;
nextPrayerTime = prayerTimesInMinutes[prayer];
break;
}
}
// If no next prayer found (after Isha), then next is Fajr tomorrow
if (!nextPrayer) {
nextPrayer = 'Fajr';
nextPrayerTime = prayerTimesInMinutes['Fajr'] + 1440; // Add 24 hours in minutes
}
// Update notification
if (nextPrayer) {
nextPrayerNotification.classList.remove('hidden');
nextPrayerNameElement.textContent = nextPrayer;
nextPrayerTimeElement.textContent = formatTime(prayerTimes[nextPrayer]);
// Calculate time remaining
const timeRemaining = nextPrayerTime - currentTime;
updateTimeRemainingDisplay(timeRemaining);
// Update every minute
nextPrayerTimer = setInterval(() => {
const newNow = new Date();
const newCurrentTime = newNow.getHours() * 60 + newNow.getMinutes();
const newTimeRemaining = nextPrayerTime - newCurrentTime;
if (newTimeRemaining <= 0) {
// Prayer time reached, refresh data
fetchPrayerTimes();
clearTimeout(nextPrayerTimer);
} else {
updateTimeRemainingDisplay(newTimeRemaining);
}
}, 60000); // Update every minute
}
}
// Update time remaining display
function updateTimeRemainingDisplay(minutes) {
const hours = Math.floor(minutes / 60);
const mins = minutes % 60;
if (hours > 0) {
timeRemainingElement.textContent = `${hours} hour${hours !== 1 ? 's' : ''} and ${mins} minute${mins !== 1 ? 's' : ''} remaining`;
} else {
timeRemainingElement.textContent = `${mins} minute${mins !== 1 ? 's' : ''} remaining`;
}
}
// Update calculation method
function updateMethod(method) {
currentMethod = method;
fetchPrayerTimes();
// Update active method button
const methodButtons = document.querySelectorAll('.method-btn');
methodButtons.forEach(btn => {
btn.classList.remove('bg-blue-700');
btn.classList.add('bg-blue-600');
});
event.target.classList.remove('bg-blue-600');
event.target.classList.add('bg-blue-700');
}
// Update date displays
function updateDates() {
const today = new Date();
// Format for Ireland locale
const options = {
timeZone: 'Europe/Dublin',
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric'
};
// Gregorian date
gregorianDateElement.textContent = today.toLocaleDateString('en-IE', {
timeZone: 'Europe/Dublin',
month: 'long',
day: 'numeric'
});
gregorianDayElement.textContent = today.toLocaleDateString('en-IE', {
timeZone: 'Europe/Dublin',
weekday: 'long',
year: 'numeric'
});
// Hijri date (approximation)
fetchHijriDate(today);
}
// Fetch Hijri date from API
async function fetchHijriDate(gregorianDate) {
try {
const dateStr = `${gregorianDate.getDate()}-${gregorianDate.getMonth() + 1}-${gregorianDate.getFullYear()}`;
const response = await fetch(`https://api.aladhan.com/v1/gToH?date=${dateStr}`);
const data = await response.json();
if (data.code === 200) {
const hijri = data.data.hijri;
hijriDateElement.textContent = `${hijri.day} ${hijri.month.en} ${hijri.year} AH`;
}
} catch (error) {
console.error("Error fetching Hijri date:", error);
// Fallback to approximate calculation if API fails
const approxHijriYear = Math.floor((gregorianDate.getFullYear() - 622) * (33 / 32));
hijriDateElement.textContent = `Approx. ${approxHijriYear} AH`;
}
}
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Moatsim1471/batcave" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>