fix(api): fix api endpoint logic #6

This commit is contained in:
Dacca Retro
2025-08-18 17:48:32 +06:00
parent 58d4d14a51
commit d74b81e962
5 changed files with 306 additions and 206 deletions

View File

@ -6,159 +6,70 @@ import { useEffect, useState } from "react";
import Header from "@/components/Header";
import DestructibleAlert from "@/components/DestructibleAlert";
import BackgroundWrapper from "@/components/BackgroundWrapper";
import { API_URL } from "@/lib/auth";
import { API_URL, getToken } from "@/lib/auth";
import { Loader, RefreshCw } from "lucide-react";
import { v4 as uuidv4 } from "uuid";
import { useAuth } from "@/context/AuthContext";
import { Question } from "@/types/exam";
interface Mock {
id: string;
title: string;
rating: number;
}
export default function PaperScreen() {
const router = useRouter();
const searchParams = useSearchParams();
const name = searchParams.get("name") || "";
const {user} = useAuth()
const [questions, setQuestions] = useState<Mock[] | null>(null);
const [errorMsg, setErrorMsg] = useState<string | null>(null);
const [refreshing, setRefreshing] = useState<boolean>(false);
const [componentKey, setComponentKey] = useState<number>(0);
interface Subject {
type Subject = {
subject_id: string;
name: string;
unit: string;
}
};
const [subjects, setSubjects] = useState<Subject[]>([
{
subject_id: uuidv4(),
name: "Biology",
unit: "Science"
},
{
subject_id: uuidv4(),
name: "Chemistry",
unit: "Science"
},
{
subject_id: uuidv4(),
name: "Physics",
unit: "Science"
},
{
subject_id: uuidv4(),
name: "Accounting",
unit: "Business"
},
{
subject_id: uuidv4(),
name: "Finance",
unit: "Business"
},
{
subject_id: uuidv4(),
name: "Marketing",
unit: "Business"
},
{
subject_id: uuidv4(),
name: "History",
unit: "Humanities"
},
{
subject_id: uuidv4(),
name: "Geography",
unit: "Humanities"
},
{
subject_id: uuidv4(),
name: "Sociology",
unit: "Humanities"
},
]);
export default function PaperScreen() {
const router = useRouter();
const searchParams = useSearchParams();
const { user } = useAuth();
const [subjects, setSubjects] = useState<Subject[]>([]);
const [errorMsg, setErrorMsg] = useState<string | null>(null);
const [refreshing, setRefreshing] = useState<boolean>(false);
async function fetchSubjects() {
setRefreshing(true);
try {
const token = await getToken();
const response = await fetch(`${API_URL}/subjects/`, {
method: "GET",
headers: {
Authorization: `Bearer ${token}`,
},
});
if (!response.ok) {
throw new Error("Failed to fetch subjects");
}
// async function fetchMocks() {
// try {
// const questionResponse = await fetch(`${API_URL}/mocks`, {
// method: "GET",
// });
// const fetchedQuestionData: Mock[] = await questionResponse.json();
// setQuestions(fetchedQuestionData);
// } catch (error) {
// setErrorMsg(error instanceof Error ? error.message : "An error occurred");
// }
// }
const fetchedSubjects: Subject[] = await response.json();
setSubjects(fetchedSubjects);
} catch (error) {
setErrorMsg(
"Error fetching subjects: " +
(error instanceof Error ? error.message : "Unknown error")
);
} finally {
setRefreshing(false);
}
}
// useEffect(() => {
// if (name) {
// fetchMocks();
// }
// }, [name]);
useEffect(() => {
const fetchData = async () => {
if (await getToken()) {
fetchSubjects();
}
};
fetchData();
}, []);
const onRefresh = async () => {
setRefreshing(true);
setSubjects([{
subject_id: uuidv4(),
name: "Biology",
unit: "Science"
},
{
subject_id: uuidv4(),
name: "Chemistry",
unit: "Science"
},
{
subject_id: uuidv4(),
name: "Physics",
unit: "Science"
},
{
subject_id: uuidv4(),
name: "Accounting",
unit: "Business Studies"
},
{
subject_id: uuidv4(),
name: "Finance",
unit: "Business Studies"
},
{
subject_id: uuidv4(),
name: "Marketing",
unit: "Business Studies"
},
{
subject_id: uuidv4(),
name: "History",
unit: "Humanities"
},
{
subject_id: uuidv4(),
name: "Geography",
unit: "Humanities"
},
{
subject_id: uuidv4(),
name: "Sociology",
unit: "Humanities"
}])
setComponentKey((prevKey) => prevKey + 1);
setTimeout(() => {
setRefreshing(false);
}, 1000);
fetchSubjects();
};
if (errorMsg) {
return (
<BackgroundWrapper>
<Header displayTabTitle={name} />
<Header displayTabTitle="Subjects" />
<div className="overflow-y-auto">
<div className="mt-5 px-5">
<DestructibleAlert text={errorMsg} extraStyles="" />
@ -182,32 +93,32 @@ const [subjects, setSubjects] = useState<Subject[]>([
<div>
<Header displayTabTitle="Subjects" />
<div className="mx-10 pt-10 overflow-y-auto">
<h1 className="text-2xl font-semibold mb-5">{user?.preparation_unit}</h1>
<h1 className="text-2xl font-semibold mb-5">
{user?.preparation_unit}
</h1>
<div className="border border-[#c0dafc] flex flex-col gap-4 w-full rounded-[25px] p-4 mb-20">
{subjects ? (
{subjects.length > 0 ? (
subjects
.filter(subject => subject.unit === user?.preparation_unit)
.map((subject) => (
<div key={subject.subject_id}>
<button
onClick={() =>
router.push(
`/exam/pretest?unitname=${name}&id=${subject.subject_id}&title=${subject.name}`
)
}
className="w-full border-2 border-[#B0C2DA] py-4 rounded-[10px] px-6 space-y-2 text-left hover:bg-gray-50 transition-colors"
>
<h3 className="text-xl font-medium">{subject.name}</h3>
<p className="text-md font-normal">
Rating: 8/10
</p>
</button>
</div>
))
.filter((subject) => subject.unit === user?.preparation_unit)
.map((subject) => (
<div key={subject.subject_id}>
<button
onClick={() =>
router.push(
`/exam/pretest?test_id=${subject.subject_id}`
)
}
className="w-full border-2 border-[#B0C2DA] py-4 rounded-[10px] px-6 space-y-2 text-left hover:bg-gray-50 transition-colors"
>
<h3 className="text-xl font-medium">{subject.name}</h3>
<p className="text-md font-normal">Rating: 8/10</p>
</button>
</div>
))
) : (
<div className="flex flex-col items-center justify-center">
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-500 mb-4"></div>
<p className="text-xl font-medium text-center">Loading...</p>
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-500 mb-4"></div>
<p className="text-xl font-medium text-center">Loading...</p>
</div>
)}
</div>

View File

@ -7,27 +7,17 @@ import DestructibleAlert from "@/components/DestructibleAlert";
import BackgroundWrapper from "@/components/BackgroundWrapper";
import { API_URL } from "@/lib/auth";
import { useExam } from "@/context/ExamContext";
import { Exam } from "@/types/exam";
interface Metadata {
metadata: {
quantity: number;
type: string;
duration: number;
marking: string;
};
}
import { Test } from "@/types/exam";
import { Metadata } from "@/types/exam";
function PretestPageContent() {
const router = useRouter();
const searchParams = useSearchParams();
const [examData, setExamData] = useState<Exam>();
const [examData, setExamData] = useState<Test>();
const { startExam, setCurrentExam } = useExam();
// Get params from URL search params
const id = searchParams.get("id") || "";
const title = searchParams.get("title") || "";
const rating = searchParams.get("rating") || "";
const [metadata, setMetadata] = useState<Metadata | null>(null);
const [loading, setLoading] = useState(true);
@ -67,7 +57,7 @@ function PretestPageContent() {
<BackgroundWrapper>
<div className="min-h-screen">
<div className="mx-10 mt-10">
<button onClick={() => router.push("/unit")} className="mb-4">
<button onClick={() => router.push("/subjects")} className="mb-4">
<ArrowLeft size={30} color="black" />
</button>
<DestructibleAlert text={error} extraStyles="" />
@ -77,6 +67,24 @@ function PretestPageContent() {
);
}
if (loading) {
return (
<BackgroundWrapper>
<div className="min-h-screen">
<div className="mx-10 pt-10">
<button onClick={() => router.push("/subjects")} className="mb-4">
<ArrowLeft size={30} color="black" />
</button>
<div className="flex flex-col items-center justify-center">
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-500 mb-4"></div>
<p className="text-lg font-medium text-gray-900">Loading...</p>
</div>
</div>
</div>
</BackgroundWrapper>
);
}
function handleStartExam() {
if (!examData) return;