diff --git a/.gitignore b/.gitignore index ae2c21a..a554492 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,7 @@ env/ # Claude Code workspace .claude/ +CLAUDE.md # IDE .vscode/ diff --git a/Plataform_Web/gades_manager/urls.py b/Plataform_Web/gades_manager/urls.py index 8d9fbea..d6ca849 100644 --- a/Plataform_Web/gades_manager/urls.py +++ b/Plataform_Web/gades_manager/urls.py @@ -28,4 +28,7 @@ urlpatterns = [ path('logout/', auth_views.LogoutView.as_view(next_page='login'), name='logout'), path('mi-perfil/', users_views.mi_perfil, name='mi_perfil'), path('miembros/', users_views.listado_miembros, name='listado_miembros'), + path('gestion/usuarios/', users_views.gestion_usuarios, name='gestion_usuarios'), + path('gestion/usuarios//editar/', users_views.editar_usuario, name='editar_usuario'), + path('gestion/usuarios//eliminar/', users_views.eliminar_usuario, name='eliminar_usuario'), ] \ No newline at end of file diff --git a/Plataform_Web/templates/base.html b/Plataform_Web/templates/base.html index 9c2c6a9..f888191 100644 --- a/Plataform_Web/templates/base.html +++ b/Plataform_Web/templates/base.html @@ -66,7 +66,7 @@ Gestión diff --git a/Plataform_Web/templates/editar_usuario.html b/Plataform_Web/templates/editar_usuario.html new file mode 100644 index 0000000..9e107d8 --- /dev/null +++ b/Plataform_Web/templates/editar_usuario.html @@ -0,0 +1,70 @@ +{% extends 'base.html' %} +{% load static %} + +{% block title %}Editar Usuario | Gades Manager{% endblock title %} + +{% block content %} +
+
+
+

Editar Usuario

+

{{ usuario.username }}

+
+
+
+ +
+
+
+
+
Datos del Usuario
+ +
+ {% csrf_token %} + +
+ + {{ form.username }} + {% for error in form.username.errors %} +
{{ error }}
+ {% endfor %} +
+ +
+
+ + {{ form.first_name }} +
+
+ + {{ form.last_name }} +
+
+ +
+ + {{ form.email }} + {% for error in form.email.errors %} +
{{ error }}
+ {% endfor %} +
+ +
+
+ + {{ form.rol }} +
+
+ + {{ form.especialidad }} +
+
+ + + Cancelar +
+
+
+
+
+{% endblock content %} diff --git a/Plataform_Web/templates/gestion_usuarios.html b/Plataform_Web/templates/gestion_usuarios.html new file mode 100644 index 0000000..312d10e --- /dev/null +++ b/Plataform_Web/templates/gestion_usuarios.html @@ -0,0 +1,125 @@ +{% extends 'base.html' %} +{% load static %} + +{% block title %}Gestión de Usuarios | Gades Manager{% endblock title %} + +{% block content %} +
+
+
+

Gestión de Usuarios

+

Administra las cuentas del sistema: edita o elimina usuarios.

