From be74958b35080e2d8aa300a97a65e1679b43235e Mon Sep 17 00:00:00 2001 From: LuizGarbini Date: Fri, 3 Apr 2026 16:16:13 -0300 Subject: [PATCH] Add onboarding and error handling UI for multiple languages --- apps/web/public/dictionaries/de-DE.json | 38 +++++++++++++++- apps/web/public/dictionaries/en-US.json | 38 +++++++++++++++- apps/web/public/dictionaries/es-ES.json | 38 +++++++++++++++- apps/web/public/dictionaries/fr-FR.json | 38 +++++++++++++++- apps/web/public/dictionaries/it-IT.json | 38 +++++++++++++++- apps/web/public/dictionaries/ja-JP.json | 38 +++++++++++++++- apps/web/public/dictionaries/pt-BR.json | 38 +++++++++++++++- apps/web/src/app/[lang]/error.tsx | 53 ++++++++++++++++++++++ apps/web/src/app/global-error.tsx | 60 +++++++++++++++++++++++++ 9 files changed, 372 insertions(+), 7 deletions(-) create mode 100644 apps/web/src/app/[lang]/error.tsx create mode 100644 apps/web/src/app/global-error.tsx diff --git a/apps/web/public/dictionaries/de-DE.json b/apps/web/public/dictionaries/de-DE.json index 8ea1b61c..ccdae440 100644 --- a/apps/web/public/dictionaries/de-DE.json +++ b/apps/web/public/dictionaries/de-DE.json @@ -887,5 +887,41 @@ "feature_stats_title": "Sieh dir deine Statistiken an", "feature_stats_description": "Visualisiere deine Gewohnheiten mit detaillierten Statistiken und Einblicken.", "app_section_title": "Nimm Plotwist mit", - "app_section_subtitle": "Verfolge unterwegs mit der Plotwist iOS-App. Wische zum Entdecken, verfolge Episoden und verpasse nie einen Titel." + "app_section_subtitle": "Verfolge unterwegs mit der Plotwist iOS-App. Wische zum Entdecken, verfolge Episoden und verpasse nie einen Titel.", + "onboarding": { + "welcome_title": "Verfolge, entdecke und verpasse keinen Titel", + "welcome_subtitle": "Tritt der Gemeinschaft der Film- und Serienliebhaber bei.", + "get_started": "Los geht's", + "name_title": "Sag uns deinen Namen, um Plotwist zu deinem zu machen", + "name_placeholder": "Dein Name", + "content_types_title": "Was schaust du am liebsten?", + "content_types_movie": "Filme", + "content_types_tv": "Serien", + "content_types_anime": "Anime", + "content_types_dorama": "Dorama", + "genres_title": "Wähle deine Lieblingsgenres", + "genres_subtitle": "Wähle mindestens ein Genre", + "genres_select_prompt": "Wähle ein Genre", + "swiper_title": "Titel entdecken", + "swiper_subtitle": "Wische zur Seite, um zu deiner Liste hinzuzufügen", + "swiper_watched": "Gesehen", + "swiper_watching": "Laufend", + "swiper_want_to_watch": "Möchte ich sehen", + "swiper_skip": "Überspringen", + "swiper_empty": "Keine Titel mit diesen Einstellungen gefunden.", + "swiper_fetching": "Suche Titel...", + "swiper_finish_ready": "Los geht's!", + "swiper_finish_remaining": "Titel übrig", + "celebration_title": "Alles bereit!", + "celebration_subtitle": "Dein Profil ist fertig. Lass uns anfangen.", + "go_to_profile": "Zum Profil", + "continue": "Weiter", + "syncing": "Profil wird gespeichert..." + }, + "error_page": { + "title": "Etwas ist schiefgelaufen", + "description": "Ein unerwarteter Fehler ist aufgetreten. Keine Sorge, es liegt nicht an dir.", + "try_again": "Erneut versuchen", + "go_home": "Zur Startseite" + } } diff --git a/apps/web/public/dictionaries/en-US.json b/apps/web/public/dictionaries/en-US.json index 1aa780b4..e1059ad3 100644 --- a/apps/web/public/dictionaries/en-US.json +++ b/apps/web/public/dictionaries/en-US.json @@ -889,5 +889,41 @@ "feature_stats_title": "See your stats", "feature_stats_description": "Visualize your watching habits with detailed statistics and insights.", "app_section_title": "Take Plotwist with you", - "app_section_subtitle": "Track on the go with the Plotwist iOS app. Swipe to discover, track episodes, and never miss a title." + "app_section_subtitle": "Track on the go with the Plotwist iOS app. Swipe to discover, track episodes, and never miss a title.", + "onboarding": { + "welcome_title": "Track, discover and never miss a title", + "welcome_subtitle": "Join the community of movie and TV show lovers.", + "get_started": "Get started", + "name_title": "Tell us your name so we can make Plotwist feel like yours", + "name_placeholder": "Your name", + "content_types_title": "What do you like to watch?", + "content_types_movie": "Movies", + "content_types_tv": "TV Series", + "content_types_anime": "Anime", + "content_types_dorama": "K-Drama", + "genres_title": "Pick your favorite genres", + "genres_subtitle": "Select at least one genre", + "genres_select_prompt": "Select a genre", + "swiper_title": "Discover titles", + "swiper_subtitle": "Swipe sideways to add to your list", + "swiper_watched": "Watched", + "swiper_watching": "Watching", + "swiper_want_to_watch": "Want to watch", + "swiper_skip": "Skip", + "swiper_empty": "No titles found with these preferences.", + "swiper_fetching": "Fetching titles...", + "swiper_finish_ready": "Let's go!", + "swiper_finish_remaining": "titles to go", + "celebration_title": "You're all set!", + "celebration_subtitle": "Your profile is ready. Let's start tracking.", + "go_to_profile": "Go to Profile", + "continue": "Continue", + "syncing": "Saving profile..." + }, + "error_page": { + "title": "Something went wrong", + "description": "An unexpected error occurred. Don't worry, it's not your fault.", + "try_again": "Try again", + "go_home": "Go to home" + } } diff --git a/apps/web/public/dictionaries/es-ES.json b/apps/web/public/dictionaries/es-ES.json index b647d487..27d9985e 100644 --- a/apps/web/public/dictionaries/es-ES.json +++ b/apps/web/public/dictionaries/es-ES.json @@ -891,5 +891,41 @@ "feature_stats_title": "Mira tus estadísticas", "feature_stats_description": "Visualiza tus hábitos con estadísticas detalladas e insights.", "app_section_title": "Lleva Plotwist contigo", - "app_section_subtitle": "Sigue desde cualquier lugar con la app de Plotwist para iOS. Desliza para descubrir, sigue episodios y nunca te pierdas un título." + "app_section_subtitle": "Sigue desde cualquier lugar con la app de Plotwist para iOS. Desliza para descubrir, sigue episodios y nunca te pierdas un título.", + "onboarding": { + "welcome_title": "Sigue, descubre y no te pierdas ningún título", + "welcome_subtitle": "Únete a la comunidad de amantes del cine y series.", + "get_started": "Empezar", + "name_title": "Dinos tu nombre para hacer que Plotwist sea tuyo", + "name_placeholder": "Tu nombre", + "content_types_title": "¿Qué prefieres ver?", + "content_types_movie": "Películas", + "content_types_tv": "Series", + "content_types_anime": "Anime", + "content_types_dorama": "Dorama", + "genres_title": "Elige tus géneros favoritos", + "genres_subtitle": "Selecciona al menos un género", + "genres_select_prompt": "Selecciona un género", + "swiper_title": "Descubre títulos", + "swiper_subtitle": "Desliza hacia los lados para agregar a tu lista", + "swiper_watched": "Visto", + "swiper_watching": "Viendo", + "swiper_want_to_watch": "Quiero ver", + "swiper_skip": "Saltar", + "swiper_empty": "No se encontraron títulos con estas preferencias.", + "swiper_fetching": "Buscando títulos...", + "swiper_finish_ready": "¡Vamos!", + "swiper_finish_remaining": "títulos faltan", + "celebration_title": "¡Todo listo!", + "celebration_subtitle": "Tu perfil está listo. Empecemos.", + "go_to_profile": "Ir a Perfil", + "continue": "Continuar", + "syncing": "Guardando perfil..." + }, + "error_page": { + "title": "Algo salió mal", + "description": "Ocurrió un error inesperado. No te preocupes, no es tu culpa.", + "try_again": "Intentar de nuevo", + "go_home": "Ir al inicio" + } } diff --git a/apps/web/public/dictionaries/fr-FR.json b/apps/web/public/dictionaries/fr-FR.json index 87b01ddd..a3485e7f 100644 --- a/apps/web/public/dictionaries/fr-FR.json +++ b/apps/web/public/dictionaries/fr-FR.json @@ -893,5 +893,41 @@ "feature_stats_title": "Consultez vos statistiques", "feature_stats_description": "Visualisez vos habitudes avec des statistiques détaillées.", "app_section_title": "Emportez Plotwist avec vous", - "app_section_subtitle": "Suivez vos titres partout avec l'app Plotwist pour iOS. Glissez pour découvrir, suivez les épisodes et ne manquez jamais un titre." + "app_section_subtitle": "Suivez vos titres partout avec l'app Plotwist pour iOS. Glissez pour découvrir, suivez les épisodes et ne manquez jamais un titre.", + "onboarding": { + "welcome_title": "Suivez, découvrez et ne manquez jamais un titre", + "welcome_subtitle": "Rejoignez la communauté des amateurs de films et séries.", + "get_started": "Commencer", + "name_title": "Dites-nous votre nom pour personnaliser Plotwist", + "name_placeholder": "Votre nom", + "content_types_title": "Que préférez-vous regarder ?", + "content_types_movie": "Films", + "content_types_tv": "Séries", + "content_types_anime": "Anime", + "content_types_dorama": "Dramas", + "genres_title": "Choisissez vos genres préférés", + "genres_subtitle": "Sélectionnez au moins un genre", + "genres_select_prompt": "Sélectionnez un genre", + "swiper_title": "Découvrez des titres", + "swiper_subtitle": "De glisser sur les côtés pour ajouter à votre liste", + "swiper_watched": "Vu", + "swiper_watching": "En cours", + "swiper_want_to_watch": "À voir", + "swiper_skip": "Passer", + "swiper_empty": "Aucun titre trouvé avec ces préférences.", + "swiper_fetching": "Recherche de titres...", + "swiper_finish_ready": "Allons-y !", + "swiper_finish_remaining": "titres restants", + "celebration_title": "Tout est prêt !", + "celebration_subtitle": "Votre profil est prêt. Commençons.", + "go_to_profile": "Aller au profil", + "continue": "Continuer", + "syncing": "Enregistrement du profil..." + }, + "error_page": { + "title": "Quelque chose s'est mal passé", + "description": "Une erreur inattendue s'est produite. Ne vous inquiétez pas, ce n'est pas de votre faute.", + "try_again": "Réessayer", + "go_home": "Retour à l'accueil" + } } diff --git a/apps/web/public/dictionaries/it-IT.json b/apps/web/public/dictionaries/it-IT.json index c59a25b0..cc936ac8 100644 --- a/apps/web/public/dictionaries/it-IT.json +++ b/apps/web/public/dictionaries/it-IT.json @@ -890,5 +890,41 @@ "feature_stats_title": "Guarda le tue statistiche", "feature_stats_description": "Visualizza le tue abitudini con statistiche dettagliate.", "app_section_title": "Porta Plotwist con te", - "app_section_subtitle": "Segui ovunque con l'app Plotwist per iOS. Scorri per scoprire, segui gli episodi e non perdere mai un titolo." + "app_section_subtitle": "Segui ovunque con l'app Plotwist per iOS. Scorri per scoprire, segui gli episodi e non perdere mai un titolo.", + "onboarding": { + "welcome_title": "Tieni traccia, scopri e non perdere mai un titolo", + "welcome_subtitle": "Unisciti alla comunità degli amanti di film e serie TV.", + "get_started": "Inizia", + "name_title": "Dicci il tuo nome per rendere Plotwist tuo", + "name_placeholder": "Il tuo nome", + "content_types_title": "Cosa preferisci guardare?", + "content_types_movie": "Film", + "content_types_tv": "Serie", + "content_types_anime": "Anime", + "content_types_dorama": "Dorama", + "genres_title": "Scegli i tuoi generi preferiti", + "genres_subtitle": "Seleziona almeno un genere", + "genres_select_prompt": "Seleziona un genere", + "swiper_title": "Scopri titoli", + "swiper_subtitle": "Scorri di lato per aggiungere alla tua lista", + "swiper_watched": "Visto", + "swiper_watching": "In corso", + "swiper_want_to_watch": "Voglio vedere", + "swiper_skip": "Salta", + "swiper_empty": "Nessun titolo trovato con queste preferenze.", + "swiper_fetching": "Ricerca titoli...", + "swiper_finish_ready": "Andiamo!", + "swiper_finish_remaining": "titoli mancanti", + "celebration_title": "Tutto pronto!", + "celebration_subtitle": "Il tuo profilo è pronto. Iniziamo.", + "go_to_profile": "Vai al Profilo", + "continue": "Continua", + "syncing": "Salvataggio profilo..." + }, + "error_page": { + "title": "Qualcosa è andato storto", + "description": "Si è verificato un errore imprevisto. Non preoccuparti, non è colpa tua.", + "try_again": "Riprova", + "go_home": "Vai alla home" + } } diff --git a/apps/web/public/dictionaries/ja-JP.json b/apps/web/public/dictionaries/ja-JP.json index 1aa88ef0..ef1d7548 100644 --- a/apps/web/public/dictionaries/ja-JP.json +++ b/apps/web/public/dictionaries/ja-JP.json @@ -893,5 +893,41 @@ "feature_stats_title": "統計を確認", "feature_stats_description": "詳細な統計とインサイトで視聴習慣を可視化。", "app_section_title": "Plotwistを持ち歩こう", - "app_section_subtitle": "Plotwist iOSアプリでどこでも追跡。スワイプで発見、エピソードを追跡、タイトルを見逃さない。" + "app_section_subtitle": "Plotwist iOSアプリでどこでも追跡。スワイプで発見、エピソードを追跡、タイトルを見逃さない。", + "onboarding": { + "welcome_title": "記録して、発見して、見逃さない", + "welcome_subtitle": "映画やドラマ好きのコミュニティに参加しよう。", + "get_started": "はじめる", + "name_title": "Plotwistをあなたらしくするために名前を教えてください", + "name_placeholder": "あなたの名前", + "content_types_title": "何を見るのが好きですか?", + "content_types_movie": "映画", + "content_types_tv": "ドラマ・アニメ", + "content_types_anime": "アニメ", + "content_types_dorama": "韓国ドラマ", + "genres_title": "好きなジャンルを選んでください", + "genres_subtitle": "少なくとも1つのジャンルを選択してください", + "genres_select_prompt": "ジャンルを選択", + "swiper_title": "タイトルを発見", + "swiper_subtitle": "左右にスワイプしてリストに追加", + "swiper_watched": "見た", + "swiper_watching": "見ている", + "swiper_want_to_watch": "見たい", + "swiper_skip": "スキップ", + "swiper_empty": "これらの設定で見つかったタイトルはありません。", + "swiper_fetching": "タイトルを検索中...", + "swiper_finish_ready": "行こう!", + "swiper_finish_remaining": "タイトル残り", + "celebration_title": "準備完了!", + "celebration_subtitle": "プロフィールが完成しました。始めましょう。", + "go_to_profile": "プロフィールへ", + "continue": "続ける", + "syncing": "プロフィールを保存中..." + }, + "error_page": { + "title": "問題が発生しました", + "description": "予期しないエラーが発生しました。ご心配なく、あなたのせいではありません。", + "try_again": "もう一度試す", + "go_home": "ホームへ戻る" + } } diff --git a/apps/web/public/dictionaries/pt-BR.json b/apps/web/public/dictionaries/pt-BR.json index 9c24decb..7c5055e0 100644 --- a/apps/web/public/dictionaries/pt-BR.json +++ b/apps/web/public/dictionaries/pt-BR.json @@ -892,5 +892,41 @@ "feature_stats_title": "Veja suas estatísticas", "feature_stats_description": "Visualize seus hábitos com estatísticas detalhadas e insights.", "app_section_title": "Leve o Plotwist com você", - "app_section_subtitle": "Acompanhe de qualquer lugar com o app Plotwist para iOS. Deslize para descobrir, acompanhe episódios e nunca perca um título." + "app_section_subtitle": "Acompanhe de qualquer lugar com o app Plotwist para iOS. Deslize para descobrir, acompanhe episódios e nunca perca um título.", + "onboarding": { + "welcome_title": "Acompanhe, descubra e nunca perca um título", + "welcome_subtitle": "Junte-se à comunidade de amantes de filmes e séries.", + "get_started": "Começar", + "name_title": "Diga-nos seu nome para tornar o Plotwist a sua cara", + "name_placeholder": "Seu nome", + "content_types_title": "O que você prefere assistir?", + "content_types_movie": "Filmes", + "content_types_tv": "Séries", + "content_types_anime": "Anime", + "content_types_dorama": "Dorama", + "genres_title": "Escolha seus gêneros favoritos", + "genres_subtitle": "Selecione ao menos um gênero", + "genres_select_prompt": "Selecione um gênero", + "swiper_title": "Descubra títulos", + "swiper_subtitle": "Arraste para os lados para adicionar à sua lista", + "swiper_watched": "Já assisti", + "swiper_watching": "Assistindo", + "swiper_want_to_watch": "Quero assistir", + "swiper_skip": "Pular", + "swiper_empty": "Nenhum título localizado com essas preferências.", + "swiper_fetching": "Buscando títulos...", + "swiper_finish_ready": "Vamos lá!", + "swiper_finish_remaining": "títulos faltando", + "celebration_title": "Tudo pronto!", + "celebration_subtitle": "Seu perfil está pronto. Vamos começar.", + "go_to_profile": "Ir para o Perfil", + "continue": "Continuar", + "syncing": "Salvando perfil..." + }, + "error_page": { + "title": "Algo deu errado", + "description": "Um erro inesperado aconteceu. Não se preocupe, não é sua culpa.", + "try_again": "Tentar novamente", + "go_home": "Ir para o início" + } } diff --git a/apps/web/src/app/[lang]/error.tsx b/apps/web/src/app/[lang]/error.tsx new file mode 100644 index 00000000..a598a207 --- /dev/null +++ b/apps/web/src/app/[lang]/error.tsx @@ -0,0 +1,53 @@ +'use client' + +import { useEffect } from 'react' +import { useParams, useRouter } from 'next/navigation' +import { AlertCircle } from 'lucide-react' +import { Button } from '@plotwist/ui/components/ui/button' +import { useLanguage } from '@/context/language' + +export default function ErrorPage({ + error, + reset, +}: { + error: Error & { digest?: string } + reset: () => void +}) { + const { dictionary } = useLanguage() + const { lang } = useParams() + const router = useRouter() + + useEffect(() => { + console.error(error) + }, [error]) + + const { error_page } = dictionary + + return ( +
+
+
+ +
+ +
+

+ {error_page.title} +

+ +

+ {error_page.description} +

+
+
+ +
+ + + +
+
+ ) +} diff --git a/apps/web/src/app/global-error.tsx b/apps/web/src/app/global-error.tsx new file mode 100644 index 00000000..b44ba5af --- /dev/null +++ b/apps/web/src/app/global-error.tsx @@ -0,0 +1,60 @@ +'use client' + +import '@plotwist/ui/globals.css' + +import { useEffect } from 'react' +import { AlertCircle } from 'lucide-react' + +export default function GlobalError({ + error, + reset, +}: { + error: Error & { digest?: string } + reset: () => void +}) { + useEffect(() => { + console.error(error) + }, [error]) + + return ( + + +
+
+
+ +
+ +
+

+ Something went wrong +

+ +

+ An unexpected error occurred. Don't worry, it's not + your fault. +

+
+
+ +
+ + Go to home + + + +
+
+ + + ) +}