Cargando…

Esto está tardando más de lo esperado.

Volver al centro de ayuda

Tu área de cuenta

Lo que una persona con sesión puede cambiar de sí misma bajo /account, y qué necesita de ti cada pantalla para funcionar.

Toda persona con sesión iniciada tiene un área de cuenta en /account: su perfil, sus notificaciones, los avisos que publicas y, cuando el programa está encendido, sus referidos. Esta guía recorre cada pantalla, qué escribe en la tabla users y la configuración que decide qué partes aparecen. La necesitas cuando un cliente pregunta dónde cambia su contraseña, y cuando decides qué campos deja editar tu producto.

Las pantallas

Todas están definidas en routes/auth.php detrás de los middleware auth y security: la persona debe tener sesión, no estar bloqueada y no tener pendiente un cambio forzado de contraseña.

URL Nombre de ruta Componente Existe cuando
/account auth.profile App\Livewire\Auth\MyProfile Siempre
/account/notifications auth.notifications.center App\Livewire\Auth\Notifications\Index Siempre
/account/referrals auth.referrals App\Livewire\Auth\Referrals\Index FEATURE_REFERRALS_ENABLED=true; si no, 404
/account/announcements auth.announcements.index App\Livewire\Auth\Announcements\Index FEATURE_ANNOUNCEMENTS=true; si no, 404
/account/announcements/{announcement} auth.announcements.show App\Livewire\Auth\Announcements\Show La misma bandera; la URL lleva el slug

La barra lateral de toda el área es resources/views/layouts/sidebars/account.blade.php. El layout elige la barra por el primer segmento de la URL, así que cualquier pantalla que agregues bajo /account también la recibe. Lista Mi Perfil, Notificaciones, Referidos y Avisos (los dos últimos sólo con su bandera encendida), Mis planes cuando hay facturación y la persona puede ver suscripciones, y Ayuda, que abre el centro de ayuda público en /help. El botón Ir a la aplicación de arriba regresa a route('app.dashboard').

La página de perfil

/account es un solo componente Livewire, App\Livewire\Auth\MyProfile, organizado en tarjetas. Cada tarjeta tiene su propio botón Guardar y su propio método, así que guardar la contraseña no vuelve a validar el nombre, ni al revés.

La página de perfil, organizada en tarjetas

Foto de perfil

La foto es un <x-image-uploader> enlazado con wire:model.live a photo: elegir un archivo lo sube de inmediato con una barra de progreso, y updatedPhoto() guarda el cambio con User::saveAvatarChanges(), así que no hay botón Guardar. El uploader acepta cualquier imagen hasta 5120 KB; el texto en pantalla sólo menciona JPG, GIF y PNG. El archivo cae en la biblioteca de medios propia de la cuenta como un registro Media, con las conversiones que la biblioteca genera para toda subida, y users.avatar_media_id apunta a él. Una foto reemplazada por otra se queda en la biblioteca. Quitar la actual ofrece Quitar de este registro, que la conserva en la biblioteca, o Eliminar de la biblioteca multimedia, que la borra. Como el archivo pertenece a la cuenta igual que cualquier otro de su biblioteca, cuenta contra la cuota de espacio en disco de la cuenta. El proceso completo y lo que necesita de tu almacenamiento están en /help/files-images-and-storage.

Mientras la persona no sube una foto, $user->avatar es un marcador generado por api.dicebear.com a partir del MD5 de su correo.

Información general

Nombre, los campos de identidad, y país, estado y ciudad. Qué campos de identidad existen lo decide LOGIN_IDENTITIES (config('auth.login_identities')): un campo Correo cuando email está en la lista, Teléfono cuando está phone, Nombre de usuario cuando está username. Cada identidad debe ser única entre usuarios; el nombre de usuario admite letras, dígitos, guiones y guiones bajos hasta 255 caracteres. Guardar también ejecuta la revisión de App\Livewire\Traits\ValidatesLoginIdentities: al menos una identidad debe estar llena, y cuando hay más de una configurada, el nombre de usuario solo no basta, tiene que acompañarlo un correo o un teléfono. El error abre un diálogo y no se guarda nada.

País, estado y ciudad se guardan en la columna JSON extra_data, no en columnas propias.

