Index: backend/subjects/migrations/0006_evaluationreview_signature_condition_and_more.py
===================================================================
--- backend/subjects/migrations/0006_evaluationreview_signature_condition_and_more.py	(revision 1ee9aacd47eb67112c459b1a64646b286b5c0abe)
+++ backend/subjects/migrations/0006_evaluationreview_signature_condition_and_more.py	(revision 1ee9aacd47eb67112c459b1a64646b286b5c0abe)
@@ -0,0 +1,34 @@
+# Generated by Django 5.1.7 on 2025-07-12 19:00
+
+import django.db.models.deletion
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('subjects', '0005_remove_review_downvotes_remove_review_upvotes_and_more'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='evaluationreview',
+            name='signature_condition',
+            field=models.CharField(blank=True, max_length=64),
+        ),
+        migrations.AlterField(
+            model_name='evaluationcomponent',
+            name='evaluation_method',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='components', to='subjects.evaluationmethod'),
+        ),
+        migrations.AlterField(
+            model_name='evaluationmethod',
+            name='evaluation_review',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='methods', to='subjects.evaluationreview'),
+        ),
+        migrations.AlterField(
+            model_name='evaluationmethod',
+            name='note',
+            field=models.CharField(blank=True, help_text='additional info about this particular evaluation method.', max_length=64, null=True),
+        ),
+    ]
Index: backend/subjects/models.py
===================================================================
--- backend/subjects/models.py	(revision 22463abb0ce76a33d80a0bf318fecd95935af16e)
+++ backend/subjects/models.py	(revision 1ee9aacd47eb67112c459b1a64646b286b5c0abe)
@@ -93,11 +93,12 @@
 class EvaluationReview(models.Model):
     review = models.OneToOneField(Review, on_delete=models.CASCADE)
+    signature_condition = models.CharField(max_length=64, blank=True)
 
 class EvaluationMethod(models.Model):
     # one evaluation review could have more evaluation methods
     # example through a project and through exams
-    # option A: project: 90%, labs: 10%
-    # option B: theory: 35%, practical: 35%, labs: 10%, project: 20%
-    # each of these (option A - project, option A - labs, option B - project etc. is a EvaluationComponent)
+    # method A: project: 90%, labs: 10%
+    # method B: theory: 35%, practical: 35%, labs: 10%, project: 20%
+    # each of these (method A - project, method A - labs, method B - project etc. is a EvaluationComponent)
     evaluation_review = models.ForeignKey(EvaluationReview, on_delete=models.CASCADE, related_name='methods')
     note = models.CharField(max_length=64, null=True, blank=True, help_text="additional info about this particular evaluation method.")
Index: backend/subjects/serializers.py
===================================================================
--- backend/subjects/serializers.py	(revision 22463abb0ce76a33d80a0bf318fecd95935af16e)
+++ backend/subjects/serializers.py	(revision 1ee9aacd47eb67112c459b1a64646b286b5c0abe)
@@ -36,5 +36,5 @@
     class Meta:
         model = Review
-        fields = ['student', 'is_confirmed', 'votes_count']
+        fields = ['id', 'student', 'is_confirmed', 'votes_count']
 
     def get_student(self, obj):
@@ -76,5 +76,5 @@
     class Meta:
         model = EvaluationReview
-        fields = ['review', 'methods']
+        fields = ['review', 'methods', 'signature_condition']
 
     def validate(self, data):
Index: backend/subjects/urls.py
===================================================================
--- backend/subjects/urls.py	(revision 22463abb0ce76a33d80a0bf318fecd95935af16e)
+++ backend/subjects/urls.py	(revision 1ee9aacd47eb67112c459b1a64646b286b5c0abe)
@@ -1,4 +1,5 @@
 from django.urls import path
-from .views import ToggleSubjectPreferences, PreferencesView, all_subjects, get_recommendations, SubjectReview, ReviewsForSubject
+from .views import (ToggleSubjectPreferences, PreferencesView, all_subjects,
+                    get_recommendations, SubjectReview, ReviewsForSubject, ToggleVote)
 urlpatterns = [
     path('all/', all_subjects, name='all_subjects'),
@@ -6,5 +7,7 @@
     path('preferences/', PreferencesView.as_view(), name='student-preferences'),
     path('toggle-subject-pref/', ToggleSubjectPreferences.as_view(), name='student-toggle-preferences'),
-    path('subject-review', SubjectReview.as_view(), name='subject-review'),
-    path('subject-review/<str:code>', ReviewsForSubject.as_view(), name='subject-review')
+    path('subject-review/', SubjectReview.as_view(), name='subject-review'),
+    path('subject-review/toggle-vote/', ToggleVote.as_view(), name='toggle-vote'),
+    path('subject-review/<str:code>/', ReviewsForSubject.as_view(), name='subject-review'),
+
 ]
Index: backend/subjects/views.py
===================================================================
--- backend/subjects/views.py	(revision 22463abb0ce76a33d80a0bf318fecd95935af16e)
+++ backend/subjects/views.py	(revision 1ee9aacd47eb67112c459b1a64646b286b5c0abe)
@@ -7,8 +7,8 @@
 from rest_framework.views import APIView
 from rest_framework.permissions import IsAuthenticated
-from django.db.models import Case, When
+from django.db.models import Case, When, F
 from subjects.utils import get_eligible_subjects, get_recommendations_cache_key, get_recommended_subjects, map_to_subjects_vector, score_for_preferences, get_student_vector
 from .serializers import SubjectSerializer, EvaluationReviewSerializer, OtherReviewSerializer
-from .models import Subject, Review, EvaluationReview, OtherReview
+from .models import Subject, Review, EvaluationReview, OtherReview, ReviewVote
 
 def index(request):
@@ -206,2 +206,32 @@
             "other": other_serializer.data
         }, status=status.HTTP_200_OK)
+
+class ToggleVote(APIView):
+    permission_classes = [IsAuthenticated]
+
+    def post(self, request):
+        review_id = request.data.get('review_id')
+        vote_type = request.data.get('vote_type')
+        if vote_type not in ['up', 'down']:
+            return Response({"error": "Invalid vote type."}, status=status.HTTP_400_BAD_REQUEST)
+        if not review_id:
+            return Response({"error": "Review ID is required."}, status=status.HTTP_400_BAD_REQUEST)
+
+        student = request.user.student
+
+        try:
+            review = Review.objects.get(pk=review_id)
+        except Review.DoesNotExist:
+            return Response({"error": "Review not found."}, status=status.HTTP_404_NOT_FOUND)
+
+        try:
+            vote = ReviewVote.objects.get(review=review, student=student)
+            if vote.vote_type == vote_type:
+                vote.delete()
+                return Response({"message": "Vote deleted."}, status=status.HTTP_200_OK)
+            vote.vote_type = vote_type
+            vote.save()
+        except ReviewVote.DoesNotExist:
+            ReviewVote.objects.create(review=review, student=student, vote_type=vote_type)
+            return Response({"message": "Vote recorded."}, status=status.HTTP_201_CREATED)
+
Index: frontend/src/components/Reviews/EvaluationReviews.tsx
===================================================================
--- frontend/src/components/Reviews/EvaluationReviews.tsx	(revision 22463abb0ce76a33d80a0bf318fecd95935af16e)
+++ frontend/src/components/Reviews/EvaluationReviews.tsx	(revision 1ee9aacd47eb67112c459b1a64646b286b5c0abe)
@@ -1,14 +1,14 @@
 import { EVALUATION_MAP_TO_MK } from "../../constants/subjects";
-import { Reviews } from "../types";
+import { EvaluationReview } from "../types";
 import Votes from "./Votes";
 
 interface EvaluationReviewsProps {
-	reviews: Reviews;
+	evaluation_review: EvaluationReview;
 }
 
