import { View, Text, TextInput, TouchableOpacity, StyleSheet, FlatList, Alert } from 'react-native'
import React, { useState, useEffect } from 'react'
import { useLayoutEffect } from 'react'
import AsyncStorage from '@react-native-async-storage/async-storage';
import { AntDesign } from '@expo/vector-icons';
import { useAppTheme } from '../hooks/colorScheme';
import MacroSplitGraph from '../components/MacroSplitGraph';
const DEFAULT_VALUES = {
protein: '150',
carbs: '150',
fats: '100',
dailyCalories: '2100',
transFat: '2',
saturatedFat: '20',
polyunsaturatedFat: '17',
monounsaturatedFat: '44',
netCarbs: '53',
sugar: '25',
fiber: '28',
cholesterol: '300',
sodium: '2300',
calcium: '1000',
magnesium: '400',
phosphorus: '700',
potassium: '3400',
iron: '18',
copper: '900',
zinc: '11',
manganese: '2.3',
selenium: '55',
vitaminA: '900',
vitaminD: '20',
vitaminE: '15',
vitaminK: '120',
vitaminC: '90',
vitaminB1: '1.2',
vitaminB12: '2.4',
vitaminB2: '1.3',
vitaminB3: '16',
vitaminB5: '5',
vitaminB6: '1.7',
folate: '400',
};
export default function Goals({ navigation }) {
const [goals, setGoals] = useState(DEFAULT_VALUES);
const colors = useAppTheme();
useEffect(() => {
loadGoals();
}, []);
useEffect(() => {
const proteinCals = parseFloat(goals.protein || '0') * 4;
const carbsCals = parseFloat(goals.carbs || '0') * 4;
const fatsCals = parseFloat(goals.fats || '0') * 9;
const total = Math.round(proteinCals + carbsCals + fatsCals);
setGoals(prev => ({
...prev,
dailyCalories: total.toString()
}));
}, [goals.protein, goals.carbs, goals.fats]);
const loadGoals = async () => {
try {
const savedGoals = await AsyncStorage.getItem('userGoals');
if (savedGoals) {
setGoals(JSON.parse(savedGoals));
}
} catch (error) {
console.error('Error loading goals:', error);
}
};
const saveGoals = async () => {
// Check for empty fields
if (!goals.protein || !goals.carbs || !goals.fats) {
alert('Please fill in all fields before saving');
return;
}
try {
await AsyncStorage.setItem('userGoals', JSON.stringify(goals));
alert('Goals saved successfully!');
navigation.goBack();
} catch (error) {
console.error('Error saving goals:', error);
}
};
const handleInputChange = (field, text) => {
const filtered = text.replace(/[^0-9]/g, '');
setGoals(prev => ({...prev, [field]: filtered}));
};
const resetToDefault = () => {
Alert.alert(
"Confirm Reset",
"Are you sure you want to reset ALL preferences?",
[
{
text: "Cancel",
style: "cancel"
},
{
text: "Reset",
onPress: () => {
setGoals(DEFAULT_VALUES);
},
style: "destructive"
}
]
);
}
const values = {
calories: goals.dailyCalories,
protein: goals.protein,
carb: goals.carbs,
fat: goals.fats,
};
const micronutrientGroups = [
{
title: 'Fats',
items: [
{ key: 'transFat', label: 'Trans Fat', unit: 'g' },
{ key: 'saturatedFat', label: 'Saturated Fat', unit: 'g' },
{ key: 'polyunsaturatedFat', label: 'Polyunsaturated Fat', unit: 'g' },
{ key: 'monounsaturatedFat', label: 'Monounsaturated Fat', unit: 'g' },
]
},
{
title: 'Carbohydrates',
items: [
//{ key: 'netCarbs', label: 'Net Carbs', unit: 'g' },
{ key: 'sugar', label: 'Sugar', unit: 'g' },
{ key: 'fiber', label: 'Fiber', unit: 'g' },
]
},
{
title: 'Cholesterol',
items: [
{ key: 'cholesterol', label: 'Cholesterol', unit: 'mg' }
]
},
{
title: 'Essential Minerals',
items: [
{ key: 'sodium', label: 'Sodium', unit: 'mg' },
{ key: 'calcium', label: 'Calcium', unit: 'mg' },
{ key: 'magnesium', label: 'Magnesium', unit: 'mg' },
{ key: 'phosphorus', label: 'Phosphorus', unit: 'mg' },
{ key: 'potassium', label: 'Potassium', unit: 'mg' },
]
},
{
title: 'Trace Minerals',
items: [
{ key: 'iron', label: 'Iron', unit: 'mg' },
{ key: 'copper', label: 'Copper', unit: 'mcg' },
{ key: 'zinc', label: 'Zinc', unit: 'mg' },
{ key: 'manganese', label: 'Manganese', unit: 'mg' },
{ key: 'selenium', label: 'Selenium', unit: 'mcg' },
]
},
{
title: 'Fat Soluble Vitamins',
items: [
{ key: 'vitaminA', label: 'Vitamin A', unit: 'mcg' },
{ key: 'vitaminD', label: 'Vitamin D', unit: 'mcg' },
{ key: 'vitaminE', label: 'Vitamin E', unit: 'mg' },
{ key: 'vitaminK', label: 'Vitamin K', unit: 'mcg' },
]
},
{
title: 'Water Soluble Vitamins',
items: [
{ key: 'vitaminC', label: 'Vitamin C', unit: 'mg' },
{ key: 'vitaminB1', label: 'Vitamin B1', unit: 'mg' },
{ key: 'vitaminB12', label: 'Vitamin B12', unit: 'mcg' },
{ key: 'vitaminB2', label: 'Vitamin B2', unit: 'mg' },
{ key: 'vitaminB3', label: 'Vitamin B3', unit: 'mg' },
{ key: 'vitaminB5', label: 'Vitamin B5', unit: 'mg' },
{ key: 'vitaminB6', label: 'Vitamin B6', unit: 'mg' },
{ key: 'folate', label: 'Folate', unit: 'mcg' },
]
},
];
const renderItem = ({ item }) => (
<View style={[styles.groupContainer, { backgroundColor: colors.boxes }]}>
<Text style={[styles.groupTitle, { color: colors.accent }]}>{item.title}</Text>
{item.items.map((nutrient) => (
<View key={nutrient.key} style={styles.nutrientRow}>
<Text style={[styles.nutrientLabel, { color: colors.text }]}>
{nutrient.label} ({nutrient.unit}):
</Text>
<TextInput
style={[styles.nutrientInput, { color: colors.text, backgroundColor: colors.innerBoxes }]}
value={goals[nutrient.key]}
onChangeText={(text) => handleInputChange(nutrient.key, text)}
keyboardType="numeric"
placeholder='0'
placeholdercolor={colors.text-222222}
returnKeyType="done"
textAlign='center'
/>
</View>
))}
</View>
);
return (
<View style={[styles.container, { backgroundColor: colors.background }]}>
<View style={styles.listContainer}>
<View style={[styles.card, { backgroundColor: colors.boxes }]}>
<View style={styles.topGraphic}>
<View style={styles.graphContainer}>
<MacroSplitGraph values={values}/>
</View>
<View style={styles.macroInfoContainer}>
<View style={styles.macroRow}>
<Text style={[styles.macroLabel, { color: colors.greenColor }]}>Protein</Text>
<View style={[styles.qtyContainer, { backgroundColor: colors.innerBoxes }]}>
<TextInput
style={[styles.qtyInput, {color: colors.text}]}
value={goals.protein}
onChangeText={(text) => handleInputChange('protein', text)}
keyboardType="numeric"
placeholder="0g"
placeholdercolor={colors.text+222222}
clearTextOnFocus={true}
returnKeyType="done"
textAlign='center'
/>
</View>
</View>
<View style={styles.macroRow}>
<Text style={[styles.macroLabel, { color: colors.blueColor }]}>Carbs</Text>
<View style={[styles.qtyContainer, { backgroundColor: colors.innerBoxes }]}>
<TextInput
style={[styles.qtyInput, {color: colors.text}]}
value={goals.carbs}
onChangeText={(text) => handleInputChange('carbs', text)}
keyboardType="numeric"
placeholder="0g"
placeholdercolor={colors.text+222222}
clearTextOnFocus={true}
returnKeyType="done"
textAlign='center'
/>
</View>
</View>
<View style={styles.macroRow}>
<Text style={[styles.macroLabel, { color: colors.yellowColor }]}>Fats</Text>
<View style={[styles.qtyContainer, { backgroundColor: colors.innerBoxes }]}>
<TextInput
style={[styles.qtyInput, {color: colors.text}]}
value={goals.fats}
onChangeText={(text) => handleInputChange('fats', text)}
keyboardType="numeric"
placeholder="0g"
placeholdercolor={colors.text+222222}
clearTextOnFocus={true}
returnKeyType="done"
textAlign='center'
/>
</View>
</View>
</View>
</View>
<TouchableOpacity
style={[styles.actionButton, { backgroundColor: 'transparent' }]}
onPress={saveGoals}>
<AntDesign name="save" size={24} color={colors.accent} />
<Text style={[styles.buttonText, { color: colors.accent }]}>Save Goals</Text>
</TouchableOpacity>
</View>
<FlatList
data={micronutrientGroups}
renderItem={renderItem}
keyExtractor={(item) => item.title}
showsVerticalScrollIndicator={false}
style={styles.list}
ListFooterComponent={() => (
<TouchableOpacity
style={[styles.resetButton, { backgroundColor: colors.boxes }]}
onPress={resetToDefault}>
<Text style={[styles.resetButtonText, { color: colors.accent }]}>Reset to Default Values</Text>
</TouchableOpacity>
)}
contentContainerStyle={styles.list}
/>
</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,
marginBottom: 8,
},
topGraphic: {
gap: 16,
justifyContent: "space-between",
flexDirection: "row",
alignItems: "center",
},
graphContainer: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
maxWidth: '50%',
},
macroInfoContainer: {
flex: 1,
gap: 8,
maxWidth: '50%',
},
macroRow: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
paddingVertical: 4,
},
macroLabel: {
fontSize: 15,
fontWeight: '600',
width: '35%',
marginRight: 4,
},
qtyContainer: {
flex: 1,
borderRadius: 12,
overflow: 'hidden',
},
qtyInput: {
fontSize: 16,
fontWeight: '600',
padding: 8,
textAlign: 'center',
},
actionButton: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
padding: 5,
marginTop: 16,
gap: 8,
borderRadius: 12,
},
buttonText: {
fontSize: 16,
fontWeight: 'bold',
},
listContainer: {
flex: 1,
borderRadius: 20,
overflow: 'hidden',
},
label: {
fontSize: 16,
fontWeight: '600',
},
input: {
width: 75,
borderRadius: 20,
padding: 10,
fontSize: 16,
alignItems: 'center',
},
saveButton: {
padding: 15,
borderRadius: 5,
alignItems: 'center',
marginTop: 10,
},
saveButtonText: {
fontSize: 16,
fontWeight: '600',
},
groupContainer: {
padding: 15,
borderRadius: 10,
marginBottom: 10,
},
groupTitle: {
fontSize: 18,
fontWeight: 'bold',
marginBottom: 10,
},
nutrientRow: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
marginBottom: 8,
},
nutrientLabel: {
fontSize: 14,
flex: 1,
},
nutrientInput: {
width: 80,
borderRadius: 15,
padding: 8,
fontSize: 14,
},
list: {
},
resetButton: {
padding: 15,
borderRadius: 10,
alignItems: 'center',
marginVertical: 10,
marginHorizontal: 5,
},
resetButtonText: {
fontSize: 16,
fontWeight: '600',
},
});