Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | 1x 1x 1x 1x 1x 10x 10x 10x 10x 10x 5x 1x 1x 4x 4x 4x 4x 4x 3x 7x 3x 3x 1x 1x 2x 1x 2x 3x 3x 3x 1x 4x 4x 10x | import { useEffect, useState } from "react"; import { UserActivityLogItem } from "../types"; import { getUserActivity } from "../api/user"; import { calculateProgress, ProgressData } from "../utils/calculateProgress"; import { LogEvent } from "../api/types/event"; /** * Custom hook to fetch user activity logs and calculate progress data. * @param {string | null} userId - The ID of the user whose activity is to be fetched. * @param {string | null} selectedClassId - The ID of the selected class (optional). * @param {"all" | "class" | "non-class" | null} selectedClassType - The type of class filter (optional). * @returns {Object} - An object containing user activity logs, progress data, loading state, error message, and empty state. */ export const useUserActivity = ( userId?: string | null, selectedClassId: string | null = null, selectedClassType: "all" | "class" | "non-class" | null = "all" ) => { const [userActivity, setUserActivity] = useState<UserActivityLogItem[]>([]); const [progressData, setProgressData] = useState<ProgressData>({ totalAccepted: 0, correctSuggestions: 0, percentageCorrect: 0, }); const [loading, setLoading] = useState(true); const [error, setError] = useState<string | null>(null); useEffect(() => { if (!userId) { setLoading(false); return; } const fetchActivity = async () => { try { setError(null); const response = await getUserActivity(userId); if (response.error) throw new Error(response.error); let filteredActivities = response.data?.filter( (activity) => activity.event === LogEvent.USER_ACCEPT || activity.event === LogEvent.USER_REJECT ); Iif (!filteredActivities) { setUserActivity([]); setLoading(false); return; } if (selectedClassType === "non-class") { filteredActivities = filteredActivities.filter( (activity) => !activity.metadata.userClassId ); } else if (selectedClassType === "class" && selectedClassId) { filteredActivities = filteredActivities.filter( (activity) => activity.metadata.userClassId === selectedClassId ); } setUserActivity(filteredActivities); const progress = calculateProgress(filteredActivities); setProgressData(progress); } catch (err) { setError(err instanceof Error ? err.message : "Unknown error"); } finally { setLoading(false); } }; fetchActivity(); }, [userId, selectedClassId, selectedClassType]); return { userActivity, progressData, loading, error, isEmpty: !loading && userActivity.length === 0, }; }; |