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,
};
};
|