antigravity/app/(tabs)/goals.tsx

82 lines
3.7 KiB
TypeScript

import { useFocusEffect } from 'expo-router';
import { useCallback, useState } from 'react';
import { ScrollView, Text, View } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { getDB } from '../../db';
import { Goal } from '../../types';
export default function GoalsScreen() {
const insets = useSafeAreaInsets();
const [goals, setGoals] = useState<Goal[]>([]);
const fetchData = useCallback(async () => {
try {
const db = getDB();
const result = await db.getAllAsync<Goal>('SELECT * FROM goals ORDER BY deadline ASC');
setGoals(result);
} catch (error) {
console.error('Error fetching goals', error);
}
}, []);
useFocusEffect(
useCallback(() => {
fetchData();
}, [fetchData])
);
const calculateProgress = (current: number, target: number) => {
if (target === 0) return 0;
return Math.min((current / target) * 100, 100);
};
return (
<View className="flex-1 bg-gray-100 dark:bg-gray-900" style={{ paddingTop: insets.top }}>
<ScrollView className="flex-1 px-6">
<View className="py-6">
<Text className="text-3xl font-bold text-gray-900 dark:text-white">Financial Goals</Text>
<Text className="text-gray-500 mt-1">Stay disciplined and reach your targets.</Text>
</View>
{goals.length === 0 ? (
<View className="items-center py-10">
<Text className="text-gray-400">No goals set yet.</Text>
</View>
) : (
goals.map((item) => {
const progress = calculateProgress(item.current_amount, item.target_amount);
return (
<View key={item.id} className="bg-white dark:bg-gray-800 p-6 mb-4 rounded-2xl shadow-sm">
<View className="flex-row justify-between items-start mb-4">
<View>
<Text className="text-xl font-bold text-gray-900 dark:text-white">{item.name}</Text>
{item.deadline && (
<Text className="text-gray-500 text-xs">Deadline: {item.deadline}</Text>
)}
</View>
<View className="bg-blue-100 px-3 py-1 rounded-full">
<Text className="text-blue-600 font-bold text-xs">{progress.toFixed(0)}%</Text>
</View>
</View>
<View className="flex-row justify-between mb-2">
<Text className="text-gray-500 text-sm">{item.current_amount.toFixed(2)} saved</Text>
<Text className="text-gray-900 dark:text-white font-bold text-sm">Target: {item.target_amount.toFixed(2)}</Text>
</View>
{/* Progress Bar */}
<View className="h-3 bg-gray-100 dark:bg-gray-700 rounded-full overflow-hidden">
<View
className="h-full bg-blue-600 rounded-full"
style={{ width: `${progress}%` }}
/>
</View>
</View>
);
})
)}
</ScrollView>
</View>
);
}