From 803bbfc30f786b46fb26342ec5ca771f49a4457b Mon Sep 17 00:00:00 2001 From: Mekan1206 Date: Sat, 20 Sep 2025 12:06:56 +0500 Subject: [PATCH] Sync cities between prayers --- app/(tabs)/_layout.tsx | 79 ++++++++++++++++++----------------- app/(tabs)/index.tsx | 30 ++----------- components/PrayerTimeCard.tsx | 4 +- context/CityContext.tsx | 54 ++++++++++++++++++++++++ 4 files changed, 100 insertions(+), 67 deletions(-) create mode 100644 context/CityContext.tsx diff --git a/app/(tabs)/_layout.tsx b/app/(tabs)/_layout.tsx index 663aed0..452acd6 100644 --- a/app/(tabs)/_layout.tsx +++ b/app/(tabs)/_layout.tsx @@ -4,6 +4,7 @@ import { useColorScheme, View } from 'react-native'; import Colors from '@/constants/Colors'; import i18n from '@/i18n'; +import { CityProvider } from '../../context/CityContext'; /** * You can explore the built-in icon families and icons on the web at https://icons.expo.fyi/ @@ -19,43 +20,45 @@ export default function TabLayout() { const colorScheme = 'dark'; // Force dark mode return ( - - , - }} - /> - , - }} - /> - , - }} - /> - , - }} - /> - + + + , + }} + /> + , + }} + /> + , + }} + /> + , + }} + /> + + ); } diff --git a/app/(tabs)/index.tsx b/app/(tabs)/index.tsx index 87ef300..bfb4993 100644 --- a/app/(tabs)/index.tsx +++ b/app/(tabs)/index.tsx @@ -1,11 +1,11 @@ import { Pressable, ScrollView, StyleSheet, Text, View } from 'react-native'; import { useCallback, useEffect, useState } from 'react'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; -import AsyncStorage from '@react-native-async-storage/async-storage'; import { getPrayerTimes, cities } from '../../utils/prayerTimeCalculator'; import i18n from '../../i18n'; import Colors from '../../constants/Colors'; +import { useCity } from '../../context/CityContext'; type Prayer = { name: string; @@ -17,26 +17,11 @@ type City = keyof typeof cities; export default function TabIndex() { const colorScheme = 'dark'; const theme = Colors[colorScheme ?? 'light']; - const [selectedCity, setSelectedCity] = useState('Makkah'); + const { selectedCity, setSelectedCity } = useCity(); const [prayerTimes, setPrayerTimes] = useState([]); const [nextPrayerName, setNextPrayerName] = useState(null); const insets = useSafeAreaInsets(); - useEffect(() => { - const loadSelectedCity = async () => { - try { - const city = (await AsyncStorage.getItem('selectedCity')) as City; - if (city) { - setSelectedCity(city); - } - } catch (error) { - console.error('Failed to load selected city:', error); - } - }; - - loadSelectedCity(); - }, []); - const prayerNameMapping: { [key: string]: string } = { fajr: i18n.t('fajr'), dhuhr: i18n.t('dhuhr'), @@ -82,15 +67,6 @@ export default function TabIndex() { return () => clearInterval(interval); }, [updatePrayerTimes]); - const handleCityChange = async (city: City) => { - setSelectedCity(city); - try { - await AsyncStorage.setItem('selectedCity', city); - } catch (error) { - console.error('Failed to save selected city:', error); - } - }; - const renderPrayerTime = (prayer: Prayer) => { const isNextPrayer = prayer.name === nextPrayerName; return ( @@ -119,7 +95,7 @@ export default function TabIndex() { {(Object.keys(cities) as City[]).map((city) => ( handleCityChange(city)} + onPress={() => setSelectedCity(city)} style={[styles.cityButton, { backgroundColor: theme.secondary }, selectedCity === city && [styles.activeCityButton, { backgroundColor: theme.tint }]]}> ([]); const [nextPrayer, setNextPrayer] = useState<{ name: string; time: string } | null>(null); const [remainingTime, setRemainingTime] = useState(''); - const [selectedCity, setSelectedCity] = useState('Makkah'); + const { selectedCity, setSelectedCity } = useCity(); useEffect(() => { const times = getPrayerTimes(selectedCity); diff --git a/context/CityContext.tsx b/context/CityContext.tsx new file mode 100644 index 0000000..32b3433 --- /dev/null +++ b/context/CityContext.tsx @@ -0,0 +1,54 @@ +import React, { createContext, useState, useEffect, useContext, ReactNode } from 'react'; +import AsyncStorage from '@react-native-async-storage/async-storage'; +import { cities } from '../utils/prayerTimeCalculator'; + +type City = keyof typeof cities; + +interface CityContextType { + selectedCity: City; + setSelectedCity: (city: City) => void; +} + +const CityContext = createContext(undefined); + +export const CityProvider = ({ children }: { children: ReactNode }) => { + const [selectedCity, setSelectedCityState] = useState('Makkah'); + + useEffect(() => { + const loadSelectedCity = async () => { + try { + const city = await AsyncStorage.getItem('selectedCity') as City; + if (city) { + setSelectedCityState(city); + } + } catch (error) { + console.error('Failed to load selected city:', error); + } + }; + + loadSelectedCity(); + }, []); + + const handleSetSelectedCity = async (city: City) => { + setSelectedCityState(city); + try { + await AsyncStorage.setItem('selectedCity', city); + } catch (error) { + console.error('Failed to save selected city:', error); + } + }; + + return ( + + {children} + + ); +}; + +export const useCity = () => { + const context = useContext(CityContext); + if (context === undefined) { + throw new Error('useCity must be used within a CityProvider'); + } + return context; +};