feat(targeted): add targeted practice functionality

feat(analytics); add analytics page
This commit is contained in:
shafin-r
2026-02-05 15:07:24 +06:00
parent 2ac88835f9
commit 903653a212
20 changed files with 2018 additions and 35 deletions

View File

@ -1,5 +1,5 @@
import { useEffect, useState } from "react";
import { useNavigate, useParams } from "react-router-dom";
import { useNavigate } from "react-router-dom";
import {
Card,
CardContent,
@ -10,7 +10,7 @@ import { Check, Loader2 } from "lucide-react";
import { api } from "../../../utils/api";
import { useAuthStore } from "../../../stores/authStore";
import type { PracticeSheet, Question } from "../../../types/sheet";
import type { Question } from "../../../types/sheet";
import { Button } from "../../../components/ui/button";
import { useSatExam } from "../../../stores/useSatExam";
import { useSatTimer } from "../../../hooks/useSatTimer";
@ -38,8 +38,10 @@ import {
DialogTrigger,
} from "../../../components/ui/dialog";
import { useExamNavigationGuard } from "../../../hooks/useExamNavGuard";
import { useExamConfigStore } from "../../../stores/useExamConfigStore";
export const Test = () => {
const sheetId = localStorage.getItem("activePracticeSheetId");
const blocker = useExamNavigationGuard();
const [eliminated, setEliminated] = useState<Record<string, Set<string>>>({});
@ -54,15 +56,11 @@ export const Test = () => {
const navigate = useNavigate();
const { user } = useAuthStore();
const token = useAuthToken();
const [practiceSheet, setPracticeSheet] = useState<PracticeSheet | null>(
null,
);
const [answers, setAnswers] = useState<Record<string, string>>({});
const [showNavigator, setShowNavigator] = useState<boolean>(false);
const [isSubmitting, setIsSubmitting] = useState(false);
const [sessionId, setSessionId] = useState<string | null>(null);
const { sheetId } = useParams<{ sheetId: string }>();
const time = useSatTimer();
const phase = useSatExam((s) => s.phase);
@ -84,15 +82,10 @@ export const Test = () => {
const startExam = async () => {
if (!user || !sheetId) return;
const payload = useExamConfigStore.getState().payload;
try {
const response = await api.startSession(token as string, {
sheet_id: sheetId,
mode: "MODULE",
topic_ids: practiceSheet?.topics.map((t) => t.id) ?? [],
difficulty: practiceSheet?.difficulty ?? "EASY",
question_count: 2,
time_limit_minutes: practiceSheet?.time_limit ?? 0,
});
const response = await api.startSession(token as string, payload);
setSessionId(response.id);
@ -185,6 +178,7 @@ export const Test = () => {
const next = await api.fetchNextModule(token!, sessionId);
if (next?.status === "COMPLETED") {
useExamConfigStore.getState().clearPayload();
finishExam();
} else {
await loadSessionQuestions(sessionId);