diff --git a/generic/templates/generic/exam_overview_headers.html b/generic/templates/generic/exam_overview_headers.html
index c608da06..1bfcabf1 100644
--- a/generic/templates/generic/exam_overview_headers.html
+++ b/generic/templates/generic/exam_overview_headers.html
@@ -109,6 +109,7 @@ Author(s): {% for author in exam.author.all %}
Extra
+ Occasionally the order of questions can get out of sync. If you are exeriancing issues with the order of questions you can reset the order here.
+ {% if exam.exam_mode %}
+ Review exam
+ {% endif %}
{% for question in questions.all %}
diff --git a/rapids/templates/rapids/question_display_block.html b/rapids/templates/rapids/question_display_block.html
index 1ed9fded..d7f35d98 100755
--- a/rapids/templates/rapids/question_display_block.html
+++ b/rapids/templates/rapids/question_display_block.html
@@ -32,6 +32,10 @@
Exam(s): {% for exam in question.exams.all %}
{{ exam }},
{% endfor %}
+ Edit exam(s)
+
{% comment %} /add_exam",
+ views.question_add_exam,
+ name="question_add_exam",
+ ),
+ path("answer//confirm", views.confirm_answer, name="confirm_answer"),
+ path("answer//delete", views.delete_answer, name="delete_answer"),
path("exam///mark", views.mark, name="mark"),
path("exam///mark/all", views.mark_all, name="mark_all"),
path(
diff --git a/rapids/views.py b/rapids/views.py
index 61ef822c..e20163bb 100755
--- a/rapids/views.py
+++ b/rapids/views.py
@@ -18,6 +18,7 @@ from django.urls import reverse_lazy, reverse
from django.http import Http404, JsonResponse
from django.http import HttpResponseRedirect, HttpResponse
+from django.utils.safestring import mark_safe
from .forms import (
ExamAuthorForm,
@@ -988,3 +989,81 @@ class AnswerAutocomplete(autocomplete.Select2QuerySetView):
qs = qs.filter(answer__istartswith=self.q)
return qs
+
+
+def confirm_answer(request, answer_id: int):
+ if request.htmx:
+ answer = get_object_or_404(Answer, pk=answer_id)
+
+ # Check if the user has permission to confirm the answer
+ if not answer.can_edit(request.user):
+ return HttpResponse("Invalid permissions", status=403)
+
+ answer.clean()
+ answer.proposed = False
+ answer.save()
+ return HttpResponse("Answer accepted")
+
+ raise PermissionDenied()
+
+def delete_answer(request, answer_id: int):
+ if request.htmx:
+ answer = get_object_or_404(Answer, pk=answer_id)
+
+ # Check if the user has permission to confirm the answer
+ if not answer.can_edit(request.user):
+ return HttpResponse("Invalid permissions", status=403)
+
+ answer.delete()
+ return HttpResponse("Answer deleted")
+ raise PermissionDenied()
+
+def question_add_exam(request, question_id: int):
+ if request.htmx:
+ question = get_object_or_404(Rapid, pk=question_id)
+
+ if not question.can_edit(request.user):
+ return HttpResponse("Invalid permissions", status=403)
+
+
+ if request.POST:
+ exam_id = request.POST.get("exam_id", None)
+
+ if exam_id is None:
+ return HttpResponse("No exam id provided", status=400)
+
+ exam = get_object_or_404(Exam, pk=exam_id)
+
+ if request.POST.get("remove", False) == "true":
+ question.exams.remove(exam)
+ return HttpResponse("Question removed from exam.")
+ else:
+ question.exams.add(exam)
+
+ return HttpResponse("Question added to exam.")
+ else:
+ # Return a list of exams that we can add to the question
+
+ exams = Exam.objects.filter(author=request.user) | Exam.objects.filter(open_access=True)
+ exams = exams.difference(question.exams.all())
+
+ if not exams:
+ return HttpResponse("No exams available to add")
+
+ html = "Exams to add to question: "
+ for exam in exams:
+ html = html + (f""
+ )
+ html = html + " Exams to remove from question: "
+ for exam in question.exams.all():
+ html = html + (f""
+ )
+ html = html + "Cancel"
+
+ return HttpResponse(mark_safe(html))
+
+
+ raise PermissionDenied()
\ No newline at end of file