diff --git a/app/(tabs)/_layout.tsx b/app/(tabs)/_layout.tsx index cfbc1e2..e413a56 100644 --- a/app/(tabs)/_layout.tsx +++ b/app/(tabs)/_layout.tsx @@ -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 ( + tabBarStyle: { + backgroundColor: "#FFCC00", // Yellow background + height: 60, + paddingBottom: 5, + borderTopWidth: 0, + }, + }} + > , + title: "Home", + tabBarIcon: ({ color }) => ( + + ), }} /> , + title: "Recipes", + tabBarIcon: ({ color }) => ( + + ), + }} + /> + ( + + ), + }} + /> + ( + + ), }} /> diff --git a/app/(tabs)/explore.tsx b/app/(tabs)/explore.tsx deleted file mode 100644 index d4fbcaa..0000000 --- a/app/(tabs)/explore.tsx +++ /dev/null @@ -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 ( - - }> - - Explore - - This app includes example code to help you get started. - - - This app has two screens:{' '} - app/(tabs)/index.tsx and{' '} - app/(tabs)/explore.tsx - - - The layout file in app/(tabs)/_layout.tsx{' '} - sets up the tab navigator. - - - Learn more - - - - - You can open this project on Android, iOS, and the web. To open the web version, press{' '} - w in the terminal running this project. - - - - - For static images, you can use the @2x and{' '} - @3x suffixes to provide files for - different screen densities - - - - Learn more - - - - - Open app/_layout.tsx to see how to load{' '} - - custom fonts such as this one. - - - - Learn more - - - - - This template has light and dark mode support. The{' '} - useColorScheme() hook lets you inspect - what the user's current color scheme is, and so you can adjust UI colors accordingly. - - - Learn more - - - - - This template includes an example of an animated component. The{' '} - components/HelloWave.tsx component uses - the powerful react-native-reanimated{' '} - library to create a waving hand animation. - - {Platform.select({ - ios: ( - - The components/ParallaxScrollView.tsx{' '} - component provides a parallax effect for the header image. - - ), - })} - - - ); -} - -const styles = StyleSheet.create({ - headerImage: { - color: '#808080', - bottom: -90, - left: -35, - position: 'absolute', - }, - titleContainer: { - flexDirection: 'row', - gap: 8, - }, -}); diff --git a/app/(tabs)/forum.tsx b/app/(tabs)/forum.tsx new file mode 100644 index 0000000..36295b3 --- /dev/null +++ b/app/(tabs)/forum.tsx @@ -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 ( + + + {/* Search Bar */} + + + + + + {/* Category Filters */} + + + Main dish + + + Dessert + + + Appetite + + + + {/* Filter Options */} + + + Rating + + + + Newest + + + + Best + + + + + {/* Post */} + + {/* User Info */} + + + + + + Mr. Chef + + + 4.2 + + + + + {/* Post Image */} + + + {/* Post Content */} + + Kajjecaw + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut at + hendrerit enim. Etiam lacinia mi nec nunc ornare, vitae tempus leo + aliquet... + + + + {/* Post Actions */} + + + + 3 + + + + 2 + + + + 2 + + + + + + + + + ); +} + +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", + }, +}); diff --git a/app/(tabs)/index.tsx b/app/(tabs)/index.tsx index 462e8cd..5723af8 100644 --- a/app/(tabs)/index.tsx +++ b/app/(tabs)/index.tsx @@ -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 ( - - }> - - Welcome! - - - - Step 1: Try it - - Edit app/(tabs)/index.tsx to see changes. - Press{' '} - - {Platform.select({ - ios: 'cmd + d', - android: 'cmd + m', - web: 'F12', - })} - {' '} - to open developer tools. - - - - Step 2: Explore - - {`Tap the Explore tab to learn more about what's included in this starter app.`} - - - - Step 3: Get a fresh start - - {`When you're ready, run `} - npm run reset-project to get a fresh{' '} - app directory. This will move the current{' '} - app to{' '} - app-example. - - - + + + {/* Header */} + + Hi! Mr. Chef + + + + + + {/* Hero Section */} + + + + + + + {/* Food Highlights Section */} + + + Food Highlights + + + + + {foodHighlights.map((food) => ( + navigateToFoodDetail(String(food.id))} + > + + + + {food.name} + + + {food.description} + + + + + {food.time} + + + + + {food.calories} + + + + + + ))} + + + + {/* Show your dishes Section */} + + + Show your dishes + + + + + + + + + + + + + + From Camera + + Snap it from Camera + + + + + From Gallery + + Select from Gallery + + + + + + ); } 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, }, }); diff --git a/app/(tabs)/profile.tsx b/app/(tabs)/profile.tsx new file mode 100644 index 0000000..a0db25d --- /dev/null +++ b/app/(tabs)/profile.tsx @@ -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 ( + + + {/* Profile Header */} + + + + 👨‍🍳 + + + Mr. Chef + + Edit + + + + {/* Tab Navigation */} + + {["Repost", "Likes", "Bookmark"].map((tab) => ( + setActiveTab(tab)} + > + {tab} + + ))} + + + + + {/* Food Grid */} + + {foodItems.map((item, index) => ( + + + + {item.name} + + + ))} + + + + ); +} + +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, + }, +}); diff --git a/app/(tabs)/recipes.tsx b/app/(tabs)/recipes.tsx new file mode 100644 index 0000000..155879c --- /dev/null +++ b/app/(tabs)/recipes.tsx @@ -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 ( + + + {/* Search Bar */} + + + + + + {/* Filter Buttons */} + + + All Recipes + + + My Recipes + + + + {/* Divider */} + + + {/* Food Grid */} + + {foodItems.map((item) => ( + + + + {item.name} + + + ))} + + + + ); +} + +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, + }, +}); diff --git a/app/_layout.tsx b/app/_layout.tsx index 8d506f7..7541fb9 100644 --- a/app/_layout.tsx +++ b/app/_layout.tsx @@ -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 ( - + // Use DarkTheme if need dark theme + diff --git a/app/cooking/[id].tsx b/app/cooking/[id].tsx new file mode 100644 index 0000000..46c1fa6 --- /dev/null +++ b/app/cooking/[id].tsx @@ -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 ( + + + {/* Header with back button */} + + router.back()} + > + + + + + {/* Step Illustration */} + + + + + {/* Step Information */} + + + Step {currentStep + 1} of {totalSteps} + + + {recipeData.steps[currentStep].title} + + + {recipeData.steps[currentStep].description} + + + + {/* Step Indicators */} + + Steps + + {recipeData.steps.map((_, index) => ( + setCurrentStep(index)} + > + + + ))} + + + + {/* Navigation Buttons */} + + + Help me! + + + + {currentStep > 0 && ( + + + Previous + + )} + + {currentStep < totalSteps - 1 ? ( + + Next Step + + + ) : ( + router.back()} + > + Finish + + + )} + + + + + {/* Stop Session Button */} + + Stop Session + + + + ); +} + +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, + }, +}); diff --git a/app/food/[id].tsx b/app/food/[id].tsx new file mode 100644 index 0000000..c582278 --- /dev/null +++ b/app/food/[id].tsx @@ -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 ( + + + {/* Header with back and share buttons */} + + router.back()} + > + + + + + + + + {/* Food Image */} + + + + + {/* Food Title and Description */} + + {foodData.name} + {foodData.description} + + {/* Info Tabs */} + + setActiveTab("Skills")} + > + Skills + {foodData.skills} + + setActiveTab("Time")} + > + Time + {foodData.time} + + setActiveTab("Ingredients")} + > + Ingredients + {foodData.ingredients.length} + + setActiveTab("Calories")} + > + Calories + {foodData.calories} + + + + {/* Ingredients Section */} + + Ingredients + + {foodData.ingredients.map((ingredient, index) => ( + + + + {ingredient.emoji} + + + {ingredient.name} + + ))} + + + + {/* Nutrition Section - Improved UI */} + + Nutrition Facts + + + + + {foodData.nutrition.fat} + + g + + Fat + + + + + {foodData.nutrition.fiber} + + g + + Fiber + + + + + {foodData.nutrition.protein} + + g + + Protein + + + + + {foodData.nutrition.carbs} + + g + + Carbs + + + + + {/* Steps Preview */} + + Cooking Steps + + {foodData.steps.slice(0, 2).map((step, index) => ( + + + {index + 1} + + {step} + + ))} + + ...and {foodData.steps.length - 2} more steps + + + + + + + {/* Cook Button */} + + Let's Cook! + + + + ); +} + +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, + }, +}); diff --git a/assets/images/cooking/step1.png b/assets/images/cooking/step1.png new file mode 100644 index 0000000..70de86e Binary files /dev/null and b/assets/images/cooking/step1.png differ diff --git a/assets/images/cooking/step2.png b/assets/images/cooking/step2.png new file mode 100644 index 0000000..70de86e Binary files /dev/null and b/assets/images/cooking/step2.png differ diff --git a/assets/images/cooking/step3.png b/assets/images/cooking/step3.png new file mode 100644 index 0000000..70de86e Binary files /dev/null and b/assets/images/cooking/step3.png differ diff --git a/assets/images/cooking/step4.png b/assets/images/cooking/step4.png new file mode 100644 index 0000000..70de86e Binary files /dev/null and b/assets/images/cooking/step4.png differ diff --git a/assets/images/cooking/step5.png b/assets/images/cooking/step5.png new file mode 100644 index 0000000..70de86e Binary files /dev/null and b/assets/images/cooking/step5.png differ diff --git a/assets/images/cooking/step6.png b/assets/images/cooking/step6.png new file mode 100644 index 0000000..70de86e Binary files /dev/null and b/assets/images/cooking/step6.png differ diff --git a/assets/images/food/beef.jpg b/assets/images/food/beef.jpg new file mode 100644 index 0000000..70de86e Binary files /dev/null and b/assets/images/food/beef.jpg differ diff --git a/assets/images/food/jjajangmyeon.jpg b/assets/images/food/jjajangmyeon.jpg new file mode 100644 index 0000000..4ee61a9 Binary files /dev/null and b/assets/images/food/jjajangmyeon.jpg differ diff --git a/assets/images/food/padkrapao.jpg b/assets/images/food/padkrapao.jpg new file mode 100644 index 0000000..99b6d80 Binary files /dev/null and b/assets/images/food/padkrapao.jpg differ diff --git a/assets/images/food/padthai.jpg b/assets/images/food/padthai.jpg new file mode 100644 index 0000000..d66ce2c Binary files /dev/null and b/assets/images/food/padthai.jpg differ diff --git a/assets/images/food/ramen.jpg b/assets/images/food/ramen.jpg new file mode 100644 index 0000000..5b18c11 Binary files /dev/null and b/assets/images/food/ramen.jpg differ diff --git a/assets/images/food/tiramisu.jpg b/assets/images/food/tiramisu.jpg new file mode 100644 index 0000000..2d55164 Binary files /dev/null and b/assets/images/food/tiramisu.jpg differ diff --git a/assets/images/food/wings.jpg b/assets/images/food/wings.jpg new file mode 100644 index 0000000..1ea043b Binary files /dev/null and b/assets/images/food/wings.jpg differ diff --git a/assets/images/notebook-orange.png b/assets/images/notebook-orange.png new file mode 100644 index 0000000..aa87d4a Binary files /dev/null and b/assets/images/notebook-orange.png differ diff --git a/assets/images/placeholder-food.jpg b/assets/images/placeholder-food.jpg new file mode 100644 index 0000000..87d0b1f Binary files /dev/null and b/assets/images/placeholder-food.jpg differ