Files
umra-app/app/(tabs)/index.tsx
Mekan1206 e542371268 Add expo-asset dependency and update layout for safe area insets
- Included expo-asset in app.json and package.json for asset management.
- Refactored layout components in HomeScreen, TabIndex, Programs, and ServicesScreen to utilize safe area insets for better UI on different devices.
- Updated StatusBar style in RootLayoutNav for improved visibility.
2025-09-17 19:14:09 +05:00

182 lines
5.0 KiB
TypeScript

import { Pressable, ScrollView, StyleSheet, Text, View } from 'react-native';
import { useCallback, useEffect, useState } from 'react';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { getPrayerTimes, cities } from '../../utils/prayerTimeCalculator';
import i18n from '../../i18n';
import { useColorScheme } from 'react-native';
import Colors from '../../constants/Colors';
type Prayer = {
name: string;
time: string;
};
type City = keyof typeof cities;
export default function TabIndex() {
const colorScheme = useColorScheme();
const theme = Colors[colorScheme ?? 'light'];
const [selectedCity, setSelectedCity] = useState<City>('Makkah');
const [prayerTimes, setPrayerTimes] = useState<Prayer[]>([]);
const [nextPrayerName, setNextPrayerName] = useState<string | null>(null);
const insets = useSafeAreaInsets();
const prayerNameMapping: { [key: string]: string } = {
fajr: i18n.t('fajr'),
dhuhr: i18n.t('dhuhr'),
asr: i18n.t('asr'),
maghrib: i18n.t('maghrib'),
isha: i18n.t('isha'),
};
const updatePrayerTimes = useCallback(() => {
const times = getPrayerTimes(selectedCity);
const prayers: Prayer[] = Object.keys(prayerNameMapping).map((key) => ({
name: prayerNameMapping[key],
time: times[key] || '-----',
}));
setPrayerTimes(prayers);
const now = new Date();
let nextPrayer: Prayer | null = null;
for (const prayer of prayers) {
if (prayer.time === '-----') continue;
const [hours, minutes] = prayer.time.split(':').map(Number);
const prayerDate = new Date(now.getFullYear(), now.getMonth(), now.getDate(), hours, minutes);
if (prayerDate > now) {
nextPrayer = prayer;
break;
}
}
if (!nextPrayer && prayers.length > 0) {
const firstPrayer = prayers.find((p) => p.time !== '-----');
if (firstPrayer) {
nextPrayer = firstPrayer;
}
}
setNextPrayerName(nextPrayer ? nextPrayer.name : null);
}, [selectedCity]);
useEffect(() => {
updatePrayerTimes();
const interval = setInterval(updatePrayerTimes, 60000); // Update every minute
return () => clearInterval(interval);
}, [updatePrayerTimes]);
const renderPrayerTime = (prayer: Prayer) => {
const isNextPrayer = prayer.name === nextPrayerName;
return (
<View
key={prayer.name}
style={[styles.prayerRow, { backgroundColor: theme.secondary }, isNextPrayer && [styles.nextPrayerRow, { backgroundColor: theme.tint }]]}>
<View>
<Text style={[styles.prayerName, { color: theme.text }, isNextPrayer && styles.nextPrayerText]}>
{prayer.name}
</Text>
</View>
<Text style={[styles.prayerTime, { color: theme.text }, isNextPrayer && styles.nextPrayerTimeText]}>
{new Date(`1970-01-01T${prayer.time}:00`).toLocaleTimeString('en-US', {
hour: 'numeric',
minute: 'numeric',
hour12: false,
})}
</Text>
</View>
);
};
return (
<View style={[styles.container, { backgroundColor: theme.background, paddingTop: insets.top }]}>
<View style={[styles.citySelector, { backgroundColor: theme.background }]}>
{(Object.keys(cities) as City[]).map((city) => (
<Pressable
key={city}
onPress={() => setSelectedCity(city)}
style={[styles.cityButton, { backgroundColor: theme.secondary }, selectedCity === city && [styles.activeCityButton, { backgroundColor: theme.tint }]]}>
<Text
style={[
styles.cityButtonText,
{ color: theme.text },
selectedCity === city && styles.activeCityButtonText,
]}>
{i18n.t(city)}
</Text>
</Pressable>
))}
</View>
<ScrollView contentContainerStyle={styles.listContainer}>
{prayerTimes.map(renderPrayerTime)}
</ScrollView>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
citySelector: {
flexDirection: 'row',
justifyContent: 'center',
paddingVertical: 20,
paddingHorizontal: 10,
},
cityButton: {
paddingVertical: 10,
paddingHorizontal: 25,
borderRadius: 20,
marginHorizontal: 5,
},
activeCityButton: {},
cityButtonText: {
fontSize: 18,
fontWeight: '500',
},
activeCityButtonText: {
color: '#fff',
},
listContainer: {
paddingHorizontal: 20,
},
prayerRow: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
paddingVertical: 25,
paddingHorizontal: 20,
borderRadius: 15,
marginBottom: 10,
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 1,
},
shadowOpacity: 0.1,
shadowRadius: 3,
elevation: 2,
},
nextPrayerRow: {},
prayerName: {
fontSize: 28,
fontWeight: '600',
},
inCityText: {
fontSize: 18,
},
prayerTime: {
fontSize: 28,
fontWeight: 'bold',
},
nextPrayerText: {
color: '#fff',
},
nextPrayerTimeText: {
color: '#fff',
fontSize: 32,
},
});