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:
@@ -21,6 +21,7 @@ import { InsightsDashboard } from './InsightsDashboard';
|
||||
import PredictionsCard from './PredictionsCard';
|
||||
import GrowthSpurtAlert from './GrowthSpurtAlert';
|
||||
import { motion } from 'framer-motion';
|
||||
import { useAuth } from '@/lib/auth/AuthContext';
|
||||
|
||||
interface TabPanelProps {
|
||||
children?: React.ReactNode;
|
||||
@@ -45,6 +46,7 @@ function TabPanel(props: TabPanelProps) {
|
||||
}
|
||||
|
||||
export function UnifiedInsightsDashboard() {
|
||||
const { user } = useAuth();
|
||||
const [children, setChildren] = useState<Child[]>([]);
|
||||
const [selectedChildId, setSelectedChildId] = useState<string>('');
|
||||
const [tabValue, setTabValue] = useState(0);
|
||||
@@ -54,27 +56,56 @@ export function UnifiedInsightsDashboard() {
|
||||
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 {
|
||||
// Invalid child ID - reset to first child
|
||||
console.warn('[UnifiedInsightsDashboard] 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('[UnifiedInsightsDashboard] Loading children for familyId:', familyId);
|
||||
const data = await childrenApi.getChildren(familyId);
|
||||
console.log('[UnifiedInsightsDashboard] Loaded children:', data);
|
||||
setChildren(data);
|
||||
if (data.length > 0 && !selectedChildId) {
|
||||
setSelectedChildId(data[0].id);
|
||||
|
||||
// Only set selectedChildId if we don't have one or if it's not in the new list
|
||||
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('[UnifiedInsightsDashboard] Failed to load children:', error);
|
||||
setError('Failed to load children');
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
@@ -141,6 +172,13 @@ export function UnifiedInsightsDashboard() {
|
||||
</Typography>
|
||||
</Box>
|
||||
|
||||
{/* Error Alert */}
|
||||
{error && (
|
||||
<Alert severity="warning" sx={{ mb: 3 }} onClose={() => setError('')}>
|
||||
{error}
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
{/* Child Selector */}
|
||||
{children.length > 1 && (
|
||||
<Box sx={{ mb: 3 }}>
|
||||
|
||||
Reference in New Issue
Block a user