feat: Implement supervisor trainee management features, including search, add, and remove functionalities
Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
@@ -99,6 +99,11 @@ urlpatterns = [
|
||||
path("accounts/", include("django.contrib.auth.urls")),
|
||||
path("accounts/profile", views.profile, name="profile"),
|
||||
path("accounts/profile/<str:slug>/", views.account_profile, name="account_profile"),
|
||||
path(
|
||||
"accounts/profile/<str:slug>/set-supervisor/",
|
||||
views.account_set_supervisor,
|
||||
name="account_set_supervisor",
|
||||
),
|
||||
#path("", TemplateView.as_view(template_name="index.html"), name="home"),
|
||||
path("", views.index, name="home"),
|
||||
path("cid/results/<int:cid>/", views.cid_results, name="cid_results"),
|
||||
|
||||
@@ -45,6 +45,7 @@ from django.urls import reverse_lazy, reverse
|
||||
from django.http import Http404, JsonResponse
|
||||
|
||||
from django.http import HttpResponseRedirect, HttpResponse
|
||||
from django.views.decorators.http import require_POST
|
||||
|
||||
from physics.models import UserAnswer as PhysicsUserAnswer
|
||||
from physics.models import Exam as PhysicsExam
|
||||
@@ -120,6 +121,12 @@ def people(request):
|
||||
|
||||
@login_required
|
||||
def profile(request):
|
||||
"""Render the current user's profile page with group management context.
|
||||
|
||||
Scope: authenticated user's own profile view.
|
||||
Functionality: provides user details, available groups, and supervisor
|
||||
account state for template actions.
|
||||
"""
|
||||
user = request.user
|
||||
available_groups = UserUserGroup.objects.filter(archive=False).exclude(
|
||||
pk__in=user.user_groups.values_list("pk", flat=True)
|
||||
@@ -128,6 +135,7 @@ def profile(request):
|
||||
pk__in=user.groups.values_list("pk", flat=True)
|
||||
)
|
||||
is_cid_user_manager = request.user.groups.filter(name="cid_user_manager").exists()
|
||||
supervisor_account = Supervisor.objects.filter(user=user).first()
|
||||
return render(
|
||||
request,
|
||||
"profile.html",
|
||||
@@ -136,6 +144,8 @@ def profile(request):
|
||||
"available_groups": available_groups,
|
||||
"available_auth_groups": available_auth_groups,
|
||||
"is_cid_user_manager": is_cid_user_manager,
|
||||
"supervisor_account": supervisor_account,
|
||||
"supervisor_action": request.GET.get("supervisor_action", ""),
|
||||
},
|
||||
)
|
||||
|
||||
@@ -160,6 +170,12 @@ def index(request):
|
||||
|
||||
@user_is_cid_user_manager
|
||||
def account_profile(request, slug):
|
||||
"""Render an account profile page for administrators.
|
||||
|
||||
Scope: cid_user_manager and superusers viewing another user's profile.
|
||||
Functionality: exposes profile details, group controls, and supervisor
|
||||
account creation/link status for admin actions.
|
||||
"""
|
||||
user = get_object_or_404(User, username=slug)
|
||||
available_groups = UserUserGroup.objects.filter(archive=False).exclude(
|
||||
pk__in=user.user_groups.values_list("pk", flat=True)
|
||||
@@ -168,6 +184,7 @@ def account_profile(request, slug):
|
||||
pk__in=user.groups.values_list("pk", flat=True)
|
||||
)
|
||||
is_cid_user_manager = request.user.groups.filter(name="cid_user_manager").exists()
|
||||
supervisor_account = Supervisor.objects.filter(user=user).first()
|
||||
return render(
|
||||
request,
|
||||
"profile.html",
|
||||
@@ -176,10 +193,49 @@ def account_profile(request, slug):
|
||||
"available_groups": available_groups,
|
||||
"available_auth_groups": available_auth_groups,
|
||||
"is_cid_user_manager": is_cid_user_manager,
|
||||
"supervisor_account": supervisor_account,
|
||||
"supervisor_action": request.GET.get("supervisor_action", ""),
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@require_POST
|
||||
@user_is_cid_user_manager
|
||||
def account_set_supervisor(request, slug):
|
||||
"""Create or link a Supervisor record for an existing user.
|
||||
|
||||
Scope: cid_user_manager and superusers only.
|
||||
Functionality: one-click action from profile pages to assign a user as a
|
||||
supervisor account, reusing an existing supervisor by email when safe.
|
||||
"""
|
||||
user = get_object_or_404(User, username=slug)
|
||||
|
||||
next_url = request.POST.get("next") or reverse("account_profile", kwargs={"slug": user.username})
|
||||
|
||||
email = (user.email or "").strip().lower()
|
||||
if not email:
|
||||
return redirect(f"{next_url}?supervisor_action=no_email")
|
||||
|
||||
existing_for_user = Supervisor.objects.filter(user=user).first()
|
||||
if existing_for_user:
|
||||
return redirect(f"{next_url}?supervisor_action=already_linked")
|
||||
|
||||
supervisor = Supervisor.objects.filter(email__iexact=email).first()
|
||||
if supervisor:
|
||||
if supervisor.user and supervisor.user != user:
|
||||
return redirect(f"{next_url}?supervisor_action=email_in_use")
|
||||
|
||||
supervisor.user = user
|
||||
if not supervisor.name:
|
||||
supervisor.name = user.get_full_name().strip() or user.username
|
||||
supervisor.save()
|
||||
return redirect(f"{next_url}?supervisor_action=linked")
|
||||
|
||||
name = user.get_full_name().strip() or user.username
|
||||
Supervisor.objects.create(email=email, name=name, user=user)
|
||||
return redirect(f"{next_url}?supervisor_action=created")
|
||||
|
||||
|
||||
def cid_selector(request):
|
||||
return render(
|
||||
request,
|
||||
|
||||
Reference in New Issue
Block a user