Ignore:
Timestamp:
12/21/25 18:28:25 (9 months ago)
Author:
Stefan-Saveski <stefansaveski19@…>
Branches:
master
Children:
90f7842
Parents:
82c9c53
Message:

Refactor Exams component to fetch passed subjects from API and remove hardcoded data; delete unused JSON data files; implement authentication token management in auth.ts

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/app/students/semesters/page.tsx

    r82c9c53 rb67f274  
    1212  faTimesCircle
    1313} from '@fortawesome/free-solid-svg-icons';
    14 import semestersData from '@/data/semesters.json';
     14import { useEffect, useState } from 'react';
     15import { getAccessToken } from '@/lib/auth';
     16
     17type Semester = {
     18  id: number | string;
     19  semester: string;
     20  direction: string;
     21  quota: string;
     22  note: string;
     23  studentCom: string;
     24  sum: string;
     25  paid: string;
     26  ukim: string;
     27  createdOn: string;
     28  dateChanged: string;
     29  credits: string;
     30  type: string;
     31  doc: string;
     32  doc1: string;
     33  verified: string;
     34  taxes: string;
     35  signatures: string;
     36  status: string;
     37  completed: string;
     38};
     39
     40type SemestersResponse = {
     41  semesters: Semester[];
     42};
    1543
    1644interface TableCellProps {
     
    81109
    82110export default function SemestersPage() {
    83   const { semesters } = semestersData;
     111  const [semesters, setSemesters] = useState<Semester[]>([]);
     112  const [isLoading, setIsLoading] = useState(true);
     113  const [errorMessage, setErrorMessage] = useState<string | null>(null);
     114
     115  useEffect(() => {
     116    let cancelled = false;
     117
     118    async function load() {
     119      setIsLoading(true);
     120      setErrorMessage(null);
     121
     122      const token = getAccessToken();
     123      if (!token) {
     124        setErrorMessage('Not authenticated. Please login again.');
     125        setIsLoading(false);
     126        return;
     127      }
     128
     129      try {
     130        const response = await fetch('http://localhost:5147/api/user/getSemesters', {
     131          method: 'GET',
     132          headers: {
     133            Authorization: `Bearer ${token}`,
     134          },
     135        });
     136
     137        if (!response.ok) {
     138          const text = await response.text().catch(() => '');
     139          throw new Error(text || `Failed to load semesters (${response.status})`);
     140        }
     141
     142        const data = (await response.json()) as SemestersResponse;
     143        if (!cancelled) setSemesters(Array.isArray(data?.semesters) ? data.semesters : []);
     144      } catch (err) {
     145        if (!cancelled) {
     146          setErrorMessage(err instanceof Error ? err.message : 'Failed to load semesters.');
     147        }
     148      } finally {
     149        if (!cancelled) setIsLoading(false);
     150      }
     151    }
     152
     153    void load();
     154
     155    return () => {
     156      cancelled = true;
     157    };
     158  }, []);
     159
     160  if (isLoading) {
     161    return (
     162      <div className="min-h-screen pb-8">
     163        <div className="bg-white rounded-xl shadow-sm border border-gray-100 p-6">
     164          Loading...
     165        </div>
     166      </div>
     167    );
     168  }
     169
     170  if (errorMessage) {
     171    return (
     172      <div className="min-h-screen pb-8">
     173        <div className="rounded-lg border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-700">
     174          {errorMessage}
     175        </div>
     176      </div>
     177    );
     178  }
    84179
    85180  return (
Note: See TracChangeset for help on using the changeset viewer.