add ui placeholder

This commit is contained in:
Sosokker 2025-05-08 19:45:39 +07:00
parent 51d2299d84
commit 88702ca54e
24 changed files with 1836 additions and 205 deletions

View File

@ -1,43 +1,57 @@
import { Tabs } from 'expo-router'; import { Tabs } from "expo-router";
import React from 'react';
import { Platform } from 'react-native';
import { HapticTab } from '@/components/HapticTab'; import { HapticTab } from "@/components/HapticTab";
import { IconSymbol } from '@/components/ui/IconSymbol'; import { IconSymbol } from "@/components/ui/IconSymbol";
import TabBarBackground from '@/components/ui/TabBarBackground';
import { Colors } from '@/constants/Colors';
import { useColorScheme } from '@/hooks/useColorScheme';
export default function TabLayout() { export default function TabLayout() {
const colorScheme = useColorScheme();
return ( return (
<Tabs <Tabs
screenOptions={{ screenOptions={{
tabBarActiveTintColor: Colors[colorScheme ?? 'light'].tint, tabBarActiveTintColor: "#FF0000", // Red active color
headerShown: false, headerShown: false,
tabBarButton: HapticTab, tabBarButton: HapticTab,
tabBarBackground: TabBarBackground, tabBarStyle: {
tabBarStyle: Platform.select({ backgroundColor: "#FFCC00", // Yellow background
ios: { height: 60,
// Use a transparent background on iOS to show the blur effect paddingBottom: 5,
position: 'absolute', borderTopWidth: 0,
}, },
default: {}, }}
}), >
}}>
<Tabs.Screen <Tabs.Screen
name="index" name="index"
options={{ options={{
title: 'Home', title: "Home",
tabBarIcon: ({ color }) => <IconSymbol size={28} name="house.fill" color={color} />, tabBarIcon: ({ color }) => (
<IconSymbol size={28} name="house.fill" color={color} />
),
}} }}
/> />
<Tabs.Screen <Tabs.Screen
name="explore" name="recipes"
options={{ options={{
title: 'Explore', title: "Recipes",
tabBarIcon: ({ color }) => <IconSymbol size={28} name="paperplane.fill" color={color} />, 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> </Tabs>

View File

@ -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&apos;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
View 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",
},
});

View File

@ -1,75 +1,321 @@
import { Image } from 'expo-image'; import { Image } from "expo-image";
import { Platform, StyleSheet } from 'react-native'; 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 { IconSymbol } from "@/components/ui/IconSymbol";
import ParallaxScrollView from '@/components/ParallaxScrollView';
import { ThemedText } from '@/components/ThemedText';
import { ThemedView } from '@/components/ThemedView';
export default function HomeScreen() { 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 ( return (
<ParallaxScrollView <SafeAreaView style={styles.container} edges={["top"]}>
headerBackgroundColor={{ light: '#A1CEDC', dark: '#1D3D47' }} <ScrollView style={styles.scrollView}>
headerImage={ {/* Header */}
<Image <View style={styles.header}>
source={require('@/assets/images/partial-react-logo.png')} <Text style={styles.greeting}>Hi! Mr. Chef</Text>
style={styles.reactLogo} <TouchableOpacity style={styles.scanButton}>
/> <IconSymbol name="qrcode.viewfinder" size={24} color="#333333" />
}> </TouchableOpacity>
<ThemedView style={styles.titleContainer}> </View>
<ThemedText type="title">Welcome!</ThemedText>
<HelloWave /> {/* Hero Section */}
</ThemedView> <View style={styles.heroContainer}>
<ThemedView style={styles.stepContainer}> <View style={styles.heroContent}>
<ThemedText type="subtitle">Step 1: Try it</ThemedText> <Image
<ThemedText> source={require("@/assets/images/notebook-orange.png")}
Edit <ThemedText type="defaultSemiBold">app/(tabs)/index.tsx</ThemedText> to see changes. style={styles.heroImage}
Press{' '} contentFit="contain"
<ThemedText type="defaultSemiBold"> />
{Platform.select({ </View>
ios: 'cmd + d', </View>
android: 'cmd + m',
web: 'F12', {/* Food Highlights Section */}
})} <View style={styles.sectionContainer}>
</ThemedText>{' '} <View style={styles.sectionHeader}>
to open developer tools. <Text style={styles.sectionTitle}>Food Highlights</Text>
</ThemedText> <IconSymbol name="star.fill" size={16} color="#FFCC00" />
</ThemedView> </View>
<ThemedView style={styles.stepContainer}>
<ThemedText type="subtitle">Step 2: Explore</ThemedText> <View style={styles.foodHighlightsContainer}>
<ThemedText> {foodHighlights.map((food) => (
{`Tap the Explore tab to learn more about what's included in this starter app.`} <TouchableOpacity
</ThemedText> key={food.id}
</ThemedView> style={styles.foodCard}
<ThemedView style={styles.stepContainer}> onPress={() => navigateToFoodDetail(String(food.id))}
<ThemedText type="subtitle">Step 3: Get a fresh start</ThemedText> >
<ThemedText> <Image
{`When you're ready, run `} source={food.image}
<ThemedText type="defaultSemiBold">npm run reset-project</ThemedText> to get a fresh{' '} style={styles.foodImage}
<ThemedText type="defaultSemiBold">app</ThemedText> directory. This will move the current{' '} contentFit="cover"
<ThemedText type="defaultSemiBold">app</ThemedText> to{' '} />
<ThemedText type="defaultSemiBold">app-example</ThemedText>. <View style={styles.foodCardContent}>
</ThemedText> <Text style={styles.foodCardTitle} numberOfLines={1}>
</ThemedView> {food.name}
</ParallaxScrollView> </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({ const styles = StyleSheet.create({
titleContainer: { container: {
flexDirection: 'row', flex: 1,
alignItems: 'center', backgroundColor: "#FFFFFF",
gap: 8,
}, },
stepContainer: { scrollView: {
gap: 8, 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, marginBottom: 8,
}, },
reactLogo: { foodCardMeta: {
height: 178, flexDirection: "row",
width: 290, justifyContent: "space-between",
bottom: 0, },
left: 0, foodCardMetaItem: {
position: 'absolute', 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
View 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
View 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,
},
});

View File

@ -1,15 +1,15 @@
import { DarkTheme, DefaultTheme, ThemeProvider } from '@react-navigation/native'; import { DefaultTheme, ThemeProvider } from "@react-navigation/native";
import { useFonts } from 'expo-font'; import { useFonts } from "expo-font";
import { Stack } from 'expo-router'; import { Stack } from "expo-router";
import { StatusBar } from 'expo-status-bar'; import { StatusBar } from "expo-status-bar";
import 'react-native-reanimated'; import "react-native-reanimated";
import { useColorScheme } from '@/hooks/useColorScheme'; import { useColorScheme } from "@/hooks/useColorScheme";
export default function RootLayout() { export default function RootLayout() {
const colorScheme = useColorScheme(); const colorScheme = useColorScheme();
const [loaded] = useFonts({ const [loaded] = useFonts({
SpaceMono: require('../assets/fonts/SpaceMono-Regular.ttf'), SpaceMono: require("../assets/fonts/SpaceMono-Regular.ttf"),
}); });
if (!loaded) { if (!loaded) {
@ -18,7 +18,8 @@ export default function RootLayout() {
} }
return ( return (
<ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}> // Use DarkTheme if need dark theme
<ThemeProvider value={colorScheme === "dark" ? DefaultTheme : DefaultTheme}>
<Stack> <Stack>
<Stack.Screen name="(tabs)" options={{ headerShown: false }} /> <Stack.Screen name="(tabs)" options={{ headerShown: false }} />
<Stack.Screen name="+not-found" /> <Stack.Screen name="+not-found" />

363
app/cooking/[id].tsx Normal file
View 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
View 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&apos;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,
},
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 650 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 650 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 650 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 650 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 650 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 650 KiB

BIN
assets/images/food/beef.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 650 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 427 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 237 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 254 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB