Index: backend/auth_form/serializers.py
===================================================================
--- backend/auth_form/serializers.py	(revision 3e206657f4d5094291f22881a8bf23022a353507)
+++ backend/auth_form/serializers.py	(revision 9c27e0b361bceb78421216a39a5504df930db6fd)
@@ -84,9 +84,8 @@
     def to_representation(self, instance):
         rep = super().to_representation(instance)
-        rep['passed_subjects'] = SubjectSerializer(instance.passed_subjects.all(), many=True).data
+        rep['passed_subjects'] = [subject.id for subject in instance.passed_subjects.all()]
+        all_subject_ids = [subj_id for subjects in (instance.passed_subjects_per_semester or {}).values() for subj_id in subjects]
         rep['passed_subjects_per_semester'] = {
-            str(sem): SubjectSerializer(
-                Subject.objects.filter(id__in=subjects), many=True
-            ).data
+            str(sem): [ subj_id for subj_id in subjects]
             for sem, subjects in (instance.passed_subjects_per_semester or {}).items()
         }
Index: backend/subjects/utils.py
===================================================================
--- backend/subjects/utils.py	(revision 3e206657f4d5094291f22881a8bf23022a353507)
+++ backend/subjects/utils.py	(revision 9c27e0b361bceb78421216a39a5504df930db6fd)
@@ -112,5 +112,5 @@
         words = vocabulary[key]
         for word in words:
-            student_vector[key].append(0 if word not in student_values else 1)
+            student_vector[key].append(1 if word in student_values else 0)
 
     student_vector['study_effort'] = student.study_effort / 5
@@ -208,8 +208,8 @@
         - all other preference scores are calculated as the ratio of matching 1's between student and subject vectors.
     """
-    filtered_subjects_vector = {}
+    subjects_tag_scores = {}
     max_tag_score = 0
     for subject in eligible_subjects:
-        filtered_subjects_vector[subject] = {}
+        subjects_tag_scores[subject] = {}
         subject_vector = eligible_subjects[subject]
         for key in student_vector:
@@ -217,5 +217,5 @@
             if key == "tags":
                 tag_score = score_tags(student_vector, subject_vector)
-                filtered_subjects_vector[subject][key] = tag_score
+                subjects_tag_scores[subject][key] = tag_score
                 max_tag_score = max(tag_score, max_tag_score)
                 continue
@@ -233,24 +233,24 @@
             
             score = match_count / tot_count if tot_count != 0 else 0
-            filtered_subjects_vector[subject][key] = score
+            subjects_tag_scores[subject][key] = score
         
         study_effort = student_vector["study_effort"]
         
         if (study_effort == 0.4 and subject_vector['isEasy']) or (study_effort == 0.8 and not subject_vector['isEasy']):
-            filtered_subjects_vector[subject]['effort'] = 1
+            subjects_tag_scores[subject]['effort'] = 1
         else:
-            filtered_subjects_vector[subject]['effort'] = 0
+            subjects_tag_scores[subject]['effort'] = 0
             
-        filtered_subjects_vector[subject]['activated'] = subject_vector['activated']
-
-        filtered_subjects_vector[subject]['participant_score'] = subject_vector['participants']
+        subjects_tag_scores[subject]['activated'] = subject_vector['activated']
+
+        subjects_tag_scores[subject]['participant_score'] = subject_vector['participants']
     
     if max_tag_score != 0:
         for subject in eligible_subjects:
-            filtered_subjects_vector[subject]['tags'] /= max_tag_score 
-
-    return filtered_subjects_vector
-
-def get_recommendations(filtered_subjects_vector):
+            subjects_tag_scores[subject]['tags'] /= max_tag_score 
+
+    return subjects_tag_scores
+
+def get_recommendations(subjects_tag_scores):
     """
     generates a list of recommended subjects based on weighted scores.
