import { StyleSheet, Text, View, TextInput, Alert, FlatList, Animated, DeviceEventEmitter } from 'react-native' import React, { useLayoutEffect, useState, useEffect, useRef } from 'react' import { useRoute, useNavigation } from '@react-navigation/native' import { AntDesign } from '@expo/vector-icons'; import AsyncStorage from '@react-native-async-storage/async-storage'; import { TouchableOpacity } from 'react-native'; import { useSQLiteContext } from 'expo-sqlite'; import { FIREBASE_AUTH } from '../FirebaseConfig'; import { storeMetrics } from '../functions/firebaseDB'; // THE PROBLEM IS THAT WHEN NOT LOGGING FOR FIRST TIME DATE IS UNKNOWN import { getFoodData } from '../functions/getFoodData'; import MacroSplitGraph from '../components/MacroSplitGraph'; import MicroNutrientDisplayElement from '../components/MicroNutrientDisplayElement'; import DaySelector from '../components/DaySelector'; import { useAppTheme } from '../hooks/colorScheme'; export default function FoodPage() { const colors = useAppTheme(); const navigation = useNavigation(); const route = useRoute(); const { name, id, qty: initialQty, iscustom, fromQuickAdd, fromIndex, calories, protein, carb, fat } = route.params; const [editMode, setEditMode] = useState(fromIndex&&!fromQuickAdd ? true : false); const [isCustom, setIsCustom] = useState(iscustom == 1 ? true : false) const [customAdjustmentPage, setCustomAdjustmentPage] = useState(fromQuickAdd == 1 ? true : false); //console.log("isCustom:", isCustom, ", editMode:", editMode, ", customAdjustmentPage:", customAdjustmentPage); const [qty, setQty] = useState(initialQty ? initialQty.toString() : '100g'); const [foodData, setFoodData] = useState({}); const [goals, setGoals] = useState({}); const [multiplier, setMultiplier] = useState(1); const [day , setDay] = useState(2); const [usingDBDate, setUsingDBDate] = useState(false); const [dbDate, setDbDate] = useState(null); const fadeAnim = useRef(new Animated.Value(0)).current; const database = useSQLiteContext(); const updateFireBase = async () => { let targetDate; if (usingDBDate && dbDate) { targetDate = dbDate; } else { targetDate = new Date(); targetDate.setDate(targetDate.getDate() - (2 - day)); targetDate.setHours(0, 0, 0, 0); // Reset time to midnight } try { await storeMetrics(FIREBASE_AUTH.currentUser, database, targetDate); //console.log('Success', 'Data sent to Firebase for date:', targetDate.toDateString()); } catch (error) { console.error('Error', 'Failed to send data.'); } }; useLayoutEffect(() => { navigation.setOptions({ title: name, titleStyle: { fontSize: 20 }, headerBackTitle: 'Back', headerTintColor: colors.accent, }); }, [navigation, name]); useEffect(() => { const loadInitialData = async () => { await retriveFoodData(); await loadGoals(); // Load day from database if in edit mode if (editMode && id) { try { const result = await database.getFirstAsync( "SELECT day FROM foodhistory WHERE id = ?;", [id] ); if (result) { const dateString = result.day; const foodDate = new Date(dateString); setDbDate(foodDate); setUsingDBDate(true); // Still calculate UI day for display purposes const currentDate = new Date(); const diffDays = Math.round((foodDate - currentDate) / (1000 * 60 * 60 * 24)); const uiDay = diffDays + 2; // Convert offset (-1,0,1) to UI day (1,2,3) setDay(uiDay); } } catch (error) { console.error("Error loading day from database:", error); } } }; loadInitialData(); }, [name, editMode, id]); useEffect(() => { const currentQty = parseInt(qty); const baseQty = isCustom ? foodData.baseQty : 100; if (baseQty && currentQty) { const newMultiplier = currentQty / baseQty; //console.log(`Updating multiplier: currentQty=${currentQty}, baseQty=${baseQty}, multiplier=${newMultiplier}`); setMultiplier(newMultiplier); } }, [qty, foodData.baseQty, isCustom]); useEffect(() => { Animated.timing(fadeAnim, { toValue: 1, duration: 500, useNativeDriver: true, }).start(); }, []); const formatNumber = (num) => { if (num === undefined || num === null) return '0'; const str = Number(num).toFixed(1); return str.replace(/\.?0+$/, ''); }; const retriveFoodData = async () => { if(isCustom) { try { const result = await database.getFirstAsync( "SELECT * FROM customfoods WHERE name = ?;", [name] ); if(result) { const baseQty = result.qty; const foodDataObj = { name: result.name, qty: qty, cal: result.cal, protein: result.protein, carbs: result.carb, fats: result.fat, iscustom: 1, baseQty: result.qty }; setFoodData(foodDataObj); //console.log("retrieved ->", foodDataObj); setMultiplier(qty / baseQty); } } catch (error) { console.error("Error fetching custom food:", error); } } else { const results = await getFoodData(name); const foodDataObj = { ...results, baseQty: 100 // Regular foods always use 100g as base }; setFoodData(foodDataObj); //console.log("retrieved ->", foodDataObj.name, foodDataObj.baseQty, foodDataObj.cal, foodDataObj.protein, foodDataObj.carbs, foodDataObj.fats); } }; const logFood = async () => { const workingQty = parseInt(qty); if(workingQty <= 0 || isNaN(workingQty)) { Alert.alert("Error", "Please delete or enter a valid quantity", [{ text: "OK" }]); return; } if(customWasEdited) { Alert.alert("Save changes before logging food"); return; } const baseQty = isCustom ? foodData.baseQty : 100; const currentDate = new Date(); const targetDate = new Date(currentDate); targetDate.setDate(currentDate.getDate() - (2 - day)); targetDate.setHours(0, 0, 0, 0); // Reset time to midnight // Store base values for non-custom foods, and calculated values for custom foods const foodValues = isCustom ? { cal: foodData.cal, protein: foodData.protein, carbs: foodData.carbs, fats: foodData.fats } : { cal: foodData.cal, protein: foodData.protein, carbs: foodData.carbs, fats: foodData.fats }; if(!editMode) { try { await database.runAsync( "INSERT INTO foodhistory (name, qty, baseQty, cal, protein, carb, fat, iscustom, day) Values (?, ?, ?, ?, ?, ?, ?, ?, ?);", [ name, workingQty, baseQty, foodValues.cal, foodValues.protein, foodValues.carbs, foodValues.fats, isCustom ? 1 : 0, targetDate.toDateString() ] ); await updateFireBase(); // Move Firebase update after database update DeviceEventEmitter.emit('foodHistoryChanged'); navigation.goBack(); } catch (error) { console.log(error); } } else { // in edit mode try { updateFireBase(); await database.runAsync( "UPDATE foodhistory SET name = ?, qty = ?, baseQty = ?, cal = ?, protein = ?, carb = ?, fat = ?, iscustom = ? WHERE id = ?;", [ name, workingQty, baseQty, foodValues.cal, foodValues.protein, foodValues.carbs, foodValues.fats, isCustom ? 1 : 0, id ] ); DeviceEventEmitter.emit('foodHistoryChanged'); navigation.goBack(); } catch (error) { console.log(error); } } }; const handleDelete = async (id) => { try { const result = await database.getFirstAsync( "SELECT day FROM foodhistory WHERE id = ?;", [id] ); if (result) { const dateString = result.day; const targetDate = new Date(dateString); await database.runAsync( "DELETE FROM foodhistory WHERE id = ?;", [id] ); await updateFireBase(); // This will use the day state that was set when loading the page DeviceEventEmitter.emit('foodHistoryChanged'); navigation.goBack(); } } catch (error) { console.error("Error in handleDelete:", error); } }; const handleCustomDelete = async (name) => { Alert.alert( "Confirm Delete", "Are you sure you want to delete this custom food? This will also delete it from your recent log.", [ { text: "Cancel", style: "cancel" }, { text: "Delete", onPress: async () => { try { await database.runAsync( "DELETE FROM foodhistory WHERE name = ? AND iscustom = 1;", [name] ); await database.runAsync( "DELETE FROM customfoods WHERE name = ?;", [name] ); await updateFireBase(); DeviceEventEmitter.emit('foodHistoryChanged'); navigation.goBack(); } catch (error) { console.error("Error in deletion:", error); Alert.alert("Error", "Failed to delete food item completely. Please try again."); } }, style: "destructive" } ] ); }; const updateCustomFood = async () => { const customProtein = ProteinQty || foodData.protein; const customCarbs = CarbQty || foodData.carbs; const customFats = FatQty || foodData.fats; const customCalories = (customProtein * 4) + (customCarbs * 4) + (customFats * 9); console.log("Updating custom food:", name, customCalories, customProtein, customCarbs, customFats); //console.log("Alternates:", ProteinQty, CarbQty, FatQty); Alert.alert( "Confirm Update", "Are you sure you want to update this custom food? This will also update it in your recent log.", [ { text: "Cancel", style: "cancel" }, { text: "Update", onPress: async () => { try { // Update both tables await database.runAsync( "UPDATE customfoods SET cal = ?, protein = ?, carb = ?, fat = ? WHERE name = ?;", [customCalories, customProtein, customCarbs, customFats, name] ); await database.runAsync( "UPDATE foodhistory SET cal = ?, protein = ?, carb = ?, fat = ? WHERE name = ? AND iscustom = 1;", [customCalories, customProtein, customCarbs, customFats, name] ); await updateFireBase(); setCustomWasEdited(false); navigation.goBack(); } catch (error) { console.error("Error updating custom food:", error); Alert.alert("Error", "Failed to update food item."); } }, style : "destructive" }]); } const goToPage = () => { if(customWasEdited) { Alert.alert("Make sure to save changes before logging food"); return; } navigation.navigate('FoodPage', {name: name, id: id, qty: qty, calories: calories*multiplier, protein: protein*multiplier, carb: carb*multiplier, fat: fat*multiplier, iscustom: "1"}); } const changeQty = () => { const value = qty === '' ? '100' : qty; setQty(value); }; const [customWasEdited, setCustomWasEdited] = useState(false); const [ProteinQty, setProteinQty] = useState(foodData.protein?.toString()); const [CarbQty, setCarbQty] = useState(foodData.carbs?.toString()); const [FatQty, setFatQty] = useState(foodData.fats?.toString()); const [customQty, setCustomQty] = useState(initialQty) const changeProteinQty = () => { const value = ProteinQty === '' ? foodData.protein : parseFloat(ProteinQty); setProteinQty(value.toString()); console.log("change qty to", value); setCustomWasEdited(true); } const changeCarbQty = () => { const value = CarbQty === '' ? foodData.carbs : parseFloat(CarbQty); setCarbQty(value.toString()); console.log("change qty to", value); setCustomWasEdited(true); } const changeFatQty = () => { const value = FatQty === '' ? foodData.fats : parseFloat(FatQty); setFatQty(value.toString()); console.log("change qty to", value); setCustomWasEdited(true); } const loadGoals = async () => { try { const savedGoals = await AsyncStorage.getItem('userGoals'); if (savedGoals) { setGoals(JSON.parse(savedGoals)); } } catch (error) { console.error("Error loading data:", error); } }; const createNutrientData = () => { return [ { title: 'Fats Breakdown', items: [ { label: 'Trans Fat', value: Math.round((foodData.transFat * multiplier) * 10) / 10, unit: 'g', goalTotal: goals.transFat}, { label: 'Saturated Fat', value: Math.round((foodData.satFat * multiplier) * 10) / 10, unit: 'g', goalTotal: goals.saturatedFat}, { label: 'Polyunsaturated Fat', value: Math.round((foodData.polyFat * multiplier) * 10) / 10, unit: 'g', goalTotal: goals.polyunsaturatedFat}, { label: 'Monounsaturated Fat', value: Math.round((foodData.monoFat * multiplier) * 10) / 10, unit: 'g', goalTotal: goals.monounsaturatedFat}, ]}, { title: 'Carbohydrates Breakdown', items: [ { label: 'Sugar', value: Math.round((foodData.sugar * multiplier) * 10) / 10, unit: 'g', goalTotal: goals.sugar}, { label: 'Fiber', value: Math.round((foodData.fiber * multiplier) * 10) / 10, unit: 'g', goalTotal: goals.fiber}, ]}, { title: 'Cholesterol', items: [ { label: 'Cholesterol', value: Math.round((foodData.cholesterol * multiplier) * 1000), unit: 'mg', goalTotal: goals.cholesterol}, ]}, { title: 'Essential Minerals', items: [ { label: 'Sodium', value: Math.round((foodData.sodium * multiplier) * 1000), unit: 'mg', goalTotal: goals.sodium}, { label: 'Calcium', value: Math.round((foodData.calcium * multiplier) * 1000), unit: 'mg', goalTotal: goals.calcium}, { label: 'Magnesium', value: Math.round((foodData.magnesium * multiplier) * 1000), unit: 'mg', goalTotal: goals.magnesium}, { label: 'Phosphorus', value: Math.round((foodData.phosphorus * multiplier) * 1000), unit: 'mg', goalTotal: goals.phosphorus}, { label: 'Potassium', value: Math.round((foodData.potassium * multiplier) * 1000), unit: 'mg', goalTotal: goals.potassium}, ]}, { title: 'Trace Minerals', items: [ { label: 'Iron', value: Math.round((foodData.iron * multiplier) * 1000), unit: 'mg', goalTotal: goals.iron}, { label: 'Copper', value: Math.round((foodData.copper * multiplier) * 1000000), unit: 'mcg', goalTotal: goals.copper}, { label: 'Zinc', value: Math.round((foodData.zinc * multiplier) * 1000), unit: 'mg', goalTotal: goals.zinc}, { label: 'Manganese', value: Math.round((foodData.manganese * multiplier) * 1000), unit: 'mg', goalTotal: goals.manganese}, { label: 'Selenium', value: Math.round((foodData.selenium * multiplier) * 1000000), unit: 'mcg', goalTotal: goals.selenium}, ]}, { title: 'Fat Soluble Vitamins', items: [ { label: 'Vitamin A', value: Math.round((foodData.vitaminA * multiplier) * 1000000), unit: 'mcg', goalTotal: goals.vitaminA}, { label: 'Vitamin D', value: Math.round((foodData.vitaminD * multiplier) * 1000000), unit: 'mcg', goalTotal: goals.vitaminD}, { label: 'Vitamin E', value: Math.round((foodData.vitaminE * multiplier) * 1000), unit: 'mg', goalTotal: goals.vitaminE}, { label: 'Vitamin K', value: Math.round((foodData.vitaminK * multiplier) * 1000000), unit: 'mcg', goalTotal: goals.vitaminK}, ]}, { title: 'Water Soluble Vitamins', items: [ { label: 'Vitamin C', value: Math.round((foodData.vitaminC * multiplier) * 1000), unit: 'mg', goalTotal: goals.vitaminC}, { label: 'Vitamin B1', value: Math.round((foodData.vitaminB1 * multiplier) * 1000), unit: 'mg', goalTotal: goals.vitaminB1}, { label: 'Vitamin B12', value: Math.round((foodData.vitaminB12 * multiplier) * 1000000), unit: 'mcg', goalTotal: goals.vitaminB12}, { label: 'Vitamin B2', value: Math.round((foodData.vitaminB2 * multiplier) * 1000), unit: 'mg', goalTotal: goals.vitaminB2}, { label: 'Vitamin B3', value: Math.round((foodData.vitaminB3 * multiplier) * 1000), unit: 'mg', goalTotal: goals.vitaminB3}, { label: 'Vitamin B5', value: Math.round((foodData.vitaminB5 * multiplier) * 1000), unit: 'mg', goalTotal: goals.vitaminB5}, { label: 'Vitamin B6', value: Math.round((foodData.vitaminB6 * multiplier) * 1000), unit: 'mg', goalTotal: goals.vitaminB6}, { label: 'Folate', value: Math.round((foodData.folate * multiplier) * 1000000), unit: 'mcg', goalTotal: goals.folate}, ]}, ]; }; const values = customAdjustmentPage ? { calories: ((parseFloat(ProteinQty || foodData.protein) * 4) + (parseFloat(CarbQty || foodData.carbs) * 4) + (parseFloat(FatQty || foodData.fats) * 9)), protein: parseFloat(ProteinQty || foodData.protein), carb: parseFloat(CarbQty || foodData.carbs), fat: parseFloat(FatQty || foodData.fats) } : { calories: foodData.cal * multiplier, protein: foodData.protein * multiplier, carb: foodData.carbs * multiplier, fat: foodData.fats * multiplier, }; // console.log("fromQuickAdd:", customAdjustmentPage, ", editMode:", editMode); // console.log("values: ", values, "multiplier: ", multiplier); // console.log("parsedData: ", ProteinQty, CarbQty, FatQty); return ( <View style={[styles.container, { backgroundColor: colors.background }]}> {!fromQuickAdd && ( <View style={[styles.card, styles.topGraphic, { backgroundColor: colors.boxes }]}> <View style={styles.graphContainer}> <MacroSplitGraph values={values}/> </View> <View style={styles.macroInfoContainer}> <MacroRow label="Protein" value={formatNumber(values.protein)} color={colors.greenColor} /> <MacroRow label="Carbs" value={formatNumber(values.carb)} color={colors.blueColor} /> <MacroRow label="Fats" value={formatNumber(values.fat)} color={colors.yellowColor} /> <View style={[styles.qtyContainer, { backgroundColor: colors.innerBoxes }]}> <TextInput value={qty} onChangeText={setQty} onEndEditing={changeQty} placeholder="100" defaultValue="100" clearTextOnFocus={true} keyboardType="numeric" returnKeyType="done" placeholderTextColor={colors.text + '80'} style={[styles.qtyInput, {color: colors.text}]} /> <Text style={[styles.unitText, { color: colors.text }]}>g</Text> </View> </View> </View> )} {fromQuickAdd && <View style={[styles.card, styles.topGraphic, { backgroundColor: colors.boxes }]}> <View style={{flexDirection: "column", alignItems: "center", gap: 5}}> <MacroSplitGraph values={values}/> <Text style={{color: colors.text}}>Mass: {foodData.qty}g</Text> </View> <View style={{flexDirection: "column", gap: 5}}> <View style={[{flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', gap: 5}]}> <Text style={[{color: colors.greenColor, fontSize: 16, fontWeight: 'bold'}]}>Protein </Text> <View style={[styles.qtyContainer, { backgroundColor: colors.innerBoxes, padding:-5 }]}> <TextInput value={ProteinQty} onChangeText={setProteinQty} onEndEditing={changeProteinQty} placeholder={''} defaultValue={foodData.protein?.toString() || ''} placeholderTextColor={colors.text + '80'} clearTextOnFocus={true} keyboardType="numeric" returnKeyType="done" style={[styles.input, {backgroundColor: colors.innerBoxes, color: colors.text, textAlign: 'center', fontSize: 16}]} /> <Text style={[styles.unitText, { color: colors.text }]}>g</Text> </View> </View> <View style={[{flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', gap: 5}]}> <Text style={[{color: colors.blueColor, fontSize: 16, fontWeight: 'bold'}]}>Carbs </Text> <View style={[styles.qtyContainer, { backgroundColor: colors.innerBoxes, padding:-5 }]}> <TextInput value={CarbQty} onChangeText={setCarbQty} onEndEditing={changeCarbQty} placeholder={''} defaultValue={foodData.carbs?.toString() || ''} placeholderTextColor={colors.text + '80'} clearTextOnFocus={true} keyboardType="numeric" returnKeyType="done" style={[styles.input, {backgroundColor: colors.innerBoxes, color: colors.text, textAlign: 'center', fontSize: 16}]} /> <Text style={[styles.unitText, { color: colors.text }]}>g</Text> </View> </View> <View style={[{flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', gap: 5}]}> <Text style={[{color: colors.yellowColor, fontSize: 16, fontWeight: 'bold'}]}>Fats </Text> <View style={[styles.qtyContainer, { backgroundColor: colors.innerBoxes, padding:-5 }]}> <TextInput value={FatQty} onChangeText={setFatQty} onEndEditing={changeFatQty} placeholder={''} defaultValue={foodData.fats?.toString() || ''} placeholderTextColor={colors.text + '80'} clearTextOnFocus={true} keyboardType="numeric" returnKeyType="done" style={[styles.input, {backgroundColor: colors.innerBoxes, color: colors.text, textAlign: 'center', fontSize: 16}]} /> <Text style={[styles.unitText, { color: colors.text }]}>g</Text> </View> </View> </View> </View>} {customWasEdited && <View style={[styles.card, { backgroundColor: colors.boxes, marginBottom: 16 }]}> <AntDesign.Button style={[styles.button, {}]} name="check" onPress={() => updateCustomFood()} backgroundColor={colors.boxes} color={colors.accent}> Save Changes </AntDesign.Button> </View>} {!isCustom && <View style={[styles.detailsContainer, { height: '60%'}]}> <FlatList data={createNutrientData()} renderItem={({ item }) => ( <View style={[styles.nutrientSection, { backgroundColor: colors.boxes }]}> <Text style={[styles.sectionTitle, { color: colors.text }]}>{item.title}</Text> {item.items.map((nutrient, index) => ( <MicroNutrientDisplayElement key={index} values={{name: nutrient.label, current: nutrient.value, unit: nutrient.unit, total: nutrient.goalTotal, color: 'grey'}} /> ))} </View> )} contentContainerStyle={styles.list} keyExtractor={(_, index) => index.toString()} /> </View>} <View style={[styles.buttonContainer, styles.card, { backgroundColor: colors.boxes }]}> <View style={styles.buttonWrapper}> {fromQuickAdd && <View style={[styles.innerButtonCard, {backgroundColor: colors.boxes}]}> <TouchableOpacity activeOpacity={0.7} onPress={() => handleCustomDelete(name)} style={styles.actionButton} > <AntDesign name="star" size={24} color={colors.accent} /> <Text style={{color: colors.accent, fontSize: 16, textAlign: "center"}}>Delete Food</Text> </TouchableOpacity> </View> } {!editMode&&!fromQuickAdd && <DaySelector onDayChange={(value) => { setDay(value); console.log("day set to", value); }} /> } {editMode && <View style={[styles.innerButtonCard, {backgroundColor: colors.boxes}]}> <TouchableOpacity activeOpacity={0.7} onPress={() => handleDelete(id)} style={styles.actionButton} > <AntDesign name="delete" size={24} color={colors.accent} /> <Text style={{color: colors.accent, fontSize: 16}}>Delete From Log</Text> </TouchableOpacity> </View> } <View style={[styles.innerButtonCard, {backgroundColor: colors.boxes}]}> <TouchableOpacity activeOpacity={0.7} onPress={() => {fromQuickAdd ? goToPage() : logFood()}} style={styles.actionButton} > <AntDesign name="pluscircleo" size={24} color={colors.accent} /> <Text style={{color: colors.accent, fontSize: 16}}> {editMode ? "Save Changes" : "Add to Log"} </Text> </TouchableOpacity> </View> </View> </View> </View>); } const MacroRow = ({ label, value, color }) => ( <View style={styles.macroRow}> <Text style={[styles.macroLabel, { color }]} numberOfLines={1}>{label}</Text> <View style={styles.macroValueContainer}> <Text style={[styles.macroValue, { color }]} numberOfLines={1}>{value}g</Text> </View> </View> ); const styles = StyleSheet.create({ container: { flex: 1, padding: 16, }, card: { borderRadius: 20, padding: 20, shadowColor: '#000', shadowOffset: { width: 0, height: 2, }, shadowOpacity: 0.1, shadowRadius: 8, elevation: 5, }, topGraphic: { gap: 16, marginBottom: 16, justifyContent: "space-between", flexDirection: "row", alignItems: "center", paddingHorizontal: 12, }, graphContainer: { flex: 1, alignItems: 'center', justifyContent: 'center', maxWidth: '50%', }, macroInfoContainer: { flex: 1, gap: 8, maxWidth: '50%', paddingLeft: 8, }, macroRow: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', paddingVertical: 6, borderBottomWidth: 1, borderBottomColor: 'rgba(0,0,0,0.05)', maxWidth: '100%', }, macroLabel: { fontSize: 15, fontWeight: '600', width: '35%', // Reduced from 40% marginRight: 4, }, macroValueContainer: { flex: 1, alignItems: 'flex-end', overflow: 'hidden', maxWidth: '60%', // Added maximum width }, macroValue: { fontSize: 15, fontWeight: '700', maxWidth: '100%', }, qtyContainer: { flexDirection: 'row', alignItems: 'center', borderRadius: 12, padding: 4, marginTop: 8, opacity: 0.8, }, qtyInput: { flex: 1, fontSize: 18, fontWeight: '600', padding: 12, textAlign: 'center', }, unitText: { fontSize: 16, fontWeight: '600', marginRight: 12, }, buttonContainer: { position: 'absolute', bottom: 0, left: 0, right: 0, padding: 20, paddingBottom: 36, // Add more padding at bottom borderTopWidth: 1, borderTopColor: 'rgba(0,0,0,0.05)', shadowColor: '#000', shadowOffset: { width: 0, height: -2, }, shadowOpacity: 0.1, shadowRadius: 8, elevation: 5, }, buttonWrapper: { flexDirection: "row", justifyContent: "center", alignItems: "center", gap: 12, }, actionButton: { flexDirection: 'row', alignItems: 'center', justifyContent: 'center', padding: 12, paddingHorizontal: 16, gap: 8, }, innerButtonCard: { borderRadius: 20, shadowColor: '#000', shadowOffset: { width: 0, height: 2, }, shadowOpacity: 0.1, shadowRadius: 4, elevation: 2, minWidth: '40%', maxWidth: '50%', }, nutrientSection: { marginBottom: 24, padding: 16, borderRadius: 16, shadowColor: '#000', shadowOffset: { width: 0, height: 1, }, shadowOpacity: 0.1, shadowRadius: 4, elevation: 2, }, sectionTitle: { fontSize: 20, fontWeight: '700', marginBottom: 16, letterSpacing: 0.5, }, detailsContainer: { flex: 1, width: '100%', marginBottom: 80, // Add space for fixed button container }, input: { fontSize: 16, fontWeight: '600', padding: 12, borderRadius: 12, minWidth: 75, textAlign: 'center', }, list: { }, })