"use client" import { getFoods, insertGenAIResult } from "@/services/data/foods" import { uploadImageToSupabase } from "@/services/data/imageUpload" import { getProfile } from "@/services/data/profile" import { callGenAIonImage } from "@/services/gemini" import { supabase } from "@/services/supabase" import { Feather, FontAwesome, Ionicons } from "@expo/vector-icons" import { useQuery } from "@tanstack/react-query" import * as FileSystem from "expo-file-system" import * as ImagePicker from "expo-image-picker" import { router } from "expo-router" import { useEffect, useState } from "react" import { Alert, Image, SafeAreaView, ScrollView, StatusBar, Text, TouchableOpacity, View } from "react-native" const useFoodsQuery = () => { return useQuery({ queryKey: ["highlight-foods"], queryFn: async () => { const { data, error } = await getFoods(undefined, true, undefined, 6) // Fetch 6 items for multiple rows if (error) throw error return data || [] }, staleTime: 1000 * 60 * 5, }) } const useUserProfile = () => { const [userId, setUserId] = useState(null) const [isLoadingUserId, setIsLoadingUserId] = useState(true) // Get current user ID useEffect(() => { const fetchUserId = async () => { try { const { data, error } = await supabase.auth.getUser() if (error) throw error setUserId(data?.user?.id || null) } catch (error) { console.error("Error fetching user:", error) } finally { setIsLoadingUserId(false) } } fetchUserId() }, []) // Fetch user profile data const { data: profileData, isLoading: isLoadingProfile, error: profileError, } = useQuery({ queryKey: ["profile", userId], queryFn: async () => { if (!userId) throw new Error("No user id") return getProfile(userId) }, enabled: !!userId, staleTime: 1000 * 60 * 5, // 5 minutes }) return { userId, profileData: profileData?.data, isLoading: isLoadingUserId || isLoadingProfile, error: profileError, } } const runImagePipeline = async (imageBase64: string, imageType: string, userId: string) => { const imageUri = await uploadImageToSupabase(imageBase64, imageType, userId) const genAIResult = await callGenAIonImage(imageUri) if (genAIResult.error) throw genAIResult.error const { data: genAIResultData } = genAIResult if (!genAIResultData) throw new Error("GenAI result is null") await insertGenAIResult(genAIResultData, userId, imageUri) } const processImage = async (asset: ImagePicker.ImagePickerAsset, userId: string) => { const base64 = await FileSystem.readAsStringAsync(asset.uri, { encoding: "base64", }) const imageType = asset.mimeType || "image/jpeg" await runImagePipeline(base64, imageType, userId) } const navigateToFoodDetail = (foodId: string) => { router.push({ pathname: "/food/[id]", params: { id: foodId } }) } export default function HomeScreen() { const [imageProcessing, setImageProcessing] = useState(false) const { profileData } = useUserProfile() const { data: foodsData = [], isLoading: isLoadingFoods, error: foodsError } = useFoodsQuery() const handleImageSelection = async ( pickerFn: typeof ImagePicker.launchCameraAsync | typeof ImagePicker.launchImageLibraryAsync, ) => { const result = await pickerFn({ mediaTypes: ImagePicker.MediaTypeOptions.Images, allowsEditing: true, aspect: [1, 1], quality: 1, }) if (!result.canceled) { setImageProcessing(true) try { const { data, error } = await supabase.auth.getUser() if (error || !data?.user?.id) throw new Error("Cannot get user id") const userId = data.user.id await processImage(result.assets[0], userId) } catch (err) { Alert.alert("Image Processing Failed", (err as Error).message || "Unknown error") } finally { setImageProcessing(false) } router.push({ pathname: "/profile", }) } } // Get username or fallback to a default greeting const username = profileData?.username || profileData?.full_name || "Chef" const greeting = `Hi! ${username}` return ( {imageProcessing && ( Processing image... Please wait )} {/* Header with greeting only (settings button removed) */} {greeting} {/* Main content container with consistent padding */} {/* "Show your dishes" section - Search bar removed */} Show your dishes {/* Upload feature section */} { const { status } = await ImagePicker.requestCameraPermissionsAsync() if (status !== "granted") { Alert.alert("Permission needed", "Please grant camera permissions.") return } await handleImageSelection(ImagePicker.launchCameraAsync) }} > From Camera Straight from Camera { const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync() if (status !== "granted") { Alert.alert("Permission needed", "Please grant gallery permissions.") return } await handleImageSelection(ImagePicker.launchImageLibraryAsync) }} > From Gallery Straight from Gallery {/* Highlights section */} Highlights router.push("/recipes")}> See All {isLoadingFoods ? ( Loading highlights... ) : foodsError ? ( Failed to load highlights ) : foodsData.length === 0 ? ( No highlights available ) : ( {foodsData.map((food, idx) => ( navigateToFoodDetail(food.id)} > {food.image_url ? ( ) : ( )} {food.name} {food.time_to_cook_minutes ? `${food.time_to_cook_minutes} min` : "-"} ))} )} {/* Extra space at bottom */} ) }