Mientras AUTH_ENABLE_VALIDATION esté encendido, el campo de correo y el de teléfono muestran cada uno una etiqueta Verificado o No verificado y un enlace Verificar ahora que envía un código, y Guardar rechaza una identidad que cambió y no se confirmó: el propio campo dice que a ese valor todavía le falta su código. A una identidad que nadie tocó no se le vuelve a pedir nada, así que guardar el nombre o el país no pide ningún código. Vaciar una identidad se permite y se lleva su verificación consigo, mientras la revisión de arriba siga encontrando una identidad utilizable.

Al confirmar un código, onIdentityVerified() escribe esa identidad y su marca de tiempo en el momento, sin pulsar Guardar, y no escribe nada más: todo lo demás de la página espera a Guardar y a su validación. El teléfono se guarda en formato internacional, y la etiqueta compara números y no cadenas, así que el número guardado escrito sin su prefijo sigue siendo el mismo número. Con el interruptor apagado ninguno de los dos campos muestra la fila de verificación. Cómo viajan los códigos está en /help/verify-email-and-phone.

Contraseña

Dos campos: la contraseña nueva y su confirmación. La regla es al menos 8 caracteres y que ambos coincidan (changePassword(), required|min:8|confirmed). No se pide la contraseña actual. Nada cierra las otras sesiones; eso lo hace la tarjeta Dispositivos conectados de más abajo.

Idioma y zona horaria

Dos selectores. El idioma ofrece las llaves de config('app.languages'), es y en de fábrica; la zona horaria ofrece la lista completa de identificadores de PHP. Ambos son obligatorios para guardar, y escriben users.locale y users.timezone. El idioma es el de la interfaz para esa cuenta, y la zona horaria decide cómo se le muestra cada fecha. Mira /help/languages-and-translations y /help/timezones-and-dates.

Notificaciones

Un interruptor, Notificación por correo electrónico, enlazado a users.send_mail. Apagado quita el canal mail de toda notificación que envía la clase base; la campana y el centro de notificaciones siguen recibiendo todo. Cuando APP_PWA=true y las llaves VAPID están configuradas, aparece un segundo interruptor, Notificación push, que suscribe o desuscribe el navegador actual, y un botón Prueba mientras está suscrito. Prueba llama a testWebPushNotification(), que envía App\Notifications\TestWebPushNotification a las suscripciones push de la persona, o avisa en su lugar cuando push no está configurado o este navegador no tiene suscripción. Mira /help/send-notifications y /help/web-push-and-the-pwa.

PIN de seguridad

La tarjeta existe sólo cuando AUTH_ENABLE_PIN=true. Incrusta App\Livewire\Auth\ManagePin: cuatro casillas de un dígito para el PIN y cuatro para su confirmación, más cuatro para el PIN actual una vez que existe uno, que debe coincidir antes de que cambie nada. El PIN es exactamente cuatro dígitos y se guarda con hash en users.pin.

Mientras la bandera está encendida y la persona no tiene PIN, App\Http\Middleware\SystemValidations deja una advertencia en cada petición, y <x-design::system-warnings/> la muestra arriba de cada página del layout de la aplicación: "Necesitas configurar un PIN para tu cuenta." con un enlace Configurar PIN a /account. Un administrador puede borrar el PIN de un usuario desde la página del usuario en el panel de administración. Qué protege el PIN está en /help/the-security-pin.

Dispositivos conectados

La tarjeta lista las sesiones de la cuenta: las filas de la tabla sessions cuyo user_id es la persona y cuyo last_activity cae dentro de SESSION_LIFETIME (525600 minutos, un año, por omisión), la más reciente primero. Cada fila muestra el navegador y el sistema operativo leídos del user agent (Edge, Opera, Samsung Internet, Firefox, Chrome o Safari, incluidas las versiones de iPhone y iPad de Chrome, Firefox, Edge y Opera; Windows, macOS, Android, iOS o Linux), la IP, el país y hace cuánto estuvo activa; la sesión actual está marcada como Este dispositivo. Desconectar termina otra sesión; cuando hay más de una, Desconectar todos los demás dispositivos pide confirmación (confirmDisconnectAll()) y borra todas las filas menos la actual. La contraseña no cambia.

