Ajout de la timebar

pull/13/head
Tony Fages 3 months ago
parent eecd1c36cf
commit e906211b66

@ -5,7 +5,6 @@ export default function RootoLayout() {
return ( return (
<Stack screenOptions={{ <Stack screenOptions={{
headerShown: false, headerShown: false,
presentation: "modal",
}}> }}>
<Stack.Screen name="index" /> <Stack.Screen name="index" />
</Stack> </Stack>

@ -1,40 +0,0 @@
import {FlatList, Text, View} from "react-native";
import React from "react";
import HeaderProfileComponent from "@/components/HeaderProfileComponent";
import Screen from "@/components/ui/Screen";
import WorkoutCardComponent from "@/components/WorkoutCardComponent";
import {useSession} from "@/ctx";
import {Workout} from "@/model/Workout";
export default function ExerciceScreen() {
const [text, onChangeText] = React.useState("");
const exercise = [new Workout("Développé couché", 25,"8 Series Workout", 412, "assets/images/Sigma-2.png","Intense" ),
new Workout("Curl halterné", 30, "8 Series Workout", 342, "assets/images/Sigma.jpg","Medium" ),
new Workout("Tirage Vertival", 29, "8 Series Workout", 793, "assets/images/Sigma.jpg","Easy" )];
return (
<Screen>
<FlatList
ListHeaderComponent={
<>
<View>
<HeaderProfileComponent/>
</View>
<View className="mt-4">
<View className="flex-row justify-between items-center mb-4">
<Text className="text-lg font-bold text-black">Séance du jour</Text>
</View>
</View>
</>
}
data={exercise}
className="h-full"
renderItem={({ item }: { item: Workout }) =>
<View className="mt-2 h-52">
<WorkoutCardComponent exercise={item}/>
</View>
}
/>
</Screen>
);
}

@ -0,0 +1,47 @@
import {FlatList, SafeAreaView, Text, View} from "react-native";
import React from "react";
import HeaderProfileComponent from "@/components/HeaderProfileComponent";
import Screen from "@/components/ui/Screen";
import WorkoutCardComponent from "@/components/WorkoutCardComponent";
import {useSession} from "@/ctx";
import {Workout} from "@/model/Workout";
import LinearTimer from "react-native-linear-timer";
export default function ExercicesScreen() {
const [text, onChangeText] = React.useState("");
const exercise = [new Workout("Développé couché", 25,"8 Series Workout", 412, "assets/images/Sigma-2.png","Intense" ),
new Workout("Curl halterné", 30, "8 Series Workout", 342, "assets/images/Sigma.jpg","Medium" ),
new Workout("Tirage Vertival", 29, "8 Series Workout", 793, "assets/images/Sigma.jpg","Easy" )];
return (
<View className="h-full p-2 mt-11">
<FlatList
ListHeaderComponent={
<>
<View className="">
<HeaderProfileComponent/>
</View>
<View className="mt-4">
<View className="flex-row justify-between items-center mb-4">
<Text className="text-lg font-bold text-black">Séance du jour</Text>
</View>
</View>
</>
}
data={exercise}
className="h-full"
renderItem={({ item }: { item: Workout }) =>
<View className="mt-2 h-52">
<WorkoutCardComponent exercise={item}/>
</View>
}
/>
</View>
);
}

@ -0,0 +1,23 @@
import * as React from 'react';
import LinearTimer from 'react-native-linear-timer';
import {Button, Image, ImageBackground, SafeAreaView, Text, TouchableOpacity, View} from "react-native";
import Screen from "@/components/ui/Screen";
import {Background} from "@react-navigation/elements";
import {AntDesign} from "@expo/vector-icons";
import {router, useRouter} from "expo-router";
import WelcomeComponent from "@/components/WelcomeComponent";
import WorkoutPresentationComponent from "@/components/WorkoutPresentationComponent";
export default function WorkoutScreen() {
const router = useRouter();
return (
<View className=" h-full rounded-2xl ">
<WorkoutPresentationComponent/>
</View>
)
}

@ -5,9 +5,13 @@ export default function RootoLayout() {
return ( return (
<Stack screenOptions={{ <Stack screenOptions={{
headerShown: false, headerShown: false,
presentation: "modal", }}
}}> initialRouteName={"ExercicesScreen"}
<Stack.Screen name="ExerciceScreen" /> >
<Stack.Screen name="ExercicesScreen" />
<Stack.Screen name="WorkoutScreen"/>
</Stack> </Stack>
); );

@ -6,7 +6,6 @@ export default function RootoLayout() {
return ( return (
<Stack screenOptions={{ <Stack screenOptions={{
headerShown: false, headerShown: false,
presentation: "modal",
}}> }}>
<Stack.Screen name="HelpsScreen" /> <Stack.Screen name="HelpsScreen" />
</Stack> </Stack>

@ -9,11 +9,12 @@ import {Workout} from "@/model/Workout";
export default function HomeScreen() { export default function HomeScreen() {
const exercise = new Workout("Développé couché", 25,"8 Series Workout", 412, "assets/images/Sigma-2.png","Intense" ); const exercise = new Workout("Faire caca par terre", 25,"8 Series Workout", 412, "assets/images/Sigma-2.png","Intense" );
return ( return (
<ScrollView className="h-full ">
<Screen> <Screen>
<ScrollView className="h-full ">
<View className="h-1/6 justify-center"> <View className="h-1/6 justify-center">
<WelcomeComponent /> <WelcomeComponent />
@ -31,7 +32,7 @@ export default function HomeScreen() {
<CalendarComponent /> <CalendarComponent />
</View> </View>
<View className="h-1/5"> <View className="h-1/5 mt-8">
<View className="flex-row justify-between items-center mb-4"> <View className="flex-row justify-between items-center mb-4">
<Text className="text-lg font-bold text-black"> <Text className="text-lg font-bold text-black">
Workout Workout
@ -54,8 +55,7 @@ export default function HomeScreen() {
</View> </View>
<ActivitiesComponent /> <ActivitiesComponent />
</View> </View>
</ScrollView>
</Screen> </Screen>
</ScrollView>
); );
} }

@ -5,7 +5,6 @@ export default function RootoLayout() {
return ( return (
<Stack screenOptions={{ <Stack screenOptions={{
headerShown: false, headerShown: false,
presentation: "modal",
}}> }}>
<Stack.Screen name="HomeScreen" /> <Stack.Screen name="HomeScreen" />
</Stack> </Stack>

@ -5,7 +5,6 @@ export default function RootoLayout() {
return ( return (
<Stack screenOptions={{ <Stack screenOptions={{
headerShown: false, headerShown: false,
presentation: "modal",
}}> }}>
<Stack.Screen name="ProfileScreen" /> <Stack.Screen name="ProfileScreen" />
</Stack> </Stack>

@ -1,4 +1,4 @@
import { Redirect, Tabs } from "expo-router"; import {Redirect, Tabs, useRouter} from "expo-router";
import { useSession } from "@/ctx"; import { useSession } from "@/ctx";
import React from "react"; import React from "react";
import { AntDesign, Ionicons, MaterialIcons } from "@expo/vector-icons"; import { AntDesign, Ionicons, MaterialIcons } from "@expo/vector-icons";
@ -7,6 +7,7 @@ import Loading from "../loading";
export default function TabBarLayout() { export default function TabBarLayout() {
const { session, isLoading } = useSession(); const { session, isLoading } = useSession();
const router = useRouter()
const sizeIcon = 24; const sizeIcon = 24;
// You can keep the splash screen open, or render a loading screen like we do here. // You can keep the splash screen open, or render a loading screen like we do here.
if (isLoading) { if (isLoading) {

@ -1,15 +1,17 @@
import { Link, Stack, usePathname } from 'expo-router'; import {Link, router, Stack, usePathname, useRouter} from 'expo-router';
import {StyleSheet, Text, View} from 'react-native'; import {Button, StyleSheet, Text, View} from 'react-native';
export default function NotFoundScreen() { export default function NotFoundScreen() {
const pathname = usePathname(); const pathname = usePathname();
const router = useRouter();
return ( return (
<> <>
<Stack.Screen options={{ title: 'Oops!' }} /> <Stack.Screen options={{ title: 'Oops!' }} />
<View style={styles.container}> <View style={styles.container}>
<Text>This screen {pathname} doesn't exist: {pathname}</Text> <Text>This screen {pathname} doesn't exist: {pathname}</Text>
<Button title="Retour Home" onPress={() => router.replace("/")}/>
<Text>Go to home screen!</Text> <Text>Go to home screen!</Text>
</View> </View>
</> </>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

@ -0,0 +1,58 @@
import React, { useEffect, useRef, useState } from 'react';
import { View, Text, Animated, TouchableOpacity } from 'react-native';
export default function LinearProgressBar({ duration = 10 }) {
const [timeLeft, setTimeLeft] = useState(duration);
const [isRunning, setIsRunning] = useState(false);
const progress = useRef(new Animated.Value(0)).current;
const intervalRef = useRef(null);
const startAnimation = () => {
setIsRunning(true);
progress.setValue(0);
setTimeLeft(duration);
Animated.timing(progress, {
toValue: 1,
duration: duration * 1000,
useNativeDriver: false,
}).start(() => setIsRunning(false));
//@ts-ignore
intervalRef.current = setInterval(() => {
setTimeLeft((prev) => (prev > 0 ? prev - 1 : 0));
}, 1000);
};
useEffect(() => {
//@ts-ignore
return () => clearInterval(intervalRef.current);
}, []);
const progressWidth = progress.interpolate({
inputRange: [0, 1],
outputRange: ["0%", "100%"],
});
return (
<View className="w-full p-4 items-center">
<Text className="text-center mb-2">Temps restant : {timeLeft}s</Text>
<View className="w-full h-4 bg-gray-200 rounded-full overflow-hidden mb-4">
<Animated.View
style={{ width: progressWidth }}
className="h-full bg-orange-400"
/>
</View>
<TouchableOpacity
onPress={startAnimation}
disabled={isRunning}
className={`px-4 py-2 rounded-full ${isRunning ? 'bg-orange-400' : 'bg-orange-400'}`}
>
<Text className="text-white font-bold">
{isRunning ? 'En cours...' : 'Play'}
</Text>
</TouchableOpacity>
</View>
);
}

@ -2,6 +2,7 @@ import {ImageBackground, Text, TouchableOpacity, View} from "react-native";
import React from "react"; import React from "react";
import {AntDesign, MaterialCommunityIcons} from "@expo/vector-icons"; import {AntDesign, MaterialCommunityIcons} from "@expo/vector-icons";
import {Workout} from "@/model/Workout"; import {Workout} from "@/model/Workout";
import {Link, useRouter} from "expo-router";
interface WorkoutCardComponentProps { interface WorkoutCardComponentProps {
exercise: Workout, exercise: Workout,
@ -15,19 +16,15 @@ export default function WorkoutCardComponent({exercise, height, background}: Wor
const style = () => { const style = () => {
return `rounded-2xl overflow-hidden ${background ?? "bg-black"}` return `h-full rounded-2xl overflow-hidden ${background ?? "bg-black"}`
} }
const styleImage = () => { const styleImage = () => {
return `w-full h ` return `w-full h-full `
} }
const router = useRouter();
console.log(styleImage())
console.log(style())
return ( return (
<View className={style()}> <View className="h-full rounded-2xl overflow-hidden bg-black">
<ImageBackground <ImageBackground
@ -57,8 +54,10 @@ export default function WorkoutCardComponent({exercise, height, background}: Wor
</Text> </Text>
</View> </View>
</View> </View>
<TouchableOpacity className="absolute bottom-2 right-4 p-4 rounded-full"
<TouchableOpacity className="absolute bottom-2 right-4 p-4 rounded-full"> onPress={() => {
router.push("/WorkoutScreen");
}}>
<AntDesign name="play" size={50} color="orange"/> <AntDesign name="play" size={50} color="orange"/>
</TouchableOpacity> </TouchableOpacity>
</ImageBackground> </ImageBackground>

@ -0,0 +1,28 @@
import {ImageBackground, TouchableOpacity, View} from "react-native";
import Screen from "@/components/ui/Screen";
import * as React from "react";
import {Ionicons} from "@expo/vector-icons";
import {useRouter} from "expo-router";
import LinearProgressBar from "@/components/LinearProgressBar";
export default function WorkoutPresentationComponent() {
const router = useRouter()
return (
<ImageBackground className="h-full w-full"
source={require("assets/images/sigmaC.jpeg")}>
<Screen>
<View>
<TouchableOpacity
onPress={() => {
router.replace("/ExercicesScreen");
}}>
<Ionicons name="chevron-back-circle-outline" size={50} color="white"/>
</TouchableOpacity>
</View>
<LinearProgressBar duration={12}/>
</Screen>
</ImageBackground>
)
}

18
package-lock.json generated

@ -37,6 +37,7 @@
"react-native": "0.76.6", "react-native": "0.76.6",
"react-native-gesture-handler": "^2.20.2", "react-native-gesture-handler": "^2.20.2",
"react-native-gifted-charts": "^1.4.54", "react-native-gifted-charts": "^1.4.54",
"react-native-linear-timer": "^1.4.0",
"react-native-reanimated": "~3.16.1", "react-native-reanimated": "~3.16.1",
"react-native-safe-area-context": "4.12.0", "react-native-safe-area-context": "4.12.0",
"react-native-screens": "^4.4.0", "react-native-screens": "^4.4.0",
@ -12287,10 +12288,21 @@
"react-native": ">=0.73.0" "react-native": ">=0.73.0"
} }
}, },
"node_modules/react-native-linear-timer": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/react-native-linear-timer/-/react-native-linear-timer-1.4.0.tgz",
"integrity": "sha512-osZqS4toVi4JGbq4xVW0DmLGXyElMltwYjMaqACSkaR7WC8mYPnKckKPBRlVjHrTnrAgeZoGm2t9UbXRGX3jOQ==",
"license": "MIT",
"peerDependencies": {
"prop-types": "*",
"react": "*",
"react-native": "*"
}
},
"node_modules/react-native-reanimated": { "node_modules/react-native-reanimated": {
"version": "3.16.6", "version": "3.16.7",
"resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-3.16.6.tgz", "resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-3.16.7.tgz",
"integrity": "sha512-jPbAfLF5t8+UCKFTO+LeOY+OmAcDP5SsAfqINvNQz5GFGvoO7UebxujjtY58CmpZNH6c3SQ514FF9//mZDpo/g==", "integrity": "sha512-qoUUQOwE1pHlmQ9cXTJ2MX9FQ9eHllopCLiWOkDkp6CER95ZWeXhJCP4cSm6AD4jigL5jHcZf/SkWrg8ttZUsw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@babel/plugin-transform-arrow-functions": "^7.0.0-0", "@babel/plugin-transform-arrow-functions": "^7.0.0-0",

@ -44,6 +44,7 @@
"react-native": "0.76.6", "react-native": "0.76.6",
"react-native-gesture-handler": "^2.20.2", "react-native-gesture-handler": "^2.20.2",
"react-native-gifted-charts": "^1.4.54", "react-native-gifted-charts": "^1.4.54",
"react-native-linear-timer": "^1.4.0",
"react-native-reanimated": "~3.16.1", "react-native-reanimated": "~3.16.1",
"react-native-safe-area-context": "4.12.0", "react-native-safe-area-context": "4.12.0",
"react-native-screens": "^4.4.0", "react-native-screens": "^4.4.0",

Loading…
Cancel
Save