196 lines
5.9 KiB
TypeScript
196 lines
5.9 KiB
TypeScript
import React, { useState, useEffect } from 'react';
|
|
import { StyleSheet, ActivityIndicator, TouchableOpacity, View } from 'react-native';
|
|
import { ThemedText } from '@/components/ThemedText';
|
|
import { ThemedView } from '@/components/ThemedView';
|
|
import { SafeAreaView } from 'react-native-safe-area-context'; // Import for safe area handling
|
|
import { LinearGradient } from 'expo-linear-gradient';
|
|
import axios from 'axios';
|
|
import ChangeDateDrawer from '@/components/ChangeDateDrawer'; // Date drawer component
|
|
|
|
const API_KEY = process.env.EXPO_PUBLIC_API_KEY;
|
|
const BASE_URL = process.env.EXPO_PUBLIC_BASE_URL;
|
|
|
|
// Separate API call function
|
|
const fetchCountdownDate = async () => {
|
|
try {
|
|
const response = await axios.get(`${BASE_URL}/getCountdown`, {
|
|
params: { apiKey: API_KEY }
|
|
});
|
|
if (response.data && response.data[0] && response.data[0].countdown) {
|
|
return new Date(response.data[0].countdown);
|
|
} else {
|
|
console.error('Unexpected API response format:', response.data);
|
|
return null;
|
|
}
|
|
} catch (error) {
|
|
console.error('API call error:', error);
|
|
return null;
|
|
}
|
|
};
|
|
|
|
export default function TabTwoScreen() {
|
|
const [countdown, setCountdown] = useState({
|
|
days: 0,
|
|
hours: 0,
|
|
minutes: 0,
|
|
seconds: 0,
|
|
});
|
|
const [targetDate, setTargetDate] = useState<Date | null>(null);
|
|
const [isLoading, setIsLoading] = useState(true);
|
|
const [isDateDrawerVisible, setIsDateDrawerVisible] = useState(false);
|
|
|
|
useEffect(() => {
|
|
const loadCountdownDate = async () => {
|
|
setIsLoading(true);
|
|
const date = await fetchCountdownDate();
|
|
if (date) {
|
|
setTargetDate(date);
|
|
}
|
|
setIsLoading(false);
|
|
};
|
|
|
|
loadCountdownDate();
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
if (targetDate === null) return;
|
|
|
|
const interval = setInterval(() => {
|
|
const now = new Date();
|
|
const distance = targetDate.getTime() - now.getTime();
|
|
|
|
const days = Math.floor(distance / (1000 * 60 * 60 * 24));
|
|
const hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
|
|
const minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
|
|
const seconds = Math.floor((distance % (1000 * 60)) / 1000);
|
|
|
|
setCountdown({ days, hours, minutes, seconds });
|
|
|
|
if (distance < 0) {
|
|
clearInterval(interval);
|
|
setCountdown({ days: 0, hours: 0, minutes: 0, seconds: 0 });
|
|
}
|
|
}, 1000);
|
|
|
|
return () => clearInterval(interval);
|
|
}, [targetDate]);
|
|
|
|
const handleDateChange = (newDate: Date) => {
|
|
setTargetDate(newDate);
|
|
};
|
|
|
|
if (isLoading) {
|
|
return (
|
|
<ThemedView style={styles.container}>
|
|
<ActivityIndicator size="large" color="#0000ff" />
|
|
</ThemedView>
|
|
);
|
|
}
|
|
let days = countdown.days === 1 ? 'Day' : 'Days';
|
|
let hours = countdown.hours === 1 ? 'Hour' : 'Hours';
|
|
let minutes = countdown.minutes === 1 ? 'Minute' : 'Minutes';
|
|
let seconds = countdown.seconds === 1 ? 'Second' : 'Seconds';
|
|
|
|
return (
|
|
<LinearGradient
|
|
colors={['#F67C0A', '#F60AD3']}
|
|
style={styles.container}
|
|
start={{ x: 0, y: 0 }}
|
|
end={{ x: 1, y: 1 }}
|
|
>
|
|
<SafeAreaView style={styles.safeContainer}>
|
|
<ThemedView style={styles.innerContainer}>
|
|
<ThemedText style={styles.title}>Countdown to Next Visit</ThemedText>
|
|
<ThemedView style={styles.countdownContainer}>
|
|
{/* Countdown items displayed horizontally with flexbox */}
|
|
<CountdownItem value={countdown.days} label={days} />
|
|
<CountdownItem value={countdown.hours} label={hours} />
|
|
<CountdownItem value={countdown.minutes} label={minutes} />
|
|
<CountdownItem value={countdown.seconds} label={seconds} />
|
|
</ThemedView>
|
|
<TouchableOpacity
|
|
style={styles.changeButton}
|
|
onPress={() => setIsDateDrawerVisible(true)}
|
|
>
|
|
<ThemedText style={styles.changeButtonText}>Change Date</ThemedText>
|
|
</TouchableOpacity>
|
|
{targetDate && (
|
|
<ChangeDateDrawer
|
|
isVisible={isDateDrawerVisible}
|
|
onClose={() => setIsDateDrawerVisible(false)}
|
|
onDateChange={handleDateChange}
|
|
currentDate={targetDate}
|
|
/>
|
|
)}
|
|
</ThemedView>
|
|
</SafeAreaView>
|
|
</LinearGradient>
|
|
);
|
|
}
|
|
|
|
function CountdownItem({ value, label }: { value: number; label: string }) {
|
|
return (
|
|
<ThemedView style={styles.countdownItem}>
|
|
<ThemedText style={styles.countdownValue}>{value}</ThemedText>
|
|
<ThemedText style={styles.countdownLabel}>{label}</ThemedText>
|
|
</ThemedView>
|
|
);
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
safeContainer: {
|
|
flex: 1,
|
|
backgroundColor: 'transparent', // Background color for safety area view
|
|
},
|
|
container: {
|
|
flex: 1,
|
|
backgroundColor: 'transparent',
|
|
},
|
|
innerContainer: {
|
|
flex: 1,
|
|
justifyContent: 'center',
|
|
alignItems: 'center',
|
|
paddingHorizontal: 20, // Padding around the edges
|
|
backgroundColor: 'transparent',
|
|
},
|
|
title: {
|
|
fontSize: 40, // Shrinking the title for smaller screens
|
|
lineHeight: 50,
|
|
fontWeight: '600',
|
|
textAlign: 'center',
|
|
paddingHorizontal: 10,
|
|
},
|
|
countdownContainer: {
|
|
flexDirection: 'row',
|
|
justifyContent: 'space-around', // Spread countdown items more evenly
|
|
alignItems: 'center',
|
|
width: '100%',
|
|
backgroundColor: 'transparent',
|
|
marginVertical: 40, // Added some space between countdown and title/button
|
|
},
|
|
countdownItem: {
|
|
alignItems: 'center',
|
|
marginHorizontal: 10, // Each item has horizontal spacing
|
|
backgroundColor: 'transparent',
|
|
},
|
|
countdownValue: {
|
|
fontSize: 36,
|
|
lineHeight: 42,
|
|
fontWeight: 'bold',
|
|
},
|
|
countdownLabel: {
|
|
fontSize: 18, // Reducing size of the label for better fit
|
|
lineHeight: 24,
|
|
},
|
|
changeButton: {
|
|
backgroundColor: '#730FF8',
|
|
padding: 12,
|
|
borderRadius: 8,
|
|
marginTop: 20,
|
|
},
|
|
changeButtonText: {
|
|
color: 'white',
|
|
fontSize: 18,
|
|
fontWeight: 'bold',
|
|
},
|
|
}); |