From 6aa40a3a6bcd01e185a7d8ef95286f95c98da55f Mon Sep 17 00:00:00 2001 From: Torpenn Date: Sun, 13 Oct 2024 13:29:36 +0200 Subject: [PATCH] add simple timers tabada --- .eslintignore | 3 + .eslintrc.js | 26 + .gitignore | 6 + .gitlab-ci.yml | 40 + .husky/pre-push | 1 + .nvmrc | 1 + app/(tabs)/_layout.tsx | 59 - app/(tabs)/index.tsx | 31 - app/(tabs)/two.tsx | 31 - app/+not-found.tsx | 6 +- app/RootStackParamList.ts | 4 + app/_layout.tsx | 15 +- app/dashboard.tsx | 134 + app/modal.tsx | 35 - app/shared/theme/colors.ts | 7 + app/shared/theme/index.ts | 16 + app/shared/theme/layout.ts | 23 + app/timer.tsx | 109 + babel.config.js | 1 + components/EditScreenInfo.tsx | 77 - components/ExternalLink.tsx | 25 - components/StyledText.tsx | 5 - components/__tests__/StyledText-test.js | 10 - components/shared/Button.tsx | 100 + components/shared/Card.tsx | 49 + components/shared/NumberSelector.tsx | 47 + components/shared/Spacers.tsx | 16 + components/{ => shared}/Themed.tsx | 8 +- components/shared/__tests__/Button-test.js | 63 + components/shared/__tests__/Card-test.js | 60 + .../shared/__tests__/NumberSelector-test.js | 72 + components/shared/__tests__/Spacers-test.js | 40 + .../__snapshots__/Button-test.js.snap | 202 ++ .../__tests__/__snapshots__/Card-test.js.snap | 24 + .../__snapshots__/NumberSelector-test.js.snap | 107 + .../__snapshots__/Spacers-test.js.snap | 33 + .../business/__tests__/timeHelpers-test.js | 26 + components/shared/business/timeHelpers.ts | 8 + components/testUtils.tsx | 20 + components/useCases/timer/business/type.ts | 1 + .../useCases/timer/view/FinishContent.tsx | 47 + .../useCases/timer/view/TimerContent.tsx | 87 + components/useClientOnlyValue.ts | 4 - components/useClientOnlyValue.web.ts | 12 - components/useColorScheme.web.ts | 8 - jest.setup.js | 1 + package-lock.json | 2961 +++++++++++++++-- package.json | 33 +- 48 files changed, 4148 insertions(+), 546 deletions(-) create mode 100644 .eslintignore create mode 100644 .eslintrc.js create mode 100644 .gitlab-ci.yml create mode 100644 .husky/pre-push create mode 100644 .nvmrc delete mode 100644 app/(tabs)/_layout.tsx delete mode 100644 app/(tabs)/index.tsx delete mode 100644 app/(tabs)/two.tsx create mode 100644 app/RootStackParamList.ts create mode 100644 app/dashboard.tsx delete mode 100644 app/modal.tsx create mode 100644 app/shared/theme/colors.ts create mode 100644 app/shared/theme/index.ts create mode 100644 app/shared/theme/layout.ts create mode 100644 app/timer.tsx delete mode 100644 components/EditScreenInfo.tsx delete mode 100644 components/ExternalLink.tsx delete mode 100644 components/StyledText.tsx delete mode 100644 components/__tests__/StyledText-test.js create mode 100644 components/shared/Button.tsx create mode 100644 components/shared/Card.tsx create mode 100644 components/shared/NumberSelector.tsx create mode 100644 components/shared/Spacers.tsx rename components/{ => shared}/Themed.tsx (84%) create mode 100644 components/shared/__tests__/Button-test.js create mode 100644 components/shared/__tests__/Card-test.js create mode 100644 components/shared/__tests__/NumberSelector-test.js create mode 100644 components/shared/__tests__/Spacers-test.js create mode 100644 components/shared/__tests__/__snapshots__/Button-test.js.snap create mode 100644 components/shared/__tests__/__snapshots__/Card-test.js.snap create mode 100644 components/shared/__tests__/__snapshots__/NumberSelector-test.js.snap create mode 100644 components/shared/__tests__/__snapshots__/Spacers-test.js.snap create mode 100644 components/shared/business/__tests__/timeHelpers-test.js create mode 100644 components/shared/business/timeHelpers.ts create mode 100644 components/testUtils.tsx create mode 100644 components/useCases/timer/business/type.ts create mode 100644 components/useCases/timer/view/FinishContent.tsx create mode 100644 components/useCases/timer/view/TimerContent.tsx delete mode 100644 components/useClientOnlyValue.ts delete mode 100644 components/useClientOnlyValue.web.ts delete mode 100644 components/useColorScheme.web.ts create mode 100644 jest.setup.js diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..da947cf --- /dev/null +++ b/.eslintignore @@ -0,0 +1,3 @@ +node_modules +package.json +.eslintrc.js diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..9d36119 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,26 @@ +module.exports = { + env: { + browser: true, + es2021: true, + }, + extends: ['plugin:react/recommended'], + parser: '@typescript-eslint/parser', + root: true, + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + ecmaVersion: 'latest', + sourceType: 'module', + }, + + plugins: ['react-native', 'jest', 'simple-import-sort', '@typescript-eslint'], + rules: { + "@typescript-eslint/method-signature-style": [ + "error", + "property" + ], + 'react/react-in-jsx-scope': 'off', + 'react/no-unescaped-entities': 'off', + }, +}; diff --git a/.gitignore b/.gitignore index 05647d5..0b37b6e 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,9 @@ yarn-error.* # typescript *.tsbuildinfo + +# @generated expo-cli sync-2b81b286409207a5da26e14c78851eb30d8ccbdb +# The following patterns were generated by expo-cli + +expo-env.d.ts +# @end expo-cli \ No newline at end of file diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..deaaa98 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,40 @@ +image: node:20 + +stages: + - install + - lint + - test + +cache: + paths: + - node_modules/ + +before_script: + - npm install + - apt-get update + +install_dependencies: + stage: install + script: + - npm install + artifacts: + paths: + - node_modules/ + expire_in: 1 week + +lint: + stage: test + script: + - npm run lint + - npm run types + only: + - branches + - merge_requests + +test: + stage: test + script: + - npm test + only: + - branches + - merge_requests diff --git a/.husky/pre-push b/.husky/pre-push new file mode 100644 index 0000000..31e0db2 --- /dev/null +++ b/.husky/pre-push @@ -0,0 +1 @@ +npm run types && npm run lint diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..209e3ef --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +20 diff --git a/app/(tabs)/_layout.tsx b/app/(tabs)/_layout.tsx deleted file mode 100644 index 30914fb..0000000 --- a/app/(tabs)/_layout.tsx +++ /dev/null @@ -1,59 +0,0 @@ -import React from 'react'; -import FontAwesome from '@expo/vector-icons/FontAwesome'; -import { Link, Tabs } from 'expo-router'; -import { Pressable } from 'react-native'; - -import Colors from '@/constants/Colors'; -import { useColorScheme } from '@/components/useColorScheme'; -import { useClientOnlyValue } from '@/components/useClientOnlyValue'; - -// You can explore the built-in icon families and icons on the web at https://icons.expo.fyi/ -function TabBarIcon(props: { - name: React.ComponentProps['name']; - color: string; -}) { - return ; -} - -export default function TabLayout() { - const colorScheme = useColorScheme(); - - return ( - - , - headerRight: () => ( - - - {({ pressed }) => ( - - )} - - - ), - }} - /> - , - }} - /> - - ); -} diff --git a/app/(tabs)/index.tsx b/app/(tabs)/index.tsx deleted file mode 100644 index 6cbee6d..0000000 --- a/app/(tabs)/index.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import { StyleSheet } from 'react-native'; - -import EditScreenInfo from '@/components/EditScreenInfo'; -import { Text, View } from '@/components/Themed'; - -export default function TabOneScreen() { - return ( - - Tab One - - - - ); -} - -const styles = StyleSheet.create({ - container: { - flex: 1, - alignItems: 'center', - justifyContent: 'center', - }, - title: { - fontSize: 20, - fontWeight: 'bold', - }, - separator: { - marginVertical: 30, - height: 1, - width: '80%', - }, -}); diff --git a/app/(tabs)/two.tsx b/app/(tabs)/two.tsx deleted file mode 100644 index f2ea47e..0000000 --- a/app/(tabs)/two.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import { StyleSheet } from 'react-native'; - -import EditScreenInfo from '@/components/EditScreenInfo'; -import { Text, View } from '@/components/Themed'; - -export default function TabTwoScreen() { - return ( - - Tab Two - - - - ); -} - -const styles = StyleSheet.create({ - container: { - flex: 1, - alignItems: 'center', - justifyContent: 'center', - }, - title: { - fontSize: 20, - fontWeight: 'bold', - }, - separator: { - marginVertical: 30, - height: 1, - width: '80%', - }, -}); diff --git a/app/+not-found.tsx b/app/+not-found.tsx index ffb5643..45c0b68 100644 --- a/app/+not-found.tsx +++ b/app/+not-found.tsx @@ -1,7 +1,7 @@ import { Link, Stack } from 'expo-router'; import { StyleSheet } from 'react-native'; -import { Text, View } from '@/components/Themed'; +import { Text, View } from '@/components/shared/Themed'; export default function NotFoundScreen() { return ( @@ -9,10 +9,6 @@ export default function NotFoundScreen() { This screen doesn't exist. - - - Go to home screen! - ); diff --git a/app/RootStackParamList.ts b/app/RootStackParamList.ts new file mode 100644 index 0000000..309d108 --- /dev/null +++ b/app/RootStackParamList.ts @@ -0,0 +1,4 @@ +export type RootStackParamList = { + dashboard: undefined; + timer: { reps: number, restTime: number, workTime: number}; +}; diff --git a/app/_layout.tsx b/app/_layout.tsx index 40cdc48..3a7f1ad 100644 --- a/app/_layout.tsx +++ b/app/_layout.tsx @@ -1,13 +1,12 @@ import FontAwesome from '@expo/vector-icons/FontAwesome'; -import { DarkTheme, DefaultTheme, ThemeProvider } from '@react-navigation/native'; +import { ThemeProvider } from '@emotion/react'; +import { theme } from '@/app/shared/theme'; import { useFonts } from 'expo-font'; import { Stack } from 'expo-router'; import * as SplashScreen from 'expo-splash-screen'; import { useEffect } from 'react'; import 'react-native-reanimated'; -import { useColorScheme } from '@/components/useColorScheme'; - export { // Catch any errors thrown by the Layout component. ErrorBoundary, @@ -15,7 +14,7 @@ export { export const unstable_settings = { // Ensure that reloading on `/modal` keeps a back button present. - initialRouteName: '(tabs)', + initialRouteName: 'dashboard', }; // Prevent the splash screen from auto-hiding before asset loading is complete. @@ -46,13 +45,11 @@ export default function RootLayout() { } function RootLayoutNav() { - const colorScheme = useColorScheme(); - return ( - + - - + + ); diff --git a/app/dashboard.tsx b/app/dashboard.tsx new file mode 100644 index 0000000..47d8e76 --- /dev/null +++ b/app/dashboard.tsx @@ -0,0 +1,134 @@ +import React, { useState } from 'react'; + +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'; + +type NavigationProp = NativeStackNavigationProp; + +export default function Dashboard() { + const navigation = useNavigation(); + + const [reps, setReps] = useState(1); + const [workTime, setWorkTime] = useState(0); + const [restTime, setRestTime] = useState(0); + const [showWorkTimePicker, setShowWorkTimePicker] = useState(false); + const [showRestTimePicker, setShowRestTimePicker] = useState(false); + + const totalWorkTime: string = formatTime((workTime + restTime) * reps); + + return ( + + Boxons + + + + + + + Reps. + + + + + setShowWorkTimePicker(true)}> + + Fight + {formatTime(workTime)} + + + + { + setWorkTime(pickedDuration.minutes * 60 + pickedDuration.seconds); + setShowWorkTimePicker(false); + }} + modalTitle="Set Round Time" + onCancel={() => setShowWorkTimePicker(false)} + closeOnOverlayPress + styles={{ + theme: "dark", + }} + modalProps={{ + overlayOpacity: 0.2, + }} + /> + + setShowRestTimePicker(true)}> + + Repos + {formatTime(restTime)} + + + + { + setRestTime(pickedDuration.minutes * 60 + pickedDuration.seconds); + setShowRestTimePicker(false); + }} + modalTitle="Set Rest Time" + onCancel={() => setShowRestTimePicker(false)} + closeOnOverlayPress + styles={{ + theme: "dark", + }} + modalProps={{ + overlayOpacity: 0.2, + }} + /> + + + + Temps total de travail : {totalWorkTime} + + + +