mirror of
https://github.com/Sosokker/chefhai.git
synced 2025-12-19 05:54:08 +01:00
commit
2b7973ab81
@ -1,21 +1,30 @@
|
||||
import { Ionicons, MaterialCommunityIcons } from "@expo/vector-icons";
|
||||
import { Tabs } from "expo-router";
|
||||
|
||||
import { HapticTab } from "@/components/HapticTab";
|
||||
import { IconSymbol } from "@/components/ui/IconSymbol";
|
||||
|
||||
export default function TabLayout() {
|
||||
return (
|
||||
<Tabs
|
||||
screenOptions={{
|
||||
tabBarActiveTintColor: "#FF0000", // Red active color
|
||||
headerShown: false,
|
||||
tabBarButton: HapticTab,
|
||||
tabBarStyle: {
|
||||
backgroundColor: "#FFCC00", // Yellow background
|
||||
height: 60,
|
||||
paddingBottom: 5,
|
||||
backgroundColor: "#ffd60a",
|
||||
height: 70,
|
||||
borderTopLeftRadius: 0,
|
||||
borderTopRightRadius: 0,
|
||||
position: "absolute",
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
elevation: 0,
|
||||
borderTopWidth: 0,
|
||||
},
|
||||
tabBarActiveTintColor: "#bb0718",
|
||||
tabBarInactiveTintColor: "#bb0718",
|
||||
tabBarShowLabel: true,
|
||||
tabBarLabelStyle: {
|
||||
fontSize: 12,
|
||||
fontWeight: "500",
|
||||
},
|
||||
headerShown: false,
|
||||
}}
|
||||
>
|
||||
<Tabs.Screen
|
||||
@ -23,34 +32,45 @@ export default function TabLayout() {
|
||||
options={{
|
||||
title: "Home",
|
||||
tabBarIcon: ({ color }) => (
|
||||
<IconSymbol size={28} name="house.fill" color={color} />
|
||||
<Ionicons name="home-outline" size={24} color={color} />
|
||||
),
|
||||
}}
|
||||
/>
|
||||
|
||||
<Tabs.Screen
|
||||
name="recipes"
|
||||
options={{
|
||||
title: "Recipes",
|
||||
tabBarIcon: ({ color }) => (
|
||||
<IconSymbol size={28} name="doc.text.fill" color={color} />
|
||||
<MaterialCommunityIcons
|
||||
name="notebook-outline"
|
||||
size={24}
|
||||
color={color}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
|
||||
<Tabs.Screen
|
||||
name="forum"
|
||||
options={{
|
||||
title: "Forum",
|
||||
tabBarIcon: ({ color }) => (
|
||||
<IconSymbol size={28} name="hand.thumbsup.fill" color={color} />
|
||||
<MaterialCommunityIcons
|
||||
name="forum-outline"
|
||||
size={24}
|
||||
color={color}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
|
||||
<Tabs.Screen
|
||||
name="profile"
|
||||
options={{
|
||||
title: "Profile",
|
||||
tabBarIcon: ({ color }) => (
|
||||
<IconSymbol size={28} name="person.fill" color={color} />
|
||||
<Ionicons name="person-outline" size={24} color={color} />
|
||||
),
|
||||
}}
|
||||
/>
|
||||
|
||||
@ -2,7 +2,6 @@ import { IconSymbol } from "@/components/ui/IconSymbol";
|
||||
import { Image } from "expo-image";
|
||||
import {
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TextInput,
|
||||
TouchableOpacity,
|
||||
@ -12,63 +11,63 @@ import { SafeAreaView } from "react-native-safe-area-context";
|
||||
|
||||
export default function ForumScreen() {
|
||||
return (
|
||||
<SafeAreaView style={styles.container} edges={["top"]}>
|
||||
<ScrollView style={styles.scrollView}>
|
||||
<SafeAreaView className="flex-1 bg-white" edges={["top"]}>
|
||||
<ScrollView className="flex-1">
|
||||
{/* Search Bar */}
|
||||
<View style={styles.searchContainer}>
|
||||
<View className="flex-row items-center mx-4 mt-2 mb-4 px-3 h-10 bg-white rounded-full border border-gray-300">
|
||||
<IconSymbol name="magnifyingglass" size={20} color="#FF0000" />
|
||||
<TextInput
|
||||
style={styles.searchInput}
|
||||
className="flex-1 ml-2 text-[#333]"
|
||||
placeholder="Search"
|
||||
placeholderTextColor="#FF0000"
|
||||
/>
|
||||
</View>
|
||||
|
||||
{/* Category Filters */}
|
||||
<View style={styles.categoryContainer}>
|
||||
<TouchableOpacity style={styles.categoryButton}>
|
||||
<Text style={styles.categoryText}>Main dish</Text>
|
||||
<View className="flex-row justify-between mx-4 mb-4">
|
||||
<TouchableOpacity className="bg-[#FFCC00] py-3 px-4 rounded-xl flex-1 mx-1 items-center">
|
||||
<Text className="font-bold text-[#333]">Main dish</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity style={styles.categoryButton}>
|
||||
<Text style={styles.categoryText}>Dessert</Text>
|
||||
<TouchableOpacity className="bg-[#FFCC00] py-3 px-4 rounded-xl flex-1 mx-1 items-center">
|
||||
<Text className="font-bold text-[#333]">Dessert</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity style={styles.categoryButton}>
|
||||
<Text style={styles.categoryText}>Appetite</Text>
|
||||
<TouchableOpacity className="bg-[#FFCC00] py-3 px-4 rounded-xl flex-1 mx-1 items-center">
|
||||
<Text className="font-bold text-[#333]">Appetite</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
{/* Filter Options */}
|
||||
<View style={styles.filterContainer}>
|
||||
<TouchableOpacity style={styles.filterButton}>
|
||||
<Text style={styles.filterText}>Rating</Text>
|
||||
<View className="flex-row mx-4 mb-4">
|
||||
<TouchableOpacity className="bg-red-600 py-2 px-3 rounded-full mr-2 flex-row items-center">
|
||||
<Text className="text-white font-bold mr-1">Rating</Text>
|
||||
<IconSymbol name="star.fill" size={16} color="#FFCC00" />
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity style={styles.filterButton}>
|
||||
<Text style={styles.filterText}>Newest</Text>
|
||||
<TouchableOpacity className="bg-red-600 py-2 px-3 rounded-full mr-2 flex-row items-center">
|
||||
<Text className="text-white font-bold mr-1">Newest</Text>
|
||||
<IconSymbol name="calendar" size={16} color="#FFFFFF" />
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity style={styles.filterButton}>
|
||||
<Text style={styles.filterText}>Best</Text>
|
||||
<TouchableOpacity className="bg-red-600 py-2 px-3 rounded-full mr-2 flex-row items-center">
|
||||
<Text className="text-white font-bold mr-1">Best</Text>
|
||||
<IconSymbol name="flame.fill" size={16} color="#FFCC00" />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
{/* Post */}
|
||||
<View style={styles.postContainer}>
|
||||
<View className="mx-4 mb-4 bg-white rounded-xl overflow-hidden border border-[#EEEEEE]">
|
||||
{/* User Info */}
|
||||
<View style={styles.userInfoContainer}>
|
||||
<View style={styles.userInfo}>
|
||||
<View style={styles.userAvatar}>
|
||||
<View className="flex-row justify-between items-center px-3 py-2">
|
||||
<View className="flex-row items-center">
|
||||
<View className="w-8 h-8 rounded-full bg-gray-200 justify-center items-center mr-2">
|
||||
<IconSymbol
|
||||
name="person.circle.fill"
|
||||
size={24}
|
||||
color="#888888"
|
||||
/>
|
||||
</View>
|
||||
<Text style={styles.userName}>Mr. Chef</Text>
|
||||
<Text className="font-bold text-[#333]">Mr. Chef</Text>
|
||||
</View>
|
||||
<View style={styles.ratingContainer}>
|
||||
<Text style={styles.ratingText}>4.2</Text>
|
||||
<View className="flex-row items-center">
|
||||
<Text className="mr-1 font-bold text-[#333]">4.2</Text>
|
||||
<IconSymbol name="star.fill" size={16} color="#FFCC00" />
|
||||
</View>
|
||||
</View>
|
||||
@ -76,14 +75,16 @@ export default function ForumScreen() {
|
||||
{/* Post Image */}
|
||||
<Image
|
||||
source={require("@/assets/images/placeholder-food.jpg")}
|
||||
style={styles.postImage}
|
||||
contentFit="cover"
|
||||
className="w-full h-[200px]"
|
||||
resizeMode="cover"
|
||||
/>
|
||||
|
||||
{/* Post Content */}
|
||||
<View style={styles.postContent}>
|
||||
<Text style={styles.postTitle}>Kajjecaw</Text>
|
||||
<Text style={styles.postDescription}>
|
||||
<View className="p-3">
|
||||
<Text className="text-base font-bold mb-1 text-[#333]">
|
||||
Kajjecaw
|
||||
</Text>
|
||||
<Text className="text-[#666] text-sm">
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut at
|
||||
hendrerit enim. Etiam lacinia mi nec nunc ornare, vitae tempus leo
|
||||
aliquet...
|
||||
@ -91,24 +92,24 @@ export default function ForumScreen() {
|
||||
</View>
|
||||
|
||||
{/* Post Actions */}
|
||||
<View style={styles.postActions}>
|
||||
<TouchableOpacity style={styles.actionButton}>
|
||||
<View className="flex-row border-t border-[#EEEEEE] py-2 px-3">
|
||||
<TouchableOpacity className="flex-row items-center mr-4">
|
||||
<IconSymbol
|
||||
name="arrowshape.turn.up.left.fill"
|
||||
size={16}
|
||||
color="#888888"
|
||||
/>
|
||||
<Text style={styles.actionText}>3</Text>
|
||||
<Text className="ml-1 text-[#888]">3</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity style={styles.actionButton}>
|
||||
<TouchableOpacity className="flex-row items-center mr-4">
|
||||
<IconSymbol name="text.bubble.fill" size={16} color="#888888" />
|
||||
<Text style={styles.actionText}>2</Text>
|
||||
<Text className="ml-1 text-[#888]">2</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity style={styles.actionButton}>
|
||||
<TouchableOpacity className="flex-row items-center mr-4">
|
||||
<IconSymbol name="heart.fill" size={16} color="#888888" />
|
||||
<Text style={styles.actionText}>2</Text>
|
||||
<Text className="ml-1 text-[#888]">2</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity style={styles.actionButton}>
|
||||
<TouchableOpacity className="flex-row items-center mr-4">
|
||||
<IconSymbol name="bookmark.fill" size={16} color="#888888" />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
@ -117,144 +118,3 @@ export default function ForumScreen() {
|
||||
</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,19 +1,22 @@
|
||||
import { Image } from "expo-image";
|
||||
import { IconSymbol } from "@/components/ui/IconSymbol";
|
||||
import { Feather, FontAwesome, Ionicons } from "@expo/vector-icons";
|
||||
import * as ImagePicker from "expo-image-picker";
|
||||
import { router } from "expo-router";
|
||||
import React, { useState } from "react";
|
||||
import {
|
||||
Alert,
|
||||
Image,
|
||||
SafeAreaView,
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
StatusBar,
|
||||
Text,
|
||||
TextInput,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
} from "react-native";
|
||||
import { SafeAreaView } from "react-native-safe-area-context";
|
||||
|
||||
import { IconSymbol } from "@/components/ui/IconSymbol";
|
||||
|
||||
export default function HomeScreen() {
|
||||
const foodHighlights = [
|
||||
// Sample recipe data
|
||||
const foodHighlights = [
|
||||
{
|
||||
id: 1,
|
||||
name: "Pad Kra Pao Moo Sab with Eggs",
|
||||
@ -46,68 +49,222 @@ export default function HomeScreen() {
|
||||
time: "90 Mins",
|
||||
calories: "750 kcal",
|
||||
},
|
||||
];
|
||||
];
|
||||
|
||||
const navigateToFoodDetail = (foodId: string) => {
|
||||
const navigateToFoodDetail = (foodId: string) => {
|
||||
router.push({ pathname: "/food/[id]", params: { id: foodId } });
|
||||
};
|
||||
|
||||
export default function HomeScreen() {
|
||||
const [searchQuery, setSearchQuery] = useState("");
|
||||
const [filteredRecipes, setFilteredRecipes] = useState(foodHighlights);
|
||||
|
||||
// Handle search
|
||||
const handleSearch = (text: string): void => {
|
||||
setSearchQuery(text);
|
||||
if (text) {
|
||||
const filtered = foodHighlights.filter((food) =>
|
||||
food.name.toLowerCase().includes(text.toLowerCase())
|
||||
);
|
||||
setFilteredRecipes(filtered);
|
||||
} else {
|
||||
setFilteredRecipes(foodHighlights);
|
||||
}
|
||||
};
|
||||
|
||||
// Handle camera
|
||||
const takePhoto = async () => {
|
||||
const { status } = await ImagePicker.requestCameraPermissionsAsync();
|
||||
|
||||
if (status !== "granted") {
|
||||
Alert.alert(
|
||||
"Permission needed",
|
||||
"Please grant camera permissions to use this feature."
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const result = await ImagePicker.launchCameraAsync({
|
||||
mediaTypes: ImagePicker.MediaTypeOptions.Images,
|
||||
allowsEditing: true,
|
||||
aspect: [1, 1],
|
||||
quality: 1,
|
||||
});
|
||||
|
||||
if (!result.canceled) {
|
||||
// Navigate to recipe detail with the captured image
|
||||
router.push({
|
||||
pathname: "/recipe-detail",
|
||||
params: {
|
||||
title: "My New Recipe",
|
||||
image: result.assets[0].uri,
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Handle gallery
|
||||
const pickImage = async () => {
|
||||
const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync();
|
||||
|
||||
if (status !== "granted") {
|
||||
Alert.alert(
|
||||
"Permission needed",
|
||||
"Please grant media library permissions to use this feature."
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const result = await ImagePicker.launchImageLibraryAsync({
|
||||
mediaTypes: ImagePicker.MediaTypeOptions.Images,
|
||||
allowsEditing: true,
|
||||
aspect: [1, 1],
|
||||
quality: 1,
|
||||
});
|
||||
|
||||
if (!result.canceled) {
|
||||
// Navigate to recipe detail with the selected image
|
||||
router.push({
|
||||
pathname: "/recipe-detail",
|
||||
params: {
|
||||
title: "My New Recipe",
|
||||
image: result.assets[0].uri,
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Navigate to recipe detail
|
||||
interface Recipe {
|
||||
id: number;
|
||||
title: string;
|
||||
image: string;
|
||||
color: string;
|
||||
}
|
||||
|
||||
const goToRecipeDetail = (recipe: Recipe): void => {
|
||||
router.push({
|
||||
pathname: "/recipe-detail",
|
||||
params: {
|
||||
title: recipe.title,
|
||||
image: recipe.image,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<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>
|
||||
<SafeAreaView className="flex-1 bg-white">
|
||||
<StatusBar barStyle="dark-content" />
|
||||
|
||||
{/* Header - Fixed at top */}
|
||||
<View className="flex-row justify-between items-center px-6 pt-4 pb-2">
|
||||
<Text className="text-3xl font-bold">Hi! Mr. Chef</Text>
|
||||
<View className="bg-[#ffd60a] p-3 rounded-lg">
|
||||
<Ionicons name="settings-outline" size={24} color="black" />
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* Hero Section */}
|
||||
<View style={styles.heroContainer}>
|
||||
<View style={styles.heroContent}>
|
||||
<Image
|
||||
source={require("@/assets/images/notebook-orange.png")}
|
||||
style={styles.heroImage}
|
||||
contentFit="contain"
|
||||
{/* Scrollable Content */}
|
||||
<ScrollView
|
||||
className="flex-1"
|
||||
showsVerticalScrollIndicator={false}
|
||||
contentContainerStyle={{ paddingBottom: 100 }}
|
||||
>
|
||||
{/* Show your dishes */}
|
||||
<View className="px-6 mb-6">
|
||||
<View className="flex-row items-center mb-4">
|
||||
<Text className="text-2xl font-bold mr-2">Show your dishes</Text>
|
||||
<Feather name="wifi" size={20} color="black" />
|
||||
</View>
|
||||
|
||||
<View className="bg-white border border-gray-300 rounded-full mb-6 flex-row items-center px-4 py-3">
|
||||
<TextInput
|
||||
className="flex-1"
|
||||
placeholder="Search..."
|
||||
value={searchQuery}
|
||||
onChangeText={handleSearch}
|
||||
/>
|
||||
<View className="bg-[#ffd60a] p-2 rounded-full">
|
||||
<Feather name="send" size={20} color="black" />
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View className="flex-row justify-between">
|
||||
<TouchableOpacity
|
||||
className="bg-[#ffd60a] p-4 rounded-xl w-[48%]"
|
||||
onPress={takePhoto}
|
||||
>
|
||||
<View className="items-center">
|
||||
<FontAwesome name="camera" size={24} color="black" />
|
||||
<Text className="text-lg font-bold mt-2">From Camera</Text>
|
||||
<Text className="text-sm text-gray-700">
|
||||
Straight from Camera
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
|
||||
<TouchableOpacity
|
||||
className="bg-[#f9be25] p-4 rounded-xl w-[48%]"
|
||||
onPress={pickImage}
|
||||
>
|
||||
<View className="items-center">
|
||||
<Feather name="image" size={24} color="black" />
|
||||
<Text className="text-lg font-bold mt-2">From Gallery</Text>
|
||||
<Text className="text-sm text-gray-700">
|
||||
Straight from Gallery
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* Food Highlights Section */}
|
||||
<View style={styles.sectionContainer}>
|
||||
<View style={styles.sectionHeader}>
|
||||
<Text style={styles.sectionTitle}>Food Highlights</Text>
|
||||
<View className="mx-4 mb-6">
|
||||
<View className="flex-row items-center mb-3">
|
||||
<Text className="text-lg font-bold text-[#333] mr-2">
|
||||
Food Highlights
|
||||
</Text>
|
||||
<IconSymbol name="star.fill" size={16} color="#FFCC00" />
|
||||
</View>
|
||||
|
||||
<View style={styles.foodHighlightsContainer}>
|
||||
<View className="w-full">
|
||||
{foodHighlights.map((food) => (
|
||||
<TouchableOpacity
|
||||
key={food.id}
|
||||
style={styles.foodCard}
|
||||
className="flex-row bg-white rounded-xl mb-3 shadow-sm overflow-hidden"
|
||||
style={{
|
||||
shadowColor: "#000",
|
||||
shadowOffset: { width: 0, height: 2 },
|
||||
shadowOpacity: 0.1,
|
||||
shadowRadius: 4,
|
||||
elevation: 2,
|
||||
}}
|
||||
onPress={() => navigateToFoodDetail(String(food.id))}
|
||||
>
|
||||
<Image
|
||||
source={food.image}
|
||||
style={styles.foodImage}
|
||||
contentFit="cover"
|
||||
className="w-[88px] h-[88px] rounded-l-xl"
|
||||
resizeMode="cover"
|
||||
/>
|
||||
<View style={styles.foodCardContent}>
|
||||
<Text style={styles.foodCardTitle} numberOfLines={1}>
|
||||
<View className="flex-1 p-3 justify-between">
|
||||
<Text
|
||||
className="text-base font-bold text-[#333] mb-1"
|
||||
numberOfLines={1}
|
||||
>
|
||||
{food.name}
|
||||
</Text>
|
||||
<Text style={styles.foodCardDescription} numberOfLines={1}>
|
||||
<Text className="text-sm text-[#666] mb-2" numberOfLines={1}>
|
||||
{food.description}
|
||||
</Text>
|
||||
<View style={styles.foodCardMeta}>
|
||||
<View style={styles.foodCardMetaItem}>
|
||||
<View className="flex-row justify-between">
|
||||
<View className="flex-row items-center">
|
||||
<IconSymbol name="clock" size={12} color="#666666" />
|
||||
<Text style={styles.foodCardMetaText}>{food.time}</Text>
|
||||
<Text className="text-xs text-[#666] ml-1">
|
||||
{food.time}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.foodCardMetaItem}>
|
||||
<View className="flex-row items-center">
|
||||
<IconSymbol name="flame" size={12} color="#666666" />
|
||||
<Text style={styles.foodCardMetaText}>
|
||||
<Text className="text-xs text-[#666] ml-1">
|
||||
{food.calories}
|
||||
</Text>
|
||||
</View>
|
||||
@ -118,204 +275,9 @@ export default function HomeScreen() {
|
||||
</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>
|
||||
{/* Extra space at bottom */}
|
||||
<View className="h-20"></View>
|
||||
</ScrollView>
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: "#FFFFFF",
|
||||
},
|
||||
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,
|
||||
},
|
||||
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,
|
||||
},
|
||||
});
|
||||
|
||||
@ -2,13 +2,7 @@
|
||||
|
||||
import { Image } from "expo-image";
|
||||
import { useState } from "react";
|
||||
import {
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
} from "react-native";
|
||||
import { ScrollView, Text, TouchableOpacity, View } from "react-native";
|
||||
import { SafeAreaView } from "react-native-safe-area-context";
|
||||
|
||||
export default function ProfileScreen() {
|
||||
@ -66,47 +60,54 @@ export default function ProfileScreen() {
|
||||
];
|
||||
|
||||
return (
|
||||
<SafeAreaView style={styles.container} edges={["top"]}>
|
||||
<ScrollView style={styles.scrollView}>
|
||||
<SafeAreaView className="flex-1 bg-white" edges={["top"]}>
|
||||
<ScrollView className="flex-1">
|
||||
{/* Profile Header */}
|
||||
<View style={styles.profileHeader}>
|
||||
<View style={styles.avatarContainer}>
|
||||
<View style={styles.avatar}>
|
||||
<Text style={styles.avatarPlaceholder}>👨🍳</Text>
|
||||
<View className="items-center py-6">
|
||||
<View className="w-[100px] h-[100px] rounded-full border border-gray-300 justify-center items-center mb-3">
|
||||
<View className="w-[96px] h-[96px] rounded-full bg-gray-100 justify-center items-center">
|
||||
<Text className="text-5xl">👨🍳</Text>
|
||||
</View>
|
||||
</View>
|
||||
<Text style={styles.username}>Mr. Chef</Text>
|
||||
<TouchableOpacity style={styles.editButton}>
|
||||
<Text style={styles.editButtonText}>Edit</Text>
|
||||
<Text className="text-xl font-bold mb-3">Mr. Chef</Text>
|
||||
<TouchableOpacity className="bg-red-600 py-2 px-10 rounded-lg">
|
||||
<Text className="text-white font-bold">Edit</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
{/* Tab Navigation */}
|
||||
<View style={styles.tabContainer}>
|
||||
<View className="flex-row justify-around py-3">
|
||||
{["Repost", "Likes", "Bookmark"].map((tab) => (
|
||||
<TouchableOpacity
|
||||
key={tab}
|
||||
style={[styles.tab, activeTab === tab && styles.activeTab]}
|
||||
className={`py-2 px-4 ${
|
||||
activeTab === tab ? "border-b-2 border-[#333]" : ""
|
||||
}`}
|
||||
onPress={() => setActiveTab(tab)}
|
||||
>
|
||||
<Text style={styles.tabText}>{tab}</Text>
|
||||
<Text className="font-medium">{tab}</Text>
|
||||
</TouchableOpacity>
|
||||
))}
|
||||
</View>
|
||||
|
||||
<View style={styles.divider} />
|
||||
<View className="h-px bg-[#EEEEEE] mx-4" />
|
||||
|
||||
{/* Food Grid */}
|
||||
<View style={styles.foodGrid}>
|
||||
<View className="flex-row flex-wrap p-2">
|
||||
{foodItems.map((item, index) => (
|
||||
<View key={`${item.id}-${index}`} style={styles.foodItem}>
|
||||
<View key={`${item.id}-${index}`} className="w-1/2 p-2 relative">
|
||||
<Image
|
||||
source={item.image}
|
||||
style={styles.foodImage}
|
||||
contentFit="cover"
|
||||
className="w-full h-[120px] rounded-lg"
|
||||
resizeMode="cover"
|
||||
/>
|
||||
<View style={[styles.foodLabel, { backgroundColor: item.color }]}>
|
||||
<Text style={styles.foodLabelText}>{item.name}</Text>
|
||||
<View
|
||||
className="absolute bottom-4 left-4 py-1 px-2 rounded bg-opacity-90"
|
||||
style={{ backgroundColor: item.color }}
|
||||
>
|
||||
<Text className="text-[#333] font-bold text-xs">
|
||||
{item.name}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
))}
|
||||
@ -115,102 +116,3 @@ export default function ProfileScreen() {
|
||||
</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,
|
||||
},
|
||||
});
|
||||
|
||||
@ -2,7 +2,6 @@ import { IconSymbol } from "@/components/ui/IconSymbol";
|
||||
import { Image } from "expo-image";
|
||||
import {
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TextInput,
|
||||
TouchableOpacity,
|
||||
@ -51,42 +50,47 @@ export default function RecipesScreen() {
|
||||
];
|
||||
|
||||
return (
|
||||
<SafeAreaView style={styles.container} edges={["top"]}>
|
||||
<ScrollView style={styles.scrollView}>
|
||||
<SafeAreaView className="flex-1 bg-white" edges={["top"]}>
|
||||
<ScrollView className="flex-1">
|
||||
{/* Search Bar */}
|
||||
<View style={styles.searchContainer}>
|
||||
<View className="flex-row items-center mx-4 mt-2 mb-4 px-3 h-10 bg-white rounded-full border border-gray-300">
|
||||
<IconSymbol name="magnifyingglass" size={20} color="#FF0000" />
|
||||
<TextInput
|
||||
style={styles.searchInput}
|
||||
className="flex-1 ml-2 text-[#333]"
|
||||
placeholder="Search"
|
||||
placeholderTextColor="#FF0000"
|
||||
/>
|
||||
</View>
|
||||
|
||||
{/* Filter Buttons */}
|
||||
<View style={styles.filterContainer}>
|
||||
<TouchableOpacity style={styles.yellowButton}>
|
||||
<Text style={styles.buttonText}>All Recipes</Text>
|
||||
<View className="flex-row mx-4 mb-4">
|
||||
<TouchableOpacity className="flex-1 bg-[#FFCC00] py-3 rounded-lg mr-2 items-center">
|
||||
<Text className="font-bold text-[#333]">All Recipes</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity style={styles.redButton}>
|
||||
<Text style={styles.redButtonText}>My Recipes</Text>
|
||||
<TouchableOpacity className="flex-1 bg-red-600 py-3 rounded-lg items-center">
|
||||
<Text className="font-bold text-white">My Recipes</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
{/* Divider */}
|
||||
<View style={styles.divider} />
|
||||
<View className="h-px bg-[#EEEEEE] mx-4 mb-4" />
|
||||
|
||||
{/* Food Grid */}
|
||||
<View style={styles.foodGrid}>
|
||||
<View className="flex-row flex-wrap p-2">
|
||||
{foodItems.map((item) => (
|
||||
<View key={item.id} style={styles.foodItem}>
|
||||
<View key={item.id} className="w-1/2 p-2 relative">
|
||||
<Image
|
||||
source={item.image}
|
||||
style={styles.foodImage}
|
||||
contentFit="cover"
|
||||
className="w-full h-[120px] rounded-lg"
|
||||
resizeMode="cover"
|
||||
/>
|
||||
<View style={[styles.foodLabel, { backgroundColor: item.color }]}>
|
||||
<Text style={styles.foodLabelText}>{item.name}</Text>
|
||||
<View
|
||||
className="absolute bottom-4 left-4 py-1 px-2 rounded bg-opacity-90"
|
||||
style={{ backgroundColor: item.color }}
|
||||
>
|
||||
<Text className="text-[#333] font-bold text-xs">
|
||||
{item.name}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
))}
|
||||
@ -95,93 +99,3 @@ export default function RecipesScreen() {
|
||||
</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,30 +1,25 @@
|
||||
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 { GestureHandlerRootView } from "react-native-gesture-handler";
|
||||
import "../global.css";
|
||||
|
||||
export default function RootLayout() {
|
||||
const colorScheme = useColorScheme();
|
||||
const [loaded] = useFonts({
|
||||
SpaceMono: require("../assets/fonts/SpaceMono-Regular.ttf"),
|
||||
});
|
||||
|
||||
if (!loaded) {
|
||||
// Async font loading only occurs in development.
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
// 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" />
|
||||
<GestureHandlerRootView style={{ flex: 1 }}>
|
||||
<Stack screenOptions={{ headerShown: false }}>
|
||||
<Stack.Screen
|
||||
name="(tabs)"
|
||||
options={{
|
||||
headerShown: false,
|
||||
}}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name="recipe-detail"
|
||||
options={{
|
||||
headerShown: false,
|
||||
presentation: "card",
|
||||
}}
|
||||
/>
|
||||
</Stack>
|
||||
<StatusBar style="auto" />
|
||||
</ThemeProvider>
|
||||
</GestureHandlerRootView>
|
||||
);
|
||||
}
|
||||
|
||||
140
app/recipe-detail.tsx
Normal file
140
app/recipe-detail.tsx
Normal file
@ -0,0 +1,140 @@
|
||||
import React from 'react';
|
||||
import { View, Text, Image, TouchableOpacity, ScrollView, SafeAreaView, StatusBar } from 'react-native';
|
||||
import { Feather, FontAwesome5 } from '@expo/vector-icons';
|
||||
import { useLocalSearchParams, router } from 'expo-router';
|
||||
|
||||
export default function RecipeDetailScreen() {
|
||||
const { title, image } = useLocalSearchParams();
|
||||
|
||||
const recipeTitle = title || "Pad Kra Pao Moo Sab with Eggs";
|
||||
const recipeImage = typeof image === 'string' ? image : "/placeholder.svg?height=400&width=400&query=thai basil stir fry with egg and rice";
|
||||
|
||||
return (
|
||||
<SafeAreaView className="flex-1 bg-white">
|
||||
<StatusBar barStyle="dark-content" />
|
||||
|
||||
<ScrollView className="flex-1" showsVerticalScrollIndicator={false}>
|
||||
{/* Header with back and share buttons */}
|
||||
<View className="flex-row justify-between items-center px-4 pt-4 absolute z-10 w-full">
|
||||
<TouchableOpacity
|
||||
className="bg-[#ffd60a] p-3 rounded-lg"
|
||||
onPress={() => router.back()}
|
||||
>
|
||||
<Feather name="arrow-left" size={24} color="#bb0718" />
|
||||
</TouchableOpacity>
|
||||
|
||||
<TouchableOpacity className="bg-white p-3 rounded-lg">
|
||||
<Feather name="send" size={24} color="#ffd60a" />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
{/* Recipe Image */}
|
||||
<View className="items-center justify-center pt-16 pb-6">
|
||||
<Image
|
||||
source={{ uri: recipeImage }}
|
||||
className="w-72 h-72 rounded-full"
|
||||
/>
|
||||
</View>
|
||||
|
||||
{/* Recipe Title and Description */}
|
||||
<View className="px-6">
|
||||
<Text className="text-4xl font-bold">{recipeTitle}</Text>
|
||||
<Text className="text-gray-600 mt-2 text-lg">
|
||||
Pad kra pao, also written as pad gaprao, is a popular Thai stir fry of ground meat and holy basil.
|
||||
</Text>
|
||||
|
||||
{/* Recipe Info */}
|
||||
<View className="flex-row justify-between mt-8">
|
||||
<View>
|
||||
<Text className="text-2xl font-bold">Skills</Text>
|
||||
<Text className="text-gray-600 mt-1">Easy</Text>
|
||||
</View>
|
||||
|
||||
<View>
|
||||
<Text className="text-2xl font-bold">Time</Text>
|
||||
<Text className="text-gray-600 mt-1">30 Mins</Text>
|
||||
</View>
|
||||
|
||||
<View>
|
||||
<Text className="text-2xl font-bold">Ingredients</Text>
|
||||
<Text className="text-gray-600 mt-1">10+</Text>
|
||||
</View>
|
||||
|
||||
<View>
|
||||
<Text className="text-2xl font-bold">Calories</Text>
|
||||
<Text className="text-gray-600 mt-1">300 kCal</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* Ingredients */}
|
||||
<Text className="text-3xl font-bold mt-12">Ingredients</Text>
|
||||
<ScrollView
|
||||
horizontal
|
||||
showsHorizontalScrollIndicator={false}
|
||||
className="mt-6 mb-4"
|
||||
contentContainerStyle={{ paddingLeft: 4, paddingRight: 20 }}
|
||||
>
|
||||
<View className="flex-row space-x-6">
|
||||
<View className="w-24 h-24 bg-gray-300 rounded-lg" />
|
||||
<View className="w-24 h-24 bg-gray-300 rounded-lg" />
|
||||
<View className="w-24 h-24 bg-gray-300 rounded-lg" />
|
||||
<View className="w-24 h-24 bg-gray-300 rounded-lg" />
|
||||
<View className="w-24 h-24 bg-gray-300 rounded-lg" />
|
||||
</View>
|
||||
</ScrollView>
|
||||
|
||||
{/* Nutrition Info */}
|
||||
<View className="bg-[#ffd60a] rounded-lg p-6 mt-10">
|
||||
<View className="flex-row justify-between">
|
||||
<View className="items-center">
|
||||
<View className="w-16 h-16 rounded-full border-4 border-[#397e36] items-center justify-center">
|
||||
<Text className="text-xl font-bold">0</Text>
|
||||
<Text className="text-xs">/32g</Text>
|
||||
</View>
|
||||
<Text className="mt-2 font-semibold">Fat</Text>
|
||||
</View>
|
||||
|
||||
<View className="items-center">
|
||||
<View className="w-16 h-16 rounded-full border-4 border-[#397e36] items-center justify-center">
|
||||
<Text className="text-xl font-bold">0</Text>
|
||||
<Text className="text-xs">/32g</Text>
|
||||
</View>
|
||||
<Text className="mt-2 font-semibold">Fiber</Text>
|
||||
</View>
|
||||
|
||||
<View className="items-center">
|
||||
<View className="w-16 h-16 rounded-full border-4 border-[#a07d1a] items-center justify-center">
|
||||
<Text className="text-xl font-bold">0</Text>
|
||||
<Text className="text-xs">/32g</Text>
|
||||
</View>
|
||||
<Text className="mt-2 font-semibold">Protein</Text>
|
||||
</View>
|
||||
|
||||
<View className="items-center">
|
||||
<View className="w-16 h-16 rounded-full border-4 border-[#c87a20] items-center justify-center">
|
||||
<Text className="text-xl font-bold">0</Text>
|
||||
<Text className="text-xs">/32g</Text>
|
||||
</View>
|
||||
<Text className="mt-2 font-semibold">Carbs</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* Bottom Spacing */}
|
||||
<View className="h-28" />
|
||||
</ScrollView>
|
||||
|
||||
{/* Cook Button */}
|
||||
<View className="absolute bottom-0 left-0 right-0">
|
||||
<View className="bg-[#bb0718] py-4 items-center">
|
||||
<View className="flex-row items-center">
|
||||
<Text className="text-[#ffd60a] text-2xl font-bold mr-2">Let's Cook!</Text>
|
||||
<FontAwesome5 name="utensils" size={24} color="#ffd60a" />
|
||||
</View>
|
||||
</View>
|
||||
<View className="bg-[#ffd60a] h-16" style={{ borderTopLeftRadius: 0, borderTopRightRadius: 0, borderBottomLeftRadius: 50, borderBottomRightRadius: 50 }} />
|
||||
</View>
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 113 KiB After Width: | Height: | Size: 650 KiB |
9
babel.config.js
Normal file
9
babel.config.js
Normal file
@ -0,0 +1,9 @@
|
||||
module.exports = function (api) {
|
||||
api.cache(true);
|
||||
return {
|
||||
presets: [
|
||||
["babel-preset-expo", { jsxImportSource: "nativewind" }],
|
||||
"nativewind/babel",
|
||||
],
|
||||
};
|
||||
};
|
||||
3
global.css
Normal file
3
global.css
Normal file
@ -0,0 +1,3 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
6
metro.config.js
Normal file
6
metro.config.js
Normal file
@ -0,0 +1,6 @@
|
||||
const { getDefaultConfig } = require("expo/metro-config");
|
||||
const { withNativeWind } = require('nativewind/metro');
|
||||
|
||||
const config = getDefaultConfig(__dirname)
|
||||
|
||||
module.exports = withNativeWind(config, { input: './global.css' })
|
||||
1
nativewind-env.d.ts
vendored
Normal file
1
nativewind-env.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
/// <reference types="nativewind/types" />
|
||||
487
package-lock.json
generated
487
package-lock.json
generated
@ -19,6 +19,7 @@
|
||||
"expo-font": "~13.3.1",
|
||||
"expo-haptics": "~14.1.4",
|
||||
"expo-image": "~2.1.7",
|
||||
"expo-image-picker": "~16.1.4",
|
||||
"expo-linking": "~7.1.4",
|
||||
"expo-router": "~5.0.6",
|
||||
"expo-splash-screen": "~0.30.8",
|
||||
@ -26,6 +27,7 @@
|
||||
"expo-symbols": "~0.4.4",
|
||||
"expo-system-ui": "~5.0.7",
|
||||
"expo-web-browser": "~14.1.6",
|
||||
"nativewind": "^4.1.23",
|
||||
"react": "19.0.0",
|
||||
"react-dom": "19.0.0",
|
||||
"react-native": "0.79.2",
|
||||
@ -34,7 +36,8 @@
|
||||
"react-native-safe-area-context": "5.4.0",
|
||||
"react-native-screens": "~4.10.0",
|
||||
"react-native-web": "~0.20.0",
|
||||
"react-native-webview": "13.13.5"
|
||||
"react-native-webview": "13.13.5",
|
||||
"tailwindcss": "^3.4.17"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.25.2",
|
||||
@ -57,6 +60,18 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@alloc/quick-lru": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz",
|
||||
"integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/@ampproject/remapping": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
|
||||
@ -2249,6 +2264,7 @@
|
||||
"version": "14.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@expo/vector-icons/-/vector-icons-14.1.0.tgz",
|
||||
"integrity": "sha512-7T09UE9h8QDTsUeMGymB4i+iqvtEeaO5VvUjryFB4tugDTG/bkzViWA74hm5pfjjDEhYMXWaX112mcvhccmIwQ==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"expo-font": "*",
|
||||
"react": "*",
|
||||
@ -2678,7 +2694,6 @@
|
||||
"version": "2.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
|
||||
"integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@nodelib/fs.stat": "2.0.5",
|
||||
"run-parallel": "^1.1.9"
|
||||
@ -2691,7 +2706,6 @@
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
|
||||
"integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
@ -2700,7 +2714,6 @@
|
||||
"version": "1.2.8",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
|
||||
"integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@nodelib/fs.scandir": "2.1.5",
|
||||
"fastq": "^1.6.0"
|
||||
@ -4014,6 +4027,12 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/array-timsort": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/array-timsort/-/array-timsort-1.0.3.tgz",
|
||||
"integrity": "sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/array.prototype.findlast": {
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz",
|
||||
@ -4403,6 +4422,18 @@
|
||||
"node": ">=0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/binary-extensions": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
|
||||
"integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/body-parser": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz",
|
||||
@ -4656,6 +4687,15 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/camelcase-css": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
|
||||
"integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/caniuse-lite": {
|
||||
"version": "1.0.30001717",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001717.tgz",
|
||||
@ -4690,6 +4730,42 @@
|
||||
"url": "https://github.com/chalk/chalk?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/chokidar": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
|
||||
"integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"anymatch": "~3.1.2",
|
||||
"braces": "~3.0.2",
|
||||
"glob-parent": "~5.1.2",
|
||||
"is-binary-path": "~2.1.0",
|
||||
"is-glob": "~4.0.1",
|
||||
"normalize-path": "~3.0.0",
|
||||
"readdirp": "~3.6.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8.10.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"fsevents": "~2.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/chokidar/node_modules/glob-parent": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
|
||||
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"is-glob": "^4.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/chownr": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz",
|
||||
@ -4875,6 +4951,22 @@
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/comment-json": {
|
||||
"version": "4.2.5",
|
||||
"resolved": "https://registry.npmjs.org/comment-json/-/comment-json-4.2.5.tgz",
|
||||
"integrity": "sha512-bKw/r35jR3HGt5PEPm1ljsQQGyCrR8sFGNiN5L+ykDHdpO8Smxkrkla9Yi6NkQyUrb8V54PGhfMs6NrIwtxtdw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"array-timsort": "^1.0.3",
|
||||
"core-util-is": "^1.0.3",
|
||||
"esprima": "^4.0.1",
|
||||
"has-own-prop": "^2.0.0",
|
||||
"repeat-string": "^1.6.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/compressible": {
|
||||
"version": "2.0.18",
|
||||
"resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz",
|
||||
@ -5012,6 +5104,12 @@
|
||||
"url": "https://opencollective.com/core-js"
|
||||
}
|
||||
},
|
||||
"node_modules/core-util-is": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
|
||||
"integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/cors": {
|
||||
"version": "2.8.5",
|
||||
"resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
|
||||
@ -5116,6 +5214,18 @@
|
||||
"hyphenate-style-name": "^1.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/cssesc": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
|
||||
"integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"cssesc": "bin/cssesc"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/csstype": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
||||
@ -5333,6 +5443,18 @@
|
||||
"node": ">=0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/didyoumean": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
|
||||
"integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/dlv": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
|
||||
"integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/doctrine": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
|
||||
@ -6197,6 +6319,27 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/expo-image-loader": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/expo-image-loader/-/expo-image-loader-5.1.0.tgz",
|
||||
"integrity": "sha512-sEBx3zDQIODWbB5JwzE7ZL5FJD+DK3LVLWBVJy6VzsqIA6nDEnSFnsnWyCfCTSvbGigMATs1lgkC2nz3Jpve1Q==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"expo": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/expo-image-picker": {
|
||||
"version": "16.1.4",
|
||||
"resolved": "https://registry.npmjs.org/expo-image-picker/-/expo-image-picker-16.1.4.tgz",
|
||||
"integrity": "sha512-bTmmxtw1AohUT+HxEBn2vYwdeOrj1CLpMXKjvi9FKSoSbpcarT4xxI0z7YyGwDGHbrJqyyic3I9TTdP2J2b4YA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"expo-image-loader": "~5.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"expo": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/expo-keep-awake": {
|
||||
"version": "14.1.4",
|
||||
"resolved": "https://registry.npmjs.org/expo-keep-awake/-/expo-keep-awake-14.1.4.tgz",
|
||||
@ -6518,7 +6661,6 @@
|
||||
"version": "3.3.3",
|
||||
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
|
||||
"integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@nodelib/fs.stat": "^2.0.2",
|
||||
"@nodelib/fs.walk": "^1.2.3",
|
||||
@ -6534,7 +6676,6 @@
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
|
||||
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"is-glob": "^4.0.1"
|
||||
},
|
||||
@ -6572,7 +6713,6 @@
|
||||
"version": "1.19.1",
|
||||
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz",
|
||||
"integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"reusify": "^1.0.4"
|
||||
}
|
||||
@ -7004,7 +7144,6 @@
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
|
||||
"integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"is-glob": "^4.0.3"
|
||||
},
|
||||
@ -7125,6 +7264,15 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/has-own-prop": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-own-prop/-/has-own-prop-2.0.0.tgz",
|
||||
"integrity": "sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/has-property-descriptors": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
|
||||
@ -7483,6 +7631,18 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/is-binary-path": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
|
||||
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"binary-extensions": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/is-boolean-object": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz",
|
||||
@ -7605,7 +7765,6 @@
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
||||
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
@ -7655,7 +7814,6 @@
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
|
||||
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"is-extglob": "^2.1.1"
|
||||
},
|
||||
@ -8092,6 +8250,15 @@
|
||||
"resolved": "https://registry.npmjs.org/jimp-compact/-/jimp-compact-0.16.1.tgz",
|
||||
"integrity": "sha512-dZ6Ra7u1G8c4Letq/B5EzAxj4tLFHL+cGtdpR+PVm4yzPDj+lCk+AbivWt1eOM+ikzkowtyV7qSqX6qr3t71Ww=="
|
||||
},
|
||||
"node_modules/jiti": {
|
||||
"version": "1.21.7",
|
||||
"resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz",
|
||||
"integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==",
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"jiti": "bin/jiti.js"
|
||||
}
|
||||
},
|
||||
"node_modules/js-tokens": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||
@ -8456,6 +8623,18 @@
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/lilconfig": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz",
|
||||
"integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antonk52"
|
||||
}
|
||||
},
|
||||
"node_modules/lines-and-columns": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
|
||||
@ -8650,7 +8829,6 @@
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
|
||||
"integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
@ -9134,6 +9312,23 @@
|
||||
"url": "https://opencollective.com/napi-postinstall"
|
||||
}
|
||||
},
|
||||
"node_modules/nativewind": {
|
||||
"version": "4.1.23",
|
||||
"resolved": "https://registry.npmjs.org/nativewind/-/nativewind-4.1.23.tgz",
|
||||
"integrity": "sha512-oLX3suGI6ojQqWxdQezOSM5GmJ4KvMnMtmaSMN9Ggb5j7ysFt4nHxb1xs8RDjZR7BWc+bsetNJU8IQdQMHqRpg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"comment-json": "^4.2.5",
|
||||
"debug": "^4.3.7",
|
||||
"react-native-css-interop": "0.1.22"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"tailwindcss": ">3.3.0"
|
||||
}
|
||||
},
|
||||
"node_modules/natural-compare": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
|
||||
@ -9258,6 +9453,15 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/object-hash": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
|
||||
"integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/object-inspect": {
|
||||
"version": "1.13.4",
|
||||
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
|
||||
@ -9716,6 +9920,15 @@
|
||||
"url": "https://github.com/sponsors/jonschlinkert"
|
||||
}
|
||||
},
|
||||
"node_modules/pify": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
|
||||
"integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/pirates": {
|
||||
"version": "4.0.7",
|
||||
"resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz",
|
||||
@ -9790,6 +10003,127 @@
|
||||
"node": "^10 || ^12 || >=14"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-import": {
|
||||
"version": "15.1.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz",
|
||||
"integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"postcss-value-parser": "^4.0.0",
|
||||
"read-cache": "^1.0.0",
|
||||
"resolve": "^1.1.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": "^8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-js": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz",
|
||||
"integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"camelcase-css": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12 || ^14 || >= 16"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/postcss/"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": "^8.4.21"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-load-config": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz",
|
||||
"integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/postcss/"
|
||||
},
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"lilconfig": "^3.0.0",
|
||||
"yaml": "^2.3.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 14"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": ">=8.0.9",
|
||||
"ts-node": ">=9.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"postcss": {
|
||||
"optional": true
|
||||
},
|
||||
"ts-node": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-load-config/node_modules/yaml": {
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.1.tgz",
|
||||
"integrity": "sha512-10ULxpnOCQXxJvBgxsn9ptjq6uviG/htZKk9veJGhlqn3w/DxQ631zFF+nlQXLwmImeS5amR2dl2U8sg6U9jsQ==",
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"yaml": "bin.mjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 14"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-nested": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz",
|
||||
"integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/postcss/"
|
||||
},
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"postcss-selector-parser": "^6.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": "^8.2.14"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-selector-parser": {
|
||||
"version": "6.1.2",
|
||||
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
|
||||
"integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cssesc": "^3.0.0",
|
||||
"util-deprecate": "^1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-value-parser": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
|
||||
@ -9979,7 +10313,6 @@
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
|
||||
"integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
@ -10178,6 +10511,49 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-css-interop": {
|
||||
"version": "0.1.22",
|
||||
"resolved": "https://registry.npmjs.org/react-native-css-interop/-/react-native-css-interop-0.1.22.tgz",
|
||||
"integrity": "sha512-Mu01e+H9G+fxSWvwtgWlF5MJBJC4VszTCBXopIpeR171lbeBInHb8aHqoqRPxmJpi3xIHryzqKFOJYAdk7PBxg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-module-imports": "^7.22.15",
|
||||
"@babel/traverse": "^7.23.0",
|
||||
"@babel/types": "^7.23.0",
|
||||
"debug": "^4.3.7",
|
||||
"lightningcss": "^1.27.0",
|
||||
"semver": "^7.6.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=18",
|
||||
"react-native": "*",
|
||||
"react-native-reanimated": ">=3.6.2",
|
||||
"tailwindcss": "~3"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"react-native-safe-area-context": {
|
||||
"optional": true
|
||||
},
|
||||
"react-native-svg": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-css-interop/node_modules/semver": {
|
||||
"version": "7.7.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
|
||||
"integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-edge-to-edge": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-edge-to-edge/-/react-native-edge-to-edge-1.6.0.tgz",
|
||||
@ -10353,6 +10729,39 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/read-cache": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
|
||||
"integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"pify": "^2.3.0"
|
||||
}
|
||||
},
|
||||
"node_modules/readdirp": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
|
||||
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"picomatch": "^2.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/readdirp/node_modules/picomatch": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
|
||||
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8.6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/jonschlinkert"
|
||||
}
|
||||
},
|
||||
"node_modules/reflect.getprototypeof": {
|
||||
"version": "1.0.10",
|
||||
"resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz",
|
||||
@ -10459,6 +10868,15 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/repeat-string": {
|
||||
"version": "1.6.1",
|
||||
"resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
|
||||
"integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/require-directory": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
|
||||
@ -10582,7 +11000,6 @@
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
|
||||
"integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"iojs": ">=1.0.0",
|
||||
"node": ">=0.10.0"
|
||||
@ -10643,7 +11060,6 @@
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
|
||||
"integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
@ -11547,6 +11963,43 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/tailwindcss": {
|
||||
"version": "3.4.17",
|
||||
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.17.tgz",
|
||||
"integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@alloc/quick-lru": "^5.2.0",
|
||||
"arg": "^5.0.2",
|
||||
"chokidar": "^3.6.0",
|
||||
"didyoumean": "^1.2.2",
|
||||
"dlv": "^1.1.3",
|
||||
"fast-glob": "^3.3.2",
|
||||
"glob-parent": "^6.0.2",
|
||||
"is-glob": "^4.0.3",
|
||||
"jiti": "^1.21.6",
|
||||
"lilconfig": "^3.1.3",
|
||||
"micromatch": "^4.0.8",
|
||||
"normalize-path": "^3.0.0",
|
||||
"object-hash": "^3.0.0",
|
||||
"picocolors": "^1.1.1",
|
||||
"postcss": "^8.4.47",
|
||||
"postcss-import": "^15.1.0",
|
||||
"postcss-js": "^4.0.1",
|
||||
"postcss-load-config": "^4.0.2",
|
||||
"postcss-nested": "^6.2.0",
|
||||
"postcss-selector-parser": "^6.1.2",
|
||||
"resolve": "^1.22.8",
|
||||
"sucrase": "^3.35.0"
|
||||
},
|
||||
"bin": {
|
||||
"tailwind": "lib/cli.js",
|
||||
"tailwindcss": "lib/cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/tar": {
|
||||
"version": "7.4.3",
|
||||
"resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz",
|
||||
@ -12130,6 +12583,12 @@
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/utils-merge": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
"expo-font": "~13.3.1",
|
||||
"expo-haptics": "~14.1.4",
|
||||
"expo-image": "~2.1.7",
|
||||
"expo-image-picker": "~16.1.4",
|
||||
"expo-linking": "~7.1.4",
|
||||
"expo-router": "~5.0.6",
|
||||
"expo-splash-screen": "~0.30.8",
|
||||
@ -29,6 +30,7 @@
|
||||
"expo-symbols": "~0.4.4",
|
||||
"expo-system-ui": "~5.0.7",
|
||||
"expo-web-browser": "~14.1.6",
|
||||
"nativewind": "^4.1.23",
|
||||
"react": "19.0.0",
|
||||
"react-dom": "19.0.0",
|
||||
"react-native": "0.79.2",
|
||||
@ -37,7 +39,8 @@
|
||||
"react-native-safe-area-context": "5.4.0",
|
||||
"react-native-screens": "~4.10.0",
|
||||
"react-native-web": "~0.20.0",
|
||||
"react-native-webview": "13.13.5"
|
||||
"react-native-webview": "13.13.5",
|
||||
"tailwindcss": "^3.4.17"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.25.2",
|
||||
|
||||
16
tailwind.config.js
Normal file
16
tailwind.config.js
Normal file
@ -0,0 +1,16 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
// NOTE: Update this to include the paths to all of your component files.
|
||||
content: ["./app/**/*.{js,jsx,ts,tsx}"],
|
||||
presets: [require("nativewind/preset")],
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
primary: "#ffd60a",
|
||||
secondary: "#f9be25",
|
||||
accent: "#bb0718",
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [],
|
||||
}
|
||||
@ -12,6 +12,7 @@
|
||||
"**/*.ts",
|
||||
"**/*.tsx",
|
||||
".expo/types/**/*.ts",
|
||||
"expo-env.d.ts"
|
||||
"expo-env.d.ts",
|
||||
"nativewind-env.d.ts"
|
||||
]
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user