docs: Add comprehensive multi-child implementation plan
Added detailed implementation plan covering: - Frontend: Dynamic UI, child selector, bulk activity logging, comparison analytics - Backend: Bulk operations, multi-child queries, family statistics - AI/Voice: Child name detection, context building, clarification flows - Database: Schema enhancements, user preferences, bulk operation tracking - State management, API enhancements, real-time sync updates - Testing strategy: Unit, integration, and E2E tests - Migration plan with feature flags for phased rollout - Performance optimizations: Caching, indexes, code splitting Also includes: - Security fixes for multi-family data leakage in analytics pages - ParentFlow branding updates - Activity tracking navigation improvements - Backend DTO and error handling fixes 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -40,6 +40,7 @@ import PredictionsCard from '@/components/features/analytics/PredictionsCard';
|
||||
import GrowthSpurtAlert from '@/components/features/analytics/GrowthSpurtAlert';
|
||||
import WeeklyReportCard from '@/components/features/analytics/WeeklyReportCard';
|
||||
import MonthlyReportCard from '@/components/features/analytics/MonthlyReportCard';
|
||||
import { useAuth } from '@/lib/auth/AuthContext';
|
||||
|
||||
interface TabPanelProps {
|
||||
children?: React.ReactNode;
|
||||
@@ -65,6 +66,7 @@ function TabPanel(props: TabPanelProps) {
|
||||
|
||||
export default function AnalyticsPage() {
|
||||
const theme = useTheme();
|
||||
const { user } = useAuth();
|
||||
const [children, setChildren] = useState<Child[]>([]);
|
||||
const [selectedChildId, setSelectedChildId] = useState<string>('');
|
||||
const [tabValue, setTabValue] = useState(0);
|
||||
@@ -74,27 +76,54 @@ export default function AnalyticsPage() {
|
||||
const [insightsLoading, setInsightsLoading] = useState(false);
|
||||
const [predictionsLoading, setPredictionsLoading] = useState(false);
|
||||
const [days, setDays] = useState<number>(7);
|
||||
const [error, setError] = useState<string>('');
|
||||
|
||||
const familyId = user?.families?.[0]?.familyId;
|
||||
|
||||
useEffect(() => {
|
||||
loadChildren();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedChildId) {
|
||||
loadInsights();
|
||||
loadPredictions();
|
||||
if (familyId) {
|
||||
loadChildren();
|
||||
}
|
||||
}, [selectedChildId, days]);
|
||||
}, [familyId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedChildId && children.length > 0) {
|
||||
// Validate that selectedChildId belongs to current user's children
|
||||
const childExists = children.some(child => child.id === selectedChildId);
|
||||
if (childExists) {
|
||||
loadInsights();
|
||||
loadPredictions();
|
||||
} else {
|
||||
console.warn('[AnalyticsPage] Selected child not found in user\'s children, resetting');
|
||||
setSelectedChildId(children[0].id);
|
||||
setError('Selected child not found. Showing data for your first child.');
|
||||
}
|
||||
}
|
||||
}, [selectedChildId, days, children]);
|
||||
|
||||
const loadChildren = async () => {
|
||||
if (!familyId) {
|
||||
setLoading(false);
|
||||
setError('No family found');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const data = await childrenApi.getChildren();
|
||||
console.log('[AnalyticsPage] Loading children for familyId:', familyId);
|
||||
const data = await childrenApi.getChildren(familyId);
|
||||
console.log('[AnalyticsPage] Loaded children:', data);
|
||||
setChildren(data);
|
||||
if (data.length > 0 && !selectedChildId) {
|
||||
setSelectedChildId(data[0].id);
|
||||
|
||||
if (data.length > 0) {
|
||||
const existingChildStillValid = data.some(child => child.id === selectedChildId);
|
||||
if (!selectedChildId || !existingChildStillValid) {
|
||||
setSelectedChildId(data[0].id);
|
||||
}
|
||||
}
|
||||
setError('');
|
||||
} catch (error) {
|
||||
console.error('Failed to load children:', error);
|
||||
console.error('[AnalyticsPage] Failed to load children:', error);
|
||||
setError('Failed to load children');
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user