notification system implemented
need refinements
This commit is contained in:
1 parent
612259f020
commit
1143f8ca02
33 files changed
+2221
-222
No files matched your search
@@ -9,6 +9,7 @@ import {
|
||||
import { useUser } from "@clerk/clerk-expo";
|
||||
import { LinearGradient } from "expo-linear-gradient";
|
||||
import { useState, useCallback, useEffect } from "react";
|
||||
import { useFocusEffect } from "@react-navigation/native";
|
||||
import AsyncStorage from "@react-native-async-storage/async-storage";
|
||||
import { theme } from "../../styles/theme";
|
||||
import { ActivityWidget } from "../../components/ActivityWidget";
|
||||
@@ -16,12 +17,18 @@ import { QuickActionGrid } from "../../components/QuickActionGrid";
|
||||
import { TrackMealModal } from "../../components/TrackMealModal";
|
||||
import { AddWaterModal } from "../../components/AddWaterModal";
|
||||
import { HydrationWidget } from "../../components/HydrationWidget";
|
||||
import { NutritionWidget } from "../../components/NutritionWidget";
|
||||
import { WeeklyProgressWidget } from "../../components/WeeklyProgressWidget";
|
||||
import { ScanFoodModal } from "../../components/ScanFoodModal";
|
||||
import { useStatistics } from "../../contexts/StatisticsContext";
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
|
||||
const CALORIE_GOAL = 2000; // kcal
|
||||
const WATER_GOAL = 2000; // ml
|
||||
|
||||
export default function HomeScreen() {
|
||||
const { user } = useUser();
|
||||
const { refetchStatistics, forceRefresh } = useStatistics();
|
||||
const [refreshing, setRefreshing] = useState(false);
|
||||
const [trackMealModalVisible, setTrackMealModalVisible] = useState(false);
|
||||
const [addWaterModalVisible, setAddWaterModalVisible] = useState(false);
|
||||
@@ -29,12 +36,19 @@ export default function HomeScreen() {
|
||||
const [calories, setCalories] = useState(0);
|
||||
const [waterIntake, setWaterIntake] = useState(0);
|
||||
|
||||
const onRefresh = useCallback(() => {
|
||||
// Refetch statistics when screen comes into focus
|
||||
useFocusEffect(
|
||||
useCallback(() => {
|
||||
refetchStatistics();
|
||||
}, [refetchStatistics]),
|
||||
);
|
||||
|
||||
const onRefresh = useCallback(async () => {
|
||||
setRefreshing(true);
|
||||
setTimeout(() => {
|
||||
setRefreshing(false);
|
||||
}, 2000);
|
||||
}, []);
|
||||
// Force refetch statistics bypassing cache
|
||||
await forceRefresh();
|
||||
setRefreshing(false);
|
||||
}, [forceRefresh]);
|
||||
|
||||
const getGreeting = () => {
|
||||
const hour = new Date().getHours();
|
||||
@@ -75,8 +89,48 @@ export default function HomeScreen() {
|
||||
setWaterIntake(0);
|
||||
const today = new Date().toDateString();
|
||||
await AsyncStorage.setItem("lastResetDate", today);
|
||||
await AsyncStorage.removeItem(`calories_${today}`);
|
||||
await AsyncStorage.removeItem(`water_${today}`);
|
||||
};
|
||||
|
||||
// Load persisted data on mount
|
||||
useEffect(() => {
|
||||
const loadPersistedData = async () => {
|
||||
const today = new Date().toDateString();
|
||||
const storedCalories = await AsyncStorage.getItem(`calories_${today}`);
|
||||
const storedWater = await AsyncStorage.getItem(`water_${today}`);
|
||||
|
||||
if (storedCalories) {
|
||||
setCalories(parseInt(storedCalories, 10));
|
||||
}
|
||||
if (storedWater) {
|
||||
setWaterIntake(parseInt(storedWater, 10));
|
||||
}
|
||||
};
|
||||
|
||||
loadPersistedData();
|
||||
}, []);
|
||||
|
||||
// Persist calories to AsyncStorage whenever it changes
|
||||
useEffect(() => {
|
||||
const persistCalories = async () => {
|
||||
const today = new Date().toDateString();
|
||||
await AsyncStorage.setItem(`calories_${today}`, calories.toString());
|
||||
};
|
||||
|
||||
persistCalories();
|
||||
}, [calories]);
|
||||
|
||||
// Persist water intake to AsyncStorage whenever it changes
|
||||
useEffect(() => {
|
||||
const persistWater = async () => {
|
||||
const today = new Date().toDateString();
|
||||
await AsyncStorage.setItem(`water_${today}`, waterIntake.toString());
|
||||
};
|
||||
|
||||
persistWater();
|
||||
}, [waterIntake]);
|
||||
|
||||
// Check for midnight reset
|
||||
useEffect(() => {
|
||||
const checkAndResetIfNeeded = async () => {
|
||||
@@ -146,6 +200,26 @@ export default function HomeScreen() {
|
||||
{/* Activity Widget */}
|
||||
<ActivityWidget calories={calories} />
|
||||
|
||||
{/* Quick Action Grid */}
|
||||
<QuickActionGrid
|
||||
onTrackMealPress={() => setTrackMealModalVisible(true)}
|
||||
onAddWaterPress={() => setAddWaterModalVisible(true)}
|
||||
onScanFoodPress={() => setScanFoodModalVisible(true)}
|
||||
onLogWorkoutPress={() => {
|
||||
// TODO: Implement workout logging
|
||||
console.log("Log workout tapped");
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Nutrition Widget */}
|
||||
<NutritionWidget current={calories} goal={CALORIE_GOAL} />
|
||||
|
||||
{/* Hydration Widget */}
|
||||
<HydrationWidget current={waterIntake} goal={WATER_GOAL} />
|
||||
|
||||
{/* Weekly Progress Widget */}
|
||||
<WeeklyProgressWidget />
|
||||
|
||||
<TrackMealModal
|
||||
visible={trackMealModalVisible}
|
||||
onClose={() => setTrackMealModalVisible(false)}
|
||||
|
||||
Reference in new issue
Block a user