Files
umra-app/components/PrayerTimeCard.tsx

178 lines
5.4 KiB
TypeScript

import React, { useState, useEffect } from 'react';
import { View, Text, StyleSheet, ImageBackground, Pressable } from 'react-native';
import Colors from '@/constants/Colors';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
import prayerTimeCalculator, { cities } from '@/utils/prayerTimeCalculator';
type Prayer = {
name: string;
time: string;
icon: string;
};
const prayerIconMapping: { [key: string]: string } = {
fajr: 'weather-sunset-up',
sunrise: 'weather-sunny',
dhuhr: 'weather-partly-cloudy',
asr: 'weather-cloudy',
maghrib: 'weather-sunset-down',
isha: 'weather-night',
};
export default function PrayerTimeCard() {
const [prayerTimes, setPrayerTimes] = useState<Prayer[]>([]);
const [nextPrayer, setNextPrayer] = useState<{ name: string; time: string } | null>(null);
const [remainingTime, setRemainingTime] = useState('');
const [selectedCity, setSelectedCity] = useState<'Makkah' | 'Medina' | 'Jeddah'>('Makkah');
useEffect(() => {
const city = cities[selectedCity];
const times = prayerTimeCalculator.getTimes(new Date(), city.coords, city.timezone, 0, '24h');
const prayers: Prayer[] = Object.keys(prayerIconMapping).map(key => ({
name: key.charAt(0).toUpperCase() + key.slice(1),
time: times[key] || '-----',
icon: prayerIconMapping[key],
}));
setPrayerTimes(prayers);
// Find next prayer and calculate remaining time
const now = new Date();
let nextPrayerInfo = null;
for (const prayer of prayers) {
const [hours, minutes] = prayer.time.split(':').map(Number);
const prayerDate = new Date(now.getFullYear(), now.getMonth(), now.getDate(), hours, minutes);
if (prayerDate > now) {
nextPrayerInfo = { name: prayer.name, time: prayer.time };
break;
}
}
if (!nextPrayerInfo && prayers.length > 0) {
// If all prayers for today have passed, next prayer is Fajr of tomorrow
nextPrayerInfo = { name: prayers[0].name, time: prayers[0].time };
}
setNextPrayer(nextPrayerInfo);
}, [selectedCity]);
useEffect(() => {
if (!nextPrayer) return;
const interval = setInterval(() => {
const now = new Date();
const [hours, minutes] = nextPrayer.time.split(':').map(Number);
let prayerDate = new Date(now.getFullYear(), now.getMonth(), now.getDate(), hours, minutes);
if (prayerDate < now) {
prayerDate.setDate(prayerDate.getDate() + 1);
}
const diff = prayerDate.getTime() - now.getTime();
const h = Math.floor(diff / (1000 * 60 * 60));
const m = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
const s = Math.floor((diff % (1000 * 60)) / 1000);
setRemainingTime(`${h.toString().padStart(2, '0')}:${m.toString().padStart(2, '0')}:${s.toString().padStart(2, '0')}`);
}, 1000);
return () => clearInterval(interval);
}, [nextPrayer]);
return (
<ImageBackground
source={{ uri: 'https://i.imgur.com/your-image.jpg' }} // Replace with a real image URL
style={styles.container}
imageStyle={{ borderRadius: 15 }}
>
<View style={styles.overlay}>
<View style={styles.header}>
<View style={styles.citySelector}>
{Object.keys(cities).map(city => (
<Pressable key={city} onPress={() => setSelectedCity(city as any)} style={[styles.cityButton, selectedCity === city && styles.activeCity]}>
<Text style={styles.cityButtonText}>{city}</Text>
</Pressable>
))}
</View>
</View>
<Text style={styles.remainingTimeLabel}>
{nextPrayer ? `Left on ${nextPrayer.name} prayer` : 'Prayer Times'}
</Text>
<Text style={styles.remainingTime}>{remainingTime}</Text>
<View style={styles.prayerTimesContainer}>
{prayerTimes.map((prayer, index) => (
<View key={index} style={styles.prayerTimeItem}>
<MaterialCommunityIcons name={prayer.icon} size={24} color={Colors.dark.text} />
<Text style={styles.prayerName}>{prayer.name}</Text>
<Text style={styles.prayerTime}>{prayer.time}</Text>
</View>
))}
</View>
</View>
</ImageBackground>
);
}
const styles = StyleSheet.create({
container: {
marginVertical: 20,
borderRadius: 15,
},
overlay: {
backgroundColor: 'rgba(0,0,0,0.5)',
borderRadius: 15,
padding: 20,
},
header: {
flexDirection: 'row',
alignItems: 'center',
marginBottom: 20,
justifyContent: 'center',
},
citySelector: {
flexDirection: 'row',
backgroundColor: Colors.dark.secondary,
borderRadius: 10,
},
cityButton: {
paddingVertical: 8,
paddingHorizontal: 15,
borderRadius: 10,
},
activeCity: {
backgroundColor: Colors.dark.tint,
},
cityButtonText: {
color: Colors.dark.text,
fontWeight: 'bold',
},
remainingTimeLabel: {
color: Colors.dark.textSecondary,
textAlign: 'center',
},
remainingTime: {
color: Colors.dark.text,
fontSize: 48,
fontWeight: 'bold',
textAlign: 'center',
marginVertical: 10,
},
prayerTimesContainer: {
flexDirection: 'row',
justifyContent: 'space-around',
marginTop: 20,
},
prayerTimeItem: {
alignItems: 'center',
},
prayerName: {
color: Colors.dark.text,
marginTop: 5,
},
prayerTime: {
color: Colors.dark.textSecondary,
fontSize: 12,
},
});