trypost/lang/es/accounts.php
Paulo Castellano 173a1e4c61
Fix Facebook Page connect pagination (#212) (#253)
* Fix Facebook and Instagram-via-Facebook Page connect pagination.

Follow Graph API paging.next on /me/accounts so authorized non-first Pages are found and multi-Page accounts get the picker instead of silently connecting the first result.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Paginate Meta accounts until paging.next is exhausted.

Drop the artificial 50-page cap and stop only when there is no next URL, or the same request URL repeats (broken pagination loop).

Co-authored-by: Cursor <cursoragent@cursor.com>

* Redact tokens in Graph pagination logs and harden test coverage.

Cover happy-path and failure cases for Meta /me/accounts pagination, including mid-loop failures, invalid paging.next, and Instagram pages without a linked IG account.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Fail closed on incomplete Meta accounts pagination.

If a later /me/accounts page fails after earlier pages succeeded, throw instead of returning a truncated list that could auto-connect the wrong Page. Also revert the IG detail timeout that could wipe the whole connect list.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Simplify Graph pagination helpers and page fetchers.

Bake the first request query into the URL, drop requestKey, and let IncompleteGraphPaginationException bubble from the controllers without catch/rethrow noise.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Move incomplete pagination exception under Social\Meta.

Colocate it with GraphPaginator so the Meta scope is clear from the namespace instead of a generic Social exception name.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Rename pagination exception to IncompleteMetaGraphPaginationException.

Keep it under Exceptions/Social with Meta in the class name instead of moving it into Services.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Make GraphPaginator results explicit before mapping pages.

Assign the paginated accounts to a variable first so the Facebook and Instagram-via-Facebook fetchers read more clearly.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Build Meta Graph pagination URLs with Laravel Uri.

Replace manual http_build_query concatenation with Uri::of()->withQuery().

Co-authored-by: Cursor <cursoragent@cursor.com>

* Use Laravel HTTP and Uri helpers in Meta Graph pagination.

Prefer response collect/json key access, filled(), and Uri path parsing over manual array and parse_url handling.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Simplify graphVersion using Uri path and str().

Drop basename and native string casts; Uri::path() already yields the Graph API version segment.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Drop unnecessary str() around graph API config.

Uri: :of() already accepts the string returned by config().
Co-authored-by: Cursor <cursoragent@cursor.com>

* Simplify GraphPaginator with Laravel helpers.

Consolidate failure handling via abort(), and use collect, when, throw_if, and Uri::value() for a shorter pagination loop.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Refactor social OAuth page/channel selection handling. Update selectPage and selectChannel methods in Facebook, Instagram, and YouTube controllers to return popup callbacks instead of redirecting on session expiration or workspace not found. Enhance HandleInertiaRequests middleware to prevent deferring onboarding progress on social OAuth popup routes. Add tests to verify behavior for expired sessions and onboarding progress.

* Unify Instagram connect behind one card with a method picker.

Hide the Instagram-via-Facebook grid card and offer Instagram Login vs Facebook Pages from a single network entry, matching LinkedIn.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Move social popup onboarding assertions into connection tests.

Cover the deferred-prop popup regression on Facebook, Instagram, and YouTube select routes instead of a synthetic onboarding share check.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Stop suppressing onboarding defer on all social routes.

Override onboardingProgress only in popupCallback so picker pages stay deferred and the close page does not re-hit select after session clear.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Always open the Instagram method dialog on connect.

Drop connectMethods and the single-method OAuth shortcut; the picker always offers both Login and Facebook Pages.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Filter Instagram dialog options by enabled platforms.

Keep always opening the method picker, but only list OAuth entry points that are turned on.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Extract Instagram connect methods into a dedicated helper.

Keep connectableOptions focused on shaping grid options while the enabled OAuth list lives in instagramConnectMethods().

Co-authored-by: Cursor <cursoragent@cursor.com>

* Harden Meta Graph pagination and localize Instagram connect copy.

Fail closed on Graph request errors and pathological paging, keep Instagram connect going when profile detail lookups time out, and translate the Instagram method dialog strings.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-08 12:01:46 -03:00

157 lines
7.6 KiB
PHP

<?php
return [
'title' => 'Conexiones',
'page_title' => 'Cuentas Sociales',
'description' => 'Resumen de todas tus cuentas sociales conectadas',
'connect_cta' => 'Conectar',
'not_connected' => 'No conectado',
'connect' => 'Conectar',
'connection_lost' => 'Conexión perdida',
'reconnect' => 'Reconectar',
'reconnect_account' => 'Reconectar cuenta',
'view_profile' => 'Ver perfil',
'disconnect' => 'Desconectar',
'descriptions' => [
'linkedin' => 'Conecta tu perfil de LinkedIn o página de empresa',
'linkedin-page' => 'Conecta una página de empresa de LinkedIn',
'x' => 'Conecta tu cuenta de X (Twitter)',
'tiktok' => 'Conecta tu cuenta de TikTok',
'youtube' => 'Conecta un canal de YouTube',
'facebook' => 'Conecta una página de Facebook',
'instagram' => 'Conecta vía Instagram Login o páginas de Facebook',
'instagram-facebook' => 'Conecta Instagram vía página de Facebook',
'threads' => 'Conecta tu cuenta de Threads',
'pinterest' => 'Conecta tu cuenta de Pinterest',
'bluesky' => 'Conecta tu cuenta de Bluesky',
'mastodon' => 'Conecta tu cuenta de Mastodon',
'telegram' => 'Conecta un canal o grupo de Telegram',
'discord' => 'Conecta un servidor de Discord',
],
'disconnect_modal' => [
'title' => 'Desconectar cuenta',
'description' => '¿Estás seguro de que deseas desconectar esta cuenta? Puedes volver a conectarla en cualquier momento.',
'confirm' => 'Desconectar',
'cancel' => 'Cancelar',
],
'bluesky' => [
'title' => 'Conectar Bluesky',
'description' => 'Introduce tus credenciales para conectar',
'email' => 'Correo electrónico',
'email_placeholder' => 'tuusuario.bsky.social',
'app_password' => 'Contraseña de app',
'app_password_placeholder' => 'xxxx-xxxx-xxxx-xxxx',
'app_password_hint' => 'Usa una <strong>Contraseña de App</strong> por seguridad. Crea una en <a href="https://bsky.app/settings/app-passwords" target="_blank" class="underline">bsky.app/settings</a>.',
'submit' => 'Conectar Bluesky',
'submitting' => 'Conectando...',
],
'mastodon' => [
'title' => 'Conectar Mastodon',
'description' => 'Introduce tu instancia de Mastodon',
'instance_url' => 'URL de la instancia',
'instance_placeholder' => 'https://mastodon.social',
'instance_hint' => 'Introduce la URL de tu instancia de Mastodon (ej: mastodon.social, techhub.social)',
'submit' => 'Continuar con Mastodon',
'submitting' => 'Conectando...',
],
'telegram' => [
'title' => 'Conectar Telegram',
'description' => 'Vincula un canal o grupo',
'step_admin' => 'Añade :bot como administrador de tu canal o grupo de Telegram.',
'step_command' => 'Publica este comando en el canal o grupo:',
'waiting' => 'Esperando a que el canal se conecte…',
'connected' => '¡Canal conectado!',
'connected_toast' => '¡Canal de Telegram conectado correctamente!',
'copied_toast' => 'Comando copiado al portapapeles',
'copy_tooltip' => 'Copiar comando',
'expired' => 'Este código ha caducado. Genera uno nuevo para volver a intentarlo.',
'new_code' => 'Generar un nuevo código',
'retry' => 'Reintentar',
'error_generic' => 'No se pudo iniciar la conexión. Inténtalo de nuevo.',
'network_taken' => 'Este workspace ya tiene un canal de Telegram conectado. Desconéctalo primero.',
],
'facebook' => [
'title' => 'Seleccionar página de Facebook',
'description' => 'Elige qué página deseas conectar',
'no_pages' => 'No se encontraron páginas',
'no_pages_description' => 'No eres administrador de ninguna página de Facebook.',
'page_label' => 'Página de Facebook',
'view' => 'Ver',
'choose' => 'Elegir',
],
'instagram_facebook' => [
'title' => 'Seleccionar cuenta de Instagram',
'description' => 'Elige qué cuenta de Instagram deseas conectar',
'no_pages' => 'No se encontraron cuentas de Instagram',
'no_pages_description' => 'No se encontraron páginas de Facebook con cuentas Instagram Business vinculadas.',
'view' => 'Ver',
'choose' => 'Elegir',
],
'instagram_connect' => [
'title' => 'Conectar Instagram',
'description' => 'Elige cómo quieres conectar tu cuenta de Instagram',
'standalone_title' => 'Instagram Login',
'standalone_description' => 'Inicia sesión con tu cuenta profesional de Instagram',
'facebook_title' => 'Páginas de Facebook',
'facebook_description' => 'Conecta una cuenta de Instagram vinculada a una página de Facebook',
],
'linkedin' => [
'title' => 'Seleccionar página de LinkedIn',
'description' => 'Elige qué página deseas conectar',
'no_pages' => 'No se encontraron páginas',
'no_pages_description' => 'No eres administrador de ninguna página de LinkedIn.',
'page_label' => 'Página de LinkedIn',
'select_title' => '¿Dónde quieres publicar?',
'select_subtitle' => 'Publica como tú mismo o elige una página de empresa que administres.',
'person_tag' => 'Persona',
'organization_tag' => 'Empresa',
'view' => 'Ver',
'choose' => 'Elegir',
],
'flash' => [
'disconnected' => '¡Cuenta desconectada correctamente!',
'connected' => '¡Cuenta conectada correctamente!',
'session_expired' => 'Sesión expirada. Inténtalo de nuevo.',
'workspace_not_found' => 'Workspace no encontrado.',
'activated' => '¡Cuenta activada!',
'deactivated' => '¡Cuenta desactivada!',
'already_connected' => 'Esta plataforma ya está conectada.',
'no_youtube_channels' => 'No se encontraron canales de YouTube. Crea un canal primero.',
],
'popup_callback' => [
'title_success' => 'Conectado',
'title_error' => 'Error',
'closing' => 'Esta ventana se cerrará automáticamente...',
'manual_close' => 'Puedes cerrar esta ventana.',
'popup_blocked' => 'No se pudo abrir la ventana de conexión. Permite las ventanas emergentes e inténtalo de nuevo.',
'connected' => '¡Cuenta conectada!',
'reconnected' => '¡Cuenta reconectada!',
'error_connecting' => 'Error al conectar la cuenta. Inténtalo de nuevo.',
'network_taken' => 'Este workspace ya tiene una cuenta para esta red. Desconéctala primero.',
'error_connecting_page' => 'Error al conectar la página. Inténtalo de nuevo.',
'error_connecting_channel' => 'Error al conectar el canal. Inténtalo de nuevo.',
'session_expired' => 'Sesión expirada. Inténtalo de nuevo.',
'workspace_not_found' => 'Workspace no encontrado.',
'invalid_state' => 'Estado inválido. Inténtalo de nuevo.',
'failed_to_authenticate' => 'Falló la autenticación.',
'failed_to_get_profile' => 'Falló al obtener el perfil.',
'page_not_found' => 'Página no encontrada.',
'channel_not_found' => 'Canal no encontrado.',
'no_facebook_pages' => 'No se encontraron páginas de Facebook. Debes ser administrador de al menos una página.',
'no_facebook_instagram_pages' => 'No se encontraron páginas de Facebook con cuentas de Instagram vinculadas.',
'no_youtube_channels' => 'No se encontraron canales de YouTube. Crea un canal primero.',
'not_linkedin_admin' => 'No eres administrador de ninguna página de LinkedIn.',
],
];