import { useState, useEffect } from "react"; import { View, Text, StyleSheet, ScrollView, TouchableOpacity, ActivityIndicator, RefreshControl, Alert, } from "react-native"; import { useAuth } from "@clerk/clerk-expo"; import { Ionicons } from "@expo/vector-icons"; import { fitnessGoalsService, type FitnessGoal, type CreateGoalData } from "../../services/fitnessGoals"; import { GoalProgressCard } from "../../components/GoalProgressCard"; import { GoalCreationModal } from "../../components/GoalCreationModal"; export default function GoalsScreen() { const { userId, getToken } = useAuth(); const [goals, setGoals] = useState([]); const [loading, setLoading] = useState(true); const [refreshing, setRefreshing] = useState(false); const [showCreateModal, setShowCreateModal] = useState(false); const fetchGoals = async () => { if (!userId) return; try { const token = await getToken(); const data = await fitnessGoalsService.getGoals(userId, token); setGoals(data); } catch (error) { console.error("Error fetching fitness goals:", error); Alert.alert("Error", "Failed to load goals. Please try again."); } finally { setLoading(false); setRefreshing(false); } }; useEffect(() => { fetchGoals(); }, [userId]); const onRefresh = () => { setRefreshing(true); fetchGoals(); }; const handleCreateGoal = async (goalData: CreateGoalData) => { try { const token = await getToken(); const newGoal = await fitnessGoalsService.createGoal(goalData, token); setGoals(prev => [newGoal, ...prev]); Alert.alert("Success", "Goal created successfully!"); } catch (error) { console.error("Error creating goal:", error); throw error; } }; const handleCompleteGoal = async (goalId: string) => { try { const token = await getToken(); const updatedGoal = await fitnessGoalsService.completeGoal(goalId, token); setGoals(prev => prev.map(g => g.id === goalId ? updatedGoal : g)); Alert.alert("Success", "Goal completed! 🎉"); } catch (error) { console.error("Error completing goal:", error); Alert.alert("Error", "Failed to complete goal. Please try again."); } }; const handleDeleteGoal = async (goalId: string) => { try { const token = await getToken(); await fitnessGoalsService.deleteGoal(goalId, token); setGoals(prev => prev.filter(g => g.id !== goalId)); Alert.alert("Success", "Goal deleted"); } catch (error) { console.error("Error deleting goal:", error); Alert.alert("Error", "Failed to delete goal. Please try again."); } }; const activeGoals = goals.filter(g => g.status === 'active'); const completedGoals = goals.filter(g => g.status === 'completed'); if (loading && !refreshing) { return ( ); } return ( } > My Fitness Goals Track your fitness journey progress {/* Stats Summary */} {goals.length > 0 && ( {activeGoals.length} Active {completedGoals.length} Completed {activeGoals.length > 0 ? Math.round( activeGoals.reduce((sum, g) => sum + g.progress, 0) / activeGoals.length ) : 0}% Avg Progress )} {/* Active Goals */} Active Goals ({activeGoals.length}) {activeGoals.length === 0 ? ( No active goals yet Tap the + button to create your first goal ) : ( activeGoals.map((goal) => ( handleCompleteGoal(goal.id)} onDelete={() => handleDeleteGoal(goal.id)} /> )) )} {/* Completed Goals */} {completedGoals.length > 0 && ( Completed Goals ({completedGoals.length}) {completedGoals.map((goal) => ( handleDeleteGoal(goal.id)} /> ))} )} {/* Floating Action Button */} setShowCreateModal(true)} > {/* Create Goal Modal */} setShowCreateModal(false)} onSubmit={handleCreateGoal} /> ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: "#f3f4f6", }, center: { flex: 1, justifyContent: "center", alignItems: "center", }, header: { padding: 20, backgroundColor: "#fff", marginBottom: 10, }, headerTitle: { fontSize: 28, fontWeight: "bold", color: "#111827", }, headerSubtitle: { fontSize: 16, color: "#6b7280", marginTop: 4, }, statsContainer: { flexDirection: "row", padding: 16, gap: 12, }, statCard: { flex: 1, backgroundColor: "#fff", padding: 16, borderRadius: 12, alignItems: "center", shadowColor: "#000", shadowOffset: { width: 0, height: 1 }, shadowOpacity: 0.05, shadowRadius: 2, elevation: 2, }, statValue: { fontSize: 24, fontWeight: "bold", color: "#2563eb", marginBottom: 4, }, statLabel: { fontSize: 12, color: "#6b7280", fontWeight: "500", }, section: { padding: 20, paddingTop: 10, }, sectionTitle: { fontSize: 18, fontWeight: "600", color: "#374151", marginBottom: 12, }, emptyState: { alignItems: "center", paddingVertical: 40, }, emptyText: { fontSize: 16, fontWeight: "500", color: "#6b7280", marginTop: 12, }, emptySubtext: { fontSize: 14, color: "#9ca3af", marginTop: 4, }, footer: { height: 100, }, fab: { position: "absolute", right: 20, bottom: 20, width: 56, height: 56, borderRadius: 28, backgroundColor: "#2563eb", justifyContent: "center", alignItems: "center", shadowColor: "#000", shadowOffset: { width: 0, height: 4 }, shadowOpacity: 0.3, shadowRadius: 8, elevation: 8, }, });