import React, { useState, useEffect } from "react"; import { View, Text, StyleSheet, ScrollView, TouchableOpacity, ActivityIndicator, Alert, TextInput, Platform, } from "react-native"; import { useRouter, Stack } from "expo-router"; import { useAuth } from "@clerk/clerk-expo"; import { Ionicons } from "@expo/vector-icons"; import { useTheme } from "../contexts/ThemeContext"; import { MinimalCard } from "../components/MinimalCard"; import { MinimalButton } from "../components/MinimalButton"; import { fitnessProfileApi, type FitnessProfile } from "../api/fitnessProfile"; interface FitnessProfileData { height?: number; weight?: number; age?: number; gender?: string; fitnessGoal?: string; activityLevel?: string; medicalConditions?: string; allergies?: string; injuries?: string; } const GENDER_OPTIONS = [ { label: "Male", value: "male", icon: "male-outline" }, { label: "Female", value: "female", icon: "female-outline" }, { label: "Other", value: "other", icon: "transgender-outline" }, { label: "Prefer not to say", value: "prefer_not_to_say", icon: "help-circle-outline", }, ]; const FITNESS_GOAL_OPTIONS = [ { label: "Weight Loss", value: "weight_loss", icon: "trending-down", color: "#FF3B3B", }, { label: "Muscle Gain", value: "muscle_gain", icon: "barbell", color: "#0066FF", }, { label: "Endurance", value: "endurance", icon: "bicycle", color: "#00D26A" }, { label: "Flexibility", value: "flexibility", icon: "body", color: "#7B2CBF", }, { label: "General Fitness", value: "general_fitness", icon: "fitness", color: "#FFB800", }, ]; const ACTIVITY_LEVEL_OPTIONS = [ { label: "Sedentary", value: "sedentary", description: "Little to no exercise", }, { label: "Lightly Active", value: "lightly_active", description: "1-3 days/week", }, { label: "Moderately Active", value: "moderately_active", description: "3-5 days/week", }, { label: "Very Active", value: "very_active", description: "6-7 days/week" }, { label: "Extremely Active", value: "extremely_active", description: "Intense daily training", }, ]; export default function FitnessProfileScreen() { const router = useRouter(); const { colors, typography } = useTheme(); const { userId, getToken } = useAuth(); const [loading, setLoading] = useState(false); const [fetchingProfile, setFetchingProfile] = useState(true); const [profileData, setProfileData] = useState({}); useEffect(() => { fetchProfile(); }, []); const fetchProfile = async () => { try { setFetchingProfile(true); const token = await getToken(); if (!token || !userId) { return; } const profile = await fitnessProfileApi.getFitnessProfile(token); if (profile) { let activityLevel = profile.activityLevel || ""; if (activityLevel === "light") activityLevel = "lightly_active"; if (activityLevel === "moderate") activityLevel = "moderately_active"; if (activityLevel === "active") activityLevel = "very_active"; setProfileData({ height: profile.height, weight: profile.weight, age: profile.age, gender: profile.gender || "", fitnessGoal: Array.isArray(profile.fitnessGoals) ? profile.fitnessGoals[0] : "", activityLevel: activityLevel, medicalConditions: profile.medicalConditions || "", allergies: profile.allergies || "", injuries: profile.injuries || "", }); } } catch (error) { console.error("Error fetching profile:", error); } finally { setFetchingProfile(false); } }; const handleSave = async () => { try { setLoading(true); const token = await getToken(); if (!token || !userId) { Alert.alert("Error", "Authentication required"); return; } const dataToSave: Omit = { userId: userId, height: profileData.height, weight: profileData.weight, age: profileData.age, gender: (profileData.gender as FitnessProfile["gender"]) || undefined, fitnessGoals: profileData.fitnessGoal ? [profileData.fitnessGoal] : [], activityLevel: (profileData.activityLevel as FitnessProfile["activityLevel"]) || undefined, medicalConditions: profileData.medicalConditions, allergies: profileData.allergies, injuries: profileData.injuries, }; await fitnessProfileApi.createFitnessProfile(dataToSave, token); Alert.alert("Success", "Fitness profile saved successfully!", [ { text: "OK", onPress: () => router.back() }, ]); } catch (error) { console.error("Error saving profile:", error); Alert.alert("Error", "Failed to save fitness profile"); } finally { setLoading(false); } }; const updateField = (field: keyof FitnessProfileData, value: any) => { setProfileData((prev) => ({ ...prev, [field]: value })); }; if (fetchingProfile) { return ( ); } return ( <> {/* Header */} router.back()} > Fitness Profile {/* Basic Information */} Basic Information HEIGHT (CM) updateField( "height", text ? parseFloat(text) : undefined, ) } keyboardType="decimal-pad" placeholder="175" placeholderTextColor={colors.textTertiary} /> WEIGHT (KG) updateField( "weight", text ? parseFloat(text) : undefined, ) } keyboardType="decimal-pad" placeholder="70" placeholderTextColor={colors.textTertiary} /> AGE updateField("age", text ? parseInt(text, 10) : undefined) } keyboardType="number-pad" placeholder="25" placeholderTextColor={colors.textTertiary} /> {/* Gender Selection */} Gender {GENDER_OPTIONS.map((option) => ( updateField("gender", option.value)} > {option.label} ))} {/* Fitness Goal */} Primary Fitness Goal {FITNESS_GOAL_OPTIONS.map((option, index) => ( updateField("fitnessGoal", option.value)} > {option.label} {profileData.fitnessGoal === option.value && ( )} {index < FITNESS_GOAL_OPTIONS.length - 1 && ( )} ))} {/* Activity Level */} Activity Level {ACTIVITY_LEVEL_OPTIONS.map((option, index) => ( updateField("activityLevel", option.value)} > {option.label} {option.description} {profileData.activityLevel === option.value && ( )} {index < ACTIVITY_LEVEL_OPTIONS.length - 1 && ( )} ))} {/* Health Information */} Health Information MEDICAL CONDITIONS updateField("medicalConditions", text) } placeholder="e.g., Asthma, diabetes..." placeholderTextColor={colors.textTertiary} multiline numberOfLines={3} textAlignVertical="top" /> ALLERGIES updateField("allergies", text)} placeholder="e.g., Peanuts, latex..." placeholderTextColor={colors.textTertiary} multiline numberOfLines={3} textAlignVertical="top" /> INJURIES updateField("injuries", text)} placeholder="e.g., Previous knee injury..." placeholderTextColor={colors.textTertiary} multiline numberOfLines={3} textAlignVertical="top" /> {/* Save Button */} ); } const styles = StyleSheet.create({ container: { flex: 1, }, loadingContainer: { flex: 1, justifyContent: "center", alignItems: "center", }, header: { flexDirection: "row", alignItems: "center", justifyContent: "space-between", paddingBottom: 20, paddingHorizontal: 20, }, backButton: { width: 40, height: 40, borderRadius: 12, backgroundColor: "rgba(255, 255, 255, 0.2)", justifyContent: "center", alignItems: "center", }, scrollView: { flex: 1, }, scrollContent: { padding: 20, paddingBottom: 100, }, section: { marginBottom: 28, }, card: { padding: 4, }, inputRow: { flexDirection: "row", gap: 12, }, inputGroup: { flex: 1, marginBottom: 4, }, inputContainer: { flexDirection: "row", alignItems: "center", borderRadius: 14, borderWidth: 1.5, paddingHorizontal: 14, gap: 10, }, input: { flex: 1, paddingVertical: 14, fontSize: 16, fontWeight: "600", }, textArea: { borderRadius: 14, borderWidth: 1.5, padding: 14, fontSize: 16, minHeight: 90, }, genderRow: { flexDirection: "row", gap: 10, }, genderCard: { flex: 1, paddingVertical: 16, paddingHorizontal: 8, borderRadius: 14, borderWidth: 2, alignItems: "center", }, listItem: { flexDirection: "row", alignItems: "center", paddingVertical: 14, paddingHorizontal: 12, gap: 14, }, iconCircle: { width: 44, height: 44, borderRadius: 12, justifyContent: "center", alignItems: "center", }, divider: { height: 1, marginLeft: 58, }, footer: { position: "absolute", bottom: 0, left: 0, right: 0, padding: 20, paddingBottom: 34, borderTopWidth: 1, }, });