Saltar al contenido principal
Versión: 1.2

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. UI — BlocListener 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).