Saltar al contenido principal
Versión: 2.0

Módulo: Mi Perfil

Scope

Tipo de organizaciónAcceso
Empresa
Agencia
Reclutador independiente

Disponible para todos los usuarios independientemente de su tipo de organización.

Permisos por rol

Empresa (COMPANY)

AcciónDisponible
Ver información personal
Cambiar foto de perfil
Ver tipo de cuenta
Acceder a seguridad
Acceder a sesiones activas
Acceder a permisos
Acceder a ayuda

Agencia (AGENCY)

AcciónDisponible
Ver información personal
Cambiar foto de perfil
Ver tipo de cuenta
Acceder a seguridad
Acceder a sesiones activas
Acceder a permisos
Acceder a ayuda

Reclutador independiente (RECRUITER)

AcciónDisponible
Ver información personal
Cambiar foto de perfil
Ver tipo de cuenta
Acceder a seguridad
Acceder a sesiones activas
Acceder a permisos
Acceder a ayuda

Todas las funciones de "Mi Perfil" son idénticas para los tres roles. No hay restricciones por tipo de organización.


¿Qué es?

"Mi Perfil" es la página personal del usuario dentro de Contratta. Muestra su información básica (nombre, email, tipo de cuenta), permite gestionar su foto de perfil y da acceso a configuraciones como seguridad, sesiones activas, permisos y ayuda.

Este módulo es accesible para todos los usuarios independientemente de su tipo de organización (Empresa, Agencia o Reclutador independiente).

¿Qué puede hacer el usuario?

Foto de perfil

  • Subir una foto desde cámara o galería
  • Eliminar la foto actual (con confirmación)
  • Ver avatar con iniciales cuando no tiene foto

Ver su información

  • Nombre completo (solo lectura)
  • Correo electrónico (solo lectura)
  • Estado de verificación del email (verificado / no verificado)
  • Tipo de cuenta (Empresa, Agencia, Independiente)

Configuración

  • Seguridad — cambio de contraseña y verificación de email
  • Sesiones activas — ver dispositivos con sesión iniciada
  • Permisos — cámara, galería y notificaciones
  • Ayuda y soporte — FAQ, contacto y licencias

Cerrar sesión

  • Botón de logout con diálogo de confirmación

Flujo del usuario

1. Navega a "Perfil" desde el bottom nav
2. Ve su card con avatar, nombre, email y tipo de cuenta
3. Toca el ícono de cámara en el avatar → abre sheet con opciones
4. Selecciona cámara/galería → se sube automáticamente
5. El avatar se actualiza en toda la app (header, drawer, etc.)
6. Puede navegar a sub-páginas de configuración
7. Puede cerrar sesión (con confirmación)

Reglas de negocio

  • El nombre y email no son editables desde esta pantalla (se gestionan desde otra sección o backend)
  • La foto se sube como multipart al endpoint /users/me/avatar
  • Al subir o eliminar avatar, se refresca el contexto global (AuthCubit.getUserContext()) para actualizar el avatar en toda la app
  • Los permisos de cámara se solicitan antes de abrir la cámara
  • El logout limpia tokens y redirige al login

Arquitectura

lib/features/profile/
├── application/
│ └── user_profile_cubit.dart ← Lógica de avatar (upload/delete)
├── data/
│ ├── datasources/
│ │ └── user_profile_remote_datasource.dart ← Llamadas Dio aisladas
│ └── repositories/
│ └── user_profile_repository_impl.dart ← Catch → Failures tipados
├── domain/
│ ├── repositories/
│ │ └── user_profile_repository.dart ← Contrato abstracto
│ └── usecases/
│ └── upload_user_avatar_usecase.dart ← Upload + Delete
└── presentation/
├── pages/
│ ├── profile_page.dart ← Página principal
│ ├── security_page.dart ← Sub-página seguridad
│ ├── sessions_page.dart ← Sub-página sesiones
│ ├── permissions_page.dart ← Sub-página permisos
│ └── help_support_page.dart ← Sub-página ayuda
└── widgets/
├── profile_avatar_widget.dart ← Avatar reutilizable
├── profile_settings_section.dart ← Tiles de configuración
└── image_source_sheet.dart ← Bottom sheet cámara/galería

Flujo de datos

ProfilePage → UserProfileCubit → UseCase → UserProfileRepository → UserProfileRemoteDatasource → API

La información del usuario (nombre, email, org type) viene del AuthCubit que ya existe a nivel global. El UserProfileCubit solo gestiona las operaciones de avatar.

Estado (UserProfileState)

enum AvatarStatus { idle, uploading, deleting, success, error }

class UserProfileState {
final AvatarStatus status;
final Failure? failure;
}

Endpoints API

MétodoEndpointDescripción
POST/users/me/avatarSubir avatar (multipart/form-data)
DELETE/users/me/avatarEliminar avatar
GET/auth/contextObtener contexto del usuario (nombre, email, avatar URL) — via AuthCubit

Widgets principales

WidgetResponsabilidad
ProfileAvatarWidgetAvatar circular con badge de cámara, loader y fallback a iniciales
ProfileSettingsSectionLista de tiles de configuración con ícono, título y subtítulo
ImageSourceSheetBottom sheet reutilizable para elegir cámara, galería o eliminar

Dependencias

  • image_picker — Selección de imágenes
  • flutter_bloc — Estado via UserProfileCubit + AuthCubit
  • ConfirmDialog (core) — Confirmaciones reutilizables
  • AppNotification (core) — Alertas de éxito/error

Registro DI (get_it)

  • Datasource: LazySingleton
  • Repository: LazySingleton
  • UseCases: LazySingleton
  • Cubit: Factory (nueva instancia por pantalla)

Manejo de errores

  1. Datasource — deja propagar DioException
  2. Repository — captura y mapea a Failure via NetworkErrorHandler
  3. Cubit — emite failure en el estado
  4. UIBlocListener muestra AppNotification.error con mensaje localizado

Localización

Todas las cadenas usan context.l10n.*. Claves relevantes con prefijo profile*:

  • profileMyTitle — "Mi Perfil"
  • profilePersonalInfo — "Información Personal"
  • profileFullName — "Nombre completo"
  • profileEmailVerified / profileEmailNotVerified
  • profileChangePhoto / profileTakePhoto / profileChooseGallery / profileDeletePhoto
  • profileAvatarUpdated / profileAvatarDeleted
  • profileAvatarDeleteConfirm / profileAvatarDeleteMessage
  • profileSecurityTitle / profileSessionsTitle / profilePermissionsTitle / profileHelpTitle

Disponibles en español (app_es.arb) e inglés (app_en.arb).