123 lines
4.0 KiB
TypeScript
123 lines
4.0 KiB
TypeScript
'use client';
|
|
|
|
import React, { createContext, useContext, useEffect, useState, useCallback } from 'react';
|
|
import { getParentDashboard } from '@/api/dashboard';
|
|
import type { ChildStats } from '@/api/dashboard';
|
|
import { useAuth } from '@/contexts/AuthContext';
|
|
|
|
export type { ChildStats };
|
|
|
|
interface SelectedChildContextType {
|
|
selectedChild: ChildStats | null;
|
|
childrenList: ChildStats[];
|
|
setSelectedChild: (child: ChildStats | null) => void;
|
|
loading: boolean;
|
|
refetch: () => Promise<void>;
|
|
}
|
|
|
|
const SelectedChildContext = createContext<SelectedChildContextType | undefined>(undefined);
|
|
|
|
function mapParentChildrenToChildStats(raw: any[]): ChildStats[] {
|
|
return raw.map((item: any) => {
|
|
const child = item.child || item;
|
|
const summary = item.summary || {};
|
|
return {
|
|
id: String(child.id),
|
|
name: child.name || [child.first_name, child.last_name].filter(Boolean).join(' ') || 'Ребёнок',
|
|
avatar: child.avatar ?? null,
|
|
avatar_url: child.avatar_url ?? null,
|
|
total_lessons: 0,
|
|
completed_lessons: 0,
|
|
average_grade: summary.average_score ?? 0,
|
|
homework_pending: summary.pending_homeworks ?? 0,
|
|
next_lesson: null,
|
|
};
|
|
});
|
|
}
|
|
|
|
export function SelectedChildProvider({ children }: { children: React.ReactNode }) {
|
|
const { user } = useAuth();
|
|
const [selectedChild, setSelectedChildState] = useState<ChildStats | null>(null);
|
|
const [childrenList, setChildrenList] = useState<ChildStats[]>([]);
|
|
const [loading, setLoading] = useState(true);
|
|
|
|
const loadChildren = useCallback(async () => {
|
|
if (user?.role !== 'parent') {
|
|
setChildrenList([]);
|
|
setSelectedChildState(null);
|
|
setLoading(false);
|
|
return;
|
|
}
|
|
try {
|
|
setLoading(true);
|
|
const stats = await getParentDashboard();
|
|
const rawChildren = (stats as any).children ?? (stats as any).children_stats ?? [];
|
|
const childrenData = mapParentChildrenToChildStats(rawChildren);
|
|
setChildrenList(childrenData);
|
|
|
|
const savedChildId = typeof window !== 'undefined' ? localStorage.getItem('selected_child_id') : null;
|
|
let childToSelect: ChildStats | null = null;
|
|
|
|
if (savedChildId && childrenData.length > 0) {
|
|
const saved = childrenData.find((c) => c.id === savedChildId);
|
|
childToSelect = saved ?? childrenData[0];
|
|
if (!saved && childrenData[0]) localStorage.setItem('selected_child_id', childrenData[0].id);
|
|
} else if (childrenData.length === 1) {
|
|
childToSelect = childrenData[0];
|
|
localStorage.setItem('selected_child_id', childrenData[0].id);
|
|
} else if (childrenData.length > 1) {
|
|
childToSelect = childrenData[0];
|
|
localStorage.setItem('selected_child_id', childrenData[0].id);
|
|
}
|
|
|
|
setSelectedChildState(childToSelect);
|
|
} catch (e) {
|
|
console.error('[SelectedChildContext] loadChildren error', e);
|
|
setChildrenList([]);
|
|
setSelectedChildState(null);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
}, []);
|
|
|
|
const setSelectedChild = useCallback((child: ChildStats | null) => {
|
|
setSelectedChildState(child);
|
|
if (typeof window !== 'undefined') {
|
|
if (child) localStorage.setItem('selected_child_id', child.id);
|
|
else localStorage.removeItem('selected_child_id');
|
|
}
|
|
}, [user?.role]);
|
|
|
|
useEffect(() => {
|
|
loadChildren();
|
|
}, [loadChildren]);
|
|
|
|
return (
|
|
<SelectedChildContext.Provider
|
|
value={{
|
|
selectedChild,
|
|
childrenList,
|
|
setSelectedChild,
|
|
loading,
|
|
refetch: loadChildren,
|
|
}}
|
|
>
|
|
{children}
|
|
</SelectedChildContext.Provider>
|
|
);
|
|
}
|
|
|
|
export function useSelectedChild(): SelectedChildContextType {
|
|
const ctx = useContext(SelectedChildContext);
|
|
if (ctx === undefined) {
|
|
return {
|
|
selectedChild: null,
|
|
childrenList: [],
|
|
setSelectedChild: () => {},
|
|
loading: false,
|
|
refetch: async () => {},
|
|
};
|
|
}
|
|
return ctx;
|
|
}
|