+
+
+
+ +
+ + {% if messages %} +
+ {% for message in messages %} +
{{ message }}
+ {% endfor %} +
+ {% endif %} + +
+
+
+ +
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + {% if filtro_rol or filtro_especialidad or filtro_apellido %} + × + {% endif %} +
+
+ +
+ + + + + + + + + + + + + + {% for usuario in usuarios %} + + + + + + + + + + + + {% empty %} + + + + {% endfor %} + +
UsuarioNombreApellidosEmailÁrea TécnicaRolAcciones
{{ usuario.username }}{{ usuario.first_name }}{{ usuario.last_name }}{{ usuario.email }}{{ usuario.get_especialidad_display|default:"—" }}{{ usuario.get_rol_display }} + Editar + +
No se han encontrado usuarios con los filtros seleccionados.
+
+ +
+
+
+
+{% endblock content %} diff --git a/Plataform_Web/users/decorators.py b/Plataform_Web/users/decorators.py new file mode 100644 index 0000000..28cd93a --- /dev/null +++ b/Plataform_Web/users/decorators.py @@ -0,0 +1,7 @@ +from django.contrib.auth.decorators import login_required, user_passes_test + + +def require_rol(*roles): + def decorator(view_func): + return login_required(user_passes_test(lambda u: u.rol in roles)(view_func)) + return decorator diff --git a/Plataform_Web/users/forms.py b/Plataform_Web/users/forms.py index 37fabbe..0d096c3 100644 --- a/Plataform_Web/users/forms.py +++ b/Plataform_Web/users/forms.py @@ -18,3 +18,25 @@ class PerfilForm(forms.ModelForm): 'last_name': 'Apellidos', 'email': 'Correo electrónico', } + + +class EditarUsuarioForm(forms.ModelForm): + class Meta: + model = CustomUser + fields = ['username', 'first_name', 'last_name', 'email', 'rol', 'especialidad'] + widgets = { + 'username': forms.TextInput(attrs={'class': 'form-control'}), + 'first_name': forms.TextInput(attrs={'class': 'form-control'}), + 'last_name': forms.TextInput(attrs={'class': 'form-control'}), + 'email': forms.EmailInput(attrs={'class': 'form-control'}), + 'rol': forms.Select(attrs={'class': 'form-select'}), + 'especialidad': forms.Select(attrs={'class': 'form-select'}), + } + labels = { + 'username': 'Usuario', + 'first_name': 'Nombre', + 'last_name': 'Apellidos', + 'email': 'Correo electrónico', + 'rol': 'Rol en el equipo', + 'especialidad': 'Área técnica', + } diff --git a/Plataform_Web/users/views.py b/Plataform_Web/users/views.py index cea88d4..4a7fc52 100644 --- a/Plataform_Web/users/views.py +++ b/Plataform_Web/users/views.py @@ -1,9 +1,11 @@ -from django.shortcuts import render, redirect +from django.shortcuts import render, redirect, get_object_or_404 from django.contrib.auth.decorators import login_required from django.contrib.auth.forms import PasswordChangeForm from django.contrib.auth import update_session_auth_hash from django.contrib import messages -from .forms import PerfilForm +from django.views.decorators.http import require_POST +from .decorators import require_rol +from .forms import PerfilForm, EditarUsuarioForm from .models import CustomUser @@ -64,3 +66,54 @@ def listado_miembros(request): 'filtro_apellido': apellido, } return render(request, 'listado_miembros.html', context) + + +@require_rol('directiva') +def gestion_usuarios(request): + usuarios = CustomUser.objects.all().order_by('last_name', 'first_name') + + rol = request.GET.get('rol', '') + especialidad = request.GET.get('especialidad', '') + apellido = request.GET.get('apellido', '') + + if rol: + usuarios = usuarios.filter(rol=rol) + if especialidad: + usuarios = usuarios.filter(especialidad=especialidad) + if apellido: + usuarios = usuarios.filter(last_name__icontains=apellido) + + context = { + 'usuarios': usuarios, + 'rol_choices': CustomUser.ROL_CHOICES, + 'especialidad_choices': CustomUser.ESPECIALIDAD_CHOICES, + 'filtro_rol': rol, + 'filtro_especialidad': especialidad, + 'filtro_apellido': apellido, + } + return render(request, 'gestion_usuarios.html', context) + + +@require_rol('directiva') +def editar_usuario(request, pk): + usuario = get_object_or_404(CustomUser, pk=pk) + + if request.method == 'POST': + form = EditarUsuarioForm(request.POST, instance=usuario) + if form.is_valid(): + form.save() + messages.success(request, 'El usuario se ha actualizado correctamente.') + return redirect('gestion_usuarios') + else: + form = EditarUsuarioForm(instance=usuario) + + return render(request, 'editar_usuario.html', {'form': form, 'usuario': usuario}) + + +@require_rol('directiva') +@require_POST +def eliminar_usuario(request, pk): + usuario = get_object_or_404(CustomUser, pk=pk) + usuario.delete() + messages.success(request, 'El usuario se ha eliminado correctamente.') + return redirect('gestion_usuarios')