pull/4/head
Tony Fages 5 months ago
parent 13d438a95a
commit 82c92a75d6

@ -1,53 +1,118 @@
import {Stack, Tabs} from "expo-router";
import "../global.css";
import { GluestackUIProvider } from "./src/components/ui/gluestack-ui-provider";
import HomeScreen from "@/src/screen/HomeScreen";
import ProfileScreen from "@/src/screen/ProfileScreen";
import React from "react";
import Navigation from "@/src/navigation/navigation";
import {SafeAreaView} from "react-native";
import {createBottomTabNavigator} from "@react-navigation/bottom-tabs";
import {AntDesign, MaterialIcons} from "@expo/vector-icons";
import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
import {
AntDesign,
Entypo,
MaterialCommunityIcons,
MaterialIcons,
} from "@expo/vector-icons";
export default function RootLayout() {
const BottomTabNavigator = createBottomTabNavigator();
return (
<GluestackUIProvider>
<BottomTabNavigator.Navigator initialRouteName={"Home"}
screenOptions={{
headerShown: false, // Désactive les en-têtes si vous voulez uniquement les onglets
tabBarActiveTintColor: '#007AFF', // Couleur des icônes actives
tabBarInactiveTintColor: '#8e8e93', // Couleur des icônes inactives
}}>
<BottomTabNavigator.Navigator
initialRouteName="Home"
screenOptions={{
headerShown: false,
tabBarShowLabel: false,
tabBarStyle: {
height: 75,
backgroundColor: "#f9f9f9",
},
tabBarActiveTintColor: "black",
tabBarInactiveTintColor: "#8e8e93",
tabBarItemStyle: {
borderRadius: 50,
},
}}
>
<BottomTabNavigator.Screen
name="Home"
component={HomeScreen}
options={{
title: 'Accueil',
tabBarIcon: ({ color, size }) => (
<MaterialIcons name="home" color={color} size={size} />
tabBarIcon: ({ color, size, focused }) => (
<MaterialIcons
name="home"
color={focused ? "black" : color}
size={focused ? size + 4 : size}
/>
),
}}
/>
<BottomTabNavigator.Screen name={"Settings"} component={ProfileScreen}
options={{
title: 'Profile',
tabBarIcon: ({ color, size }) => (
<MaterialIcons name="account-circle" size={24} color={color} />
),
}}/>
<BottomTabNavigator.Screen
name="Exercice"
component={ProfileScreen}
options={{
tabBarIcon: ({ color, size, focused }) => (
<MaterialCommunityIcons
name="dumbbell"
size={focused ? size + 4 : size}
color={focused ? "black" : color}
/>
),
}}
/>
</BottomTabNavigator.Navigator>
</GluestackUIProvider>
);
}
<BottomTabNavigator.Screen
name="Add"
component={ProfileScreen}
options={{
tabBarIcon: ({ color, size, focused }) => (
<Entypo
name="plus"
size={focused ? size + 6 : size}
color='white'
/>
),
tabBarItemStyle: {
borderRadius: 50,
backgroundColor: "orange",
},
}}
/>
<BottomTabNavigator.Screen
name="Help"
component={ProfileScreen}
options={{
tabBarIcon: ({ color, size, focused }) => (
<AntDesign
name="question"
size={focused ? size + 2 : size} // Augmente la taille si actif
color={focused ? "black" : color}
/>
),
}}
/>
<BottomTabNavigator.Screen
name="Settings"
component={ProfileScreen}
options={{
tabBarIcon: ({ color, size, focused }) => (
<MaterialIcons
name="account-circle"
size={focused ? size + 3 : size}
color={focused ? "black" : color}
/>
),
}}
/>
</BottomTabNavigator.Navigator>
</GluestackUIProvider>
);
}

