All files / hooks useUserActivity.ts

92.5% Statements 37/40
85% Branches 17/20
100% Functions 7/7
91.89% Lines 34/37

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