commit
ebd7cbc1ad
@ -1 +1,9 @@
|
|||||||
*.pbxproj -text
|
#
|
||||||
|
# https://help.github.com/articles/dealing-with-line-endings/
|
||||||
|
#
|
||||||
|
# Linux start script should use lf
|
||||||
|
/gradlew text eol=lf
|
||||||
|
|
||||||
|
# These are Windows script files and should use crlf
|
||||||
|
*.bat text eol=crlf
|
||||||
|
|
||||||
|
@ -1,63 +1,30 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {StyleSheet, View } from 'react-native';
|
import { NavigationContainer } from '@react-navigation/native';
|
||||||
import ProfileModification from './components/ProfileModification';
|
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
|
||||||
import ValidateButton from './components/ValidateButton';
|
|
||||||
import { LinearGradient } from 'expo-linear-gradient';
|
|
||||||
import RecipeSuggestion from './screens/RecipeSuggestion';
|
|
||||||
import RecipeDetails from './screens/RecipeDetails';
|
|
||||||
import IngredientSelection from './screens/IngredientSelection';
|
|
||||||
|
|
||||||
export default function App() {
|
import HomeStackScreen from './navigation/HomeStackScreen';
|
||||||
const all = [{value: "Mussels"}, {value: "Skimmed Milk"}, {value: "Nuts"}]
|
import ProfilesStackScreen from './navigation/ProfileStackScreen';
|
||||||
const die = [{value: "Dairy free"}, {value: "Gluten free"}, {value: "Porkless"}, {value: "Vegan"}, {value: "Vegetarian"}, {value: "Pescatarian"}]
|
import CookingStackScreen from './navigation/CookingStackScreen';
|
||||||
const ingredient = [{value: "Chocolate"}, {value: "Skimmed Milk"}, {value: "Eggs"}, , {value: "Farine"}]
|
import BottomBar from './navigation/BottomBar';
|
||||||
const ustensils = [{value: "Bol"}, {value: "Fouet"}, {value: "Casserole"}]
|
import { ThemeProvider } from './theme/ThemeContext';
|
||||||
const steps = [{value: "Chauffer chocolat"},
|
import { ColorProvider } from './theme/ColorContext';
|
||||||
{value: "1. Casser oeuf"},
|
|
||||||
{value: "2. Melanger la farine, le lait et les oeufs"},
|
|
||||||
{value: "3. Battre fort"},
|
|
||||||
{value: "4. Voler la montre de Louison"},
|
|
||||||
{value: "5. Melanger avec le chocolat"},
|
|
||||||
{value: "6. Mettre au four"},
|
|
||||||
]
|
|
||||||
|
|
||||||
function generateList() {
|
|
||||||
const list = [];
|
|
||||||
list.push("Meat");
|
|
||||||
list.push("Meat");
|
|
||||||
list.push("Meat");
|
|
||||||
list.push("Meat");
|
|
||||||
list.push("Teat");
|
|
||||||
list.push("Meat");
|
|
||||||
list.push("Meat");
|
|
||||||
list.push("Meat");
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ingredients = generateList();
|
const Tab = createBottomTabNavigator();
|
||||||
|
|
||||||
|
export default function App() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
/*<IngredientSelection listIngredient={ingredients}></IngredientSelection>*/
|
<ThemeProvider>
|
||||||
/*<RecipeSuggestion list={ingredients} diets={die} allergy={all}></RecipeSuggestion>*/
|
<ColorProvider>
|
||||||
<RecipeDetails id={123}></RecipeDetails>
|
<NavigationContainer>
|
||||||
|
<Tab.Navigator initialRouteName='HOME' tabBar={ (props) => <BottomBar {...props}/> }>
|
||||||
|
<Tab.Screen name='PROFILE' component={ProfilesStackScreen} options={{ headerShown: false, title: 'Profile' }} />
|
||||||
|
<Tab.Screen name='HOME' component={HomeStackScreen} options={{ headerShown: false, title: 'Home' }}/>
|
||||||
|
<Tab.Screen name='COOKING' component={CookingStackScreen} options={{ headerShown: false, title: 'Cooking' }}/>
|
||||||
|
</Tab.Navigator>
|
||||||
|
</NavigationContainer>
|
||||||
|
</ColorProvider>
|
||||||
|
</ThemeProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
|
||||||
container: {
|
|
||||||
flex: 1,
|
|
||||||
backgroundColor: '#3F3C42',
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center',
|
|
||||||
},
|
|
||||||
linearGradient: {
|
|
||||||
//height: 844,
|
|
||||||
//width: 390,
|
|
||||||
flex: 1,
|
|
||||||
padding: 10,
|
|
||||||
paddingTop: 0,
|
|
||||||
//backgroundColor: "#59BDCD",
|
|
||||||
//alignItems: 'center',
|
|
||||||
//justifyContent: 'flex-start',
|
|
||||||
},
|
|
||||||
});
|
|
After Width: | Height: | Size: 9.0 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 11 KiB |
@ -0,0 +1,135 @@
|
|||||||
|
import React, { useContext, useState } from 'react';
|
||||||
|
import { View, Text, TouchableOpacity, Image, Pressable } from 'react-native';
|
||||||
|
import { GestureResponderEvent, StyleSheet } from 'react-native';
|
||||||
|
import { BlurView } from 'expo-blur';
|
||||||
|
import ThemeContext from '../theme/ThemeContext';
|
||||||
|
import ColorContext from '../theme/ColorContext';
|
||||||
|
import { LightTheme, DarkTheme } from '../theme/colors';
|
||||||
|
|
||||||
|
import HomeIcon from '../assets/images/home.png';
|
||||||
|
import ProfileIcon from '../assets/images/person_icon.png';
|
||||||
|
import CookingIcon from '../assets/images/cook.png';
|
||||||
|
import LightIcon from '../assets/images/sun.png';
|
||||||
|
import DarkIcon from '../assets/images/moon.png';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export default function BottomBar({ state, descriptors, navigation }) {
|
||||||
|
const {theme, toggleTheme} = useContext(ThemeContext);
|
||||||
|
const {colors, toggleColors} = useContext(ColorContext)
|
||||||
|
const [iconThemeButton, setThemeIconButton] = useState(( theme === 'dark' ) ? LightIcon : DarkIcon)
|
||||||
|
const [textThemeButton, setTextThemeButton] = useState(( theme === 'dark' ) ? 'Light' : 'Dark');
|
||||||
|
|
||||||
|
const onThemeButtonPress = (event: GestureResponderEvent) => {
|
||||||
|
if (textThemeButton === "Light") {
|
||||||
|
setThemeIconButton(DarkIcon);
|
||||||
|
setTextThemeButton("Dark");
|
||||||
|
toggleTheme('light');
|
||||||
|
toggleColors(LightTheme)
|
||||||
|
} else {
|
||||||
|
setThemeIconButton(LightIcon);
|
||||||
|
setTextThemeButton("Light");
|
||||||
|
toggleTheme('dark')
|
||||||
|
toggleColors(DarkTheme)
|
||||||
|
}
|
||||||
|
console.log('TextThemeButton is now: ' + textThemeButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
BottomBarMainContainer: {
|
||||||
|
position: 'absolute',
|
||||||
|
bottom: 0,
|
||||||
|
right: 0,
|
||||||
|
left: 0,
|
||||||
|
height: 70,
|
||||||
|
backgroundColor: theme === 'dark' ? "#3F3C42" : "transparent"
|
||||||
|
},
|
||||||
|
BottomBarBlurContainer: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
alignContent: 'space-around',
|
||||||
|
padding: 2,
|
||||||
|
borderBlockColor: theme === 'light' ? '#F2F0E4' : '#222222',
|
||||||
|
borderWidth: 3,
|
||||||
|
borderLeftColor: theme === 'light'? '#F2F0E4' : '#222222',
|
||||||
|
borderLeftWidth: 3,
|
||||||
|
borderRightColor: theme === 'light'? '#F2F0E4' : '#222222',
|
||||||
|
borderRightWidth: 3
|
||||||
|
},
|
||||||
|
BottomBarIcon: {
|
||||||
|
width: 35,
|
||||||
|
height: 35
|
||||||
|
},
|
||||||
|
BottomBarElementContainer: {
|
||||||
|
flexDirection: 'column',
|
||||||
|
alignItems: 'center',
|
||||||
|
margin: 3
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.BottomBarMainContainer}>
|
||||||
|
<BlurView
|
||||||
|
style={[StyleSheet.absoluteFill, styles.BottomBarBlurContainer]}
|
||||||
|
tint='dark'
|
||||||
|
intensity={theme === 'light' ? 50 : 0}
|
||||||
|
>
|
||||||
|
{state.routes.map((route, index) => {
|
||||||
|
const { options } = descriptors[route.key];
|
||||||
|
const label =
|
||||||
|
options.tabBarLabel !== undefined
|
||||||
|
? options.tabBarLabel
|
||||||
|
: options.title !== undefined
|
||||||
|
? options.title
|
||||||
|
: route.name;
|
||||||
|
|
||||||
|
let icon;
|
||||||
|
if (route.name === 'HOME') {
|
||||||
|
icon = HomeIcon;
|
||||||
|
} else if (route.name === 'PROFILE') {
|
||||||
|
icon = ProfileIcon;
|
||||||
|
} else if (route.name === 'COOKING') {
|
||||||
|
icon = CookingIcon;
|
||||||
|
}
|
||||||
|
|
||||||
|
const isFocused = state.index === index;
|
||||||
|
|
||||||
|
const onPress = () => {
|
||||||
|
const event = navigation.emit({
|
||||||
|
type: 'tabPress',
|
||||||
|
target: route.key,
|
||||||
|
canPreventDefault: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!isFocused && !event.defaultPrevented) {
|
||||||
|
navigation.navigate(route.name, route.params);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TouchableOpacity
|
||||||
|
accessibilityRole="button"
|
||||||
|
accessibilityState={isFocused ? { selected: true } : {}}
|
||||||
|
accessibilityLabel={options.tabBarAccessibilityLabel}
|
||||||
|
testID={options.tabBarTestID}
|
||||||
|
onPress={onPress}
|
||||||
|
style={[styles.BottomBarElementContainer, { flex: 1 }]}
|
||||||
|
key={route.name}
|
||||||
|
>
|
||||||
|
<Image source={icon} style={[styles.BottomBarIcon, {tintColor: isFocused ? (theme === 'light' ? '#59BDCD': '#8DB4D9'): '#F2F0E4'}]} />
|
||||||
|
<Text style={{ color: isFocused ? '#59BDCD' : '#F2F0E4' }}>
|
||||||
|
{label}
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
<Pressable onPress={ onThemeButtonPress }>
|
||||||
|
<Image source={iconThemeButton} style={[styles.BottomBarIcon, {tintColor: '#F2F0E4'}]} />
|
||||||
|
<Text style={{color: '#F2F0E4'}}>
|
||||||
|
{textThemeButton}
|
||||||
|
</Text>
|
||||||
|
</Pressable>
|
||||||
|
</BlurView>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
import React, { useContext } from 'react'
|
||||||
|
import { StyleSheet } from 'react-native'
|
||||||
|
import { createNativeStackNavigator } from '@react-navigation/native-stack';
|
||||||
|
|
||||||
|
import IngredientSelection from '../screens/IngredientSelection';
|
||||||
|
import { HeaderTitle } from './Utils';
|
||||||
|
import ThemeContext from '../theme/ThemeContext';
|
||||||
|
|
||||||
|
const CookingStack = createNativeStackNavigator()
|
||||||
|
|
||||||
|
export default function CookingStackScreen() {
|
||||||
|
const {theme, toggleTheme} = useContext(ThemeContext);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<CookingStack.Navigator>
|
||||||
|
<CookingStack.Screen
|
||||||
|
name='IngredientSelection'
|
||||||
|
component={IngredientSelection}
|
||||||
|
options={{
|
||||||
|
headerStyle: {backgroundColor: theme === 'light' ? '#F2F0E4' : '#3F3C42'},
|
||||||
|
headerTitle: () => (
|
||||||
|
<HeaderTitle title='Profile Modification'/>
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</CookingStack.Navigator>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
headerBarContainer: {
|
||||||
|
backgroundColor: '#F2F0E4',
|
||||||
|
},
|
||||||
|
})
|
@ -0,0 +1,81 @@
|
|||||||
|
import React, { useContext } from 'react';
|
||||||
|
import { Image, Text, StyleSheet } from 'react-native';
|
||||||
|
import { createNativeStackNavigator } from '@react-navigation/native-stack';
|
||||||
|
|
||||||
|
import HomePage from '../screens/HomePage';
|
||||||
|
import Profiles from '../screens/Profiles';
|
||||||
|
import CreateProfile from '../screens/CreateProfile';
|
||||||
|
import ModifyProfile from '../screens/ModifyProfile';
|
||||||
|
import ThemeContext from '../theme/ThemeContext';
|
||||||
|
import ColorContext from '../theme/ColorContext';
|
||||||
|
import { HeaderTitle } from './Utils';
|
||||||
|
|
||||||
|
import appLogo from '../assets/images/logo.png';
|
||||||
|
|
||||||
|
const HomeStack = createNativeStackNavigator()
|
||||||
|
|
||||||
|
function AppIcon() {
|
||||||
|
return (
|
||||||
|
<Image
|
||||||
|
source={appLogo}
|
||||||
|
style={styles.headerAppIcon}/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function HomeStackScreen() {
|
||||||
|
const {theme, toggleTheme} = useContext(ThemeContext)
|
||||||
|
const {colors, toggleColors} = useContext(ColorContext)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<HomeStack.Navigator>
|
||||||
|
<HomeStack.Screen
|
||||||
|
name='Home'
|
||||||
|
component={HomePage}
|
||||||
|
options={{
|
||||||
|
headerStyle: {backgroundColor: colors.cardBackground},
|
||||||
|
|
||||||
|
headerLeft: () => (
|
||||||
|
<AppIcon/>
|
||||||
|
),
|
||||||
|
|
||||||
|
headerTitle: () => (
|
||||||
|
<HeaderTitle title='LeftOvers'/>
|
||||||
|
),
|
||||||
|
headerTitleAlign: 'center',
|
||||||
|
|
||||||
|
headerRight: () => (
|
||||||
|
<AppIcon/>
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<HomeStack.Screen
|
||||||
|
name='Profiles'
|
||||||
|
component={Profiles}
|
||||||
|
options={{
|
||||||
|
headerStyle: {backgroundColor: colors.cardBackground},
|
||||||
|
headerTitle: () => (
|
||||||
|
<HeaderTitle title='Profiles'/>
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<HomeStack.Screen
|
||||||
|
name='ProfileModification'
|
||||||
|
component={ModifyProfile}
|
||||||
|
options={{
|
||||||
|
headerStyle: {backgroundColor: colors.cardBackground},
|
||||||
|
headerTitle: () => (
|
||||||
|
<HeaderTitle title='Profile Modification'/>
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</HomeStack.Navigator>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
headerAppIcon: {
|
||||||
|
width: 45,
|
||||||
|
height: 45,
|
||||||
|
marginHorizontal: 10,
|
||||||
|
}
|
||||||
|
})
|
@ -0,0 +1,91 @@
|
|||||||
|
import React, { useContext } from 'react'
|
||||||
|
import { StyleSheet, View, Image, Pressable } from 'react-native'
|
||||||
|
import { createNativeStackNavigator } from '@react-navigation/native-stack';
|
||||||
|
|
||||||
|
import Profiles from '../screens/Profiles';
|
||||||
|
import CreateProfile from '../screens/CreateProfile';
|
||||||
|
import ModifyProfile from '../screens/ModifyProfile';
|
||||||
|
import ThemeContext from '../theme/ThemeContext';
|
||||||
|
|
||||||
|
import { HeaderTitle } from './Utils';
|
||||||
|
|
||||||
|
import SearchIcon from '../assets/images/search.png';
|
||||||
|
import AddIcon from '../assets/images/plus.png'
|
||||||
|
|
||||||
|
const ProfilesStack = createNativeStackNavigator()
|
||||||
|
|
||||||
|
export default function ProfilesStackScreen({ navigation }) {
|
||||||
|
const {theme, toggleTheme} = useContext(ThemeContext);
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
headerBarContainer: {
|
||||||
|
backgroundColor: theme === 'light' ? '#F2F0E4' : '#3F3C42',
|
||||||
|
},
|
||||||
|
headerBarRightContainer: {
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignContent: 'space-between',
|
||||||
|
marginHorizontal: 10,
|
||||||
|
},
|
||||||
|
headerBarIcon: {
|
||||||
|
width: 30,
|
||||||
|
height: 30,
|
||||||
|
marginHorizontal: 10
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const _handleSearch = () => console.log('Searching');
|
||||||
|
const _handleHeaderAdd = () => navigation.navigate('ProfileCreation');
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ProfilesStack.Navigator>
|
||||||
|
<ProfilesStack.Screen
|
||||||
|
name='Profiles'
|
||||||
|
component={Profiles}
|
||||||
|
options={{
|
||||||
|
headerStyle: styles.headerBarContainer,
|
||||||
|
headerTitle: () => (
|
||||||
|
<HeaderTitle title='Profiles'/>
|
||||||
|
),
|
||||||
|
headerRight: () => (
|
||||||
|
<View style={styles.headerBarRightContainer}>
|
||||||
|
<Pressable onPress={_handleSearch}>
|
||||||
|
<Image
|
||||||
|
source={SearchIcon}
|
||||||
|
style={styles.headerBarIcon}
|
||||||
|
tintColor={theme === 'light' ? '#3F3C42' : '#F2F0E4'}/>
|
||||||
|
</Pressable>
|
||||||
|
<Pressable onPress={_handleHeaderAdd}>
|
||||||
|
<Image
|
||||||
|
source={AddIcon}
|
||||||
|
style={styles.headerBarIcon}
|
||||||
|
tintColor={theme === 'light' ? '#3F3C42' : '#F2F0E4'}/>
|
||||||
|
</Pressable>
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<ProfilesStack.Screen
|
||||||
|
name='ProfileCreation'
|
||||||
|
component={CreateProfile}
|
||||||
|
options={{
|
||||||
|
headerStyle: styles.headerBarContainer,
|
||||||
|
headerTitle: () => (
|
||||||
|
<HeaderTitle title='Profile Creation'/>
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<ProfilesStack.Screen
|
||||||
|
name='ProfileModification'
|
||||||
|
component={ModifyProfile}
|
||||||
|
options={{
|
||||||
|
headerStyle: styles.headerBarContainer,
|
||||||
|
headerTitle: () => (
|
||||||
|
<HeaderTitle title='Profile Modification'/>
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</ProfilesStack.Navigator>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,23 @@
|
|||||||
|
import React, { useContext } from 'react';
|
||||||
|
import { Text, StyleSheet } from 'react-native';
|
||||||
|
|
||||||
|
import ColorContext from '../theme/ColorContext';
|
||||||
|
|
||||||
|
export function HeaderTitle(props) {
|
||||||
|
const {colors, toggleColors} = useContext(ColorContext)
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
headerTitle: {
|
||||||
|
fontSize: 20,
|
||||||
|
fontWeight: "bold",
|
||||||
|
color: colors.cardDetail,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Text
|
||||||
|
style={styles.headerTitle}>
|
||||||
|
{props.title}
|
||||||
|
</Text>
|
||||||
|
)
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,42 @@
|
|||||||
|
import React, {createContext, useState, useEffect} from 'react';
|
||||||
|
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||||
|
|
||||||
|
import { LightTheme, Theme } from './colors';
|
||||||
|
|
||||||
|
interface ColorContextType {
|
||||||
|
colors: Theme,
|
||||||
|
toggleColors: (Theme) => void
|
||||||
|
};
|
||||||
|
|
||||||
|
const ColorContext = createContext<ColorContextType | null>(null);
|
||||||
|
|
||||||
|
export const ColorProvider = ({ children }) => {
|
||||||
|
const [colors, setColors] = useState(LightTheme);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const getColors = async () => {
|
||||||
|
try {
|
||||||
|
const savedColors = await AsyncStorage.getItem('colors');
|
||||||
|
if (savedColors) {
|
||||||
|
setColors(JSON.parse(savedColors));
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log('Error loading colors:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
getColors();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const toggleColors = (newColors: Theme) => {
|
||||||
|
setColors(newColors);
|
||||||
|
AsyncStorage.setItem('colors', JSON.stringify(newColors))
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ColorContext.Provider value={{colors, toggleColors}}>
|
||||||
|
{children}
|
||||||
|
</ColorContext.Provider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ColorContext;
|
@ -0,0 +1,42 @@
|
|||||||
|
import React, {createContext, useState, useEffect} from 'react';
|
||||||
|
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||||
|
|
||||||
|
|
||||||
|
interface ThemeContextType {
|
||||||
|
theme: string,
|
||||||
|
toggleTheme: (any)=> void
|
||||||
|
};
|
||||||
|
|
||||||
|
const ThemeContext = createContext<ThemeContextType | null>(null);
|
||||||
|
|
||||||
|
export const ThemeProvider = ({ children }) => {
|
||||||
|
const [theme, setTheme] = useState('light');
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// Load saved theme from storage
|
||||||
|
const getTheme = async () => {
|
||||||
|
try {
|
||||||
|
const savedTheme = await AsyncStorage.getItem('theme');
|
||||||
|
if (savedTheme) {
|
||||||
|
setTheme(savedTheme);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log('Error loading theme:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
getTheme();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const toggleTheme = newTheme => {
|
||||||
|
setTheme(newTheme);
|
||||||
|
AsyncStorage.setItem('theme', newTheme)
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ThemeContext.Provider value={{theme, toggleTheme}}>
|
||||||
|
{children}
|
||||||
|
</ThemeContext.Provider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ThemeContext;
|
@ -0,0 +1,81 @@
|
|||||||
|
const Ecru = '#ACA279'
|
||||||
|
const Alabaster = '#F2F0E4'
|
||||||
|
const Jet = '#3F3C42'
|
||||||
|
const Moonstone = '#59BDCD'
|
||||||
|
const Cerulean = '#2680AA'
|
||||||
|
const Celeste = '#ADF3EA'
|
||||||
|
const Tan = '#E0C293'
|
||||||
|
const Pearl = '#E3DEC9'
|
||||||
|
const EerieBlack = '#222222'
|
||||||
|
const CarolinaBlue = '#8DB4D9'
|
||||||
|
const SteelBlue = '#5882A8'
|
||||||
|
|
||||||
|
export interface Theme {
|
||||||
|
primary: string,
|
||||||
|
primaryComplement: string,
|
||||||
|
cardBackground: string,
|
||||||
|
cardTitle: string,
|
||||||
|
cardDetail: string,
|
||||||
|
cardElementBackground: string,
|
||||||
|
cardElementText: string,
|
||||||
|
cardElementBorder: string,
|
||||||
|
cardElementTitle: string,
|
||||||
|
cardElementTitleBackground: string,
|
||||||
|
ingredientBackground: string,
|
||||||
|
ingredientContent: string,
|
||||||
|
ingredientBorder: string,
|
||||||
|
buttonBackground: string,
|
||||||
|
buttonDetail: string,
|
||||||
|
welcomeText: string,
|
||||||
|
welcomeName: string,
|
||||||
|
carrouselBackground: string,
|
||||||
|
carrouselText: string,
|
||||||
|
carrouselDetail: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export const LightTheme : Theme = {
|
||||||
|
primary: Cerulean,
|
||||||
|
primaryComplement: Moonstone,
|
||||||
|
cardBackground: Alabaster,
|
||||||
|
cardTitle: Ecru,
|
||||||
|
cardDetail: Jet,
|
||||||
|
cardElementBackground: Pearl,
|
||||||
|
cardElementText: Jet,
|
||||||
|
cardElementBorder: Ecru,
|
||||||
|
cardElementTitle: Jet,
|
||||||
|
cardElementTitleBackground: Alabaster,
|
||||||
|
ingredientBackground: Pearl,
|
||||||
|
ingredientBorder: EerieBlack,
|
||||||
|
ingredientContent: Jet,
|
||||||
|
buttonBackground: Pearl,
|
||||||
|
buttonDetail: Moonstone,
|
||||||
|
welcomeText: Ecru,
|
||||||
|
welcomeName: Moonstone,
|
||||||
|
carrouselBackground: Pearl,
|
||||||
|
carrouselText: Ecru,
|
||||||
|
carrouselDetail: Moonstone
|
||||||
|
}
|
||||||
|
|
||||||
|
export const DarkTheme : Theme = {
|
||||||
|
primary: EerieBlack,
|
||||||
|
primaryComplement: Jet,
|
||||||
|
cardBackground: Jet,
|
||||||
|
cardTitle: Alabaster,
|
||||||
|
cardDetail: Alabaster,
|
||||||
|
cardElementBackground: SteelBlue,
|
||||||
|
cardElementText: Jet,
|
||||||
|
cardElementTitle: Alabaster,
|
||||||
|
cardElementBorder: SteelBlue,
|
||||||
|
cardElementTitleBackground: CarolinaBlue,
|
||||||
|
ingredientBackground: EerieBlack,
|
||||||
|
ingredientBorder: SteelBlue,
|
||||||
|
ingredientContent: Alabaster,
|
||||||
|
buttonBackground: Jet,
|
||||||
|
buttonDetail: CarolinaBlue,
|
||||||
|
welcomeText: SteelBlue,
|
||||||
|
welcomeName:Alabaster,
|
||||||
|
carrouselBackground: CarolinaBlue,
|
||||||
|
carrouselText: SteelBlue,
|
||||||
|
carrouselDetail: Alabaster
|
||||||
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"dependencies": {
|
|
||||||
"@eva-design/eva": "^2.2.0",
|
|
||||||
"@ui-kitten/components": "^5.3.1",
|
|
||||||
"expo": "^49.0.17",
|
|
||||||
"react-native-svg": "^13.14.0",
|
|
||||||
"typescript": "^5.1.3",
|
|
||||||
"@types/react": "~18.2.14",
|
|
||||||
"react-native-web": "~0.19.6",
|
|
||||||
"react-dom": "18.2.0",
|
|
||||||
"@expo/webpack-config": "^19.0.0"
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in new issue