2025-04-08 20:30:14 +00:00
|
|
|
import React, { useEffect, useState } from 'react';
|
2024-10-13 11:29:36 +00:00
|
|
|
|
|
|
|
|
import { Text } from '@/components/shared/Themed';
|
|
|
|
|
import Card from '@/components/shared/Card';
|
|
|
|
|
import styled from '@emotion/native';
|
|
|
|
|
import { formatTime } from '@/components/shared/business/timeHelpers';
|
|
|
|
|
import { useNavigation } from '@react-navigation/native';
|
|
|
|
|
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
|
|
|
|
|
import { RootStackParamList } from '@/app/RootStackParamList';
|
|
|
|
|
import { VerticalSpacer } from '@/components/shared/Spacers';
|
|
|
|
|
import { TimerPickerModal } from 'react-native-timer-picker';
|
|
|
|
|
import Button from '@/components/shared/Button';
|
|
|
|
|
import NumberSelector from '@/components/shared/NumberSelector';
|
2024-10-13 22:20:52 +00:00
|
|
|
import { i18n } from '@/app/i18n/i18n';
|
2025-04-08 20:30:14 +00:00
|
|
|
import { useTimerContext } from '@/app/store/TimerContext';
|
|
|
|
|
import { ActivityIndicator } from 'react-native';
|
2024-10-13 11:29:36 +00:00
|
|
|
|
2024-10-13 21:18:08 +00:00
|
|
|
type NavigationProp = NativeStackNavigationProp<RootStackParamList, 'Timer'>;
|
2024-10-13 11:29:36 +00:00
|
|
|
|
2024-10-13 22:20:52 +00:00
|
|
|
const t = i18n.scoped('dashboard');
|
|
|
|
|
|
2024-10-13 11:29:36 +00:00
|
|
|
export default function Dashboard() {
|
|
|
|
|
const navigation = useNavigation<NavigationProp>();
|
2025-04-08 20:30:14 +00:00
|
|
|
const { timerState, isLoading, updateReps, updateWorkTime, updateRestTime } = useTimerContext();
|
2024-10-13 11:29:36 +00:00
|
|
|
|
|
|
|
|
const [showWorkTimePicker, setShowWorkTimePicker] = useState<boolean>(false);
|
|
|
|
|
const [showRestTimePicker, setShowRestTimePicker] = useState<boolean>(false);
|
|
|
|
|
|
2025-04-08 20:30:14 +00:00
|
|
|
// Local variables for UI changes
|
|
|
|
|
const [localReps, setLocalReps] = useState<number>(timerState.reps);
|
|
|
|
|
const [localWorkTime, setLocalWorkTime] = useState<number>(timerState.workTime);
|
|
|
|
|
const [localRestTime, setLocalRestTime] = useState<number>(timerState.restTime);
|
|
|
|
|
|
|
|
|
|
// Update local states when store data is loaded
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (!isLoading) {
|
|
|
|
|
setLocalReps(timerState.reps);
|
|
|
|
|
setLocalWorkTime(timerState.workTime);
|
|
|
|
|
setLocalRestTime(timerState.restTime);
|
|
|
|
|
}
|
|
|
|
|
}, [isLoading, timerState]);
|
|
|
|
|
|
|
|
|
|
// Handle repetition changes
|
|
|
|
|
const handleRepsChange = (value: number) => {
|
|
|
|
|
setLocalReps(value);
|
|
|
|
|
updateReps(value);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const totalWorkTime: string = formatTime((localWorkTime + localRestTime) * localReps);
|
|
|
|
|
|
|
|
|
|
if (isLoading) {
|
|
|
|
|
return (
|
|
|
|
|
<LoadingContainer>
|
|
|
|
|
<ActivityIndicator size="large" />
|
|
|
|
|
<Text>Chargement...</Text>
|
|
|
|
|
</LoadingContainer>
|
|
|
|
|
);
|
|
|
|
|
}
|
2024-10-13 11:29:36 +00:00
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<Container>
|
2024-10-13 22:20:52 +00:00
|
|
|
<Title>{i18n.t('appTitle')}</Title>
|
2024-10-13 11:29:36 +00:00
|
|
|
|
|
|
|
|
<VerticalSpacer heightUnits={8} />
|
|
|
|
|
|
|
|
|
|
<CardContainer>
|
|
|
|
|
<Card backgroundColor="black">
|
|
|
|
|
<CardTextContainer>
|
2024-10-13 22:20:52 +00:00
|
|
|
<CustomText>{t('repetition')}</CustomText>
|
2025-04-08 20:30:14 +00:00
|
|
|
<NumberSelector reps={localReps} setReps={handleRepsChange} />
|
2024-10-13 11:29:36 +00:00
|
|
|
</CardTextContainer>
|
|
|
|
|
</Card>
|
|
|
|
|
|
|
|
|
|
<Card backgroundColor="red" onPress={() => setShowWorkTimePicker(true)}>
|
|
|
|
|
<CardTextContainer>
|
2024-10-13 22:20:52 +00:00
|
|
|
<CustomText>{t('fight')}</CustomText>
|
2025-04-08 20:30:14 +00:00
|
|
|
<CustomText>{formatTime(localWorkTime)}</CustomText>
|
2024-10-13 11:29:36 +00:00
|
|
|
</CardTextContainer>
|
|
|
|
|
</Card>
|
|
|
|
|
|
|
|
|
|
<TimerPickerModal
|
|
|
|
|
hideHours
|
|
|
|
|
visible={showWorkTimePicker}
|
|
|
|
|
setIsVisible={setShowWorkTimePicker}
|
|
|
|
|
onConfirm={(pickedDuration: any) => {
|
2025-04-08 20:30:14 +00:00
|
|
|
const newWorkTime = pickedDuration.minutes * 60 + pickedDuration.seconds;
|
|
|
|
|
setLocalWorkTime(newWorkTime);
|
|
|
|
|
updateWorkTime(newWorkTime);
|
2024-10-13 11:29:36 +00:00
|
|
|
setShowWorkTimePicker(false);
|
|
|
|
|
}}
|
2024-10-13 22:20:52 +00:00
|
|
|
modalTitle={t('setWorkTime')}
|
2024-10-13 11:29:36 +00:00
|
|
|
onCancel={() => setShowWorkTimePicker(false)}
|
|
|
|
|
closeOnOverlayPress
|
|
|
|
|
styles={{
|
|
|
|
|
theme: "dark",
|
|
|
|
|
}}
|
2025-04-08 20:30:14 +00:00
|
|
|
initialValue={{ minutes: Math.floor(timerState.workTime / 60), seconds: timerState.workTime % 60 }}
|
2024-10-13 11:29:36 +00:00
|
|
|
modalProps={{
|
|
|
|
|
overlayOpacity: 0.2,
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
<Card backgroundColor="green" onPress={() => setShowRestTimePicker(true)}>
|
|
|
|
|
<CardTextContainer>
|
2024-10-13 22:20:52 +00:00
|
|
|
<CustomText>{t('rest')}</CustomText>
|
2025-04-08 20:30:14 +00:00
|
|
|
<CustomText>{formatTime(localRestTime)}</CustomText>
|
2024-10-13 11:29:36 +00:00
|
|
|
</CardTextContainer>
|
|
|
|
|
</Card>
|
|
|
|
|
|
|
|
|
|
<TimerPickerModal
|
|
|
|
|
hideHours
|
|
|
|
|
visible={showRestTimePicker}
|
|
|
|
|
setIsVisible={setShowRestTimePicker}
|
|
|
|
|
onConfirm={(pickedDuration: any) => {
|
2025-04-08 20:30:14 +00:00
|
|
|
const newRestTime = pickedDuration.minutes * 60 + pickedDuration.seconds;
|
|
|
|
|
setLocalRestTime(newRestTime);
|
|
|
|
|
updateRestTime(newRestTime);
|
2024-10-13 11:29:36 +00:00
|
|
|
setShowRestTimePicker(false);
|
|
|
|
|
}}
|
2024-10-13 22:20:52 +00:00
|
|
|
modalTitle={t('setRestTime')}
|
2024-10-13 11:29:36 +00:00
|
|
|
onCancel={() => setShowRestTimePicker(false)}
|
|
|
|
|
closeOnOverlayPress
|
2025-04-08 20:30:14 +00:00
|
|
|
initialValue={{ minutes: Math.floor(timerState.restTime / 60), seconds: timerState.restTime % 60 }}
|
2024-10-13 11:29:36 +00:00
|
|
|
styles={{
|
|
|
|
|
theme: "dark",
|
|
|
|
|
}}
|
|
|
|
|
modalProps={{
|
|
|
|
|
overlayOpacity: 0.2,
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</CardContainer>
|
|
|
|
|
|
|
|
|
|
<VerticalSpacer heightUnits={5} />
|
2024-10-13 22:20:52 +00:00
|
|
|
<Text>{t('totalTime')}: {totalWorkTime}</Text>
|
2024-10-13 11:29:36 +00:00
|
|
|
|
|
|
|
|
<VerticalSpacer heightUnits={5} />
|
|
|
|
|
|
2025-04-08 20:30:14 +00:00
|
|
|
<Button label={t('begin')} onPress={() => navigation.navigate('Timer')} />
|
2024-10-13 21:18:08 +00:00
|
|
|
|
|
|
|
|
<VerticalSpacer heightUnits={5} />
|
|
|
|
|
|
2024-10-13 22:20:52 +00:00
|
|
|
<Button label={t('settings')} onPress={() => navigation.navigate('Settings')} />
|
2024-10-13 11:29:36 +00:00
|
|
|
</Container>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-08 20:30:14 +00:00
|
|
|
const LoadingContainer = styled.View({
|
|
|
|
|
flex: 1,
|
|
|
|
|
justifyContent: 'center',
|
|
|
|
|
alignItems: 'center',
|
|
|
|
|
padding: 20
|
|
|
|
|
});
|
|
|
|
|
|
2024-10-13 11:29:36 +00:00
|
|
|
const Title = styled(Text)(({ theme }) => ({
|
|
|
|
|
textAlign: 'center',
|
|
|
|
|
fontSize: 40,
|
|
|
|
|
fontWeight: 'bold',
|
2025-04-08 19:44:56 +00:00
|
|
|
color: theme.colors.fixed.black
|
2024-10-13 11:29:36 +00:00
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
const Container = styled.View({
|
|
|
|
|
padding: 20
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
const CardTextContainer = styled.View({
|
|
|
|
|
flexDirection: 'row',
|
|
|
|
|
justifyContent: 'space-between',
|
|
|
|
|
alignItems: 'center'
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
const CardContainer = styled.View({
|
|
|
|
|
flexDirection: 'column',
|
|
|
|
|
gap: 10
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
const CustomText = styled(Text)(({ theme }) => ({
|
|
|
|
|
fontSize: 20,
|
|
|
|
|
fontWeight: 'bold',
|
|
|
|
|
textAlign: 'center',
|
2025-04-08 19:44:56 +00:00
|
|
|
color: theme.colors.fixed.white
|
2024-10-13 11:29:36 +00:00
|
|
|
}))
|