-const EvaluationReviews = ({ reviews }: EvaluationReviewsProps) => {
+const EvaluationReviews = ({ evaluation_review }: EvaluationReviewsProps) => {
 	return (
 		<>
-			{reviews.evaluation?.methods?.length > 0 && (
+			{evaluation_review.methods?.length > 0 && (
 				<div className="mb-8">
 					<h3 className="text-lg font-medium mb-4 text-gray-900">
@@ -16,14 +16,13 @@
 					</h3>
 					<div className="space-y-4">
-						{reviews &&
-							reviews.evaluation &&
-							(reviews.evaluation?.methods?.length > 0 ? (
+						{evaluation_review &&
+							(evaluation_review.methods?.length > 0 ? (
 								<div className="border border-gray-200 rounded-lg p-4">
 									<div className="flex items-start justify-between mb-3">
 										<div className="flex items-center space-x-2">
 											<span className="text-sm text-gray-600">
-												Индекс: {reviews.evaluation?.review.student}
+												Индекс: {evaluation_review.review.student}
 											</span>
-											{reviews.evaluation?.review.is_confirmed ? (
+											{evaluation_review.review.is_confirmed ? (
 												<div className="flex items-center text-green-600">
 													{/* <CheckCircle className="w-4 h-4 mr-1" /> */}
@@ -42,7 +41,7 @@
 											)}
 										</div>
-										<Votes reviews={reviews} />
+										<Votes review={evaluation_review.review} />
 									</div>
-									{reviews.evaluation?.methods?.map((method, index) => (
+									{evaluation_review.methods?.map((method, index) => (
 										<div key={index}>
 											<div className="space-y-4 mb-3">
@@ -50,4 +49,5 @@
 													<p className="text-sm text-gray-600 mb-2 font-semibold">
 														Начин на оценување {index + 1}:
+														{evaluation_review.review.id}
 													</p>
 													<div className="overflow-x-auto">
@@ -93,7 +93,7 @@
 										Услов за потпис:{" "}
 										<span>
-											{reviews.evaluation.signature_condition &&
-											reviews.evaluation.signature_condition != "None"
-												? reviews.evaluation.signature_condition
+											{evaluation_review.signature_condition &&
+											evaluation_review.signature_condition != "None"
+												? evaluation_review.signature_condition
 												: "Нема"}
 										</span>
Index: frontend/src/components/Reviews/OtherReviews.tsx
===================================================================
--- frontend/src/components/Reviews/OtherReviews.tsx	(revision 22463abb0ce76a33d80a0bf318fecd95935af16e)
+++ frontend/src/components/Reviews/OtherReviews.tsx	(revision 1ee9aacd47eb67112c459b1a64646b286b5c0abe)
@@ -1,11 +1,12 @@
+import { CheckCircle } from "lucide-react";
 import { MAP_REVIEW_CATEGORY_TO_MK } from "../SubjectCatalog/utils";
-import { Reviews } from "../types";
+import { OtherReview } from "../types";
 import Votes from "./Votes";
 
 interface OtherReviewsProps {
-	reviews: Reviews;
+	other_reviews: OtherReview[];
 }
 
-const OtherReviews = ({ reviews }: OtherReviewsProps) => {
+const OtherReviews = ({ other_reviews }: OtherReviewsProps) => {
 	return (
 		<div>
@@ -15,17 +16,18 @@
 
 			<div className="space-y-4">
-				{reviews.other.map((review) => (
+				{other_reviews.map((other_review) => (
 					<div className="border border-gray-200 rounded-lg p-4">
 						<div className="flex items-start justify-between mb-3">
 							<div className="flex items-center space-x-2">
 								<span className="text-sm text-gray-600">
-									Индекс: {review.review.student}
+									{other_review.review.id}
+									Индекс: {other_review.review.student}
 								</span>
 								<span className="bg-blue-100 text-blue-800 px-2 py-1 rounded text-xs">
-									{MAP_REVIEW_CATEGORY_TO_MK[review.category]}
+									{MAP_REVIEW_CATEGORY_TO_MK[other_review.category]}
 								</span>
-								{reviews.evaluation?.review.is_confirmed ? (
+								{other_review.review.is_confirmed ? (
 									<div className="flex items-center text-green-600">
-										{/* <CheckCircle className="w-4 h-4 mr-1" /> */}
+										<CheckCircle className="w-4 h-4 mr-1" />
 										<span className="text-sm">Потврдено</span>
 									</div>
@@ -42,7 +44,7 @@
 								)}
 							</div>
-							<Votes reviews={reviews} />
+							<Votes review={other_review.review} />
 						</div>
-						<p className="text-gray-700 text-sm">{review.content}</p>
+						<p className="text-gray-700 text-sm">{other_review.content}</p>
 					</div>
 				))}
Index: frontend/src/components/Reviews/Votes.tsx
===================================================================
--- frontend/src/components/Reviews/Votes.tsx	(revision 22463abb0ce76a33d80a0bf318fecd95935af16e)
+++ frontend/src/components/Reviews/Votes.tsx	(revision 1ee9aacd47eb67112c459b1a64646b286b5c0abe)
@@ -1,15 +1,34 @@
 import { ArrowDown, ArrowUp } from "lucide-react";
+import { useState } from "react";
+import axiosInstance from "../../api/axiosInstance";
 import { useAuth } from "../../hooks/useAuth";
-import { Reviews } from "../types";
+import { Review } from "../types";
 
 interface VotesProps {
-	reviews: Reviews;
-	review_id?: number;
+	review: Review;
 }
 
-const Votes = ({ reviews }: VotesProps) => {
+const Votes = ({ review }: VotesProps) => {
+	const [localCount, setLocalCount] = useState<number>(review.votes_count ?? 0);
 	const { isAuthenticated } = useAuth();
-	const handleClick = (action: "up" | "down") => {
-		console.log(action);
+	const handleClick = async (vote_type: "up" | "down") => {
+		const review_id = review.id;
+		console.log(review_id);
+		console.log(vote_type);
+		try {
+			const response = await axiosInstance.post(
+				"subjects/subject-review/toggle-vote/",
+				{
+					review_id: review_id,
+					vote_type: vote_type,
+				}
+			);
+			setLocalCount((prevCount) =>
+				vote_type == "up" ? prevCount + 1 : prevCount - 1
+			);
+			console.log(response.data);
+		} catch (err) {
+			console.error("Error occured: ", err);
+		}
 	};
 
@@ -28,5 +47,5 @@
 			</button>
 			<span className="text-sm font-medium text-gray-700 min-w-[20px] text-center">
-				{reviews.evaluation?.review.votes_count}
+				{localCount}
 			</span>
 			<button
@@ -36,4 +55,5 @@
 						: "cursor-pointer hover:text-red-600 hover:bg-red-50"
 				}`}
+				onClick={() => handleClick("down")}
 				disabled={!isAuthenticated}
 			>
Index: frontend/src/pages/SubjectView.tsx
===================================================================
--- frontend/src/pages/SubjectView.tsx	(revision 22463abb0ce76a33d80a0bf318fecd95935af16e)
+++ frontend/src/pages/SubjectView.tsx	(revision 1ee9aacd47eb67112c459b1a64646b286b5c0abe)
@@ -285,8 +285,8 @@
 									</h2>
 									{reviews.evaluation.methods.length > 0 && (
-										<EvaluationReviews reviews={reviews} />
+										<EvaluationReviews evaluation_review={reviews.evaluation} />
 									)}
 									{reviews.other.length > 0 && (
-										<OtherReviews reviews={reviews} />
+										<OtherReviews other_reviews={reviews.other} />
 									)}
 								</>