@ -0,0 +1,186 @@
'use client';
import React from 'react';
import { createAvatar } from '@gluestack-ui/avatar';
import { View, Text, Image, Platform } from 'react-native';
import { tva } from '@gluestack-ui/nativewind-utils/tva';
import {
withStyleContext,
useStyleContext,
} from '@gluestack-ui/nativewind-utils/withStyleContext';
const SCOPE = 'AVATAR';
import type { VariantProps } from '@gluestack-ui/nativewind-utils';
const UIAvatar = createAvatar({
Root: withStyleContext(View, SCOPE),
Badge: View,
Group: View,
Image: Image,
FallbackText: Text,
});
const avatarStyle = tva({
base: 'rounded-full justify-center items-center relative bg-primary-600 group-[.avatar-group]/avatar-group:-ml-2.5',
variants: {
size: {
'xs': 'w-6 h-6',
'sm': 'w-8 h-8',
'md': 'w-12 h-12',
'lg': 'w-16 h-16',
'xl': 'w-24 h-24',
'2xl': 'w-32 h-32',
},
},
});
const avatarFallbackTextStyle = tva({
base: 'text-typography-0 font-semibold overflow-hidden text-transform:uppercase web:cursor-default',
parentVariants: {
size: {
'xs': 'text-2xs',
'sm': 'text-xs',
'md': 'text-base',
'lg': 'text-xl',
'xl': 'text-3xl',
'2xl': 'text-5xl',
},
},
});
const avatarGroupStyle = tva({
base: 'group/avatar-group flex-row-reverse relative avatar-group',
});
const avatarBadgeStyle = tva({
base: 'w-5 h-5 bg-success-500 rounded-full absolute right-0 bottom-0 border-background-0 border-2',
parentVariants: {
size: {
'xs': 'w-2 h-2',
'sm': 'w-2 h-2',
'md': 'w-3 h-3',
'lg': 'w-4 h-4',
'xl': 'w-6 h-6',
'2xl': 'w-8 h-8',
},
},
});
const avatarImageStyle = tva({
base: 'h-full w-full rounded-full absolute',
});
type IAvatarProps = Omit<
React.ComponentPropsWithoutRef<typeof UIAvatar>,
'context'
> &
VariantProps<typeof avatarStyle>;
const Avatar = React.forwardRef<
React.ElementRef<typeof UIAvatar>,
IAvatarProps
>(({ className, size = 'md', ...props }, ref) => {
return (
<UIAvatar
ref={ref}
{...props}
className={avatarStyle({ size, class: className })}
context={{ size }}
/>
);
});
type IAvatarBadgeProps = React.ComponentPropsWithoutRef<typeof UIAvatar.Badge> &
VariantProps<typeof avatarBadgeStyle>;
const AvatarBadge = React.forwardRef<
React.ElementRef<typeof UIAvatar.Badge>,
IAvatarBadgeProps
>(({ className, size, ...props }, ref) => {
const { size: parentSize } = useStyleContext(SCOPE);
return (
<UIAvatar.Badge
ref={ref}
{...props}
className={avatarBadgeStyle({
parentVariants: {
size: parentSize,
},
size,
class: className,
})}
/>
);
});
type IAvatarFallbackTextProps = React.ComponentPropsWithoutRef<
typeof UIAvatar.FallbackText
> &
VariantProps<typeof avatarFallbackTextStyle>;
const AvatarFallbackText = React.forwardRef<
React.ElementRef<typeof UIAvatar.FallbackText>,
IAvatarFallbackTextProps
>(({ className, size, ...props }, ref) => {
const { size: parentSize } = useStyleContext(SCOPE);
return (
<UIAvatar.FallbackText
ref={ref}
{...props}
className={avatarFallbackTextStyle({
parentVariants: {
size: parentSize,
},
size,
class: className,
})}
/>
);
});
type IAvatarImageProps = React.ComponentPropsWithoutRef<typeof UIAvatar.Image> &
VariantProps<typeof avatarImageStyle>;
const AvatarImage = React.forwardRef<
React.ElementRef<typeof UIAvatar.Image>,
IAvatarImageProps
>(({ className, ...props }, ref) => {
return (
<UIAvatar.Image
ref={ref}
{...props}
className={avatarImageStyle({
class: className,
})}
// @ts-expect-error
style={
Platform.OS === 'web'
? // eslint-disable-next-line react-native/no-inline-styles
{ height: 'revert-layer', width: 'revert-layer' }
: undefined
}
/>
);
});
type IAvatarGroupProps = React.ComponentPropsWithoutRef<typeof UIAvatar.Group> &
VariantProps<typeof avatarGroupStyle>;
const AvatarGroup = React.forwardRef<
React.ElementRef<typeof UIAvatar.Group>,
IAvatarGroupProps
>(({ className, ...props }, ref) => {
return (
<UIAvatar.Group
ref={ref}
{...props}
className={avatarGroupStyle({
class: className,
})}
/>
);
});
export { Avatar, AvatarBadge, AvatarFallbackText, AvatarImage, AvatarGroup };

