add ui placeholder
@ -1,43 +1,57 @@
|
||||
import { Tabs } from 'expo-router';
|
||||
import React from 'react';
|
||||
import { Platform } from 'react-native';
|
||||
import { Tabs } from "expo-router";
|
||||
|
||||
import { HapticTab } from '@/components/HapticTab';
|
||||
import { IconSymbol } from '@/components/ui/IconSymbol';
|
||||
import TabBarBackground from '@/components/ui/TabBarBackground';
|
||||
import { Colors } from '@/constants/Colors';
|
||||
import { useColorScheme } from '@/hooks/useColorScheme';
|
||||
import { HapticTab } from "@/components/HapticTab";
|
||||
import { IconSymbol } from "@/components/ui/IconSymbol";
|
||||
|
||||
export default function TabLayout() {
|
||||
const colorScheme = useColorScheme();
|
||||
|
||||
return (
|
||||
<Tabs
|
||||
screenOptions={{
|
||||
tabBarActiveTintColor: Colors[colorScheme ?? 'light'].tint,
|
||||
tabBarActiveTintColor: "#FF0000", // Red active color
|
||||
headerShown: false,
|
||||
tabBarButton: HapticTab,
|
||||
tabBarBackground: TabBarBackground,
|
||||
tabBarStyle: Platform.select({
|
||||
ios: {
|
||||
// Use a transparent background on iOS to show the blur effect
|
||||
position: 'absolute',
|
||||
},
|
||||
default: {},
|
||||
}),
|
||||
}}>
|
||||
tabBarStyle: {
|
||||
backgroundColor: "#FFCC00", // Yellow background
|
||||
height: 60,
|
||||
paddingBottom: 5,
|
||||
borderTopWidth: 0,
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Tabs.Screen
|
||||
name="index"
|
||||
options={{
|
||||
title: 'Home',
|
||||
tabBarIcon: ({ color }) => <IconSymbol size={28} name="house.fill" color={color} />,
|
||||
title: "Home",
|
||||
tabBarIcon: ({ color }) => (
|
||||
<IconSymbol size={28} name="house.fill" color={color} />
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<Tabs.Screen
|
||||
name="explore"
|
||||
name="recipes"
|
||||
options={{
|
||||
title: 'Explore',
|
||||
tabBarIcon: ({ color }) => <IconSymbol size={28} name="paperplane.fill" color={color} />,
|
||||
title: "Recipes",
|
||||
tabBarIcon: ({ color }) => (
|
||||
<IconSymbol size={28} name="doc.text.fill" color={color} />
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<Tabs.Screen
|
||||
name="forum"
|
||||
options={{
|
||||
title: "Forum",
|
||||
tabBarIcon: ({ color }) => (
|
||||
<IconSymbol size={28} name="hand.thumbsup.fill" color={color} />
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<Tabs.Screen
|
||||
name="profile"
|
||||
options={{
|
||||
title: "Profile",
|
||||
tabBarIcon: ({ color }) => (
|
||||
<IconSymbol size={28} name="person.fill" color={color} />
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</Tabs>
|
||||
|
||||
@ -1,110 +0,0 @@
|
||||
import { Image } from 'expo-image';
|
||||
import { Platform, StyleSheet } from 'react-native';
|
||||
|
||||
import { Collapsible } from '@/components/Collapsible';
|
||||
import { ExternalLink } from '@/components/ExternalLink';
|
||||
import ParallaxScrollView from '@/components/ParallaxScrollView';
|
||||
import { ThemedText } from '@/components/ThemedText';
|
||||
import { ThemedView } from '@/components/ThemedView';
|
||||
import { IconSymbol } from '@/components/ui/IconSymbol';
|
||||
|
||||
export default function TabTwoScreen() {
|
||||
return (
|
||||
<ParallaxScrollView
|
||||
headerBackgroundColor={{ light: '#D0D0D0', dark: '#353636' }}
|
||||
headerImage={
|
||||
<IconSymbol
|
||||
size={310}
|
||||
color="#808080"
|
||||
name="chevron.left.forwardslash.chevron.right"
|
||||
style={styles.headerImage}
|
||||
/>
|
||||
}>
|
||||
<ThemedView style={styles.titleContainer}>
|
||||
<ThemedText type="title">Explore</ThemedText>
|
||||
</ThemedView>
|
||||
<ThemedText>This app includes example code to help you get started.</ThemedText>
|
||||
<Collapsible title="File-based routing">
|
||||
<ThemedText>
|
||||
This app has two screens:{' '}
|
||||
<ThemedText type="defaultSemiBold">app/(tabs)/index.tsx</ThemedText> and{' '}
|
||||
<ThemedText type="defaultSemiBold">app/(tabs)/explore.tsx</ThemedText>
|
||||
</ThemedText>
|
||||
<ThemedText>
|
||||
The layout file in <ThemedText type="defaultSemiBold">app/(tabs)/_layout.tsx</ThemedText>{' '}
|
||||
sets up the tab navigator.
|
||||
</ThemedText>
|
||||
<ExternalLink href="https://docs.expo.dev/router/introduction">
|
||||
<ThemedText type="link">Learn more</ThemedText>
|
||||
</ExternalLink>
|
||||
</Collapsible>
|
||||
<Collapsible title="Android, iOS, and web support">
|
||||
<ThemedText>
|
||||
You can open this project on Android, iOS, and the web. To open the web version, press{' '}
|
||||
<ThemedText type="defaultSemiBold">w</ThemedText> in the terminal running this project.
|
||||
</ThemedText>
|
||||
</Collapsible>
|
||||
<Collapsible title="Images">
|
||||
<ThemedText>
|
||||
For static images, you can use the <ThemedText type="defaultSemiBold">@2x</ThemedText> and{' '}
|
||||
<ThemedText type="defaultSemiBold">@3x</ThemedText> suffixes to provide files for
|
||||
different screen densities
|
||||
</ThemedText>
|
||||
<Image source={require('@/assets/images/react-logo.png')} style={{ alignSelf: 'center' }} />
|
||||
<ExternalLink href="https://reactnative.dev/docs/images">
|
||||
<ThemedText type="link">Learn more</ThemedText>
|
||||
</ExternalLink>
|
||||
</Collapsible>
|
||||
<Collapsible title="Custom fonts">
|
||||
<ThemedText>
|
||||
Open <ThemedText type="defaultSemiBold">app/_layout.tsx</ThemedText> to see how to load{' '}
|
||||
<ThemedText style={{ fontFamily: 'SpaceMono' }}>
|
||||
custom fonts such as this one.
|
||||
</ThemedText>
|
||||
</ThemedText>
|
||||
<ExternalLink href="https://docs.expo.dev/versions/latest/sdk/font">
|
||||
<ThemedText type="link">Learn more</ThemedText>
|
||||
</ExternalLink>
|
||||
</Collapsible>
|
||||
<Collapsible title="Light and dark mode components">
|
||||
<ThemedText>
|
||||
This template has light and dark mode support. The{' '}
|
||||
<ThemedText type="defaultSemiBold">useColorScheme()</ThemedText> hook lets you inspect
|
||||
what the user's current color scheme is, and so you can adjust UI colors accordingly.
|
||||
</ThemedText>
|
||||
<ExternalLink href="https://docs.expo.dev/develop/user-interface/color-themes/">
|
||||
<ThemedText type="link">Learn more</ThemedText>
|
||||
</ExternalLink>
|
||||
</Collapsible>
|
||||
<Collapsible title="Animations">
|
||||
<ThemedText>
|
||||
This template includes an example of an animated component. The{' '}
|
||||
<ThemedText type="defaultSemiBold">components/HelloWave.tsx</ThemedText> component uses
|
||||
the powerful <ThemedText type="defaultSemiBold">react-native-reanimated</ThemedText>{' '}
|
||||
library to create a waving hand animation.
|
||||
</ThemedText>
|
||||
{Platform.select({
|
||||
ios: (
|
||||
<ThemedText>
|
||||
The <ThemedText type="defaultSemiBold">components/ParallaxScrollView.tsx</ThemedText>{' '}
|
||||
component provides a parallax effect for the header image.
|
||||
</ThemedText>
|
||||
),
|
||||
})}
|
||||
</Collapsible>
|
||||
</ParallaxScrollView>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
headerImage: {
|
||||
color: '#808080',
|
||||
bottom: -90,
|
||||
left: -35,
|
||||
position: 'absolute',
|
||||
},
|
||||
titleContainer: {
|
||||
flexDirection: 'row',
|
||||
gap: 8,
|
||||
},
|
||||
});
|
||||
260
app/(tabs)/forum.tsx
Normal file
@ -0,0 +1,260 @@
|
||||
import { IconSymbol } from "@/components/ui/IconSymbol";
|
||||
import { Image } from "expo-image";
|
||||
import {
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TextInput,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
} from "react-native";
|
||||
import { SafeAreaView } from "react-native-safe-area-context";
|
||||
|
||||
export default function ForumScreen() {
|
||||
return (
|
||||
<SafeAreaView style={styles.container} edges={["top"]}>
|
||||
<ScrollView style={styles.scrollView}>
|
||||
{/* Search Bar */}
|
||||
<View style={styles.searchContainer}>
|
||||
<IconSymbol name="magnifyingglass" size={20} color="#FF0000" />
|
||||
<TextInput
|
||||
style={styles.searchInput}
|
||||
placeholder="Search"
|
||||
placeholderTextColor="#FF0000"
|
||||
/>
|
||||
</View>
|
||||
|
||||
{/* Category Filters */}
|
||||
<View style={styles.categoryContainer}>
|
||||
<TouchableOpacity style={styles.categoryButton}>
|
||||
<Text style={styles.categoryText}>Main dish</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity style={styles.categoryButton}>
|
||||
<Text style={styles.categoryText}>Dessert</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity style={styles.categoryButton}>
|
||||
<Text style={styles.categoryText}>Appetite</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
{/* Filter Options */}
|
||||
<View style={styles.filterContainer}>
|
||||
<TouchableOpacity style={styles.filterButton}>
|
||||
<Text style={styles.filterText}>Rating</Text>
|
||||
<IconSymbol name="star.fill" size={16} color="#FFCC00" />
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity style={styles.filterButton}>
|
||||
<Text style={styles.filterText}>Newest</Text>
|
||||
<IconSymbol name="calendar" size={16} color="#FFFFFF" />
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity style={styles.filterButton}>
|
||||
<Text style={styles.filterText}>Best</Text>
|
||||
<IconSymbol name="flame.fill" size={16} color="#FFCC00" />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
{/* Post */}
|
||||
<View style={styles.postContainer}>
|
||||
{/* User Info */}
|
||||
<View style={styles.userInfoContainer}>
|
||||
<View style={styles.userInfo}>
|
||||
<View style={styles.userAvatar}>
|
||||
<IconSymbol
|
||||
name="person.circle.fill"
|
||||
size={24}
|
||||
color="#888888"
|
||||
/>
|
||||
</View>
|
||||
<Text style={styles.userName}>Mr. Chef</Text>
|
||||
</View>
|
||||
<View style={styles.ratingContainer}>
|
||||
<Text style={styles.ratingText}>4.2</Text>
|
||||
<IconSymbol name="star.fill" size={16} color="#FFCC00" />
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* Post Image */}
|
||||
<Image
|
||||
source={require("@/assets/images/placeholder-food.jpg")}
|
||||
style={styles.postImage}
|
||||
contentFit="cover"
|
||||
/>
|
||||
|
||||
{/* Post Content */}
|
||||
<View style={styles.postContent}>
|
||||
<Text style={styles.postTitle}>Kajjecaw</Text>
|
||||
<Text style={styles.postDescription}>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut at
|
||||
hendrerit enim. Etiam lacinia mi nec nunc ornare, vitae tempus leo
|
||||
aliquet...
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
{/* Post Actions */}
|
||||
<View style={styles.postActions}>
|
||||
<TouchableOpacity style={styles.actionButton}>
|
||||
<IconSymbol
|
||||
name="arrowshape.turn.up.left.fill"
|
||||
size={16}
|
||||
color="#888888"
|
||||
/>
|
||||
<Text style={styles.actionText}>3</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity style={styles.actionButton}>
|
||||
<IconSymbol name="text.bubble.fill" size={16} color="#888888" />
|
||||
<Text style={styles.actionText}>2</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity style={styles.actionButton}>
|
||||
<IconSymbol name="heart.fill" size={16} color="#888888" />
|
||||
<Text style={styles.actionText}>2</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity style={styles.actionButton}>
|
||||
<IconSymbol name="bookmark.fill" size={16} color="#888888" />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
</ScrollView>
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: "#FFFFFF",
|
||||
},
|
||||
scrollView: {
|
||||
flex: 1,
|
||||
},
|
||||
searchContainer: {
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
marginHorizontal: 16,
|
||||
marginTop: 10,
|
||||
marginBottom: 16,
|
||||
paddingHorizontal: 12,
|
||||
height: 40,
|
||||
backgroundColor: "#FFFFFF",
|
||||
borderRadius: 20,
|
||||
borderWidth: 1,
|
||||
borderColor: "#DDDDDD",
|
||||
},
|
||||
searchInput: {
|
||||
flex: 1,
|
||||
marginLeft: 8,
|
||||
color: "#333333",
|
||||
},
|
||||
categoryContainer: {
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
marginHorizontal: 16,
|
||||
marginBottom: 16,
|
||||
},
|
||||
categoryButton: {
|
||||
backgroundColor: "#FFCC00",
|
||||
paddingVertical: 12,
|
||||
paddingHorizontal: 16,
|
||||
borderRadius: 12,
|
||||
flex: 1,
|
||||
marginHorizontal: 4,
|
||||
alignItems: "center",
|
||||
},
|
||||
categoryText: {
|
||||
fontWeight: "bold",
|
||||
color: "#333333",
|
||||
},
|
||||
filterContainer: {
|
||||
flexDirection: "row",
|
||||
marginHorizontal: 16,
|
||||
marginBottom: 16,
|
||||
},
|
||||
filterButton: {
|
||||
backgroundColor: "#FF0000",
|
||||
paddingVertical: 8,
|
||||
paddingHorizontal: 12,
|
||||
borderRadius: 20,
|
||||
marginRight: 8,
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
},
|
||||
filterText: {
|
||||
color: "#FFFFFF",
|
||||
fontWeight: "bold",
|
||||
marginRight: 4,
|
||||
},
|
||||
postContainer: {
|
||||
marginHorizontal: 16,
|
||||
marginBottom: 16,
|
||||
backgroundColor: "#FFFFFF",
|
||||
borderRadius: 12,
|
||||
overflow: "hidden",
|
||||
borderWidth: 1,
|
||||
borderColor: "#EEEEEE",
|
||||
},
|
||||
userInfoContainer: {
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
paddingHorizontal: 12,
|
||||
paddingVertical: 8,
|
||||
},
|
||||
userInfo: {
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
},
|
||||
userAvatar: {
|
||||
width: 32,
|
||||
height: 32,
|
||||
borderRadius: 16,
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
backgroundColor: "#F5F5F5",
|
||||
},
|
||||
userName: {
|
||||
marginLeft: 8,
|
||||
fontWeight: "bold",
|
||||
color: "#333333",
|
||||
},
|
||||
ratingContainer: {
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
},
|
||||
ratingText: {
|
||||
marginRight: 4,
|
||||
fontWeight: "bold",
|
||||
color: "#333333",
|
||||
},
|
||||
postImage: {
|
||||
width: "100%",
|
||||
height: 200,
|
||||
},
|
||||
postContent: {
|
||||
padding: 12,
|
||||
},
|
||||
postTitle: {
|
||||
fontSize: 16,
|
||||
fontWeight: "bold",
|
||||
marginBottom: 4,
|
||||
color: "#333333",
|
||||
},
|
||||
postDescription: {
|
||||
color: "#666666",
|
||||
fontSize: 14,
|
||||
},
|
||||
postActions: {
|
||||
flexDirection: "row",
|
||||
borderTopWidth: 1,
|
||||
borderTopColor: "#EEEEEE",
|
||||
paddingVertical: 8,
|
||||
paddingHorizontal: 12,
|
||||
},
|
||||
actionButton: {
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
marginRight: 16,
|
||||
},
|
||||
actionText: {
|
||||
marginLeft: 4,
|
||||
color: "#666666",
|
||||
},
|
||||
});
|
||||
@ -1,75 +1,321 @@
|
||||
import { Image } from 'expo-image';
|
||||
import { Platform, StyleSheet } from 'react-native';
|
||||
import { Image } from "expo-image";
|
||||
import { router } from "expo-router";
|
||||
import {
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TextInput,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
} from "react-native";
|
||||
import { SafeAreaView } from "react-native-safe-area-context";
|
||||
|
||||
import { HelloWave } from '@/components/HelloWave';
|
||||
import ParallaxScrollView from '@/components/ParallaxScrollView';
|
||||
import { ThemedText } from '@/components/ThemedText';
|
||||
import { ThemedView } from '@/components/ThemedView';
|
||||
import { IconSymbol } from "@/components/ui/IconSymbol";
|
||||
|
||||
export default function HomeScreen() {
|
||||
const foodHighlights = [
|
||||
{
|
||||
id: 1,
|
||||
name: "Pad Kra Pao Moo Sab with Eggs",
|
||||
image: require("@/assets/images/food/padkrapao.jpg"),
|
||||
description: "Thai stir-fry with ground pork and holy basil",
|
||||
time: "30 Mins",
|
||||
calories: "520 kcal",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "Jjajangmyeon",
|
||||
image: require("@/assets/images/food/jjajangmyeon.jpg"),
|
||||
description: "Korean black bean noodles",
|
||||
time: "45 Mins",
|
||||
calories: "650 kcal",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: "Ramen",
|
||||
image: require("@/assets/images/food/ramen.jpg"),
|
||||
description: "Japanese noodle soup",
|
||||
time: "60 Mins",
|
||||
calories: "480 kcal",
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: "Beef Wellington",
|
||||
image: require("@/assets/images/food/beef.jpg"),
|
||||
description: "Tender beef wrapped in puff pastry",
|
||||
time: "90 Mins",
|
||||
calories: "750 kcal",
|
||||
},
|
||||
];
|
||||
|
||||
const navigateToFoodDetail = (foodId: string) => {
|
||||
router.push({ pathname: "/food/[id]", params: { id: foodId } });
|
||||
};
|
||||
|
||||
return (
|
||||
<ParallaxScrollView
|
||||
headerBackgroundColor={{ light: '#A1CEDC', dark: '#1D3D47' }}
|
||||
headerImage={
|
||||
<Image
|
||||
source={require('@/assets/images/partial-react-logo.png')}
|
||||
style={styles.reactLogo}
|
||||
/>
|
||||
}>
|
||||
<ThemedView style={styles.titleContainer}>
|
||||
<ThemedText type="title">Welcome!</ThemedText>
|
||||
<HelloWave />
|
||||
</ThemedView>
|
||||
<ThemedView style={styles.stepContainer}>
|
||||
<ThemedText type="subtitle">Step 1: Try it</ThemedText>
|
||||
<ThemedText>
|
||||
Edit <ThemedText type="defaultSemiBold">app/(tabs)/index.tsx</ThemedText> to see changes.
|
||||
Press{' '}
|
||||
<ThemedText type="defaultSemiBold">
|
||||
{Platform.select({
|
||||
ios: 'cmd + d',
|
||||
android: 'cmd + m',
|
||||
web: 'F12',
|
||||
})}
|
||||
</ThemedText>{' '}
|
||||
to open developer tools.
|
||||
</ThemedText>
|
||||
</ThemedView>
|
||||
<ThemedView style={styles.stepContainer}>
|
||||
<ThemedText type="subtitle">Step 2: Explore</ThemedText>
|
||||
<ThemedText>
|
||||
{`Tap the Explore tab to learn more about what's included in this starter app.`}
|
||||
</ThemedText>
|
||||
</ThemedView>
|
||||
<ThemedView style={styles.stepContainer}>
|
||||
<ThemedText type="subtitle">Step 3: Get a fresh start</ThemedText>
|
||||
<ThemedText>
|
||||
{`When you're ready, run `}
|
||||
<ThemedText type="defaultSemiBold">npm run reset-project</ThemedText> to get a fresh{' '}
|
||||
<ThemedText type="defaultSemiBold">app</ThemedText> directory. This will move the current{' '}
|
||||
<ThemedText type="defaultSemiBold">app</ThemedText> to{' '}
|
||||
<ThemedText type="defaultSemiBold">app-example</ThemedText>.
|
||||
</ThemedText>
|
||||
</ThemedView>
|
||||
</ParallaxScrollView>
|
||||
<SafeAreaView style={styles.container} edges={["top"]}>
|
||||
<ScrollView style={styles.scrollView}>
|
||||
{/* Header */}
|
||||
<View style={styles.header}>
|
||||
<Text style={styles.greeting}>Hi! Mr. Chef</Text>
|
||||
<TouchableOpacity style={styles.scanButton}>
|
||||
<IconSymbol name="qrcode.viewfinder" size={24} color="#333333" />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
{/* Hero Section */}
|
||||
<View style={styles.heroContainer}>
|
||||
<View style={styles.heroContent}>
|
||||
<Image
|
||||
source={require("@/assets/images/notebook-orange.png")}
|
||||
style={styles.heroImage}
|
||||
contentFit="contain"
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* Food Highlights Section */}
|
||||
<View style={styles.sectionContainer}>
|
||||
<View style={styles.sectionHeader}>
|
||||
<Text style={styles.sectionTitle}>Food Highlights</Text>
|
||||
<IconSymbol name="star.fill" size={16} color="#FFCC00" />
|
||||
</View>
|
||||
|
||||
<View style={styles.foodHighlightsContainer}>
|
||||
{foodHighlights.map((food) => (
|
||||
<TouchableOpacity
|
||||
key={food.id}
|
||||
style={styles.foodCard}
|
||||
onPress={() => navigateToFoodDetail(String(food.id))}
|
||||
>
|
||||
<Image
|
||||
source={food.image}
|
||||
style={styles.foodImage}
|
||||
contentFit="cover"
|
||||
/>
|
||||
<View style={styles.foodCardContent}>
|
||||
<Text style={styles.foodCardTitle} numberOfLines={1}>
|
||||
{food.name}
|
||||
</Text>
|
||||
<Text style={styles.foodCardDescription} numberOfLines={1}>
|
||||
{food.description}
|
||||
</Text>
|
||||
<View style={styles.foodCardMeta}>
|
||||
<View style={styles.foodCardMetaItem}>
|
||||
<IconSymbol name="clock" size={12} color="#666666" />
|
||||
<Text style={styles.foodCardMetaText}>{food.time}</Text>
|
||||
</View>
|
||||
<View style={styles.foodCardMetaItem}>
|
||||
<IconSymbol name="flame" size={12} color="#666666" />
|
||||
<Text style={styles.foodCardMetaText}>
|
||||
{food.calories}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
))}
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* Show your dishes Section */}
|
||||
<View style={styles.sectionContainer}>
|
||||
<View style={styles.sectionHeader}>
|
||||
<Text style={styles.sectionTitle}>Show your dishes</Text>
|
||||
<IconSymbol name="chevron.down" size={16} color="#333333" />
|
||||
</View>
|
||||
|
||||
<View style={styles.searchContainer}>
|
||||
<TextInput style={styles.searchInput} placeholder="Search..." />
|
||||
<TouchableOpacity style={styles.searchButton}>
|
||||
<IconSymbol name="arrow.right" size={16} color="#333333" />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
<View style={styles.uploadOptions}>
|
||||
<TouchableOpacity style={styles.uploadOption}>
|
||||
<IconSymbol name="camera.fill" size={24} color="#333333" />
|
||||
<Text style={styles.uploadOptionTitle}>From Camera</Text>
|
||||
<Text style={styles.uploadOptionSubtitle}>
|
||||
Snap it from Camera
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity
|
||||
style={[styles.uploadOption, styles.orangeOption]}
|
||||
>
|
||||
<IconSymbol name="photo.fill" size={24} color="#333333" />
|
||||
<Text style={styles.uploadOptionTitle}>From Gallery</Text>
|
||||
<Text style={styles.uploadOptionSubtitle}>
|
||||
Select from Gallery
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
</ScrollView>
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
titleContainer: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
gap: 8,
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: "#FFFFFF",
|
||||
},
|
||||
stepContainer: {
|
||||
gap: 8,
|
||||
scrollView: {
|
||||
flex: 1,
|
||||
},
|
||||
header: {
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
paddingHorizontal: 16,
|
||||
paddingVertical: 12,
|
||||
},
|
||||
greeting: {
|
||||
fontSize: 20,
|
||||
fontWeight: "bold",
|
||||
color: "#333333",
|
||||
},
|
||||
scanButton: {
|
||||
width: 36,
|
||||
height: 36,
|
||||
borderRadius: 18,
|
||||
backgroundColor: "#FFCC00",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
},
|
||||
heroContainer: {
|
||||
height: 180,
|
||||
marginHorizontal: 16,
|
||||
marginVertical: 16,
|
||||
borderRadius: 16,
|
||||
backgroundColor: "#FFF3D9", // Light yellow/orange gradient
|
||||
overflow: "hidden",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
},
|
||||
heroContent: {
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
position: "relative",
|
||||
},
|
||||
heroImage: {
|
||||
width: 120,
|
||||
height: 120,
|
||||
},
|
||||
sectionContainer: {
|
||||
marginHorizontal: 16,
|
||||
marginBottom: 24,
|
||||
},
|
||||
sectionHeader: {
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
marginBottom: 12,
|
||||
},
|
||||
sectionTitle: {
|
||||
fontSize: 18,
|
||||
fontWeight: "bold",
|
||||
color: "#333333",
|
||||
marginRight: 8,
|
||||
},
|
||||
foodHighlightsContainer: {
|
||||
width: "100%",
|
||||
},
|
||||
foodCard: {
|
||||
flexDirection: "row",
|
||||
backgroundColor: "#FFFFFF",
|
||||
borderRadius: 12,
|
||||
marginBottom: 12,
|
||||
shadowColor: "#000",
|
||||
shadowOffset: { width: 0, height: 2 },
|
||||
shadowOpacity: 0.1,
|
||||
shadowRadius: 4,
|
||||
elevation: 2,
|
||||
overflow: "hidden",
|
||||
},
|
||||
foodImage: {
|
||||
width: 100,
|
||||
height: 100,
|
||||
},
|
||||
foodCardContent: {
|
||||
flex: 1,
|
||||
padding: 12,
|
||||
justifyContent: "space-between",
|
||||
},
|
||||
foodCardTitle: {
|
||||
fontSize: 16,
|
||||
fontWeight: "bold",
|
||||
color: "#333333",
|
||||
marginBottom: 4,
|
||||
},
|
||||
foodCardDescription: {
|
||||
fontSize: 14,
|
||||
color: "#666666",
|
||||
marginBottom: 8,
|
||||
},
|
||||
reactLogo: {
|
||||
height: 178,
|
||||
width: 290,
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
position: 'absolute',
|
||||
foodCardMeta: {
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
},
|
||||
foodCardMetaItem: {
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
},
|
||||
foodCardMetaText: {
|
||||
fontSize: 12,
|
||||
color: "#666666",
|
||||
marginLeft: 4,
|
||||
},
|
||||
searchContainer: {
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
marginBottom: 16,
|
||||
borderWidth: 1,
|
||||
borderColor: "#DDDDDD",
|
||||
borderRadius: 24,
|
||||
paddingHorizontal: 12,
|
||||
height: 48,
|
||||
},
|
||||
searchInput: {
|
||||
flex: 1,
|
||||
height: "100%",
|
||||
},
|
||||
searchButton: {
|
||||
width: 32,
|
||||
height: 32,
|
||||
borderRadius: 16,
|
||||
backgroundColor: "#FFCC00",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
},
|
||||
uploadOptions: {
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
},
|
||||
uploadOption: {
|
||||
flex: 1,
|
||||
height: 100,
|
||||
backgroundColor: "#FFCC00",
|
||||
borderRadius: 12,
|
||||
marginRight: 8,
|
||||
padding: 12,
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
},
|
||||
orangeOption: {
|
||||
backgroundColor: "#FFA500", // Darker orange
|
||||
marginRight: 0,
|
||||
},
|
||||
uploadOptionTitle: {
|
||||
fontWeight: "bold",
|
||||
color: "#333333",
|
||||
marginTop: 8,
|
||||
},
|
||||
uploadOptionSubtitle: {
|
||||
fontSize: 12,
|
||||
color: "#333333",
|
||||
opacity: 0.8,
|
||||
},
|
||||
});
|
||||
|
||||
216
app/(tabs)/profile.tsx
Normal file
@ -0,0 +1,216 @@
|
||||
"use client";
|
||||
|
||||
import { Image } from "expo-image";
|
||||
import { useState } from "react";
|
||||
import {
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
} from "react-native";
|
||||
import { SafeAreaView } from "react-native-safe-area-context";
|
||||
|
||||
export default function ProfileScreen() {
|
||||
const [activeTab, setActiveTab] = useState("Repost");
|
||||
|
||||
const foodItems = [
|
||||
{
|
||||
id: 1,
|
||||
name: "Padthaipro",
|
||||
image: require("@/assets/images/food/padthai.jpg"),
|
||||
color: "#FFCC00",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "Jjajangmyeon",
|
||||
image: require("@/assets/images/food/jjajangmyeon.jpg"),
|
||||
color: "#FFA500",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: "Wingztab",
|
||||
image: require("@/assets/images/food/wings.jpg"),
|
||||
color: "#FFCC00",
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: "Ramen",
|
||||
image: require("@/assets/images/food/ramen.jpg"),
|
||||
color: "#FFA500",
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
name: "Tiramisu",
|
||||
image: require("@/assets/images/food/tiramisu.jpg"),
|
||||
color: "#FFCC00",
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
name: "Beef wellington",
|
||||
image: require("@/assets/images/food/beef.jpg"),
|
||||
color: "#FFA500",
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
name: "Tiramisu",
|
||||
image: require("@/assets/images/food/tiramisu.jpg"),
|
||||
color: "#FFCC00",
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
name: "Beef wellington",
|
||||
image: require("@/assets/images/food/beef.jpg"),
|
||||
color: "#FFA500",
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<SafeAreaView style={styles.container} edges={["top"]}>
|
||||
<ScrollView style={styles.scrollView}>
|
||||
{/* Profile Header */}
|
||||
<View style={styles.profileHeader}>
|
||||
<View style={styles.avatarContainer}>
|
||||
<View style={styles.avatar}>
|
||||
<Text style={styles.avatarPlaceholder}>👨🍳</Text>
|
||||
</View>
|
||||
</View>
|
||||
<Text style={styles.username}>Mr. Chef</Text>
|
||||
<TouchableOpacity style={styles.editButton}>
|
||||
<Text style={styles.editButtonText}>Edit</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
{/* Tab Navigation */}
|
||||
<View style={styles.tabContainer}>
|
||||
{["Repost", "Likes", "Bookmark"].map((tab) => (
|
||||
<TouchableOpacity
|
||||
key={tab}
|
||||
style={[styles.tab, activeTab === tab && styles.activeTab]}
|
||||
onPress={() => setActiveTab(tab)}
|
||||
>
|
||||
<Text style={styles.tabText}>{tab}</Text>
|
||||
</TouchableOpacity>
|
||||
))}
|
||||
</View>
|
||||
|
||||
<View style={styles.divider} />
|
||||
|
||||
{/* Food Grid */}
|
||||
<View style={styles.foodGrid}>
|
||||
{foodItems.map((item, index) => (
|
||||
<View key={`${item.id}-${index}`} style={styles.foodItem}>
|
||||
<Image
|
||||
source={item.image}
|
||||
style={styles.foodImage}
|
||||
contentFit="cover"
|
||||
/>
|
||||
<View style={[styles.foodLabel, { backgroundColor: item.color }]}>
|
||||
<Text style={styles.foodLabelText}>{item.name}</Text>
|
||||
</View>
|
||||
</View>
|
||||
))}
|
||||
</View>
|
||||
</ScrollView>
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: "#FFFFFF",
|
||||
},
|
||||
scrollView: {
|
||||
flex: 1,
|
||||
},
|
||||
profileHeader: {
|
||||
alignItems: "center",
|
||||
paddingVertical: 24,
|
||||
},
|
||||
avatarContainer: {
|
||||
width: 100,
|
||||
height: 100,
|
||||
borderRadius: 50,
|
||||
borderWidth: 1,
|
||||
borderColor: "#DDDDDD",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
marginBottom: 12,
|
||||
},
|
||||
avatar: {
|
||||
width: 96,
|
||||
height: 96,
|
||||
borderRadius: 48,
|
||||
backgroundColor: "#F5F5F5",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
},
|
||||
avatarPlaceholder: {
|
||||
fontSize: 40,
|
||||
},
|
||||
username: {
|
||||
fontSize: 20,
|
||||
fontWeight: "bold",
|
||||
marginBottom: 12,
|
||||
},
|
||||
editButton: {
|
||||
backgroundColor: "#FF0000",
|
||||
paddingVertical: 10,
|
||||
paddingHorizontal: 40,
|
||||
borderRadius: 8,
|
||||
},
|
||||
editButtonText: {
|
||||
color: "#FFFFFF",
|
||||
fontWeight: "bold",
|
||||
},
|
||||
tabContainer: {
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-around",
|
||||
paddingVertical: 12,
|
||||
},
|
||||
tab: {
|
||||
paddingVertical: 8,
|
||||
paddingHorizontal: 16,
|
||||
},
|
||||
activeTab: {
|
||||
borderBottomWidth: 2,
|
||||
borderBottomColor: "#333333",
|
||||
},
|
||||
tabText: {
|
||||
fontWeight: "500",
|
||||
},
|
||||
divider: {
|
||||
height: 1,
|
||||
backgroundColor: "#EEEEEE",
|
||||
marginHorizontal: 16,
|
||||
},
|
||||
foodGrid: {
|
||||
flexDirection: "row",
|
||||
flexWrap: "wrap",
|
||||
padding: 8,
|
||||
},
|
||||
foodItem: {
|
||||
width: "50%",
|
||||
padding: 8,
|
||||
position: "relative",
|
||||
},
|
||||
foodImage: {
|
||||
width: "100%",
|
||||
height: 120,
|
||||
borderRadius: 8,
|
||||
},
|
||||
foodLabel: {
|
||||
position: "absolute",
|
||||
bottom: 16,
|
||||
left: 16,
|
||||
paddingVertical: 4,
|
||||
paddingHorizontal: 8,
|
||||
borderRadius: 4,
|
||||
},
|
||||
foodLabelText: {
|
||||
color: "#333333",
|
||||
fontWeight: "bold",
|
||||
fontSize: 12,
|
||||
},
|
||||
});
|
||||
187
app/(tabs)/recipes.tsx
Normal file
@ -0,0 +1,187 @@
|
||||
import { IconSymbol } from "@/components/ui/IconSymbol";
|
||||
import { Image } from "expo-image";
|
||||
import {
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TextInput,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
} from "react-native";
|
||||
import { SafeAreaView } from "react-native-safe-area-context";
|
||||
|
||||
export default function RecipesScreen() {
|
||||
const foodItems = [
|
||||
{
|
||||
id: 1,
|
||||
name: "Padthaipro",
|
||||
image: require("@/assets/images/food/padthai.jpg"),
|
||||
color: "#FFCC00",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "Jjajangmyeon",
|
||||
image: require("@/assets/images/food/jjajangmyeon.jpg"),
|
||||
color: "#FFA500",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: "Wingztab",
|
||||
image: require("@/assets/images/food/wings.jpg"),
|
||||
color: "#FFCC00",
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: "Ramen",
|
||||
image: require("@/assets/images/food/ramen.jpg"),
|
||||
color: "#FFA500",
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
name: "Tiramisu",
|
||||
image: require("@/assets/images/food/tiramisu.jpg"),
|
||||
color: "#FFCC00",
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
name: "Beef wellington",
|
||||
image: require("@/assets/images/food/beef.jpg"),
|
||||
color: "#FFA500",
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<SafeAreaView style={styles.container} edges={["top"]}>
|
||||
<ScrollView style={styles.scrollView}>
|
||||
{/* Search Bar */}
|
||||
<View style={styles.searchContainer}>
|
||||
<IconSymbol name="magnifyingglass" size={20} color="#FF0000" />
|
||||
<TextInput
|
||||
style={styles.searchInput}
|
||||
placeholder="Search"
|
||||
placeholderTextColor="#FF0000"
|
||||
/>
|
||||
</View>
|
||||
|
||||
{/* Filter Buttons */}
|
||||
<View style={styles.filterContainer}>
|
||||
<TouchableOpacity style={styles.yellowButton}>
|
||||
<Text style={styles.buttonText}>All Recipes</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity style={styles.redButton}>
|
||||
<Text style={styles.redButtonText}>My Recipes</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
{/* Divider */}
|
||||
<View style={styles.divider} />
|
||||
|
||||
{/* Food Grid */}
|
||||
<View style={styles.foodGrid}>
|
||||
{foodItems.map((item) => (
|
||||
<View key={item.id} style={styles.foodItem}>
|
||||
<Image
|
||||
source={item.image}
|
||||
style={styles.foodImage}
|
||||
contentFit="cover"
|
||||
/>
|
||||
<View style={[styles.foodLabel, { backgroundColor: item.color }]}>
|
||||
<Text style={styles.foodLabelText}>{item.name}</Text>
|
||||
</View>
|
||||
</View>
|
||||
))}
|
||||
</View>
|
||||
</ScrollView>
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: "#FFFFFF",
|
||||
},
|
||||
scrollView: {
|
||||
flex: 1,
|
||||
},
|
||||
searchContainer: {
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
marginHorizontal: 16,
|
||||
marginTop: 10,
|
||||
marginBottom: 16,
|
||||
paddingHorizontal: 12,
|
||||
height: 40,
|
||||
backgroundColor: "#FFFFFF",
|
||||
borderRadius: 20,
|
||||
borderWidth: 1,
|
||||
borderColor: "#DDDDDD",
|
||||
},
|
||||
searchInput: {
|
||||
flex: 1,
|
||||
marginLeft: 8,
|
||||
color: "#333333",
|
||||
},
|
||||
filterContainer: {
|
||||
flexDirection: "row",
|
||||
marginHorizontal: 16,
|
||||
marginBottom: 16,
|
||||
},
|
||||
yellowButton: {
|
||||
flex: 1,
|
||||
backgroundColor: "#FFCC00",
|
||||
paddingVertical: 12,
|
||||
borderRadius: 8,
|
||||
marginRight: 8,
|
||||
alignItems: "center",
|
||||
},
|
||||
redButton: {
|
||||
flex: 1,
|
||||
backgroundColor: "#FF0000",
|
||||
paddingVertical: 12,
|
||||
borderRadius: 8,
|
||||
alignItems: "center",
|
||||
},
|
||||
buttonText: {
|
||||
fontWeight: "bold",
|
||||
color: "#333333",
|
||||
},
|
||||
redButtonText: {
|
||||
fontWeight: "bold",
|
||||
color: "#FFFFFF",
|
||||
},
|
||||
divider: {
|
||||
height: 1,
|
||||
backgroundColor: "#EEEEEE",
|
||||
marginHorizontal: 16,
|
||||
marginBottom: 16,
|
||||
},
|
||||
foodGrid: {
|
||||
flexDirection: "row",
|
||||
flexWrap: "wrap",
|
||||
padding: 8,
|
||||
},
|
||||
foodItem: {
|
||||
width: "50%",
|
||||
padding: 8,
|
||||
position: "relative",
|
||||
},
|
||||
foodImage: {
|
||||
width: "100%",
|
||||
height: 120,
|
||||
borderRadius: 8,
|
||||
},
|
||||
foodLabel: {
|
||||
position: "absolute",
|
||||
bottom: 16,
|
||||
left: 16,
|
||||
paddingVertical: 4,
|
||||
paddingHorizontal: 8,
|
||||
borderRadius: 4,
|
||||
},
|
||||
foodLabelText: {
|
||||
color: "#333333",
|
||||
fontWeight: "bold",
|
||||
fontSize: 12,
|
||||
},
|
||||
});
|
||||
@ -1,15 +1,15 @@
|
||||
import { DarkTheme, DefaultTheme, ThemeProvider } from '@react-navigation/native';
|
||||
import { useFonts } from 'expo-font';
|
||||
import { Stack } from 'expo-router';
|
||||
import { StatusBar } from 'expo-status-bar';
|
||||
import 'react-native-reanimated';
|
||||
import { DefaultTheme, ThemeProvider } from "@react-navigation/native";
|
||||
import { useFonts } from "expo-font";
|
||||
import { Stack } from "expo-router";
|
||||
import { StatusBar } from "expo-status-bar";
|
||||
import "react-native-reanimated";
|
||||
|
||||
import { useColorScheme } from '@/hooks/useColorScheme';
|
||||
import { useColorScheme } from "@/hooks/useColorScheme";
|
||||
|
||||
export default function RootLayout() {
|
||||
const colorScheme = useColorScheme();
|
||||
const [loaded] = useFonts({
|
||||
SpaceMono: require('../assets/fonts/SpaceMono-Regular.ttf'),
|
||||
SpaceMono: require("../assets/fonts/SpaceMono-Regular.ttf"),
|
||||
});
|
||||
|
||||
if (!loaded) {
|
||||
@ -18,7 +18,8 @@ export default function RootLayout() {
|
||||
}
|
||||
|
||||
return (
|
||||
<ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
|
||||
// Use DarkTheme if need dark theme
|
||||
<ThemeProvider value={colorScheme === "dark" ? DefaultTheme : DefaultTheme}>
|
||||
<Stack>
|
||||
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
|
||||
<Stack.Screen name="+not-found" />
|
||||
|
||||
363
app/cooking/[id].tsx
Normal file
@ -0,0 +1,363 @@
|
||||
"use client";
|
||||
|
||||
import { IconSymbol } from "@/components/ui/IconSymbol";
|
||||
import { Image } from "expo-image";
|
||||
import { router, useLocalSearchParams } from "expo-router";
|
||||
import { useState } from "react";
|
||||
import {
|
||||
Alert,
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
} from "react-native";
|
||||
import { SafeAreaView } from "react-native-safe-area-context";
|
||||
|
||||
export default function CookingSessionScreen() {
|
||||
const { id } = useLocalSearchParams();
|
||||
const [currentStep, setCurrentStep] = useState(0);
|
||||
|
||||
// Mock data - in a real app, you would fetch this based on the ID
|
||||
const recipeData = {
|
||||
id: 1,
|
||||
name: "Pad Kra Pao Moo Sab with Eggs",
|
||||
steps: [
|
||||
{
|
||||
title: "Gather and prepare all ingredients",
|
||||
description:
|
||||
"Chop garlic, Thai chilies, and protein of choice (chicken, pork, beef, or tofu)",
|
||||
image: require("@/assets/images/cooking/step1.png"),
|
||||
},
|
||||
{
|
||||
title: "Heat oil in a wok or large frying pan",
|
||||
description:
|
||||
"Use medium-high heat. The oil should be hot but not smoking.",
|
||||
image: require("@/assets/images/cooking/step2.png"),
|
||||
},
|
||||
{
|
||||
title: "Fry the eggs sunny side up",
|
||||
description:
|
||||
"Heat oil in a separate pan and fry eggs until whites are set but yolks are still runny. Set aside.",
|
||||
image: require("@/assets/images/cooking/step3.png"),
|
||||
},
|
||||
{
|
||||
title: "Stir-fry garlic and chilies",
|
||||
description:
|
||||
"Add chopped garlic and chilies to the hot oil and stir-fry until fragrant, about 30 seconds.",
|
||||
image: require("@/assets/images/cooking/step4.png"),
|
||||
},
|
||||
{
|
||||
title: "Add ground pork and cook until browned",
|
||||
description:
|
||||
"Break up the meat with a spatula and cook until no longer pink, about 3-4 minutes.",
|
||||
image: require("@/assets/images/cooking/step5.png"),
|
||||
},
|
||||
{
|
||||
title: "Add sauces and basil",
|
||||
description:
|
||||
"Add soy sauce, oyster sauce, sugar, and holy basil. Stir well and cook for another minute. Serve with rice and top with the fried egg.",
|
||||
image: require("@/assets/images/cooking/step6.png"),
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const totalSteps = recipeData.steps.length;
|
||||
|
||||
const goToNextStep = () => {
|
||||
if (currentStep < totalSteps - 1) {
|
||||
setCurrentStep(currentStep + 1);
|
||||
}
|
||||
};
|
||||
|
||||
const goToPreviousStep = () => {
|
||||
if (currentStep > 0) {
|
||||
setCurrentStep(currentStep - 1);
|
||||
}
|
||||
};
|
||||
|
||||
const getHelpWithStep = () => {
|
||||
Alert.alert(
|
||||
"Need Help?",
|
||||
`Tips for ${recipeData.steps[currentStep].title}:\n\n` +
|
||||
"• Make sure ingredients are properly prepared\n" +
|
||||
"• Watch your heat level\n" +
|
||||
"• Don't overcook the ingredients\n\n" +
|
||||
"Would you like to see a video tutorial?",
|
||||
[
|
||||
{ text: "No, thanks", style: "cancel" },
|
||||
{
|
||||
text: "Yes, show video",
|
||||
onPress: () => console.log("Show video tutorial"),
|
||||
},
|
||||
]
|
||||
);
|
||||
};
|
||||
|
||||
const stopCookingSession = () => {
|
||||
Alert.alert(
|
||||
"Stop Cooking?",
|
||||
"Are you sure you want to stop this cooking session?",
|
||||
[
|
||||
{ text: "Cancel", style: "cancel" },
|
||||
{ text: "Yes, stop", onPress: () => router.back() },
|
||||
]
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<SafeAreaView style={styles.container} edges={["top"]}>
|
||||
<ScrollView style={styles.scrollView}>
|
||||
{/* Header with back button */}
|
||||
<View style={styles.header}>
|
||||
<TouchableOpacity
|
||||
style={styles.backButton}
|
||||
onPress={() => router.back()}
|
||||
>
|
||||
<IconSymbol name="chevron.left" size={24} color="#333333" />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
{/* Step Illustration */}
|
||||
<View style={styles.illustrationContainer}>
|
||||
<Image
|
||||
source={recipeData.steps[currentStep].image}
|
||||
style={styles.stepImage}
|
||||
contentFit="contain"
|
||||
/>
|
||||
</View>
|
||||
|
||||
{/* Step Information */}
|
||||
<View style={styles.stepInfoContainer}>
|
||||
<Text style={styles.stepCounter}>
|
||||
Step {currentStep + 1} of {totalSteps}
|
||||
</Text>
|
||||
<Text style={styles.stepTitle}>
|
||||
{recipeData.steps[currentStep].title}
|
||||
</Text>
|
||||
<Text style={styles.stepDescription}>
|
||||
{recipeData.steps[currentStep].description}
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
{/* Step Indicators */}
|
||||
<View style={styles.stepIndicatorsContainer}>
|
||||
<Text style={styles.stepsLabel}>Steps</Text>
|
||||
<View style={styles.stepDots}>
|
||||
{recipeData.steps.map((_, index) => (
|
||||
<TouchableOpacity
|
||||
key={index}
|
||||
onPress={() => setCurrentStep(index)}
|
||||
>
|
||||
<View
|
||||
style={[
|
||||
styles.stepDot,
|
||||
currentStep === index && styles.activeStepDot,
|
||||
]}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
))}
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* Navigation Buttons */}
|
||||
<View style={styles.navigationContainer}>
|
||||
<TouchableOpacity style={styles.helpButton} onPress={getHelpWithStep}>
|
||||
<Text style={styles.helpButtonText}>Help me!</Text>
|
||||
</TouchableOpacity>
|
||||
|
||||
<View style={styles.stepNavigation}>
|
||||
{currentStep > 0 && (
|
||||
<TouchableOpacity
|
||||
style={[styles.navButton, styles.prevButton]}
|
||||
onPress={goToPreviousStep}
|
||||
>
|
||||
<IconSymbol name="chevron.left" size={20} color="#333333" />
|
||||
<Text style={styles.prevButtonText}>Previous</Text>
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
|
||||
{currentStep < totalSteps - 1 ? (
|
||||
<TouchableOpacity
|
||||
style={[styles.navButton, styles.nextButton]}
|
||||
onPress={goToNextStep}
|
||||
>
|
||||
<Text style={styles.nextButtonText}>Next Step</Text>
|
||||
<IconSymbol name="chevron.right" size={20} color="#333333" />
|
||||
</TouchableOpacity>
|
||||
) : (
|
||||
<TouchableOpacity
|
||||
style={[styles.navButton, styles.finishButton]}
|
||||
onPress={() => router.back()}
|
||||
>
|
||||
<Text style={styles.finishButtonText}>Finish</Text>
|
||||
<IconSymbol name="checkmark" size={20} color="#FFFFFF" />
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
</ScrollView>
|
||||
|
||||
{/* Stop Session Button */}
|
||||
<TouchableOpacity style={styles.stopButton} onPress={stopCookingSession}>
|
||||
<Text style={styles.stopButtonText}>Stop Session</Text>
|
||||
<IconSymbol name="fork.knife" size={20} color="#FFCC00" />
|
||||
</TouchableOpacity>
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: "#FFFFFF",
|
||||
},
|
||||
scrollView: {
|
||||
flex: 1,
|
||||
},
|
||||
header: {
|
||||
paddingHorizontal: 16,
|
||||
paddingVertical: 12,
|
||||
},
|
||||
backButton: {
|
||||
width: 40,
|
||||
height: 40,
|
||||
borderRadius: 20,
|
||||
backgroundColor: "#FFCC00",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
},
|
||||
illustrationContainer: {
|
||||
alignItems: "center",
|
||||
marginVertical: 20,
|
||||
},
|
||||
stepImage: {
|
||||
width: 200,
|
||||
height: 200,
|
||||
borderRadius: 100,
|
||||
backgroundColor: "#FFCC00",
|
||||
},
|
||||
stepInfoContainer: {
|
||||
paddingHorizontal: 24,
|
||||
alignItems: "center",
|
||||
marginBottom: 30,
|
||||
},
|
||||
stepCounter: {
|
||||
fontSize: 18,
|
||||
color: "#8BC34A",
|
||||
fontWeight: "bold",
|
||||
marginBottom: 8,
|
||||
},
|
||||
stepTitle: {
|
||||
fontSize: 24,
|
||||
fontWeight: "bold",
|
||||
color: "#333333",
|
||||
textAlign: "center",
|
||||
marginBottom: 12,
|
||||
},
|
||||
stepDescription: {
|
||||
fontSize: 16,
|
||||
color: "#666666",
|
||||
textAlign: "center",
|
||||
lineHeight: 24,
|
||||
},
|
||||
stepIndicatorsContainer: {
|
||||
paddingHorizontal: 24,
|
||||
marginBottom: 24,
|
||||
},
|
||||
stepsLabel: {
|
||||
fontSize: 18,
|
||||
fontWeight: "bold",
|
||||
color: "#333333",
|
||||
marginBottom: 12,
|
||||
},
|
||||
stepDots: {
|
||||
flexDirection: "row",
|
||||
justifyContent: "center",
|
||||
},
|
||||
stepDot: {
|
||||
width: 40,
|
||||
height: 40,
|
||||
borderRadius: 20,
|
||||
backgroundColor: "#EEEEEE",
|
||||
marginHorizontal: 8,
|
||||
},
|
||||
activeStepDot: {
|
||||
backgroundColor: "#FFCC00",
|
||||
},
|
||||
navigationContainer: {
|
||||
paddingHorizontal: 24,
|
||||
marginBottom: 80,
|
||||
},
|
||||
helpButton: {
|
||||
backgroundColor: "#FF6B6B",
|
||||
borderRadius: 8,
|
||||
paddingVertical: 16,
|
||||
alignItems: "center",
|
||||
marginBottom: 16,
|
||||
},
|
||||
helpButtonText: {
|
||||
fontSize: 18,
|
||||
fontWeight: "bold",
|
||||
color: "#FFFFFF",
|
||||
},
|
||||
stepNavigation: {
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
},
|
||||
navButton: {
|
||||
flex: 1,
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
paddingVertical: 16,
|
||||
borderRadius: 8,
|
||||
},
|
||||
prevButton: {
|
||||
backgroundColor: "#FFFFFF",
|
||||
borderWidth: 1,
|
||||
borderColor: "#DDDDDD",
|
||||
marginRight: 8,
|
||||
},
|
||||
prevButtonText: {
|
||||
fontSize: 16,
|
||||
fontWeight: "bold",
|
||||
color: "#333333",
|
||||
marginLeft: 8,
|
||||
},
|
||||
nextButton: {
|
||||
backgroundColor: "#FFCC00",
|
||||
},
|
||||
nextButtonText: {
|
||||
fontSize: 16,
|
||||
fontWeight: "bold",
|
||||
color: "#333333",
|
||||
marginRight: 8,
|
||||
},
|
||||
finishButton: {
|
||||
backgroundColor: "#4CAF50",
|
||||
},
|
||||
finishButtonText: {
|
||||
fontSize: 16,
|
||||
fontWeight: "bold",
|
||||
color: "#FFFFFF",
|
||||
marginRight: 8,
|
||||
},
|
||||
stopButton: {
|
||||
position: "absolute",
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
backgroundColor: "#C62828",
|
||||
flexDirection: "row",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
paddingVertical: 16,
|
||||
},
|
||||
stopButtonText: {
|
||||
fontSize: 18,
|
||||
fontWeight: "bold",
|
||||
color: "#FFCC00",
|
||||
marginRight: 8,
|
||||
},
|
||||
});
|
||||
454
app/food/[id].tsx
Normal file
@ -0,0 +1,454 @@
|
||||
"use client";
|
||||
|
||||
import { IconSymbol } from "@/components/ui/IconSymbol";
|
||||
import { Image } from "expo-image";
|
||||
import { router, useLocalSearchParams } from "expo-router";
|
||||
import { useState } from "react";
|
||||
import {
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
} from "react-native";
|
||||
import { SafeAreaView } from "react-native-safe-area-context";
|
||||
|
||||
export default function FoodDetailScreen() {
|
||||
const { id } = useLocalSearchParams();
|
||||
const [activeTab, setActiveTab] = useState("Ingredients");
|
||||
|
||||
// Mock data - in a real app, you would fetch this based on the ID
|
||||
const foodData = {
|
||||
id: 1,
|
||||
name: "Pad Kra Pao Moo Sab with Eggs",
|
||||
image: require("@/assets/images/food/padkrapao.jpg"),
|
||||
description:
|
||||
"Pad kra pao, also written as pad gaprao, is a popular Thai stir-fry of ground meat and holy basil.",
|
||||
time: "30 Mins",
|
||||
skills: "Easy",
|
||||
ingredients: [
|
||||
{ name: "Ground pork", emoji: "🥩" },
|
||||
{ name: "Holy basil", emoji: "🌿" },
|
||||
{ name: "Garlic", emoji: "🧄" },
|
||||
{ name: "Thai chili", emoji: "🌶️" },
|
||||
{ name: "Soy sauce", emoji: "🍶" },
|
||||
{ name: "Oyster sauce", emoji: "🦪" },
|
||||
{ name: "Sugar", emoji: "🧂" },
|
||||
{ name: "Eggs", emoji: "🥚" },
|
||||
],
|
||||
calories: "520 kcal",
|
||||
nutrition: {
|
||||
fat: 15,
|
||||
fiber: 3,
|
||||
protein: 25,
|
||||
carbs: 40,
|
||||
},
|
||||
steps: [
|
||||
"Gather and prepare all ingredients",
|
||||
"Heat oil in a wok or large frying pan",
|
||||
"Fry the eggs sunny side up and set aside",
|
||||
"Stir-fry garlic and chilies until fragrant",
|
||||
"Add ground pork and cook until browned",
|
||||
"Add sauces and basil, serve with rice and egg on top",
|
||||
],
|
||||
};
|
||||
|
||||
const startCookingSession = () => {
|
||||
router.push(`/cooking/[id]`);
|
||||
};
|
||||
|
||||
return (
|
||||
<SafeAreaView style={styles.container} edges={["top"]}>
|
||||
<ScrollView style={styles.scrollView}>
|
||||
{/* Header with back and share buttons */}
|
||||
<View style={styles.header}>
|
||||
<TouchableOpacity
|
||||
style={styles.backButton}
|
||||
onPress={() => router.back()}
|
||||
>
|
||||
<IconSymbol name="chevron.left" size={24} color="#333333" />
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity style={styles.shareButton}>
|
||||
<IconSymbol name="square.and.arrow.up" size={24} color="#FFCC00" />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
{/* Food Image */}
|
||||
<View style={styles.imageContainer}>
|
||||
<Image
|
||||
source={foodData.image}
|
||||
style={styles.foodImage}
|
||||
contentFit="cover"
|
||||
/>
|
||||
</View>
|
||||
|
||||
{/* Food Title and Description */}
|
||||
<View style={styles.contentContainer}>
|
||||
<Text style={styles.foodTitle}>{foodData.name}</Text>
|
||||
<Text style={styles.foodDescription}>{foodData.description}</Text>
|
||||
|
||||
{/* Info Tabs */}
|
||||
<View style={styles.tabsContainer}>
|
||||
<TouchableOpacity
|
||||
style={styles.tabItem}
|
||||
onPress={() => setActiveTab("Skills")}
|
||||
>
|
||||
<Text style={styles.tabLabel}>Skills</Text>
|
||||
<Text style={styles.tabValue}>{foodData.skills}</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity
|
||||
style={styles.tabItem}
|
||||
onPress={() => setActiveTab("Time")}
|
||||
>
|
||||
<Text style={styles.tabLabel}>Time</Text>
|
||||
<Text style={styles.tabValue}>{foodData.time}</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity
|
||||
style={[
|
||||
styles.tabItem,
|
||||
activeTab === "Ingredients" && styles.activeTabItem,
|
||||
]}
|
||||
onPress={() => setActiveTab("Ingredients")}
|
||||
>
|
||||
<Text style={styles.tabLabel}>Ingredients</Text>
|
||||
<Text style={styles.tabValue}>{foodData.ingredients.length}</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity
|
||||
style={styles.tabItem}
|
||||
onPress={() => setActiveTab("Calories")}
|
||||
>
|
||||
<Text style={styles.tabLabel}>Calories</Text>
|
||||
<Text style={styles.tabValue}>{foodData.calories}</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
{/* Ingredients Section */}
|
||||
<View style={styles.sectionContainer}>
|
||||
<Text style={styles.sectionTitle}>Ingredients</Text>
|
||||
<View style={styles.ingredientsGrid}>
|
||||
{foodData.ingredients.map((ingredient, index) => (
|
||||
<View key={index} style={styles.ingredientItem}>
|
||||
<View style={styles.ingredientIconContainer}>
|
||||
<Text style={styles.ingredientEmoji}>
|
||||
{ingredient.emoji}
|
||||
</Text>
|
||||
</View>
|
||||
<Text style={styles.ingredientName}>{ingredient.name}</Text>
|
||||
</View>
|
||||
))}
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* Nutrition Section - Improved UI */}
|
||||
<View style={styles.nutritionSection}>
|
||||
<Text style={styles.sectionTitle}>Nutrition Facts</Text>
|
||||
<View style={styles.nutritionContainer}>
|
||||
<View style={styles.nutritionItem}>
|
||||
<View
|
||||
style={[
|
||||
styles.nutritionCircle,
|
||||
{ backgroundColor: "#FFD700" },
|
||||
]}
|
||||
>
|
||||
<Text style={styles.nutritionValue}>
|
||||
{foodData.nutrition.fat}
|
||||
</Text>
|
||||
<Text style={styles.nutritionUnit}>g</Text>
|
||||
</View>
|
||||
<Text style={styles.nutritionLabel}>Fat</Text>
|
||||
</View>
|
||||
<View style={styles.nutritionItem}>
|
||||
<View
|
||||
style={[
|
||||
styles.nutritionCircle,
|
||||
{ backgroundColor: "#90EE90" },
|
||||
]}
|
||||
>
|
||||
<Text style={styles.nutritionValue}>
|
||||
{foodData.nutrition.fiber}
|
||||
</Text>
|
||||
<Text style={styles.nutritionUnit}>g</Text>
|
||||
</View>
|
||||
<Text style={styles.nutritionLabel}>Fiber</Text>
|
||||
</View>
|
||||
<View style={styles.nutritionItem}>
|
||||
<View
|
||||
style={[
|
||||
styles.nutritionCircle,
|
||||
{ backgroundColor: "#ADD8E6" },
|
||||
]}
|
||||
>
|
||||
<Text style={styles.nutritionValue}>
|
||||
{foodData.nutrition.protein}
|
||||
</Text>
|
||||
<Text style={styles.nutritionUnit}>g</Text>
|
||||
</View>
|
||||
<Text style={styles.nutritionLabel}>Protein</Text>
|
||||
</View>
|
||||
<View style={styles.nutritionItem}>
|
||||
<View
|
||||
style={[
|
||||
styles.nutritionCircle,
|
||||
{ backgroundColor: "#FFA07A" },
|
||||
]}
|
||||
>
|
||||
<Text style={styles.nutritionValue}>
|
||||
{foodData.nutrition.carbs}
|
||||
</Text>
|
||||
<Text style={styles.nutritionUnit}>g</Text>
|
||||
</View>
|
||||
<Text style={styles.nutritionLabel}>Carbs</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* Steps Preview */}
|
||||
<View style={styles.sectionContainer}>
|
||||
<Text style={styles.sectionTitle}>Cooking Steps</Text>
|
||||
<View style={styles.stepsPreviewContainer}>
|
||||
{foodData.steps.slice(0, 2).map((step, index) => (
|
||||
<View key={index} style={styles.stepPreviewItem}>
|
||||
<View style={styles.stepNumberCircle}>
|
||||
<Text style={styles.stepNumber}>{index + 1}</Text>
|
||||
</View>
|
||||
<Text style={styles.stepPreviewText}>{step}</Text>
|
||||
</View>
|
||||
))}
|
||||
<Text style={styles.moreStepsText}>
|
||||
...and {foodData.steps.length - 2} more steps
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</ScrollView>
|
||||
|
||||
{/* Cook Button */}
|
||||
<TouchableOpacity style={styles.cookButton} onPress={startCookingSession}>
|
||||
<Text style={styles.cookButtonText}>Let's Cook!</Text>
|
||||
<IconSymbol name="fork.knife" size={20} color="#FFCC00" />
|
||||
</TouchableOpacity>
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: "#FFFFFF",
|
||||
},
|
||||
scrollView: {
|
||||
flex: 1,
|
||||
},
|
||||
header: {
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
paddingHorizontal: 16,
|
||||
paddingVertical: 12,
|
||||
position: "absolute",
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
zIndex: 10,
|
||||
},
|
||||
backButton: {
|
||||
width: 40,
|
||||
height: 40,
|
||||
borderRadius: 20,
|
||||
backgroundColor: "#FFCC00",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
},
|
||||
shareButton: {
|
||||
width: 40,
|
||||
height: 40,
|
||||
borderRadius: 20,
|
||||
backgroundColor: "#FFFFFF",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
},
|
||||
imageContainer: {
|
||||
alignItems: "center",
|
||||
marginTop: 60,
|
||||
marginBottom: 20,
|
||||
},
|
||||
foodImage: {
|
||||
width: 200,
|
||||
height: 200,
|
||||
borderRadius: 100,
|
||||
borderWidth: 5,
|
||||
borderColor: "#FFFFFF",
|
||||
},
|
||||
contentContainer: {
|
||||
paddingHorizontal: 16,
|
||||
},
|
||||
foodTitle: {
|
||||
fontSize: 24,
|
||||
fontWeight: "bold",
|
||||
color: "#333333",
|
||||
marginBottom: 8,
|
||||
},
|
||||
foodDescription: {
|
||||
fontSize: 16,
|
||||
color: "#666666",
|
||||
marginBottom: 20,
|
||||
lineHeight: 22,
|
||||
},
|
||||
tabsContainer: {
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
marginBottom: 20,
|
||||
},
|
||||
tabItem: {
|
||||
alignItems: "center",
|
||||
},
|
||||
activeTabItem: {
|
||||
borderBottomWidth: 2,
|
||||
borderBottomColor: "#333333",
|
||||
},
|
||||
tabLabel: {
|
||||
fontSize: 14,
|
||||
color: "#666666",
|
||||
},
|
||||
tabValue: {
|
||||
fontSize: 16,
|
||||
fontWeight: "bold",
|
||||
color: "#333333",
|
||||
marginTop: 4,
|
||||
},
|
||||
sectionContainer: {
|
||||
marginBottom: 20,
|
||||
},
|
||||
sectionTitle: {
|
||||
fontSize: 20,
|
||||
fontWeight: "bold",
|
||||
color: "#333333",
|
||||
marginBottom: 16,
|
||||
},
|
||||
ingredientsGrid: {
|
||||
flexDirection: "row",
|
||||
flexWrap: "wrap",
|
||||
},
|
||||
ingredientItem: {
|
||||
width: "25%",
|
||||
alignItems: "center",
|
||||
marginBottom: 16,
|
||||
},
|
||||
ingredientIconContainer: {
|
||||
width: 60,
|
||||
height: 60,
|
||||
borderRadius: 30,
|
||||
backgroundColor: "#F8F8F8",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
marginBottom: 8,
|
||||
shadowColor: "#000",
|
||||
shadowOffset: { width: 0, height: 2 },
|
||||
shadowOpacity: 0.1,
|
||||
shadowRadius: 4,
|
||||
elevation: 2,
|
||||
},
|
||||
ingredientEmoji: {
|
||||
fontSize: 30,
|
||||
},
|
||||
ingredientName: {
|
||||
fontSize: 12,
|
||||
textAlign: "center",
|
||||
color: "#333333",
|
||||
},
|
||||
nutritionSection: {
|
||||
marginBottom: 20,
|
||||
},
|
||||
nutritionContainer: {
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
backgroundColor: "#FFFFFF",
|
||||
borderRadius: 12,
|
||||
padding: 16,
|
||||
shadowColor: "#000",
|
||||
shadowOffset: { width: 0, height: 2 },
|
||||
shadowOpacity: 0.1,
|
||||
shadowRadius: 4,
|
||||
elevation: 2,
|
||||
},
|
||||
nutritionItem: {
|
||||
alignItems: "center",
|
||||
},
|
||||
nutritionCircle: {
|
||||
width: 60,
|
||||
height: 60,
|
||||
borderRadius: 30,
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
marginBottom: 8,
|
||||
},
|
||||
nutritionValue: {
|
||||
fontSize: 18,
|
||||
fontWeight: "bold",
|
||||
color: "#333333",
|
||||
},
|
||||
nutritionUnit: {
|
||||
fontSize: 12,
|
||||
color: "#333333",
|
||||
position: "absolute",
|
||||
bottom: 10,
|
||||
right: 10,
|
||||
},
|
||||
nutritionLabel: {
|
||||
fontSize: 14,
|
||||
fontWeight: "500",
|
||||
color: "#333333",
|
||||
},
|
||||
stepsPreviewContainer: {
|
||||
backgroundColor: "#F8F8F8",
|
||||
borderRadius: 12,
|
||||
padding: 16,
|
||||
},
|
||||
stepPreviewItem: {
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
marginBottom: 12,
|
||||
},
|
||||
stepNumberCircle: {
|
||||
width: 30,
|
||||
height: 30,
|
||||
borderRadius: 15,
|
||||
backgroundColor: "#FFCC00",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
marginRight: 12,
|
||||
},
|
||||
stepNumber: {
|
||||
fontSize: 16,
|
||||
fontWeight: "bold",
|
||||
color: "#333333",
|
||||
},
|
||||
stepPreviewText: {
|
||||
fontSize: 16,
|
||||
color: "#333333",
|
||||
flex: 1,
|
||||
},
|
||||
moreStepsText: {
|
||||
fontSize: 14,
|
||||
color: "#666666",
|
||||
fontStyle: "italic",
|
||||
textAlign: "center",
|
||||
marginTop: 8,
|
||||
},
|
||||
cookButton: {
|
||||
position: "absolute",
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
backgroundColor: "#FF0000",
|
||||
flexDirection: "row",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
paddingVertical: 16,
|
||||
},
|
||||
cookButtonText: {
|
||||
fontSize: 18,
|
||||
fontWeight: "bold",
|
||||
color: "#FFCC00",
|
||||
marginRight: 8,
|
||||
},
|
||||
});
|
||||
BIN
assets/images/cooking/step1.png
Normal file
|
After Width: | Height: | Size: 650 KiB |
BIN
assets/images/cooking/step2.png
Normal file
|
After Width: | Height: | Size: 650 KiB |
BIN
assets/images/cooking/step3.png
Normal file
|
After Width: | Height: | Size: 650 KiB |
BIN
assets/images/cooking/step4.png
Normal file
|
After Width: | Height: | Size: 650 KiB |
BIN
assets/images/cooking/step5.png
Normal file
|
After Width: | Height: | Size: 650 KiB |
BIN
assets/images/cooking/step6.png
Normal file
|
After Width: | Height: | Size: 650 KiB |
BIN
assets/images/food/beef.jpg
Normal file
|
After Width: | Height: | Size: 650 KiB |
BIN
assets/images/food/jjajangmyeon.jpg
Normal file
|
After Width: | Height: | Size: 427 KiB |
BIN
assets/images/food/padkrapao.jpg
Normal file
|
After Width: | Height: | Size: 237 KiB |
BIN
assets/images/food/padthai.jpg
Normal file
|
After Width: | Height: | Size: 173 KiB |
BIN
assets/images/food/ramen.jpg
Normal file
BIN
assets/images/food/tiramisu.jpg
Normal file
|
After Width: | Height: | Size: 254 KiB |
BIN
assets/images/food/wings.jpg
Normal file
|
After Width: | Height: | Size: 142 KiB |
BIN
assets/images/notebook-orange.png
Normal file
|
After Width: | Height: | Size: 76 KiB |
BIN
assets/images/placeholder-food.jpg
Normal file
|
After Width: | Height: | Size: 113 KiB |