Add stale data handling in Programs component

- Enhanced the getPrograms function to return a stale flag indicating if cached data is being used.
- Implemented a warning message in the Programs component to inform users when stale data is displayed.
- Updated styles for the warning message to improve visibility.
This commit is contained in:
Mekan1206
2025-09-20 13:23:55 +05:00
parent 3ee7ec87be
commit a1871510a8
2 changed files with 34 additions and 5 deletions

View File

@@ -27,12 +27,14 @@ export default function Programs() {
const [activities, setActivities] = useState<ProgramActivities>({}); const [activities, setActivities] = useState<ProgramActivities>({});
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null); const [error, setError] = useState<string | null>(null);
const [isStale, setIsStale] = useState(false);
useEffect(() => { useEffect(() => {
const fetchPrograms = async () => { const fetchPrograms = async () => {
try { try {
const data = await getPrograms(); const { activities: data, isStale } = await getPrograms();
setActivities(data); setActivities(data);
setIsStale(isStale);
if (Object.keys(data).length > 0) { if (Object.keys(data).length > 0) {
const today = new Date(); const today = new Date();
const day = String(today.getDate()).padStart(2, '0'); const day = String(today.getDate()).padStart(2, '0');
@@ -80,6 +82,12 @@ export default function Programs() {
<Text style={[styles.title, { color: Colors[colorScheme].text }]}>Umrah Pilgrimage</Text> <Text style={[styles.title, { color: Colors[colorScheme].text }]}>Umrah Pilgrimage</Text>
</View> </View>
{isStale && (
<View style={styles.warningContainer}>
<Text style={styles.warningText}>Failed to fetch latest data. Showing cached activities.</Text>
</View>
)}
<View> <View>
<ScrollView horizontal showsHorizontalScrollIndicator={false} style={styles.daysScroll}> <ScrollView horizontal showsHorizontalScrollIndicator={false} style={styles.daysScroll}>
{dayKeys.map((day) => ( {dayKeys.map((day) => (
@@ -136,6 +144,15 @@ const styles = StyleSheet.create({
paddingVertical: 10, paddingVertical: 10,
paddingHorizontal: 20, paddingHorizontal: 20,
}, },
warningContainer: {
backgroundColor: 'orange',
padding: 10,
alignItems: 'center',
},
warningText: {
color: 'white',
textAlign: 'center',
},
title: { title: {
fontSize: 24, fontSize: 24,
fontWeight: 'bold', fontWeight: 'bold',

View File

@@ -1,5 +1,6 @@
import { FontAwesome, FontAwesome5, MaterialCommunityIcons } from '@expo/vector-icons'; import { FontAwesome, FontAwesome5, MaterialCommunityIcons } from '@expo/vector-icons';
import AsyncStorage from '@react-native-async-storage/async-storage';
export type ProgramActivity = { export type ProgramActivity = {
time: string; time: string;
@@ -14,18 +15,29 @@ export type ProgramActivities = {
[date: string]: ProgramActivity[]; [date: string]: ProgramActivity[];
}; };
const PROGRAMS_URL = 'http://kepilhyzmat.com/assets/programs.json'; export type ProgramData = {
activities: ProgramActivities;
isStale: boolean;
};
export const getPrograms = async (): Promise<ProgramActivities> => { const PROGRAMS_URL = 'http://kepilhyzmat.com/assets/programs.json';
const PROGRAMS_CACHE_KEY = 'program_activities_cache';
export const getPrograms = async (): Promise<ProgramData> => {
try { try {
const response = await fetch(PROGRAMS_URL); const response = await fetch(PROGRAMS_URL);
if (!response.ok) { if (!response.ok) {
throw new Error(`Request failed with status ${response.status}`); throw new Error(`Request failed with status ${response.status}`);
} }
const data: ProgramActivities = await response.json(); const data: ProgramActivities = await response.json();
return data; await AsyncStorage.setItem(PROGRAMS_CACHE_KEY, JSON.stringify(data));
return { activities: data, isStale: false };
} catch (error) { } catch (error) {
console.error('Failed to fetch programs:', error); console.error('Failed to fetch programs:', error);
throw error; const cachedData = await AsyncStorage.getItem(PROGRAMS_CACHE_KEY);
if (cachedData) {
return { activities: JSON.parse(cachedData), isStale: true };
}
throw new Error('Failed to fetch programs and no cache available.');
} }
}; };