@ -0,0 +1,19 @@
import React from 'react';
import { View, ViewProps } from 'react-native';
import type { VariantProps } from '@gluestack-ui/nativewind-utils';
import { boxStyle } from './styles';
type IBoxProps = ViewProps &
VariantProps<typeof boxStyle> & { className?: string };
const Box = React.forwardRef<React.ElementRef<typeof View>, IBoxProps>(
({ className, ...props }, ref) => {
return (
<View ref={ref} {...props} className={boxStyle({ class: className })} />
);
}
);
Box.displayName = 'Box';
export { Box };

@ -0,0 +1,18 @@
import React from 'react';
import { boxStyle } from './styles';
import type { VariantProps } from '@gluestack-ui/nativewind-utils';
type IBoxProps = React.ComponentPropsWithoutRef<'div'> &
VariantProps<typeof boxStyle> & { className?: string };
const Box = React.forwardRef<HTMLDivElement, IBoxProps>(
({ className, ...props }, ref) => {
return (
<div ref={ref} className={boxStyle({ class: className })} {...props} />
);
}
);
Box.displayName = 'Box';
export { Box };

@ -0,0 +1,10 @@
import { tva } from '@gluestack-ui/nativewind-utils/tva';
import { isWeb } from '@gluestack-ui/nativewind-utils/IsWeb';
const baseStyle = isWeb
? 'flex flex-col relative z-0 box-border border-0 list-none min-w-0 min-h-0 bg-transparent items-stretch m-0 p-0 text-decoration-none'
: '';
export const boxStyle = tva({
base: baseStyle,
});

13
package-lock.json generated

@ -9,6 +9,7 @@
"version": "1.0.0",
"dependencies": {
"@expo/vector-icons": "^14.0.2",
"@gluestack-ui/avatar": "^0.1.18",
"@gluestack-ui/button": "^1.0.8",
"@gluestack-ui/icon": "^0.1.25",
"@gluestack-ui/nativewind-utils": "^1.0.26",
@ -2383,6 +2384,18 @@
"tslib": "2"
}
},
"node_modules/@gluestack-ui/avatar": {
"version": "0.1.18",
"resolved": "https://registry.npmjs.org/@gluestack-ui/avatar/-/avatar-0.1.18.tgz",
"integrity": "sha512-VA9XwtavYLYCWrjxHc2u9gRpV97cPRcr/6KJ4tLiMiQbiRL1b4zckiL+/F39fB6xjUOUQHl3Fjo/Yd8swa0MBg==",
"dependencies": {
"@gluestack-ui/utils": "^0.1.14"
},
"peerDependencies": {
"react": ">=16",
"react-dom": ">=16"
}
},
"node_modules/@gluestack-ui/button": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/@gluestack-ui/button/-/button-1.0.8.tgz",

