from django.shortcuts import render, redirect from django.urls import reverse_lazy from django.views.generic.edit import CreateView from django.contrib.auth.decorators import login_required from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin from django.contrib.auth import views as auth_views, login from django.contrib import messages from django.db.models import Q from django.http import JsonResponse from .forms import CustomUserCreationForm, CustomUserChangeForm, PlayerCreationForm, PlayerVerificationForm, ParentVerificationForm from .models import CustomUser from .utils import send_verification_email import uuid @login_required def edit_profile(request): if request.method == 'POST': form = CustomUserChangeForm(request.POST, instance=request.user) if form.is_valid(): form.save() return redirect('edit_profile') # Or wherever you want to redirect else: form = CustomUserChangeForm(instance=request.user) return render(request, 'accounts/edit_profile.html', {'form': form}) class HeadCoachCheckMixin(UserPassesTestMixin): def test_func(self): return self.request.user.is_superuser or self.request.user.coached_teams.exists() class PlayerCreateView(LoginRequiredMixin, HeadCoachCheckMixin, CreateView): model = CustomUser form_class = PlayerCreationForm template_name = 'accounts/player_form.html' success_url = reverse_lazy('dashboard') def form_valid(self, form): # Create player user player = form.save(commit=False) player.is_active = False # Player is inactive until verified player.set_unusable_password() # Password must be set via verification player.verification_code = uuid.uuid4() player.save() # Send verification email to player send_verification_email(player, self.request, is_parent=False) # Handle parents for i in ['1', '2']: search_identifier = form.cleaned_data.get(f'parent{i}_search') new_email = form.cleaned_data.get(f'parent{i}_new') if search_identifier: import re match = re.search(r'\((\w+)\)', search_identifier) if match: username = match.group(1) try: parent_user = CustomUser.objects.get(username=username) player.parents.add(parent_user) except CustomUser.DoesNotExist: form.add_error(f'parent{i}_search', 'User not found.') else: try: parent_user = CustomUser.objects.get(Q(username=search_identifier) | Q(email=search_identifier)) player.parents.add(parent_user) except CustomUser.DoesNotExist: form.add_error(f'parent{i}_search', 'User not found.') except CustomUser.MultipleObjectsReturned: form.add_error(f'parent{i}_search', 'Multiple users found. Please be more specific.') elif new_email: parent_user, created = CustomUser.objects.get_or_create( email=new_email, defaults={'username': new_email, 'is_active': False} ) if created: parent_user.set_unusable_password() parent_user.verification_code = uuid.uuid4() parent_user.save() # Send verification email to new parent send_verification_email(parent_user, self.request, is_parent=True) player.parents.add(parent_user) if form.errors: return self.form_invalid(form) return redirect(self.success_url) class MyLoginView(auth_views.LoginView): def get(self, request, *args, **kwargs): if request.user.is_authenticated: return redirect('dashboard') return super().get(request, *args, **kwargs) def user_search(request): q = request.GET.get('q', '') users = CustomUser.objects.filter(last_name__istartswith=q).values('username', 'first_name', 'last_name') results = [] for user in users: results.append(f"{user['last_name']}, {user['first_name']} ({user['username']})") return JsonResponse(results, safe=False) def verify_account(request, verification_code): user = get_object_or_404(CustomUser, verification_code=verification_code, is_verified=False) # Determine if user is a parent (has no team) or player is_parent = user.team is None FormClass = ParentVerificationForm if is_parent else PlayerVerificationForm if request.method == 'POST': form = FormClass(request.POST) if form.is_valid(): user.set_password(form.cleaned_data['password']) if is_parent: user.username = form.cleaned_data['username'] user.is_active = True user.is_verified = True user.verification_code = None # Invalidate the code user.save() login(request, user) # Log the user in messages.success(request, 'Your account has been verified! You are now logged in.') return redirect('dashboard') else: form = FormClass() return render(request, 'accounts/verify_account.html', {'form': form, 'is_parent': is_parent})