Dos requisitos. La lista lee la base de datos, así que sólo funciona con SESSION_DRIVER=database, que .env.example ya trae, y con la tabla sessions de las migraciones por omisión; con el driver file la tarjeta dice que no se encontraron dispositivos conectados. El país sale de App\Services\CountryDetectionService::detectFromIp(): una IP privada, que es toda petición en desarrollo local, regresa COUNTRY_CODE_FALLBACK; una IP pública se consulta en ipapi.co con dos segundos de espera, y una consulta fallida deja la ubicación vacía.

Eliminar cuenta

Eliminar abre un diálogo de confirmación (confirmDeletion()). Aceptar ejecuta deleteAccount(): cierra la sesión de la persona, elimina el usuario y redirige a /. El modelo User usa SoftDeletes, así que la fila se queda con deleted_at puesto aunque el diálogo anuncie una eliminación permanente, y nada más se borra: notificaciones, sesiones y registros relacionados siguen apuntando al id. Decide qué tiene que hacer tu producto con ellos y hazlo en un observer o en deleteAccount().

Una persona cuya suscripción todavía puede cobrarle no puede eliminar su cuenta. Antes de cerrar ninguna sesión, deleteAccount() pregunta User::hasActiveSubscription(); si es verdadero, la cuenta y la sesión se quedan, y un diálogo le pide cancelar la suscripción en Planes, con un botón que lleva ahí. La misma regla vive en UserObserver::deleting(), así que eliminar al usuario desde administración, a la papelera o para siempre, también se rechaza, con el error Este usuario tiene una suscripción activa. Cancélala antes de eliminar al usuario. Un usuario que ya está en la papelera se restaura primero, y se cancela la suscripción, antes de poder eliminarlo para siempre. Nada se cancela automáticamente. Una suscripción bloquea cuando está activa, en prueba, con pago vencido, sin pagar o incompleta, no tiene la cancelación pedida (ends_at vacío) y tiene al menos un precio de pago: un plan gratuito, una suscripción cancelada o una que termina al final de su periodo no bloquean. Sin el paquete de facturación, o con él apagado, nada bloquea.

El centro de notificaciones

/account/notifications lista las notificaciones de la cuenta, veinte por página, las no leídas primero y luego las más recientes, que es como las ordena User::notifications(). Cada fila es un enlace a la url de la notificación (# cuando no tiene) con su imagen, su icono, su título, su descripción y una fecha relativa; las filas no leídas tienen fondo ámbar.

El centro de notificaciones, con las filas no leídas primero

Las filas son App\Models\DatabaseNotification, el modelo de Laravel más cuatro accesores: is_read (read_at tiene valor), image (la imagen guardada a través de la miniatura b, o config('app.icon') cuando no hay), url y target (_self por omisión).

Abrir el centro no marca nada como leído. Eso pasa desde la campana de la barra superior, App\Livewire\Auth\Notifications\Notification: muestra el conteo de no leídas, las diez primeras notificaciones agrupadas por día, y al hacer clic en una la marca como leída, mientras que Marcar como leído marca todas las pendientes. Cómo se crean las notificaciones y qué canales toman está en /help/send-notifications.

Avisos

Con FEATURE_ANNOUNCEMENTS=true, el encabezado muestra un megáfono, App\Livewire\Auth\Announcements\Dropdown, con el conteo de avisos no leídos (9+ a partir de diez) y los diez publicados más recientes. /account/announcements los lista de diez en diez con los primeros 150 caracteres de cada uno, y la página del aviso muestra el Markdown completo con su fecha de publicación.

La lista de anuncios en /account/announcements

El estado de lectura es una sola marca de tiempo, users.last_announcement_read_at: un aviso está sin leer cuando se publicó después de ella. Abrir cualquier página de aviso la pone en ahora, y lo mismo hace Marcar como leído en el desplegable, así que ambos marcan todo como leído de una vez; la página de lista no cambia nada. Escribir y publicar avisos está en /help/announcements.

Referidos

Con FEATURE_REFERRALS_ENABLED=true, /account/referrals muestra el enlace de referido de la persona con un botón Copiar enlace, la recompensa por registro y el porcentaje de recompensa por suscripción pagada, el dinero virtual que ha generado, y una tabla de los usuarios que se registraron con su enlace. El programa, sus recompensas y su cookie están en /help/referrals.