feat: Integrate ChildSelector in activity tracking form
- Replace local child state with Redux state management - Use ChildSelector component instead of custom select - Sync selectedChildIds with Redux store - Update API calls to use selectedChild.id - Remove loadChildren function
This commit is contained in:
@@ -47,6 +47,10 @@ import { FormSkeleton, ActivityListSkeleton } from '@/components/common/LoadingS
|
||||
import { motion } from 'framer-motion';
|
||||
import { useLocalizedDate } from '@/hooks/useLocalizedDate';
|
||||
import { useTranslation } from '@/hooks/useTranslation';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { fetchChildren, selectChild, selectSelectedChild, childrenSelectors } from '@/store/slices/childrenSlice';
|
||||
import { AppDispatch, RootState } from '@/store/store';
|
||||
import ChildSelector from '@/components/common/ChildSelector';
|
||||
|
||||
interface ActivityData {
|
||||
activityType: string;
|
||||
@@ -59,8 +63,15 @@ function ActivityTrackPage() {
|
||||
const { user } = useAuth();
|
||||
const { formatDistanceToNow } = useLocalizedDate();
|
||||
const { t } = useTranslation('tracking');
|
||||
const [children, setChildren] = useState<Child[]>([]);
|
||||
const [selectedChild, setSelectedChild] = useState<string>('');
|
||||
const dispatch = useDispatch<AppDispatch>();
|
||||
|
||||
// Redux state
|
||||
const children = useSelector((state: RootState) => childrenSelectors.selectAll(state));
|
||||
const selectedChild = useSelector(selectSelectedChild);
|
||||
const familyId = useSelector((state: RootState) => state.auth.user?.familyId);
|
||||
|
||||
// Local state
|
||||
const [selectedChildIds, setSelectedChildIds] = useState<string[]>([]);
|
||||
|
||||
// Activity state
|
||||
const [activityType, setActivityType] = useState<string>('play');
|
||||
@@ -71,7 +82,6 @@ function ActivityTrackPage() {
|
||||
const [notes, setNotes] = useState<string>('');
|
||||
const [recentActivities, setRecentActivities] = useState<Activity[]>([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [childrenLoading, setChildrenLoading] = useState(true);
|
||||
const [activitiesLoading, setActivitiesLoading] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [successMessage, setSuccessMessage] = useState<string | null>(null);
|
||||
@@ -80,46 +90,33 @@ function ActivityTrackPage() {
|
||||
const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
|
||||
const [activityToDelete, setActivityToDelete] = useState<string | null>(null);
|
||||
|
||||
const familyId = user?.families?.[0]?.familyId;
|
||||
|
||||
// Load children
|
||||
// Load children from Redux
|
||||
useEffect(() => {
|
||||
if (familyId) {
|
||||
loadChildren();
|
||||
if (familyId && children.length === 0) {
|
||||
dispatch(fetchChildren(familyId));
|
||||
}
|
||||
}, [familyId]);
|
||||
}, [familyId, dispatch, children.length]);
|
||||
|
||||
// Load recent activities when child is selected
|
||||
// Sync selectedChildIds with Redux selectedChild
|
||||
useEffect(() => {
|
||||
if (selectedChild) {
|
||||
loadRecentActivities();
|
||||
if (selectedChild?.id) {
|
||||
setSelectedChildIds([selectedChild.id]);
|
||||
}
|
||||
}, [selectedChild]);
|
||||
|
||||
const loadChildren = async () => {
|
||||
if (!familyId) return;
|
||||
|
||||
try {
|
||||
setChildrenLoading(true);
|
||||
const childrenData = await childrenApi.getChildren(familyId);
|
||||
setChildren(childrenData);
|
||||
if (childrenData.length > 0) {
|
||||
setSelectedChild(childrenData[0].id);
|
||||
}
|
||||
} catch (err: any) {
|
||||
console.error('Failed to load children:', err);
|
||||
setError(err.response?.data?.message || 'Failed to load children');
|
||||
} finally {
|
||||
setChildrenLoading(false);
|
||||
// Load recent activities when child is selected
|
||||
useEffect(() => {
|
||||
if (selectedChild?.id) {
|
||||
loadRecentActivities();
|
||||
}
|
||||
};
|
||||
}, [selectedChild?.id]);
|
||||
|
||||
const loadRecentActivities = async () => {
|
||||
if (!selectedChild) return;
|
||||
if (!selectedChild?.id) return;
|
||||
|
||||
try {
|
||||
setActivitiesLoading(true);
|
||||
const activities = await trackingApi.getActivities(selectedChild, 'activity');
|
||||
const activities = await trackingApi.getActivities(selectedChild.id, 'activity');
|
||||
// Sort by timestamp descending and take last 10
|
||||
const sorted = activities.sort((a, b) =>
|
||||
new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()
|
||||
@@ -133,7 +130,7 @@ function ActivityTrackPage() {
|
||||
};
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (!selectedChild) {
|
||||
if (!selectedChild?.id) {
|
||||
setError('Please select a child');
|
||||
return;
|
||||
}
|
||||
@@ -154,7 +151,7 @@ function ActivityTrackPage() {
|
||||
description: description || undefined,
|
||||
};
|
||||
|
||||
await trackingApi.createActivity(selectedChild, {
|
||||
await trackingApi.createActivity(selectedChild.id, {
|
||||
type: 'activity',
|
||||
timestamp: new Date().toISOString(),
|
||||
data,
|
||||
@@ -231,7 +228,9 @@ function ActivityTrackPage() {
|
||||
return details;
|
||||
};
|
||||
|
||||
if (childrenLoading) {
|
||||
const childrenLoading = useSelector((state: RootState) => state.children.loading);
|
||||
|
||||
if (childrenLoading && children.length === 0) {
|
||||
return (
|
||||
<ProtectedRoute>
|
||||
<AppShell>
|
||||
@@ -319,22 +318,21 @@ function ActivityTrackPage() {
|
||||
transition={{ duration: 0.3 }}
|
||||
>
|
||||
{/* Child Selector */}
|
||||
{children.length > 1 && (
|
||||
{children.length > 0 && (
|
||||
<Paper sx={{ p: 2, mb: 3 }}>
|
||||
<FormControl fullWidth>
|
||||
<InputLabel>{t('common.selectChild')}</InputLabel>
|
||||
<Select
|
||||
value={selectedChild}
|
||||
onChange={(e) => setSelectedChild(e.target.value)}
|
||||
label={t('common.selectChild')}
|
||||
>
|
||||
{children.map((child) => (
|
||||
<MenuItem key={child.id} value={child.id}>
|
||||
{child.name}
|
||||
</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
</FormControl>
|
||||
<ChildSelector
|
||||
children={children}
|
||||
selectedChildIds={selectedChildIds}
|
||||
onChange={(childIds) => {
|
||||
setSelectedChildIds(childIds);
|
||||
if (childIds.length > 0) {
|
||||
dispatch(selectChild(childIds[0]));
|
||||
}
|
||||
}}
|
||||
mode="single"
|
||||
label={t('common.selectChild')}
|
||||
required
|
||||
/>
|
||||
</Paper>
|
||||
)}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user