fix: Replace GraphQL with REST API for home page dashboard

GraphQL endpoint was returning 400 errors due to authentication issues
with the GqlAuthGuard. Replaced GraphQL query with REST API calls to
match the working insights page pattern.

Changes:
- Removed useQuery(GET_DASHBOARD) GraphQL call
- Added REST API calls: childrenApi.getChildren(), trackingApi.getActivities()
- Calculate today's summary from activities client-side
- Load children and dashboard data separately
- Removed all GraphQL debug logging

Now home page uses same REST pattern as insights page:
1. Load children via childrenApi
2. Load activities via trackingApi
3. Calculate summary from filtered activities

This eliminates the GraphQL 400 errors and makes Today's Summary
display correctly with feeding count, sleep duration, diaper count.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-10-05 07:11:29 +00:00
parent de45dbddba
commit b94f298d2b
2 changed files with 83 additions and 63 deletions

View File

@@ -22,8 +22,8 @@ import {
import { motion } from 'framer-motion';
import { useAuth } from '@/lib/auth/AuthContext';
import { useRouter } from 'next/navigation';
import { useQuery } from '@apollo/client/react';
import { GET_DASHBOARD } from '@/graphql/queries/dashboard';
import { childrenApi, Child } from '@/lib/api/children';
import { trackingApi } from '@/lib/api/tracking';
import { format, formatDistanceToNow } from 'date-fns';
import { useRealTimeActivities } from '@/hooks/useWebSocket';
import { useTranslation } from '@/hooks/useTranslation';
@@ -44,58 +44,91 @@ export default function HomePage() {
const [selectedChildId, setSelectedChildId] = useState<string | null>(null);
const [predictions, setPredictions] = useState<any>(null);
const [predictionsLoading, setPredictionsLoading] = useState(false);
const [children, setChildren] = useState<Child[]>([]);
const [recentActivities, setRecentActivities] = useState<any[]>([]);
const [todaySummary, setTodaySummary] = useState<any>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<any>(null);
// Fetch children on mount
// Load children
useEffect(() => {
if (familyId && !authLoading) {
dispatch(fetchChildren(familyId));
loadChildren();
}
}, [familyId, authLoading, dispatch]);
}, [familyId, authLoading]);
// GraphQL query for dashboard data
const { data, loading, error, refetch } = useQuery(GET_DASHBOARD, {
variables: { childId: selectedChildId },
skip: authLoading || !user,
fetchPolicy: 'cache-and-network',
});
const loadChildren = async () => {
if (!familyId) return;
// Log GraphQL errors and data for debugging
try {
const data = await childrenApi.getChildren(familyId);
setChildren(data);
if (data.length > 0 && !selectedChildId) {
setSelectedChildId(data[0].id);
}
} catch (err) {
console.error('Failed to load children:', err);
setError(err);
}
};
// Load dashboard data when child selected
useEffect(() => {
console.log('[HomePage] === GraphQL Debug Info ===');
console.log('[HomePage] Raw data:', data);
console.log('[HomePage] Data type:', typeof data);
console.log('[HomePage] Data keys:', data ? Object.keys(data) : 'null');
if (error) {
console.error('[HomePage] GraphQL error:', error);
console.error('[HomePage] GraphQL error details:', {
message: error.message,
networkError: error.networkError,
graphQLErrors: error.graphQLErrors,
});
if (selectedChildId) {
loadDashboardData();
}
if (data) {
console.log('[HomePage] GraphQL data:', data);
console.log('[HomePage] Dashboard data:', data.dashboard);
}
console.log('[HomePage] Query state:', {
loading,
error: !!error,
hasData: !!data,
user: !!user,
skip: authLoading || !user,
childrenCount: data?.dashboard?.children?.length || 0,
selectedChildId,
});
console.log('[HomePage] LocalStorage token:', typeof window !== 'undefined' ? localStorage.getItem('accessToken')?.substring(0, 20) : 'SSR');
}, [error, data, loading, user, authLoading, selectedChildId]);
}, [selectedChildId]);
// Real-time activity handler to refetch dashboard data
const loadDashboardData = async () => {
if (!selectedChildId) return;
setLoading(true);
try {
// Load recent activities
const activities = await trackingApi.getActivities(selectedChildId);
setRecentActivities(activities.slice(0, 10));
// Calculate today's summary from activities
const today = new Date();
today.setHours(0, 0, 0, 0);
const todayActivities = activities.filter((a: any) => {
const activityDate = new Date(a.timestamp || a.startedAt);
return activityDate >= today;
});
const summary = {
feedingCount: todayActivities.filter((a: any) => a.type === 'feeding').length,
sleepCount: todayActivities.filter((a: any) => a.type === 'sleep').length,
diaperCount: todayActivities.filter((a: any) => a.type === 'diaper').length,
medicationCount: todayActivities.filter((a: any) => ['medication', 'medicine'].includes(a.type)).length,
totalFeedingAmount: todayActivities
.filter((a: any) => a.type === 'feeding')
.reduce((sum: number, a: any) => sum + (a.data?.amount || 0), 0),
totalSleepDuration: todayActivities
.filter((a: any) => a.type === 'sleep')
.reduce((sum: number, a: any) => {
const start = new Date(a.startedAt);
const end = a.endedAt ? new Date(a.endedAt) : new Date();
return sum + (end.getTime() - start.getTime()) / (1000 * 60);
}, 0),
};
setTodaySummary(summary);
setError(null);
} catch (err) {
console.error('Failed to load dashboard data:', err);
setError(err);
} finally {
setLoading(false);
}
};
const refetch = loadDashboardData;
// Real-time activity handler
const refreshDashboard = useCallback(async () => {
if (refetch) {
console.log('[HomePage] Refreshing dashboard data...');
await refetch();
}
}, [refetch]);
// Subscribe to real-time activity updates
@@ -105,14 +138,6 @@ export default function HomePage() {
refreshDashboard // On activity deleted
);
// Set the first child as selected when data loads
useEffect(() => {
if (data?.dashboard?.children && data.dashboard.children.length > 0 && !selectedChildId) {
const firstChild = data.dashboard.children[0];
setSelectedChildId(firstChild.id);
}
}, [data, selectedChildId]);
// Sync selectedChildId with Redux selectedChild
useEffect(() => {
if (selectedChild?.id && selectedChild.id !== selectedChildId) {
@@ -161,22 +186,17 @@ export default function HomePage() {
}
};
// Extract data from GraphQL response
const children = data?.dashboard?.children || [];
const graphqlSelectedChild = data?.dashboard?.selectedChild;
const dailySummary = data?.dashboard?.todaySummary;
const isLoading = authLoading || loading;
// Build child metrics object for DynamicChildDashboard
const childMetrics = children.reduce((acc: any, child: any) => {
// For now, use the same summary for selected child, or zero for others
// TODO: Fetch per-child summaries from backend
if (child.id === selectedChildId && dailySummary) {
// Use todaySummary for selected child, or zero for others
if (child.id === selectedChildId && todaySummary) {
acc[child.id] = {
feedingCount: dailySummary.feedingCount || 0,
sleepDuration: dailySummary.totalSleepDuration || 0,
diaperCount: dailySummary.diaperCount || 0,
medicationCount: dailySummary.medicationCount || 0,
feedingCount: todaySummary.feedingCount || 0,
sleepDuration: todaySummary.totalSleepDuration || 0,
diaperCount: todaySummary.diaperCount || 0,
medicationCount: todaySummary.medicationCount || 0,
};
} else {
acc[child.id] = {

File diff suppressed because one or more lines are too long