@@ -263,6 +263,6 @@
     """
     subject_scores = {}
-    for subject in filtered_subjects_vector:
-        keys = filtered_subjects_vector[subject]
+    for subject in subjects_tag_scores:
+        keys = subjects_tag_scores[subject]
         score = 0
         for key in keys:
Index: frontend/src/App.tsx
===================================================================
--- frontend/src/App.tsx	(revision 3e206657f4d5094291f22881a8bf23022a353507)
+++ frontend/src/App.tsx	(revision 9c27e0b361bceb78421216a39a5504df930db6fd)
@@ -1,5 +1,7 @@
+import { useEffect } from "react";
 import { createBrowserRouter, Outlet, RouterProvider } from "react-router-dom";
 import { ToastContainer } from "react-toastify";
 import "react-toastify/dist/ReactToastify.css";
+import { fetchUser } from "./api/user";
 import Footer from "./components/Footer";
 import Navbar from "./components/Navbar";
@@ -7,4 +9,5 @@
 import CourseCatalog from "./components/SubjectCatalog/SubjectCatalog";
 import { AuthProvider } from "./context/AuthProvider";
+import { useAuth } from "./hooks/useAuth";
 import "./index.css";
 import Account from "./pages/Account";
@@ -85,4 +88,12 @@
 
 function App() {
+	const { setUser } = useAuth();
+	// TODO
+	useEffect(() => {
+		const token = localStorage.getItem("access");
+		if (token) {
+			fetchUser(token, setUser);
+		}
+	}, []);
 	return (
 		<AuthProvider>
Index: frontend/src/api/preferences.ts
===================================================================
--- frontend/src/api/preferences.ts	(revision 9c27e0b361bceb78421216a39a5504df930db6fd)
+++ frontend/src/api/preferences.ts	(revision 9c27e0b361bceb78421216a39a5504df930db6fd)
@@ -0,0 +1,44 @@
+import { Dispatch, SetStateAction } from "react";
+import axiosInstance from "../api/axiosInstance";
+
+interface FetchPreferencesProps {
+	setIsLoaded?: Dispatch<SetStateAction<boolean>>;
+	setIsLoading?: Dispatch<SetStateAction<boolean>>;
+	setDislikedIds: Dispatch<SetStateAction<Set<number> | undefined>>;
+	setFavoriteIds: Dispatch<SetStateAction<Set<number> | undefined>>;
+	setLikedIds: Dispatch<SetStateAction<Set<number> | undefined>>;
+}
+
+export const fetchPreferences = async ({
+	setIsLoading,
+	setDislikedIds,
+	setFavoriteIds,
+	setLikedIds,
+	setIsLoaded,
+}: FetchPreferencesProps) => {
+	const accessToken = localStorage.getItem("access");
+	if (accessToken) {
+		axiosInstance
+			.get<{
+				favorite_ids: number[];
+				liked_ids: number[];
+				disliked_ids: number[];
+			}>("/student/preferences/")
+			.then((response) => {
+				setFavoriteIds(new Set(response.data.favorite_ids || []));
+				setLikedIds(new Set(response.data.liked_ids || []));
+				setDislikedIds(new Set(response.data.disliked_ids || []));
+			})
+			.catch((error) => console.error("Failed to fetch preferences:", error))
+			.finally(() => {
+				setIsLoaded && setIsLoaded(true);
+				setIsLoading && setIsLoading(false);
+			});
+	} else {
+		setFavoriteIds(new Set());
+		setLikedIds(new Set());
+		setDislikedIds(new Set());
+		setIsLoaded && setIsLoaded(true);
+		setIsLoading && setIsLoading(false);
+	}
+};
Index: frontend/src/api/subjects.ts
===================================================================
--- frontend/src/api/subjects.ts	(revision 9c27e0b361bceb78421216a39a5504df930db6fd)
+++ frontend/src/api/subjects.ts	(revision 9c27e0b361bceb78421216a39a5504df930db6fd)
@@ -0,0 +1,18 @@
+import { Dispatch, SetStateAction } from "react";
+import { Subject } from "../components/types";
+
+interface fetchSubjectsProps {
+	setSubjects: Dispatch<SetStateAction<Subject[]>>;
+}
+
+export const fetchSubjects = async ({ setSubjects }: fetchSubjectsProps) => {
+	try {
+		const resSubjects = await fetch("http://localhost:8000/subjects/");
+		if (resSubjects.ok) {
+			const subJson: Subject[] = await resSubjects.json();
+			setSubjects(subJson || []);
+		}
+	} catch (error) {
+		console.error("Error fetching subjects:", error);
+	}
+};
Index: frontend/src/api/user.ts
===================================================================
--- frontend/src/api/user.ts	(revision 9c27e0b361bceb78421216a39a5504df930db6fd)
+++ frontend/src/api/user.ts	(revision 9c27e0b361bceb78421216a39a5504df930db6fd)
@@ -0,0 +1,17 @@
+import { Dispatch, SetStateAction } from "react";
+import { User } from "../context/AuthContext";
+import axiosInstance from "./axiosInstance";
+
+export const fetchUser = async (
+	token: string,
+	setUser: Dispatch<SetStateAction<User | null>>
+) => {
+	try {
+		const response = await axiosInstance.get<User>("/auth/user/", {
+			headers: { Authorization: `Bearer ${token}` },
+		});
+		setUser(response.data);
+	} catch (error) {
+		console.error("Could not fetch user data on load", error);
+	}
+};
Index: frontend/src/components/Navbar.tsx
===================================================================
--- frontend/src/components/Navbar.tsx	(revision 3e206657f4d5094291f22881a8bf23022a353507)
+++ frontend/src/components/Navbar.tsx	(revision 9c27e0b361bceb78421216a39a5504df930db6fd)
@@ -1,7 +1,7 @@
-import axios from "axios";
 import { useEffect, useRef, useState } from "react";
 import { Link, useNavigate } from "react-router-dom";
 import { toast } from "react-toastify";
 import IOimage from "../assets/IOLogo.png";
+import { usePreferences } from "../context/PreferencesContext";
 import { useRecommendations } from "../context/RecommendationsContext";
 import { useAuth } from "../hooks/useAuth";
@@ -12,4 +12,5 @@
 	const [, setRecommendations] = useRecommendations();
 	const { isAuthenticated, logout, login, user } = useAuth();
+	const { setFavoriteIds, setLikedIds, setDislikedIds } = usePreferences();
 	const navigate = useNavigate();
 	const profileMenuRef = useRef<HTMLDivElement>(null);
@@ -34,25 +35,28 @@
 		logout();
 		setRecommendations([]);
+		setFavoriteIds(new Set());
+		setLikedIds(new Set());
+		setDislikedIds(new Set());
 		navigate("/");
 		toast.success("Успешно сте одјавени!");
 	};
 
-	const testAccountLogin = async () => {
-		if (isAuthenticated) return;
-		try {
-			const response = await axios.post("http://localhost:8000/auth/login/", {
-				email: "fffff@finki.ukim.mk",
-				password: "testTestTEST123",
-			});
-			const { access, refresh, full_name, user_type } = response.data;
-			login(access, refresh, {
-				full_name,
-				user_type,
-			});
-			navigate("/");
-		} catch (err: unknown) {
-			console.log(err);
-		}
-	};
+	// const testAccountLogin = async () => {
+	// 	if (isAuthenticated) return;
+	// 	try {
+	// 		const response = await axios.post("http://localhost:8000/auth/login/", {
+	// 			email: "fffff@finki.ukim.mk",
+	// 			password: "testTestTEST123",
+	// 		});
+	// 		const { access, refresh, full_name, user_type } = response.data;
+	// 		login(access, refresh, {
+	// 			full_name,
+	// 			user_type,
+	// 		});
+	// 		navigate("/");
+	// 	} catch (err: unknown) {
+	// 		console.log(err);
+	// 	}
+	// };
 
 	return (
@@ -98,7 +102,7 @@
 				{/* Desktop Menu */}
 				<div className="hidden sm:flex space-x-4 items-center text-sm sm:text-base">
-					<button onClick={testAccountLogin}>quick login</button>
+					{/* <button onClick={testAccountLogin}>quick login</button> */}
 					<Link to="/subjects" className="hover:underline">
-						Предмети
+						Сите предмети
 					</Link>
 					{isAuthenticated ? (
Index: frontend/src/components/StudentForm/StudentForm.tsx
===================================================================
--- frontend/src/components/StudentForm/StudentForm.tsx	(revision 3e206657f4d5094291f22881a8bf23022a353507)
+++ frontend/src/components/StudentForm/StudentForm.tsx	(revision 9c27e0b361bceb78421216a39a5504df930db6fd)
@@ -1,3 +1,7 @@
+import { isAxiosError } from "axios";
 import { useCallback, useEffect, useState } from "react";
+import { toast } from "react-toastify";
+import axiosInstance from "../../api/axiosInstance";
+import { fetchSubjects } from "../../api/subjects";
 import {
 	EVALUATIONS,
@@ -18,8 +22,7 @@
 	LatinToCyrillic,
 	mapToID,
+	mapToSubjects,
 	validateForm,
 } from "./utils";
-import axiosInstance from "../../api/axiosInstance";
-import { isAxiosError } from 'axios';
 
 interface StudentFormProps {
@@ -35,35 +38,35 @@
 }
 
-
 const parseBackendError = (error: unknown): string => {
-  if (isAxiosError(error) && error.response) {
-    const data = error.response.data;
-
-    if (data && data.detail) {
-      return data.detail;
-    }
-
-    if (data && data.message) {
-      return data.message;
-    }
-
-    if (data && typeof data === 'object' && Object.keys(data).length > 0) {
-      const firstErrorField = Object.keys(data)[0];
-      const errorMessages = data[firstErrorField];
-
-      if (Array.isArray(errorMessages) && errorMessages.length > 0) {
-        return errorMessages[0];
-      }
-    }
-  }
-
-  if (error instanceof Error) {
-    return error.message;
-  }
-
-  return 'An unknown error occurred. Please try again.';
+	if (isAxiosError(error) && error.response) {
+		const data = error.response.data;
+
+		if (data && data.detail) {
+			return data.detail;
+		}
+
+		if (data && data.message) {
+			return data.message;
+		}
+
+		if (data && typeof data === "object" && Object.keys(data).length > 0) {
+			const firstErrorField = Object.keys(data)[0];
+			const errorMessages = data[firstErrorField];
+
+			if (Array.isArray(errorMessages) && errorMessages.length > 0) {
+				return errorMessages[0];
+			}
+		}
+	}
+
+	if (error instanceof Error) {
+		return error.message;
+	}
+
+	return "An unknown error occurred. Please try again.";
 };
 
 const StudentForm = ({ formData, isLoading }: StudentFormProps) => {
+	const [subjects] = useSubjects();
 	const [hasSubmitted, setHasSubmitted] = useState(false);
 	const [validationErrors, setValidationErrors] = useState<{
@@ -78,5 +81,6 @@
 		Record<number, Subject[]>
 	>(
-		formData?.passed_subjects_per_semester ??
+		(formData?.passed_subjects_per_semester &&
+			mapToSubjects(formData.passed_subjects_per_semester, subjects || [])) ||
 			Object.fromEntries(Array.from({ length: 8 }, (_, i) => [[i + 1], []]))
 	);
@@ -117,5 +121,5 @@
 	const [showProfessors, setShowProfessors] = useState(false);
 	const [showAssistants, setShowAssistants] = useState(false);
-	const [subjects] = useSubjects();
+	const [, setSubjects] = useSubjects();
 	const [distinctSubjectData, setDistinctSubjectData] =
 		useState<DistinctSubjectData>({
@@ -133,4 +137,26 @@
 	// Update form when formData changes (e.g., after fetching user data)
 	useEffect(() => {
+		if (!subjects || subjects.length === 0) {
+			fetchSubjects({ setSubjects });
+		}
+		const fetchFormData = async (token: string) => {
+			try {
+				const response = await axiosInstance.get<StudentData>("/auth/form/", {
+					headers: { Authorization: `Bearer ${token}` },
+				});
+				setFormData(response.data);
+			} catch (error) {
+				console.error("Could not fetch user form data", error);
+				if ((error as any).response?.status !== 401) {
+					toast.error("Could not load form data.");
+				}
+			}
+		};
+		const token = localStorage.getItem("access");
+		if (token) {
+			fetchFormData(token);
+		}
+	}, []);
+	useEffect(() => {
 		if (formData) {
 			setIndex(formData.index || "");
@@ -170,6 +196,19 @@
 			setFavoriteAssistants(favoriteAssistants_);
 
-			setPassedSubjectsPerSemester(formData.passed_subjects_per_semester || []);
-
+			if (
+				formData.passed_subjects_per_semester &&
+				subjects &&
+				subjects.length > 0
+			) {
+				const mappedSubjects = mapToSubjects(
+					formData.passed_subjects_per_semester,
+					subjects
+				);
+				setPassedSubjectsPerSemester(mappedSubjects);
+			} else {
+				setPassedSubjectsPerSemester(
+					Object.fromEntries(Array.from({ length: 8 }, (_, i) => [[i + 1], []]))
+				);
+			}
 			setHasExtracurricular(formData.has_extracurricular || false);
 		}
Index: frontend/src/components/StudentForm/utils.ts
===================================================================
--- frontend/src/components/StudentForm/utils.ts	(revision 3e206657f4d5094291f22881a8bf23022a353507)
+++ frontend/src/components/StudentForm/utils.ts	(revision 9c27e0b361bceb78421216a39a5504df930db6fd)
@@ -125,4 +125,25 @@
 };
 
+export const mapToSubjects = (
+	passedSubjects: Record<string, number[]> | Record<number, Subject[]>,
+	subjects: Subject[]
+) => {
+	const mapped = Object.fromEntries(
+		Object.entries(passedSubjects).map(([semester, subjectIDs]) => [
+			semester,
+			subjectIDs
+				.map((id: SubjectID) => subjects.find((s) => s.id === id))
+				.filter(Boolean),
+		])
+	);
+	const normalized: Record<number, Subject[]> = Object.fromEntries(
+		Object.entries(mapped).map(([k, arr]) => [
+			Number(k),
+			(arr as (Subject | undefined)[]).filter((s): s is Subject => !!s),
+		])
+	);
+	return normalized || {};
+};
+
 export const getPassedSubjects = (
 	passedSubjects: Record<number, Subject[]>
Index: frontend/src/components/SubjectCatalog/FavoriteButton.tsx
===================================================================
--- frontend/src/components/SubjectCatalog/FavoriteButton.tsx	(revision 3e206657f4d5094291f22881a8bf23022a353507)
+++ frontend/src/components/SubjectCatalog/FavoriteButton.tsx	(revision 9c27e0b361bceb78421216a39a5504df930db6fd)
@@ -21,10 +21,11 @@
 interface FavoriteButtonProps {
 	subjectId: number;
+	isLoading?: boolean;
 }
 
-const FavoriteButton = ({ subjectId }: FavoriteButtonProps) => {
-	const { favoriteIds, toggleFavorite, isLoading } = usePreferences();
+const FavoriteButton = ({ subjectId, isLoading }: FavoriteButtonProps) => {
+	const { favoriteIds, toggleFavorite } = usePreferences();
 	const { isAuthenticated } = useAuth();
-	const isFavorite = favoriteIds.has(subjectId);
+	const isFavorite = favoriteIds?.has(subjectId) || false;
 	const isFilled = isAuthenticated && isFavorite;
 	return (
@@ -32,5 +33,5 @@
 			onClick={() => toggleFavorite(subjectId)}
 			disabled={isLoading || !isAuthenticated}
-			className={`group relative flex items-center justify-center transition-all duration-200 p-2 rounded-full 
+			className={`relative flex items-center justify-center transition-all duration-200 p-2 rounded-full 
 				${!isAuthenticated ? "cursor-not-allowed" : ""}
 				${isFavorite ? "text-red-500" : "text-gray-400"}
Index: frontend/src/components/SubjectCatalog/SubjectCard.tsx
===================================================================
--- frontend/src/components/SubjectCatalog/SubjectCard.tsx	(revision 3e206657f4d5094291f22881a8bf23022a353507)
+++ frontend/src/components/SubjectCatalog/SubjectCard.tsx	(revision 9c27e0b361bceb78421216a39a5504df930db6fd)
@@ -11,4 +11,5 @@
 	isFirst?: boolean;
 	isRecommended?: boolean;
+	isLoading?: boolean;
 }
 
@@ -20,4 +21,5 @@
 	isFirst = false,
 	isRecommended = false,
+	isLoading = false,
 }: SubjectCardProps) => {
 	return (
@@ -52,5 +54,5 @@
 							<img src="src/assets/eye.svg" className="w-5 h-5" />
 						</button>
-						<FavoriteButton subjectId={subject.id} />
+						<FavoriteButton subjectId={subject.id} isLoading={isLoading} />
 						{canReview && (
 							<>
Index: frontend/src/components/SubjectCatalog/SubjectCatalog.tsx
===================================================================
--- frontend/src/components/SubjectCatalog/SubjectCatalog.tsx	(revision 3e206657f4d5094291f22881a8bf23022a353507)
+++ frontend/src/components/SubjectCatalog/SubjectCatalog.tsx	(revision 9c27e0b361bceb78421216a39a5504df930db6fd)
@@ -1,4 +1,8 @@
 import { useEffect, useMemo, useState } from "react";
+import { fetchPreferences } from "../../api/preferences";
+import { fetchSubjects } from "../../api/subjects";
+import { usePreferences } from "../../context/PreferencesContext";
 import { useSubjects } from "../../context/SubjectsContext";
+import { useAuth } from "../../hooks/useAuth";
 import { Filters, Subject } from "../types";
 import FilterSidebar from "./FilterSidebar";
@@ -14,5 +18,6 @@
 } from "./utils";
 const SubjectCatalog = () => {
-	const [subjects] = useSubjects();
+	const { accessToken } = useAuth();
+	const [subjects, setSubjects] = useSubjects();
 	const [visibleCourses, setVisibleCourses] = useState<number>(12);
 	const [searchTerm, setSearchTerm] = useState<string>("");
@@ -44,4 +49,13 @@
 		subjects,
 	});
+	const { setDislikedIds, setLikedIds, setFavoriteIds } = usePreferences();
+
+	useEffect(() => {
+		fetchPreferences({
+			setDislikedIds,
+			setFavoriteIds,
+			setLikedIds,
+		});
+	}, [accessToken]);
 
 	useEffect(() => {
@@ -76,4 +90,10 @@
 		setShowModal(true);
 	};
+
+	useEffect(() => {
+		if (!subjects || subjects.length === 0) {
+			fetchSubjects({ setSubjects });
+		}
+	}, []);
 
 	const closeModal = () => {
Index: frontend/src/components/types.ts
===================================================================
--- frontend/src/components/types.ts	(revision 3e206657f4d5094291f22881a8bf23022a353507)
+++ frontend/src/components/types.ts	(revision 9c27e0b361bceb78421216a39a5504df930db6fd)
@@ -25,5 +25,5 @@
 	has_filled_form: boolean;
 	has_extracurricular: boolean;
-	passed_subjects_per_semester: Record<number, Subject[] | []>;
+	passed_subjects_per_semester: Record<string, number[]> | [];
 }
 
Index: frontend/src/context/AuthContext.tsx
===================================================================
--- frontend/src/context/AuthContext.tsx	(revision 3e206657f4d5094291f22881a8bf23022a353507)
+++ frontend/src/context/AuthContext.tsx	(revision 9c27e0b361bceb78421216a39a5504df930db6fd)
@@ -1,3 +1,3 @@
-import { createContext } from "react";
+import { createContext, Dispatch, SetStateAction } from "react";
 import { StudentData } from "../components/types";
 
@@ -17,4 +17,5 @@
 	sessionInitialized: boolean;
 	initializeUser: () => Promise<void>;
+	setUser: Dispatch<SetStateAction<User | null>>;
 }
 
Index: frontend/src/context/AuthProvider.tsx
===================================================================
--- frontend/src/context/AuthProvider.tsx	(revision 3e206657f4d5094291f22881a8bf23022a353507)
+++ frontend/src/context/AuthProvider.tsx	(revision 9c27e0b361bceb78421216a39a5504df930db6fd)
@@ -1,16 +1,16 @@
+import { AxiosError, AxiosRequestConfig } from "axios";
+import { jwtDecode } from "jwt-decode";
 import React, {
+	ReactNode,
+	useCallback,
+	useEffect,
 	useRef,
 	useState,
-	useEffect,
-	ReactNode,
-	useCallback,
 } from "react";
+import { toast } from "react-toastify";
 import axiosInstance from "../api/axiosInstance";
-import { jwtDecode } from "jwt-decode";
-import { toast } from "react-toastify";
-import { User } from "./AuthContext";
+import { fetchUser } from "../api/user";
 import { StudentData } from "../components/types";
-import AuthContext, { AuthContextType } from "./AuthContext";
-import { AxiosError, AxiosRequestConfig, isAxiosError } from "axios";
+import AuthContext, { AuthContextType, User } from "../context/AuthContext";
 
 interface DecodedToken {
@@ -192,29 +192,4 @@
 	}, [logout, scheduleProactiveRefresh]);
 
-	const fetchUser = useCallback(async (token: string) => {
-		try {
-			const response = await axiosInstance.get<User>("/auth/user/", {
-				headers: { Authorization: `Bearer ${token}` },
-			});
-			setUser(response.data);
-		} catch (error) {
-			console.error("Could not fetch user data", error);
-		}
-	}, []);
-
-	const fetchFormData = useCallback(async (token: string) => {
-		try {
-			const response = await axiosInstance.get<StudentData>("/auth/form/", {
-				headers: { Authorization: `Bearer ${token}` },
-			});
-			setFormData(response.data);
-		} catch (error) {
-			console.error("Could not fetch user form data", error);
-			if (isAxiosError(error) && error.response?.status !== 401) {
-				toast.error("Could not load form data.");
-			}
-		}
-	}, []);
-
 	const login = useCallback(
 		async (newAccessToken: string, newRefreshToken: string, userData: User) => {
@@ -224,8 +199,6 @@
 			setUser(userData);
 			scheduleProactiveRefresh(newAccessToken);
-			await fetchFormData(newAccessToken);
-			setSessionInitialized(true);
 		},
-		[fetchFormData, scheduleProactiveRefresh]
+		[scheduleProactiveRefresh]
 	);
 
@@ -234,8 +207,8 @@
 		if (token) {
 			scheduleProactiveRefresh(token);
-			await Promise.all([fetchUser(token), fetchFormData(token)]);
+			await fetchUser(token, setUser);
 		}
 		setSessionInitialized(true);
-	}, [fetchUser, fetchFormData, scheduleProactiveRefresh]);
+	}, [fetchUser, scheduleProactiveRefresh]);
 
 	useEffect(() => {
@@ -258,4 +231,5 @@
 		sessionInitialized,
 		initializeUser,
+		setUser,
 	};
 
Index: frontend/src/context/PreferencesContext.tsx
===================================================================
--- frontend/src/context/PreferencesContext.tsx	(revision 3e206657f4d5094291f22881a8bf23022a353507)
+++ frontend/src/context/PreferencesContext.tsx	(revision 9c27e0b361bceb78421216a39a5504df930db6fd)
@@ -4,18 +4,18 @@
 	useCallback,
 	useContext,
-	useEffect,
 	useState,
 } from "react";
 import { toast } from "react-toastify";
-import { useAuth } from "../hooks/useAuth";
 import axiosInstance from "../api/axiosInstance";
 interface PreferencesContextType {
-	favoriteIds: Set<number>;
-	likedIds: Set<number>;
-	dislikedIds: Set<number>;
+	favoriteIds: Set<number> | undefined;
+	setFavoriteIds: React.Dispatch<React.SetStateAction<Set<number> | undefined>>;
+	likedIds: Set<number> | undefined;
+	setLikedIds: React.Dispatch<React.SetStateAction<Set<number> | undefined>>;
+	dislikedIds: Set<number> | undefined;
+	setDislikedIds: React.Dispatch<React.SetStateAction<Set<number> | undefined>>;
 	toggleFavorite: (subjectId: number) => Promise<void>;
 	toggleLike: (subjectId: number) => Promise<void>;
 	toggleDislike: (subjectId: number) => Promise<void>;
-	isLoading: boolean;
 }
 
@@ -25,34 +25,11 @@
 
 export const PreferencesProvider = ({ children }: { children: ReactNode }) => {
-	const { accessToken } = useAuth();
-	const [isLoading, setIsLoading] = useState(true);
-	const [favoriteIds, setFavoriteIds] = useState<Set<number>>(new Set());
-	const [likedIds, setLikedIds] = useState<Set<number>>(new Set());
-	const [dislikedIds, setDislikedIds] = useState<Set<number>>(new Set());
-
-	useEffect(() => {
-		if (accessToken) {
-			setIsLoading(true);
-			axiosInstance
-				.get<{
-					favorite_ids: number[];
-					liked_ids: number[];
-					disliked_ids: number[];
-				}>("/student/preferences/")
-				.then((response) => {
-					setFavoriteIds(new Set(response.data.favorite_ids || []));
-					setLikedIds(new Set(response.data.liked_ids || []));
-					setDislikedIds(new Set(response.data.disliked_ids || []));
-				})
-				.catch((error) => console.error("Failed to fetch preferences:", error))
-				.finally(() => setIsLoading(false));
-		} else {
-			// If user logs out, clear preferences
-			setFavoriteIds(new Set());
-			setLikedIds(new Set());
-			setDislikedIds(new Set());
-			setIsLoading(false);
-		}
-	}, [accessToken]);
+	const [favoriteIds, setFavoriteIds] = useState<Set<number> | undefined>(
+		undefined
+	);
+	const [likedIds, setLikedIds] = useState<Set<number> | undefined>(undefined);
+	const [dislikedIds, setDislikedIds] = useState<Set<number> | undefined>(
+		undefined
+	);
 
 	const toggleFavorite = useCallback(
@@ -86,5 +63,5 @@
 	const toggleLike = useCallback(
 		async (subjectId: number) => {
-			const wasDisliked = dislikedIds.has(subjectId);
+			const wasDisliked = dislikedIds?.has(subjectId);
 			if (wasDisliked) {
 				const newDisliked = new Set(dislikedIds);
@@ -125,5 +102,5 @@
 	const toggleDislike = useCallback(
 		async (subjectId: number) => {
-			const wasLiked = likedIds.has(subjectId);
+			const wasLiked = likedIds?.has(subjectId);
 			if (wasLiked) {
 				const newLiked = new Set(likedIds);
@@ -164,10 +141,12 @@
 	const value = {
 		favoriteIds,
+		setFavoriteIds,
 		likedIds,
+		setLikedIds,
 		dislikedIds,
+		setDislikedIds,
 		toggleFavorite,
 		toggleLike,
 		toggleDislike,
-		isLoading,
 	};
 
Index: frontend/src/context/SubjectsContext.tsx
===================================================================
--- frontend/src/context/SubjectsContext.tsx	(revision 3e206657f4d5094291f22881a8bf23022a353507)
+++ frontend/src/context/SubjectsContext.tsx	(revision 9c27e0b361bceb78421216a39a5504df930db6fd)
@@ -6,5 +6,4 @@
 	useContext,
 	useState,
-	useEffect,
 } from "react";
 import { Subject } from "../components/types";
@@ -21,20 +20,4 @@
 	const [subjects, setSubjects] = useState<Subject[]>([]);
 
-	useEffect(() => {
-		const fetchSubjects = async () => {
-			try {
-				const resSubjects = await fetch("http://localhost:8000/subjects/");
-				if (resSubjects.ok) {
-					const subJson: Subject[] = await resSubjects.json();
-					setSubjects(subJson || []);
-				}
-			} catch (error) {
-				console.error("Error fetching subjects:", error);
-			}
-		};
-
-		fetchSubjects();
-	}, []); 
-
 	return (
 		<SubjectsContext.Provider value={[subjects, setSubjects]}>
Index: frontend/src/pages/Recommendations.tsx
===================================================================
--- frontend/src/pages/Recommendations.tsx	(revision 3e206657f4d5094291f22881a8bf23022a353507)
+++ frontend/src/pages/Recommendations.tsx	(revision 9c27e0b361bceb78421216a39a5504df930db6fd)
@@ -1,23 +1,28 @@
-import { useMemo, useState } from "react";
+import { useEffect, useMemo, useState } from "react";
 import { useNavigate } from "react-router-dom";
+import axiosInstance from "../api/axiosInstance";
+import { fetchPreferences } from "../api/preferences";
+import { fetchSubjects } from "../api/subjects";
 import SubjectCard from "../components/SubjectCatalog/SubjectCard";
 import SubjectModal from "../components/SubjectCatalog/SubjectModal";
 import { getSubjectPrerequisites } from "../components/SubjectCatalog/utils";
 import { Subject } from "../components/types";
+import { usePreferences } from "../context/PreferencesContext";
 import { useRecommendations } from "../context/RecommendationsContext";
 import { useSubjects } from "../context/SubjectsContext";
 import { useAuth } from "../hooks/useAuth";
-import axiosInstance from "../api/axiosInstance";
 
 const Recommendations = () => {
 	const navigate = useNavigate();
+	const { setDislikedIds, setFavoriteIds, setLikedIds } = usePreferences();
+	const [isLoading, setIsLoading] = useState(false);
 	const { formData } = useAuth();
-	const [subjects] = useSubjects();
+	const { accessToken } = useAuth();
+	const [subjects, setSubjects] = useSubjects();
 	const [recommendations, setRecommendations] = useRecommendations();
+	const [recommendationsLoaded, setRecommendationsLoaded] = useState(true);
 	const [season_, setSeason] = useState<"winter" | "summer" | "all">("all");
-	const [isLoading, setIsLoading] = useState(false);
 	const [showModal, setShowModal] = useState(false);
 	const [hasSearched, setHasSearched] = useState(false);
-
 	const mapToSeasonInt = (season: "winter" | "summer" | "all") => {
 		if (season == "summer") return 0;
@@ -26,6 +31,12 @@
 	};
 
+	useEffect(() => {
+		if (!subjects || subjects.length === 0) {
+			fetchSubjects({ setSubjects });
+		}
+	}, []);
+
 	const fetchRecommendations = async () => {
-		setIsLoading(true);
+		setRecommendationsLoaded(false);
 		try {
 			const season = mapToSeasonInt(season_);
@@ -37,5 +48,5 @@
 			console.error("Error fetching recommendations:", error);
 		} finally {
-			setIsLoading(false);
+			setRecommendationsLoaded(true);
 			setHasSearched(true);
 			const container = document.querySelector(".flex-1.p-8.overflow-y-auto");
@@ -45,16 +56,4 @@
 		}
 	};
-
-	// (new) Now we use the context to get the subjects, but we can also fetch them directly from the backend if needed!
-	// (old) need to fetch subject data so that we can compare the subject IDs (prerequisites store IDs, but we need names) in the modals for the recommendations
-	// useEffect(() => {
-	// 	const fetchData = async () => {
-	// 		const response = await fetch("http://localhost:8000/subjects");
-	// 		const data = await response.json();
-	// 		setSubjects(data);
-	// 	};
-	// 	fetchData();
-	// 	if (subjects.length == 0) fetchData();
-	// }, []);
 
 	const subjectIdToNameMap = useMemo(() => {
@@ -100,4 +99,13 @@
 		}
 	};
+
+	useEffect(() => {
+		fetchPreferences({
+			setIsLoading,
+			setDislikedIds,
+			setFavoriteIds,
+			setLikedIds,
+		});
+	}, [accessToken]);
 
 	return (
@@ -136,12 +144,12 @@
 						<button
 							onClick={fetchRecommendations}
-							disabled={isLoading}
+							disabled={!recommendationsLoaded}
 							className={`${
-								isLoading
+								!recommendationsLoaded
 									? "bg-gray-400 cursor-not-allowed"
 									: "bg-green-500 hover:bg-green-600 hover:scale-105 shadow-md hover:shadow-lg"
 							} text-white px-8 py-4 rounded-lg text-xl font-bold transition-all duration-200 flex items-center space-x-2`}
 						>
-							{isLoading ? (
+							{!recommendationsLoaded ? (
 								<>
 									<div className="animate-spin rounded-full h-5 w-5 border-b-2 border-white"></div>
@@ -196,4 +204,5 @@
 												isFirst={index == 0}
 												isRecommended={true}
+												isLoading={isLoading}
 											/>
 										</div>
Index: frontend/src/pages/Register.tsx
===================================================================
--- frontend/src/pages/Register.tsx	(revision 3e206657f4d5094291f22881a8bf23022a353507)
+++ frontend/src/pages/Register.tsx	(revision 9c27e0b361bceb78421216a39a5504df930db6fd)
@@ -4,6 +4,6 @@
 import { toast } from "react-toastify";
 import PasswordInput from "../components/PasswordInput";
+import { User } from "../context/AuthContext";
 import { useAuth } from "../hooks/useAuth";
-import { User } from "../context/AuthContext";
 
 interface RegisterForm {
@@ -57,5 +57,4 @@
 				full_name: formData.fullName,
 			});
-			console.log(response.data);
 			const { access, refresh, user } = response.data;
 			login(access, refresh, user);
Index: frontend/src/pages/SubjectPreferences.tsx
===================================================================
--- frontend/src/pages/SubjectPreferences.tsx	(revision 3e206657f4d5094291f22881a8bf23022a353507)
+++ frontend/src/pages/SubjectPreferences.tsx	(revision 9c27e0b361bceb78421216a39a5504df930db6fd)
@@ -1,3 +1,5 @@
 import { useEffect, useState } from "react";
+import { fetchPreferences } from "../api/preferences";
+import { fetchSubjects } from "../api/subjects";
 import SkeletonCard from "../components/SubjectCatalog/SkeletonCard";
 import SubjectList from "../components/SubjectCatalog/SubjectList";
@@ -7,8 +9,17 @@
 import { usePreferences } from "../context/PreferencesContext";
 import { useSubjects } from "../context/SubjectsContext";
+import { useAuth } from "../hooks/useAuth";
 
 const SubjectPreferences = () => {
-	const [subjects] = useSubjects();
-	const { favoriteIds, likedIds, dislikedIds } = usePreferences();
+	const [subjects, setSubjects] = useSubjects();
+	const { accessToken } = useAuth();
+	const {
+		favoriteIds,
+		setDislikedIds,
+		likedIds,
+		setLikedIds,
+		dislikedIds,
+		setFavoriteIds,
+	} = usePreferences();
 	const [visibleCourses, setVisibleCourses] = useState<number>(12);
 	const [selectedSubject, setSelectedSubject] = useState<Subject | null>(null);
@@ -21,6 +32,12 @@
 	>("favorite");
 
-	// Helper functions
+	useEffect(() => {
+		if (!subjects || subjects.length === 0) {
+			fetchSubjects({ setSubjects });
+		}
+	}, []);
+
 	const favoriteIDsToMap = () => {
+		if (!favoriteIds) return new Map<number, string>();
 		const map = new Map<number, string>();
 		subjects.forEach((subject) => {
@@ -33,7 +50,8 @@
 
 	const likedIDsToMap = () => {
+		if (!likedIds) return new Map<number, string>();
 		const map = new Map<number, string>();
 		subjects.forEach((subject) => {
-			if (likedIds.has(subject.id)) {
+			if (likedIds?.has(subject.id)) {
 				map.set(subject.id, subject.name);
 			}
@@ -43,4 +61,5 @@
 
 	const dislikedIDsToMap = () => {
+		if (!dislikedIds) return new Map<number, string>();
 		const map = new Map<number, string>();
 		subjects.forEach((subject) => {
@@ -52,17 +71,29 @@
 	};
 
+	useEffect(() => {
+		fetchPreferences({
+			setDislikedIds,
+			setFavoriteIds,
+			setLikedIds,
+		});
+	}, [accessToken]);
+
 	const favoriteSubjects = () => {
+		if (!favoriteIds) return [];
 		return subjects.filter((subject) => favoriteIds.has(subject.id));
 	};
 
 	const likedSubjects = () => {
+		if (!likedIds) return [];
 		return subjects.filter((subject) => likedIds.has(subject.id));
 	};
 
 	const dislikedSubjects = () => {
+		if (!dislikedIds) return [];
 		return subjects.filter((subject) => dislikedIds.has(subject.id));
 	};
 
 	useEffect(() => {
+		if (!subjects || subjects.length === 0 || favoriteIds === undefined) return;
 		let newSubjects: Subject[] = [];
 		let newMap: Map<number, string> = new Map();
@@ -83,4 +114,5 @@
 		setSelectedSubjects(newSubjects);
 		setIdsToMap(newMap);
+		console.log(newSubjects);
 		setIsLoaded(true);
 	}, [favoriteIds, likedIds, dislikedIds, activeFilter, subjects]);
