diff --git a/app/(app)/(tabs)/home/index.tsx b/app/(app)/(tabs)/home/index.tsx index dbfe944..e4d3773 100644 --- a/app/(app)/(tabs)/home/index.tsx +++ b/app/(app)/(tabs)/home/index.tsx @@ -1,8 +1,8 @@ -import { Pressable, ScrollView, Text, View } from 'react-native' +import { ColorValue, Pressable, ScrollView, Text, View } from 'react-native' import { createStyleSheet, useStyles } from 'react-native-unistyles' import React, { useCallback, useMemo } from 'react' import { AntDesign, MaterialIcons } from '@expo/vector-icons' -import { Link } from 'expo-router' +import { Href, Link } from 'expo-router' import typography from '@/src/constants/typography' import Animated, { LightSpeedInLeft, @@ -94,22 +94,6 @@ export default function Index() { }, [triggerDbUpdate]) const duration = 600 - const enteringAnimationLeft = useMemo( - () => LightSpeedInLeft.duration(duration), - [], - ) - const enteringAnimationRight = useMemo( - () => LightSpeedInRight.duration(duration), - [], - ) - const exitingAnimationLeft = useMemo( - () => LightSpeedOutLeft.duration(duration), - [], - ) - const exitingAnimationRight = useMemo( - () => LightSpeedOutRight.duration(duration), - [], - ) return ( @@ -119,7 +103,7 @@ export default function Index() { }> - + - - - - - - Start Lessons - - - - - - - + + } + href={{ + pathname: '/lessons', + params: { assignmentIds: lessonIdsBatch }, + }} + /> - - - - - - - Advanced - - - - + + } + href={{ + pathname: '/lessonPicker', + params: { assignmentIds: lessonIdsBatch }, + }} + /> } /> - + - - - - - Start Reviews - - - - - - - + + } + /> } /> - + @@ -281,15 +243,9 @@ type AssignmentsCardProps = { } const AssignmentsCard = ({ - backgroundColor, - title, - suptitle, - assignmentsCount, - message, - actions, - loading, - layoutAnimationDuration, bdageAnimationDuration = 125, + assignmentsCount, + ...props }: AssignmentsCardProps) => { const { styles } = useStyles(assignmentsCardStylesheet) const enteringAnimation = useMemo( @@ -300,6 +256,64 @@ const AssignmentsCard = ({ () => ZoomOut.duration(bdageAnimationDuration), [bdageAnimationDuration], ) + + return ( + 0 ? props.actions : null} + badge={ + assignmentsCount > 0 ? ( + + + {assignmentsCount} + + + ) : null + } + /> + ) +} + +const assignmentsCardStylesheet = createStyleSheet({ + badge: { + backgroundColor: 'white', + borderRadius: 18, + paddingHorizontal: 7, + paddingVertical: 3, + // Adjust so that it's aligned visually at the same line as title + marginTop: 2.5, + }, + badgeText: { + ...typography.label, + lineHeight: typography.label.fontSize * 1.2, + }, +}) + +type CardProps = { + backgroundColor: string + textColor?: ColorValue + title: string + suptitle?: string + message: string + actions: React.ReactNode + layoutAnimationDuration: number + badge?: React.ReactNode +} + +const Card = ({ + backgroundColor, + textColor = 'white', + title, + suptitle, + message, + actions, + layoutAnimationDuration, + badge, +}: CardProps) => { + const { styles } = useStyles(cardStylesheet) const layoutAnimation = useMemo( () => SequencedTransition.duration(layoutAnimationDuration), [layoutAnimationDuration], @@ -310,31 +324,30 @@ const AssignmentsCard = ({ style={[styles.view, { backgroundColor }]} layout={layoutAnimation}> - {suptitle && {suptitle}} + {suptitle && ( + {suptitle} + )} - {title} - - {assignmentsCount > 0 && ( - - - {assignmentsCount} - - + + {title} + + {badge && ( + <> + + {badge} + )} - {message} + {message} - {assignmentsCount > 0 && actions} + {actions} ) } -const assignmentsCardStylesheet = createStyleSheet({ +const cardStylesheet = createStyleSheet({ view: { marginHorizontal: 20, padding: 20, @@ -349,16 +362,114 @@ const assignmentsCardStylesheet = createStyleSheet({ ...typography.titleC, color: 'white', }, - badge: { +}) + +type CardButtonProps = { + animationDirection: 'left' | 'right' + animationDuration: number + textColor: ColorValue + href: Href + label: string + labelPrefix?: React.ReactNode + labelPostfix?: React.ReactNode + style?: 'filled' | 'outlined' +} + +const CardButton = ({ + animationDirection, + animationDuration, + textColor, + href, + label, + labelPrefix, + labelPostfix, + style = 'filled', +}: CardButtonProps) => { + const { styles } = useStyles(cardButtonStylesheet) + + const enteringAnimationLeft = useMemo( + () => LightSpeedInLeft.duration(animationDuration), + [animationDuration], + ) + const enteringAnimationRight = useMemo( + () => LightSpeedInRight.duration(animationDuration), + [animationDuration], + ) + const exitingAnimationLeft = useMemo( + () => LightSpeedOutLeft.duration(animationDuration), + [animationDuration], + ) + const exitingAnimationRight = useMemo( + () => LightSpeedOutRight.duration(animationDuration), + [animationDuration], + ) + const animations = useMemo( + () => + animationDirection === 'left' + ? { entering: enteringAnimationLeft, exiting: exitingAnimationRight } + : { entering: enteringAnimationRight, exiting: exitingAnimationLeft }, + [ + animationDirection, + enteringAnimationLeft, + enteringAnimationRight, + exitingAnimationLeft, + exitingAnimationRight, + ], + ) + + return ( + + + + + {labelPrefix && ( + <> + {labelPrefix} + + + )} + + {label} + + {labelPostfix && ( + <> + + {labelPostfix} + + )} + + + + + ) +} + +const cardButtonStylesheet = createStyleSheet({ + button: { + color: 'transparent', backgroundColor: 'white', - borderRadius: 18, - paddingHorizontal: 7, - paddingVertical: 3, - // Adjust so that it's aligned visually at the same line as title - marginTop: 2.5, }, - badgeText: { - ...typography.label, - lineHeight: typography.label.fontSize * 1.2, + filledButton: { + backgroundColor: 'white', + paddingVertical: 12, + paddingHorizontal: 20, + borderRadius: 3, + alignItems: 'center', + }, + buttonText: { + fontSize: typography.body.fontSize, + lineHeight: typography.body.fontSize * 1.1, + }, + outlinedButton: { + backgroundColor: 'transparent', + borderColor: 'white', + borderWidth: 1, + paddingVertical: 12, + paddingHorizontal: 20, + borderRadius: 3, + alignItems: 'center', }, })