diff --git a/app/(tabs)/_layout.tsx b/app/(tabs)/_layout.tsx index e413a56..e6b977c 100644 --- a/app/(tabs)/_layout.tsx +++ b/app/(tabs)/_layout.tsx @@ -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 ( ( - + ), }} /> + ( - + ), }} /> + ( - + ), }} /> + ( - + ), }} /> diff --git a/app/(tabs)/forum.tsx b/app/(tabs)/forum.tsx index 36295b3..caa0986 100644 --- a/app/(tabs)/forum.tsx +++ b/app/(tabs)/forum.tsx @@ -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 ( - - + + {/* Search Bar */} - + {/* Category Filters */} - - - Main dish + + + Main dish - - Dessert + + Dessert - - Appetite + + Appetite {/* Filter Options */} - - - Rating + + + Rating - - Newest + + Newest - - Best + + Best {/* Post */} - + {/* User Info */} - - - + + + - Mr. Chef + Mr. Chef - - 4.2 + + 4.2 @@ -76,14 +75,16 @@ export default function ForumScreen() { {/* Post Image */} {/* Post Content */} - - Kajjecaw - + + + Kajjecaw + + 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() { {/* Post Actions */} - - + + - 3 + 3 - + - 2 + 2 - + - 2 + 2 - + @@ -117,144 +118,3 @@ export default function ForumScreen() { ); } - -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 5723af8..072d868 100644 --- a/app/(tabs)/index.tsx +++ b/app/(tabs)/index.tsx @@ -1,113 +1,270 @@ -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"; +// Sample recipe data +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 } }); +}; 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 [searchQuery, setSearchQuery] = useState(""); + const [filteredRecipes, setFilteredRecipes] = useState(foodHighlights); - const navigateToFoodDetail = (foodId: string) => { - router.push({ pathname: "/food/[id]", params: { id: foodId } }); + // 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 ( - - - {/* Header */} - - Hi! Mr. Chef - - - - + + - {/* Hero Section */} - - - + Hi! Mr. Chef + + + + + + {/* Scrollable Content */} + + {/* Show your dishes */} + + + Show your dishes + + + + + + + + + + + + + + + From Camera + + Straight from Camera + + + + + + + + From Gallery + + Straight from Gallery + + + {/* Food Highlights Section */} - - - Food Highlights + + + + Food Highlights + - - + {foodHighlights.map((food) => ( navigateToFoodDetail(String(food.id))} > - - + + {food.name} - + {food.description} - - + + - {food.time} + + {food.time} + - + - + {food.calories} @@ -118,204 +275,9 @@ export default function HomeScreen() { - {/* Show your dishes Section */} - - - Show your dishes - - - - - - - - - - - - - - From Camera - - Snap it from Camera - - - - - From Gallery - - Select from Gallery - - - - + {/* Extra space at bottom */} + ); } - -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, - }, -}); diff --git a/app/(tabs)/profile.tsx b/app/(tabs)/profile.tsx index a0db25d..5074790 100644 --- a/app/(tabs)/profile.tsx +++ b/app/(tabs)/profile.tsx @@ -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 ( - - + + {/* Profile Header */} - - - - 👨‍🍳 + + + + 👨‍🍳 - Mr. Chef - - Edit + Mr. Chef + + Edit {/* Tab Navigation */} - + {["Repost", "Likes", "Bookmark"].map((tab) => ( setActiveTab(tab)} > - {tab} + {tab} ))} - + {/* Food Grid */} - + {foodItems.map((item, index) => ( - + - - {item.name} + + + {item.name} + ))} @@ -115,102 +116,3 @@ export default function ProfileScreen() { ); } - -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 index 155879c..66d5001 100644 --- a/app/(tabs)/recipes.tsx +++ b/app/(tabs)/recipes.tsx @@ -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 ( - - + + {/* Search Bar */} - + {/* Filter Buttons */} - - - All Recipes + + + All Recipes - - My Recipes + + My Recipes {/* Divider */} - + {/* Food Grid */} - + {foodItems.map((item) => ( - + - - {item.name} + + + {item.name} + ))} @@ -95,93 +99,3 @@ export default function RecipesScreen() { ); } - -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 7541fb9..79068cd 100644 --- a/app/_layout.tsx +++ b/app/_layout.tsx @@ -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 - - - - + + + + - - + ); } diff --git a/app/recipe-detail.tsx b/app/recipe-detail.tsx new file mode 100644 index 0000000..19ddc47 --- /dev/null +++ b/app/recipe-detail.tsx @@ -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 ( + + + + + {/* Header with back and share buttons */} + + router.back()} + > + + + + + + + + + {/* Recipe Image */} + + + + + {/* Recipe Title and Description */} + + {recipeTitle} + + Pad kra pao, also written as pad gaprao, is a popular Thai stir fry of ground meat and holy basil. + + + {/* Recipe Info */} + + + Skills + Easy + + + + Time + 30 Mins + + + + Ingredients + 10+ + + + + Calories + 300 kCal + + + + {/* Ingredients */} + Ingredients + + + + + + + + + + + {/* Nutrition Info */} + + + + + 0 + /32g + + Fat + + + + + 0 + /32g + + Fiber + + + + + 0 + /32g + + Protein + + + + + 0 + /32g + + Carbs + + + + + + {/* Bottom Spacing */} + + + + {/* Cook Button */} + + + + Let's Cook! + + + + + + + ); +} \ No newline at end of file diff --git a/assets/images/placeholder-food.jpg b/assets/images/placeholder-food.jpg index 87d0b1f..70de86e 100644 Binary files a/assets/images/placeholder-food.jpg and b/assets/images/placeholder-food.jpg differ diff --git a/babel.config.js b/babel.config.js new file mode 100644 index 0000000..577e38b --- /dev/null +++ b/babel.config.js @@ -0,0 +1,9 @@ +module.exports = function (api) { + api.cache(true); + return { + presets: [ + ["babel-preset-expo", { jsxImportSource: "nativewind" }], + "nativewind/babel", + ], + }; + }; \ No newline at end of file diff --git a/global.css b/global.css new file mode 100644 index 0000000..bd6213e --- /dev/null +++ b/global.css @@ -0,0 +1,3 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; \ No newline at end of file diff --git a/metro.config.js b/metro.config.js new file mode 100644 index 0000000..37cbbed --- /dev/null +++ b/metro.config.js @@ -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' }) \ No newline at end of file diff --git a/nativewind-env.d.ts b/nativewind-env.d.ts new file mode 100644 index 0000000..fbca8c7 --- /dev/null +++ b/nativewind-env.d.ts @@ -0,0 +1 @@ +/// \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index db9f338..a73cf83 100644 --- a/package-lock.json +++ b/package-lock.json @@ -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", diff --git a/package.json b/package.json index 94631b6..bd73d78 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/tailwind.config.js b/tailwind.config.js new file mode 100644 index 0000000..f6807b2 --- /dev/null +++ b/tailwind.config.js @@ -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: [], +} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 909e901..2f35dd4 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -12,6 +12,7 @@ "**/*.ts", "**/*.tsx", ".expo/types/**/*.ts", - "expo-env.d.ts" + "expo-env.d.ts", + "nativewind-env.d.ts" ] -} +} \ No newline at end of file