from django.shortcuts import render, redirect from django.contrib import messages from django.contrib.auth import authenticate, login as auth_login, logout as auth_logout from django.contrib.auth.models import User from courses.models import Course from progression.models import Progression from .forms import UserRegistrationForm, UserLoginForm, UserUpdateForm, ProfileUpdateForm, CompleteProfileForm from django.contrib.auth.decorators import login_required from django.core.mail import send_mail from django.urls import reverse from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode from django.utils.encoding import force_bytes from .tokens import activation_token def register(request): # Si l'utilisateur est deja connecté, on le redirige vers la page de profil if request.user.is_authenticated: return redirect('profile') if request.method == 'POST': form = UserRegistrationForm(request.POST) if form.is_valid(): # Crée un utilisateur inactif en attente d'activation par e‑mail user = User.objects.create_user( username=form.cleaned_data['username'], email=form.cleaned_data['email'], password=form.cleaned_data['password1'] ) user.is_active = False user.save() # Envoi du lien d'activation par e‑mail uid = urlsafe_base64_encode(force_bytes(user.pk)) token = activation_token.make_token(user) activation_link = request.build_absolute_uri( reverse('activate', kwargs={'uidb64': uid, 'token': token}) ) subject = 'Active ton compte sur partirdezero' message = ( 'Bienvenue !\n\n' 'Pour activer ton compte, clique sur le lien suivant (valide pendant une durée limitée) :\n' f'{activation_link}\n\n' "Si tu n'es pas à l'origine de cette inscription, ignore ce message." ) try: send_mail(subject, message, None, [user.email], fail_silently=True) except Exception: # Même si l'envoi échoue, on n'interrompt pas le flux; un admin vérifiera la config e‑mail pass messages.success(request, "Inscription réussie. Vérifie ta boîte mail pour activer ton compte.") return redirect('login') else: form = UserRegistrationForm() return render(request, 'users/register.html', {'form': form}) def login(request): if request.method == 'POST': form = UserLoginForm(request.POST) if form.is_valid(): username = form.cleaned_data['username'] password = form.cleaned_data['password'] user = authenticate(request, username=username, password=password) if user is not None: if not user.is_active: messages.error(request, "Votre compte n'est pas encore activé. Consultez l'e‑mail d'activation envoyé." ) return render(request, 'users/login.html', {'form': form}) auth_login(request, user) return redirect('profile') else: # Identifiants invalides: avertir l'utilisateur messages.error(request, "Nom d'utilisateur ou mot de passe incorrect.") return render(request, 'users/login.html', {'form': form}) else: form = UserLoginForm() return render(request, 'users/login.html', {'form': form}) def logout(request): auth_logout(request) return redirect('login') @login_required(login_url='login') def profile(request): if not hasattr(request.user, 'profile'): return redirect('complete_profile') latest_progress = ( Progression.objects .filter(user=request.user) .select_related('course') .prefetch_related('completed_lessons') .order_by('-updated_at')[:5] ) # Affiche les 5 derniers cours regardés avec leur progression return render(request, 'users/profile.html', {'latest_progress': latest_progress}) @login_required(login_url='login') def complete_profile(request): if hasattr(request.user, 'profile'): return redirect('profile') # Redirige si le profil existe déjà if request.method == 'POST': form = CompleteProfileForm(request.POST) if form.is_valid(): profile = form.save(commit=False) profile.user = request.user profile.save() messages.success(request, 'Votre profil a été créé avec succès !') return redirect('profile') else: form = CompleteProfileForm() return render(request, 'users/complete_profile.html', {'form': form}) @login_required(login_url='login') def profile_update(request): if request.method == 'POST': user_form = UserUpdateForm(request.POST, instance=request.user) profile_form = ProfileUpdateForm(request.POST, request.FILES, instance=request.user.profile) if profile_form.is_valid(): profile_form.save() messages.success(request, 'Votre profil a été mis à jour avec succès !') return redirect('profile') else: user_form = UserUpdateForm(instance=request.user) profile_form = ProfileUpdateForm(instance=request.user.profile) return render(request, 'users/profile_update.html', {'user_form': user_form, 'profile_form': profile_form}) @login_required(login_url='login') def account_update(request): if request.method == 'POST': user_form = UserUpdateForm(request.POST, instance=request.user) if user_form.is_valid(): user_form.save() # On affiche un message flash pour confirmer la modification messages.success(request, 'Les paramètre de votre compte ont été mis à jour avec succès !') return redirect('profile') else: user_form = UserUpdateForm(instance=request.user) return render(request, 'users/account_update.html', {'user_form': user_form}) @login_required(login_url='login') def my_courses(request): # Liste tous les cours suivis par l'utilisateur avec leur progression progress_list = ( Progression.objects .filter(user=request.user) .select_related('course') .prefetch_related('completed_lessons') .order_by('-updated_at') ) return render(request, 'users/my_courses.html', {'progress_list': progress_list}) def create_post(request): # Implement post creation logic here return render(request, 'users/create_post.html') def another_profile(request, user_id): user = User.objects.get(id=user_id) return render(request, 'users/another_profile.html', {'user': user}) # Activation de compte via lien tokenisé def activate(request, uidb64, token): try: uid = urlsafe_base64_decode(uidb64).decode() user = User.objects.get(pk=uid) except Exception: user = None if user and activation_token.check_token(user, token): if not user.is_active: user.is_active = True user.save() messages.success(request, 'Votre compte a été activé. Vous pouvez maintenant vous connecter.') return redirect('login') messages.error(request, "Lien d'activation invalide ou expiré. Demandez un nouveau lien ou inscrivez‑vous à nouveau.") return redirect('register')