@ -16,6 +16,7 @@
},
"dependencies": {
"@expo/vector-icons": "^14.0.2",
"@gluestack-ui/avatar": "^0.1.18",
"@gluestack-ui/button": "^1.0.8",
"@gluestack-ui/icon": "^0.1.25",
"@gluestack-ui/nativewind-utils": "^1.0.26",

@ -0,0 +1,50 @@
import React from "react";
import {View, TouchableOpacity, ImageBackground, ImageBase} from "react-native";
import { AntDesign } from "@expo/vector-icons"; // Assure-toi d'avoir installé les icônes
import { Text } from "@/app/src/components/ui/text";
export default function ExerciceOverview() {
const exercise = {
name: "Jumping Jacks",
time: "00:30",
kcal: 5,
sets: 3,
difficulty: "Medium",
imageUri: "https://random-image-pepebigotes.vercel.app/api/random-image",
};
const image = {uri: exercise.imageUri};
return (
<View className="h-auto">
<ImageBackground
source={image}
imageStyle={{ borderRadius: 15 }}
className="rounded-xl flex-1" // Ajoutez flex-1 ici pour que l'ImageBackground prenne toute la hauteur disponible
>
<View className="flex-row p-80 ">
<Text className="font-extrabold text-black">{exercise.time}</Text>
<Text className="text-black">{exercise.kcal} kcal</Text>
</View>
<View className="flex-row">
<Text className="text-black">{exercise.name}</Text>
<Text className="text-black">{exercise.sets} Sets</Text>
<Text className="text-black">{exercise.difficulty} Difficulty</Text>
</View>
<View className="flex items-end">
<TouchableOpacity
onPress={() => console.log("Play exercise started")}
>
<AntDesign name="play" size={50} color="orange"/>
</TouchableOpacity>
</View>
</ImageBackground>
</View>
);
}

@ -1,13 +1,104 @@
import {View, Text, SafeAreaView} from "react-native";
import {SafeAreaView, StyleSheet, View} from "react-native";
import React from "react";
import {Avatar, AvatarFallbackText, AvatarImage,} from "@/app/src/components/ui/avatar"
import {AntDesign} from "@expo/vector-icons";
import {Text} from "@/app/src/components/ui/text";
import {Box} from "@/app/src/components/ui/box";
import ExerciceOverview from "@/src/component/ExerciceOverview";
export default function HomeScreen() {
const date = new Date();
const formattedDate = date.toLocaleDateString('fr-FR', {
year: 'numeric',
month: 'long',
day: 'numeric',
});
return (
<SafeAreaView>
<View>
<Text className="m-4">Edit src/screen/HomeScreen.tsx to edit this screen.</Text>
<SafeAreaView style={styles.container}>
<View style={styles.headerStyle}>
<View style={styles.dateContainer}>
<AntDesign name="calendar" size={24} color="white" />
<Text style={styles.dateText}>{formattedDate}</Text>
</View>
<View style={styles.avatarContainer}>
<Avatar size="xl">
<AvatarFallbackText>Jane Doe</AvatarFallbackText>
<AvatarImage
source={{
uri: 'https://images.unsplash.com/photo-1494790108377-be9c29b29330?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=687&q=80',
}}
/>
</Avatar>
<Text style={styles.titleNameUser}>Hello, Tata Monique</Text>
</View>
</View>
<View >
<ExerciceOverview/>
</View>
</SafeAreaView>
</SafeAreaView>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#f9f9f9', // Fond de l'écran avec une couleur claire
},
headerStyle: {
height: 200,
backgroundColor: '#333333', // Gris foncé pour l'arrière-plan du header
borderBottomEndRadius: 25,
borderBottomStartRadius: 25,
padding: 20,
alignItems: 'flex-start',
justifyContent: 'flex-start',
},
dateContainer: {
flexDirection: 'row',
alignItems: 'flex-start',
marginBottom: 20,
},
dateText: {
fontSize: 18,
fontWeight: 'bold',
marginLeft: 10,
color: '#ffffff',
},
avatarContainer: {
marginBottom: 15,
flexDirection: 'row',
alignItems: 'center',
},
titleNameUser: {
fontSize: 24,
color: '#ffffff',
fontWeight: 'bold',
marginLeft: 10,
},
contentContainer: {
marginTop: 20,
padding: 15,
alignItems: 'flex-start',
},
contentText: {
fontSize: 16,
color: '#333333', // Texte en gris foncé pour une bonne lisibilité
textAlign: 'center',
},
fitness: {
}
});
Loading…
Cancel
Save