feat: add new UI
parent
8c4ee87622
commit
6343a8bc04
|
|
@ -7,7 +7,7 @@ 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 { HorizontalSpacer, VerticalSpacer } from '@/components/shared/Spacers';
|
||||
import { TimerPickerModal } from 'react-native-timer-picker';
|
||||
import Button from '@/components/shared/Button';
|
||||
import NumberSelector from '@/components/shared/NumberSelector';
|
||||
|
|
@ -63,14 +63,11 @@ export default function Dashboard() {
|
|||
|
||||
return (
|
||||
<Container>
|
||||
<Title>{i18n.t('appTitle')}</Title>
|
||||
|
||||
<VerticalSpacer heightUnits={8} />
|
||||
|
||||
<CardContainer>
|
||||
<Card backgroundColor="grey" onPress={() => setShowPreparationTimePicker(true)}>
|
||||
<Card backgroundColor="darkGrey" color="black" borderColor="darkGrey" onPress={() => setShowPreparationTimePicker(true)}>
|
||||
<CardTextContainer>
|
||||
<BlackCustomText>{t('preparation')}</BlackCustomText>
|
||||
<VerticalSpacer heightUnits={3} />
|
||||
<BlackCustomText>{formatTime(localPreparationTime)}</BlackCustomText>
|
||||
</CardTextContainer>
|
||||
</Card>
|
||||
|
|
@ -97,9 +94,10 @@ export default function Dashboard() {
|
|||
}}
|
||||
/>
|
||||
|
||||
<Card backgroundColor="red" onPress={() => setShowWorkTimePicker(true)}>
|
||||
<Card backgroundColor="white" borderColor="pink" color="black" onPress={() => setShowWorkTimePicker(true)}>
|
||||
<CardTextContainer>
|
||||
<CustomText>{t('fight')}</CustomText>
|
||||
<VerticalSpacer heightUnits={3} />
|
||||
<CustomText>{formatTime(localWorkTime)}</CustomText>
|
||||
</CardTextContainer>
|
||||
</Card>
|
||||
|
|
@ -126,9 +124,10 @@ export default function Dashboard() {
|
|||
}}
|
||||
/>
|
||||
|
||||
<Card backgroundColor="green" onPress={() => setShowRestTimePicker(true)}>
|
||||
<Card backgroundColor="white" borderColor="blue" color='black' onPress={() => setShowRestTimePicker(true)}>
|
||||
<CardTextContainer>
|
||||
<CustomText>{t('rest')}</CustomText>
|
||||
<VerticalSpacer heightUnits={3} />
|
||||
<CustomText>{formatTime(localRestTime)}</CustomText>
|
||||
</CardTextContainer>
|
||||
</Card>
|
||||
|
|
@ -155,28 +154,43 @@ export default function Dashboard() {
|
|||
}}
|
||||
/>
|
||||
|
||||
<Card backgroundColor="black">
|
||||
<Card backgroundColor="black" color="white" borderColor="black">
|
||||
<CardTextContainer>
|
||||
<CustomText>{t('repetition')}</CustomText>
|
||||
<WhiteCustomText>{t('repetition')}</WhiteCustomText>
|
||||
<VerticalSpacer heightUnits={3} />
|
||||
<NumberSelector reps={localReps} setReps={handleRepsChange} />
|
||||
</CardTextContainer>
|
||||
</Card>
|
||||
</CardContainer>
|
||||
|
||||
<VerticalSpacer heightUnits={5} />
|
||||
<Text>{t('totalTime')}: {totalWorkTime}</Text>
|
||||
<CenterText>{t('totalTime')}: {totalWorkTime}</CenterText>
|
||||
|
||||
<VerticalSpacer heightUnits={5} />
|
||||
|
||||
<Button label={t('begin')} onPress={() => navigation.navigate('Timer')} />
|
||||
|
||||
<VerticalSpacer heightUnits={5} />
|
||||
|
||||
<Button label={t('settings')} onPress={() => navigation.navigate('Settings')} />
|
||||
<Row>
|
||||
<SmallButton color="blue" labelColor="white" label={t('settings')} onPress={() => navigation.navigate('Settings')} />
|
||||
<LargeButton color="pink" labelColor="white" label={t('begin')} onPress={() => navigation.navigate('Timer')} />
|
||||
</Row>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
const Row = styled.View({
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
width: '100%'
|
||||
})
|
||||
|
||||
const SmallButton = styled(Button)({
|
||||
width: '30%'
|
||||
})
|
||||
|
||||
const LargeButton = styled(Button)({
|
||||
width: '65%'
|
||||
})
|
||||
|
||||
const LoadingContainer = styled.View({
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
|
|
@ -196,7 +210,7 @@ const Container = styled.View({
|
|||
})
|
||||
|
||||
const CardTextContainer = styled.View({
|
||||
flexDirection: 'row',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center'
|
||||
})
|
||||
|
|
@ -207,12 +221,21 @@ const CardContainer = styled.View({
|
|||
})
|
||||
|
||||
const CustomText = styled(Text)(({ theme }) => ({
|
||||
fontSize: 20,
|
||||
fontSize: 23,
|
||||
fontWeight: 'bold',
|
||||
textAlign: 'center',
|
||||
}))
|
||||
|
||||
const WhiteCustomText = styled(CustomText)(({ theme }) => ({
|
||||
color: theme.colors.fixed.white
|
||||
}))
|
||||
|
||||
const BlackCustomText = styled(CustomText)(({ theme }) => ({
|
||||
color: theme.colors.fixed.black
|
||||
}))
|
||||
|
||||
const CenterText = styled(Text)(({ theme }) => ({
|
||||
textAlign: 'center',
|
||||
fontSize: 22,
|
||||
color: theme.colors.fixed.black
|
||||
}))
|
||||
|
|
@ -189,9 +189,9 @@ export default function Timer() {
|
|||
const renderBgColor: () => TimerBgColor = () => {
|
||||
if (isFinish) return "black";
|
||||
if (isPreparationPhase) return "grey";
|
||||
if (isWorkPhase) return "red";
|
||||
if (isWorkPhase) return "pink";
|
||||
|
||||
return "green";
|
||||
return "blue";
|
||||
};
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import styled from '@emotion/native';
|
|||
import { HorizontalSpacer } from '@/components/shared/Spacers';
|
||||
import { Text } from '@/components/shared/Themed';
|
||||
|
||||
type ButtonColor = 'green' | 'red' | 'grey' | 'white';
|
||||
type ButtonColor = 'green' | 'red' | 'grey' | 'white' | 'black' | 'darkGrey' | 'blue' | 'pink';
|
||||
type LabelColor = ButtonColor | 'black';
|
||||
type IconLocation = 'left' | 'right';
|
||||
|
||||
|
|
@ -69,11 +69,11 @@ const Container = styled.TouchableOpacity<{
|
|||
disabled: boolean;
|
||||
secondary: boolean;
|
||||
}>(({ theme, bgColor, secondary }) => ({
|
||||
backgroundColor: theme.colors.fixed[bgColor],
|
||||
borderWidth: secondary ? 1 : 0,
|
||||
backgroundColor: secondary ? theme.colors.fixed.white : theme.colors.fixed[bgColor],
|
||||
borderWidth: 4,
|
||||
borderColor: theme.colors.fixed[bgColor],
|
||||
borderRadius: 6,
|
||||
height: theme.layout.gridUnit * 12,
|
||||
borderRadius: 0,
|
||||
height: theme.layout.gridUnit * 20,
|
||||
justifyContent: 'center',
|
||||
paddingHorizontal: theme.layout.gridUnit * 4,
|
||||
alignItems: 'center',
|
||||
|
|
|
|||
|
|
@ -5,30 +5,46 @@ import { TouchableOpacity } from 'react-native';
|
|||
export interface CardProps {
|
||||
children: React.ReactNode;
|
||||
backgroundColor: CardBackgroundColor;
|
||||
borderColor: CardBorderColor;
|
||||
color: CardColor;
|
||||
testID?: string;
|
||||
onPress?: () => void;
|
||||
}
|
||||
|
||||
type CardBackgroundColor = 'red' | 'green' | 'grey' | 'black';
|
||||
type CardBackgroundColor = 'red' | 'green' | 'grey' | 'black' | 'white' | 'darkGrey';
|
||||
type CardBorderColor = 'pink' | 'blue' | 'grey' | 'black' | 'white' | 'darkGrey';
|
||||
type CardColor = 'black' | 'white';
|
||||
|
||||
const Card: React.FC<CardProps> = ({
|
||||
children,
|
||||
backgroundColor = 'red',
|
||||
color = 'black',
|
||||
borderColor = 'pink',
|
||||
testID = undefined,
|
||||
onPress
|
||||
}) => {
|
||||
const safeOnPress = useCallback(() => onPress?.(), [onPress]);
|
||||
|
||||
const content = (
|
||||
<Container bgColor={backgroundColor} testID={testID}>
|
||||
<Container
|
||||
color={color}
|
||||
bgColor={backgroundColor}
|
||||
testID={testID}
|
||||
borderColor={borderColor}
|
||||
>
|
||||
{children}
|
||||
</Container>
|
||||
);
|
||||
|
||||
const touchableContent = (
|
||||
<TouchableOpacity onPress={safeOnPress}>
|
||||
<CustomTouchableOpacity
|
||||
onPress={safeOnPress}
|
||||
bgColor={backgroundColor}
|
||||
color={color}
|
||||
borderColor={borderColor}
|
||||
>
|
||||
{content}
|
||||
</TouchableOpacity>
|
||||
</CustomTouchableOpacity>
|
||||
)
|
||||
|
||||
return (
|
||||
|
|
@ -36,14 +52,29 @@ const Card: React.FC<CardProps> = ({
|
|||
);
|
||||
};
|
||||
|
||||
const Container = styled.View<{
|
||||
const CustomTouchableOpacity = styled(TouchableOpacity)<{
|
||||
color: CardColor;
|
||||
borderColor: CardBorderColor;
|
||||
bgColor: CardBackgroundColor;
|
||||
}>(({ theme, bgColor }) => ({
|
||||
padding: 30,
|
||||
width: '100%',
|
||||
borderRadius: 10,
|
||||
overflow: 'hidden',
|
||||
}>(({ theme, color, borderColor, bgColor }) => ({
|
||||
color: theme.colors.fixed[color],
|
||||
borderColor: theme.colors.fixed[borderColor],
|
||||
backgroundColor: theme.colors.fixed[bgColor]
|
||||
}));
|
||||
|
||||
const Container = styled.View<{
|
||||
bgColor: CardBackgroundColor;
|
||||
borderColor: CardBorderColor;
|
||||
color: CardColor;
|
||||
}>(({ theme, bgColor, borderColor, color }) => ({
|
||||
padding: 25,
|
||||
width: '100%',
|
||||
borderRadius: 0,
|
||||
overflow: 'hidden',
|
||||
backgroundColor: theme.colors.fixed[bgColor],
|
||||
borderWidth: 4,
|
||||
borderColor: theme.colors.fixed[borderColor],
|
||||
color: theme.colors.fixed[color]
|
||||
}));
|
||||
|
||||
export default Card;
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
export type TimerBgColor = 'red' | 'green' | 'black' | 'grey';
|
||||
export type TimerBgColor = 'pink' | 'blue' | 'black' | 'grey';
|
||||
|
|
|
|||
|
|
@ -58,56 +58,69 @@ export default function TimerContent({
|
|||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Title isPreparationPhase={isPreparationPhase}>{getTitle()}</Title>
|
||||
<View>
|
||||
<Column bgColor={bgColor}>
|
||||
<PartContainer>
|
||||
<Text>3:23</Text>
|
||||
{!isPreparationPhase && <Reps>{currentRep} / {reps}</Reps>}
|
||||
{isPreparationPhase && <Reps isPreparationPhase={true}>{t('preparationDescription')}</Reps>}
|
||||
</PartContainer>
|
||||
|
||||
<VerticalSpacer heightUnits={8} />
|
||||
<PartContainer>
|
||||
<Title isPreparationPhase={isPreparationPhase}>{getTitle()}</Title>
|
||||
<VerticalSpacer heightUnits={2} />
|
||||
<Time isPreparationPhase={isPreparationPhase}>
|
||||
{formatTime(timeLeft)}
|
||||
</Time>
|
||||
</PartContainer>
|
||||
|
||||
<Time isPreparationPhase={isPreparationPhase}>
|
||||
{formatTime(timeLeft)}
|
||||
</Time>
|
||||
<PartContainer>
|
||||
<ButtonContainer bgColor={bgColor}>
|
||||
<Button
|
||||
secondary={true}
|
||||
label={t('prev')}
|
||||
color={'black'}
|
||||
labelColor={'white'}
|
||||
onPress={isPreparationPhase ? handleNoop : previousRep}
|
||||
status={isPreparationPhase ? 'disabled' : 'ready'}
|
||||
/>
|
||||
|
||||
<VerticalSpacer heightUnits={8} />
|
||||
<ElasticSpacer />
|
||||
|
||||
{!isPreparationPhase && <Reps>{currentRep} / {reps}</Reps>}
|
||||
{isPreparationPhase && <Reps isPreparationPhase={true}>{t('preparationDescription')}</Reps>}
|
||||
{isRunning ? (
|
||||
<Button secondary={true} color={'black'} label={t('stop')} onPress={handleStop} />
|
||||
) : (
|
||||
<Button secondary={true} color={'black'} label={t('start')} onPress={handleContinue} />
|
||||
)}
|
||||
|
||||
<VerticalSpacer heightUnits={8} />
|
||||
<ElasticSpacer />
|
||||
|
||||
<ButtonContainer bgColor={bgColor}>
|
||||
<Button
|
||||
label={t('prev')}
|
||||
onPress={isPreparationPhase ? handleNoop : previousRep}
|
||||
status={isPreparationPhase ? 'disabled' : 'ready'}
|
||||
/>
|
||||
<Button
|
||||
secondary={true}
|
||||
label={t('next')}
|
||||
color={'black'}
|
||||
onPress={isPreparationPhase ? nextRep : nextRep}
|
||||
status="ready"
|
||||
/>
|
||||
</ButtonContainer>
|
||||
|
||||
<ElasticSpacer />
|
||||
<VerticalSpacer heightUnits={4} />
|
||||
|
||||
{isRunning ? (
|
||||
<Button label={t('stop')} onPress={handleStop} />
|
||||
) : (
|
||||
<Button label={t('start')} onPress={handleContinue} />
|
||||
)}
|
||||
|
||||
<ElasticSpacer />
|
||||
|
||||
<Button
|
||||
label={t('next')}
|
||||
onPress={isPreparationPhase ? nextRep : nextRep}
|
||||
status="ready"
|
||||
/>
|
||||
</ButtonContainer>
|
||||
|
||||
<VerticalSpacer heightUnits={4} />
|
||||
|
||||
<Button label={i18n.t('back')} onPress={handleBackClick} />
|
||||
</>
|
||||
<Button label={i18n.t('back')} onPress={handleBackClick} />
|
||||
</PartContainer>
|
||||
</Column>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
const PartContainer = styled(View)({
|
||||
backgroundColor: 'transparent',
|
||||
});
|
||||
|
||||
const ButtonContainer = styled(View)<{ bgColor: TimerBgColor }>(({ theme, bgColor }) => ({
|
||||
backgroundColor: theme.colors.fixed[bgColor],
|
||||
flexDirection: 'row',
|
||||
gap: 10,
|
||||
justifyContent: 'space-between',
|
||||
}));
|
||||
|
||||
|
|
@ -123,6 +136,13 @@ const Time = styled(Text)<{ isPreparationPhase?: boolean }>(({ theme, isPreparat
|
|||
color: isPreparationPhase ? theme.colors.fixed.black : theme.colors.fixed.white
|
||||
}));
|
||||
|
||||
const Column = styled(View)<{ bgColor: TimerBgColor }>(({ theme, bgColor }) => ({
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'space-around',
|
||||
height: '100%',
|
||||
backgroundColor: theme.colors.fixed[bgColor],
|
||||
}));
|
||||
|
||||
const Reps = styled(Text)<{ isPreparationPhase?: boolean }>(({ theme, isPreparationPhase = false }) => ({
|
||||
fontSize: 30,
|
||||
fontWeight: 'bold',
|
||||
|
|
|
|||
|
|
@ -3,7 +3,11 @@ const baseColors = {
|
|||
white: '#FFFFFF',
|
||||
red: '#FF4141',
|
||||
green: '#3AC26E',
|
||||
grey: '#F9F9F9',
|
||||
grey: '#F5F5F5',
|
||||
darkGrey: '#D9CFC7',
|
||||
yellow: '#FFD700',
|
||||
pink: '#E4007C',
|
||||
blue: '#86C3E3'
|
||||
} as const;
|
||||
|
||||
export default {
|
||||
|
|
|
|||
Loading…
Reference in New Issue