diff --git a/locales/ar/error.json b/locales/ar/error.json index 0fbb78930f37..3769176958a6 100644 --- a/locales/ar/error.json +++ b/locales/ar/error.json @@ -1,4 +1,15 @@ { + "error": { + "backHome": "العودة إلى الصفحة الرئيسية", + "desc": "حاول مرة أخرى في وقت لاحق، أو عد إلى العالم المألوف", + "retry": "إعادة التحميل", + "title": "واجهت الصفحة مشكلة ما.." + }, + "notFound": { + "backHome": "العودة إلى الصفحة الرئيسية", + "desc": "لم نتمكن من العثور على الصفحة التي تبحث عنها، يرجى التحقق مما إذا كان الرابط صحيحًا", + "title": "هل دخلت إلى مجال غير معروف؟" + }, "pluginSettings": { "desc": "أكمل الإعدادات التالية لبدء استخدام هذا المكون الإضافي", "title": "تكوين مكون الإضافة {{name}}" diff --git a/locales/bg-BG/error.json b/locales/bg-BG/error.json index e5ead67d192e..e1df23ff1118 100644 --- a/locales/bg-BG/error.json +++ b/locales/bg-BG/error.json @@ -1,4 +1,15 @@ { + "error": { + "backHome": "Върни се в началото", + "desc": "Опитайте отново по-късно или се върнете в познатия свят", + "retry": "Опитай отново", + "title": "Страницата се е сблъскала с проблем.." + }, + "notFound": { + "backHome": "Върни се в началото", + "desc": "Не можем да намерим страницата, която търсите. Моля, проверете дали връзката е правилна.", + "title": "Влезли сте в неизвестна територия?" + }, "pluginSettings": { "desc": "Попълнете следната конфигурация, за да започнете да използвате този плъгин", "title": "Настройки на плъгина {{name}}" diff --git a/locales/de-DE/error.json b/locales/de-DE/error.json index 696364ef6989..a6b419d7c699 100644 --- a/locales/de-DE/error.json +++ b/locales/de-DE/error.json @@ -1,4 +1,15 @@ { + "error": { + "backHome": "Zurück zur Startseite", + "desc": "Versuchen Sie es später erneut oder kehren Sie in die bekannte Welt zurück", + "retry": "Erneut laden", + "title": "Ein Problem ist aufgetreten auf der Seite.." + }, + "notFound": { + "backHome": "Zurück zur Startseite", + "desc": "Die von Ihnen gesuchte Seite konnte nicht gefunden werden. Bitte überprüfen Sie, ob der Link korrekt ist.", + "title": "In unbekanntes Gebiet geraten?" + }, "pluginSettings": { "desc": "Führen Sie die folgende Konfiguration durch, um das Plugin zu verwenden", "title": "{{name}} Plugin-Konfiguration" diff --git a/locales/en-US/error.json b/locales/en-US/error.json index 98ce152caae1..b3b7fccf636d 100644 --- a/locales/en-US/error.json +++ b/locales/en-US/error.json @@ -1,4 +1,15 @@ { + "error": { + "backHome": "Back to Home", + "desc": "Give it a try later, or go back to the known world.", + "retry": "Reload", + "title": "Oops, something went wrong.." + }, + "notFound": { + "backHome": "Back to Home", + "desc": "We couldn't find the page you're looking for, please check if the link is correct", + "title": "Entered Unknown Territory?" + }, "pluginSettings": { "desc": "Complete the following configuration to start using this plugin", "title": "{{name}} Plugin Settings" diff --git a/locales/es-ES/error.json b/locales/es-ES/error.json index ef32f3eae26a..631fd8739826 100644 --- a/locales/es-ES/error.json +++ b/locales/es-ES/error.json @@ -1,4 +1,15 @@ { + "error": { + "backHome": "Volver a la página de inicio", + "desc": "Inténtalo de nuevo más tarde, o regresa al mundo conocido", + "retry": "Reintentar", + "title": "Se ha producido un problema en la página.." + }, + "notFound": { + "backHome": "Volver a la página de inicio", + "desc": "No podemos encontrar la página que estás buscando, por favor verifica si el enlace es correcto", + "title": "¿Has entrado en un área desconocida?" + }, "pluginSettings": { "desc": "Complete la siguiente configuración para comenzar a usar este complemento", "title": "Configuración del complemento {{name}}" diff --git a/locales/fr-FR/error.json b/locales/fr-FR/error.json index d109e758c0cb..5a432ae323f9 100644 --- a/locales/fr-FR/error.json +++ b/locales/fr-FR/error.json @@ -1,4 +1,15 @@ { + "error": { + "backHome": "Retour à la page d'accueil", + "desc": "Réessayez plus tard, ou retournez au monde connu", + "retry": "Recharger", + "title": "Un problème est survenu sur la page.." + }, + "notFound": { + "backHome": "Retour à la page d'accueil", + "desc": "La page que vous recherchez est introuvable. Veuillez vérifier si le lien est correct.", + "title": "Êtes-vous entré dans un domaine inconnu ?" + }, "pluginSettings": { "desc": "Completez la configuration suivante pour commencer à utiliser ce plugin", "title": "Configuration du plugin {{name}}" diff --git a/locales/it-IT/error.json b/locales/it-IT/error.json index 7fca28189828..7b67e5a0f3de 100644 --- a/locales/it-IT/error.json +++ b/locales/it-IT/error.json @@ -1,4 +1,15 @@ { + "error": { + "backHome": "Torna alla homepage", + "desc": "Prova di nuovo più tardi, o torna al mondo conosciuto", + "retry": "Ricarica", + "title": "La pagina ha riscontrato un problema.." + }, + "notFound": { + "backHome": "Torna alla homepage", + "desc": "Non riusciamo a trovare la pagina che stai cercando, controlla che il link sia corretto", + "title": "Hai raggiunto un territorio sconosciuto?" + }, "pluginSettings": { "desc": "Completa la seguente configurazione per iniziare a utilizzare il plugin", "title": "Configurazione del plugin {{name}}" diff --git a/locales/ja-JP/error.json b/locales/ja-JP/error.json index b0c493633eff..c7144f339c20 100644 --- a/locales/ja-JP/error.json +++ b/locales/ja-JP/error.json @@ -1,4 +1,15 @@ { + "error": { + "backHome": "ホームに戻る", + "desc": "後で試してみるか、既知の世界に戻る", + "retry": "再読み込み", + "title": "ページに問題が発生しました.." + }, + "notFound": { + "backHome": "ホームに戻る", + "desc": "お探しのページが見つかりません。リンクが正しいかどうかをご確認ください", + "title": "未知の領域に入りましたか?" + }, "pluginSettings": { "desc": "以下の設定を完了すると、プラグインを使用することができます", "title": "{{name}} プラグイン設定" diff --git a/locales/ko-KR/error.json b/locales/ko-KR/error.json index 60ff89c3f63e..e4d58dcf975b 100644 --- a/locales/ko-KR/error.json +++ b/locales/ko-KR/error.json @@ -1,4 +1,15 @@ { + "error": { + "backHome": "홈페이지로 돌아가기", + "desc": "잠시 후 다시 시도하거나 익숙한 세계로 돌아가세요", + "retry": "다시 시도", + "title": "페이지에서 문제가 발생했습니다." + }, + "notFound": { + "backHome": "홈페이지로 돌아가기", + "desc": "찾고 있는 페이지를 찾을 수 없습니다. 링크가 올바른지 확인해주세요.", + "title": "알 수 없는 영역에 들어갔나요?" + }, "pluginSettings": { "desc": "다음 구성을 완료하면 플러그인을 사용할 수 있습니다.", "title": "{{name}} 플러그인 설정" diff --git a/locales/nl-NL/error.json b/locales/nl-NL/error.json index 4d3d69891017..e3c39e69be62 100644 --- a/locales/nl-NL/error.json +++ b/locales/nl-NL/error.json @@ -1,4 +1,15 @@ { + "error": { + "backHome": "Terug naar startpagina", + "desc": "Probeer het later opnieuw of keer terug naar de bekende wereld", + "retry": "Opnieuw proberen", + "title": "Er is een probleem opgetreden op de pagina.." + }, + "notFound": { + "backHome": "Terug naar startpagina", + "desc": "We kunnen de pagina die je zoekt niet vinden, controleer of de link juist is", + "title": "Betreden onbekend terrein?" + }, "pluginSettings": { "desc": "Voltooi de volgende instellingen om de plugin te gebruiken", "title": "{{name}} Plugin Instellingen" diff --git a/locales/pl-PL/error.json b/locales/pl-PL/error.json index 40fff23710a4..da548fe854cf 100644 --- a/locales/pl-PL/error.json +++ b/locales/pl-PL/error.json @@ -1,4 +1,15 @@ { + "error": { + "backHome": "Powrót do strony głównej", + "desc": "Spróbuj ponownie później lub wróć do znanego świata", + "retry": "Ponów próbę", + "title": "Napotkano problem na stronie.." + }, + "notFound": { + "backHome": "Powrót do strony głównej", + "desc": "Nie możemy odnaleźć strony, której szukasz. Sprawdź, czy link jest poprawny.", + "title": "Wkraczasz w nieznane terytorium?" + }, "pluginSettings": { "desc": "Wykonaj poniższą konfigurację, aby rozpocząć korzystanie z tego wtyczki", "title": "Konfiguracja wtyczki {{name}}" diff --git a/locales/pt-BR/error.json b/locales/pt-BR/error.json index 27dbae3535c4..0d478db8df95 100644 --- a/locales/pt-BR/error.json +++ b/locales/pt-BR/error.json @@ -1,4 +1,15 @@ { + "error": { + "backHome": "Voltar para a página inicial", + "desc": "Tente novamente mais tarde, ou retorne ao mundo conhecido", + "retry": "Tentar novamente", + "title": "Ocorreu um problema na página.." + }, + "notFound": { + "backHome": "Voltar para a página inicial", + "desc": "Não conseguimos encontrar a página que você está procurando, por favor, verifique se o link está correto", + "title": "Entrou em um território desconhecido?" + }, "pluginSettings": { "desc": "Complete a seguinte configuração para começar a usar este plugin", "title": "Configuração do plugin {{name}}" diff --git a/locales/ru-RU/error.json b/locales/ru-RU/error.json index 90914ad27791..2495f9b53fc5 100644 --- a/locales/ru-RU/error.json +++ b/locales/ru-RU/error.json @@ -1,4 +1,15 @@ { + "error": { + "backHome": "Вернуться на главную", + "desc": "Попробуйте позже или вернитесь в знакомый мир", + "retry": "Повторить попытку", + "title": "Произошла проблема на странице.." + }, + "notFound": { + "backHome": "Вернуться на главную", + "desc": "Мы не можем найти страницу, которую вы ищете. Пожалуйста, проверьте правильность ссылки", + "title": "Заблудились в неизведанных местах?" + }, "pluginSettings": { "desc": "Чтобы начать использовать этот плагин, выполните следующую конфигурацию", "title": "{{name}} Настройки плагина" diff --git a/locales/tr-TR/error.json b/locales/tr-TR/error.json index 0813fdda87b9..d33925ffedb2 100644 --- a/locales/tr-TR/error.json +++ b/locales/tr-TR/error.json @@ -1,4 +1,15 @@ { + "error": { + "backHome": "Ana Sayfaya Dön", + "desc": "Biraz sonra tekrar deneyin veya bilinen dünyaya geri dönün", + "retry": "Yeniden Yükle", + "title": "Sayfa bir sorunla karşılaştı.." + }, + "notFound": { + "backHome": "Ana Sayfaya Dön", + "desc": "Aradığınız sayfayı bulamadık, lütfen bağlantının doğru olduğundan emin olun", + "title": "Bilinmeyen bir alana mı girdiniz?" + }, "pluginSettings": { "desc": "Bu eklentiyi kullanmaya başlamak için aşağıdaki yapılandırmayı tamamlayın", "title": "{{name}} Eklenti Ayarları" diff --git a/locales/vi-VN/error.json b/locales/vi-VN/error.json index 7f3e5d729cb4..41ee14189ac2 100644 --- a/locales/vi-VN/error.json +++ b/locales/vi-VN/error.json @@ -1,4 +1,15 @@ { + "error": { + "backHome": "Quay về Trang chủ", + "desc": "Hãy thử lại sau, hoặc quay về thế giới đã biết", + "retry": "Thử lại", + "title": "Trang gặp một chút vấn đề.." + }, + "notFound": { + "backHome": "Quay về Trang chủ", + "desc": "Chúng tôi không thể tìm thấy trang bạn đang tìm, vui lòng kiểm tra xem liên kết có đúng không", + "title": "Bước vào vùng đất chưa biết?" + }, "pluginSettings": { "desc": "Hoàn thành cấu hình sau để bắt đầu sử dụng plugin này", "title": "Cấu hình Plugin {{name}}" diff --git a/locales/zh-CN/error.json b/locales/zh-CN/error.json index 9d2e133f10f5..2ad48b3c78a0 100644 --- a/locales/zh-CN/error.json +++ b/locales/zh-CN/error.json @@ -1,4 +1,15 @@ { + "error": { + "backHome": "返回首页", + "desc": "待会来试试,或者回到已知的世界", + "retry": "重新加载", + "title": "页面遇到一点问题.." + }, + "notFound": { + "backHome": "返回首页", + "desc": "我们找不到你正在寻找的页面,请检查链接是否正确", + "title": "进入了未知领域?" + }, "pluginSettings": { "desc": "完成以下配置,即可开始使用该插件", "title": "{{name}} 插件配置" diff --git a/locales/zh-TW/error.json b/locales/zh-TW/error.json index a42516ede6e3..1380baa6da2e 100644 --- a/locales/zh-TW/error.json +++ b/locales/zh-TW/error.json @@ -1,4 +1,15 @@ { + "error": { + "backHome": "返回首頁", + "desc": "待會再試試,或者回到已知的世界", + "retry": "重新加載", + "title": "頁面遇到一點問題.." + }, + "notFound": { + "backHome": "返回首頁", + "desc": "我們找不到您正在尋找的頁面,請檢查連結是否正確", + "title": "進入了未知領域?" + }, "pluginSettings": { "desc": "完成以下設定後,即可開始使用此外掛", "title": "{{name}} 插件設定" diff --git a/src/app/error.tsx b/src/app/error.tsx new file mode 100644 index 000000000000..071491038c70 --- /dev/null +++ b/src/app/error.tsx @@ -0,0 +1,5 @@ +'use client'; + +import dynamic from 'next/dynamic'; + +export default dynamic(() => import('@/components/Error')); diff --git a/src/app/global-error.tsx b/src/app/global-error.tsx new file mode 100644 index 000000000000..5fe10fae675d --- /dev/null +++ b/src/app/global-error.tsx @@ -0,0 +1,20 @@ +'use client'; + +import Error from 'next/error'; +import { useLayoutEffect } from 'react'; + +import { type ErrorType, sentryCaptureException } from '@/components/Error/sentryCaptureException'; + +export default function GlobalError({ error }: { error: ErrorType; reset: () => void }) { + useLayoutEffect(() => { + sentryCaptureException(error); + }, [error]); + + return ( + + + + + + ); +} diff --git a/src/app/not-found.tsx b/src/app/not-found.tsx new file mode 100644 index 000000000000..02503bc7fa46 --- /dev/null +++ b/src/app/not-found.tsx @@ -0,0 +1,3 @@ +import dynamic from 'next/dynamic'; + +export default dynamic(() => import('@/components/404')); diff --git a/src/components/404/index.tsx b/src/components/404/index.tsx new file mode 100644 index 000000000000..a33e0caf7f77 --- /dev/null +++ b/src/components/404/index.tsx @@ -0,0 +1,41 @@ +'use client'; + +import { FluentEmoji } from '@lobehub/ui'; +import { Button } from 'antd'; +import Link from 'next/link'; +import { memo } from 'react'; +import { useTranslation } from 'react-i18next'; +import { Flexbox } from 'react-layout-kit'; + +import { MAX_WIDTH } from '@/const/layoutTokens'; + +const Page404 = memo(() => { + const { t } = useTranslation('error'); + return ( + +

+ 404 +

+ +

+ {t('notFound.title')} +

+

{t('notFound.desc')}

+ + + +
+ ); +}); + +export default Page404; diff --git a/src/components/Error/index.tsx b/src/components/Error/index.tsx new file mode 100644 index 000000000000..47207a30612e --- /dev/null +++ b/src/components/Error/index.tsx @@ -0,0 +1,56 @@ +'use client'; + +import { FluentEmoji } from '@lobehub/ui'; +import { Button } from 'antd'; +import Link from 'next/link'; +import { memo, useLayoutEffect } from 'react'; +import { useTranslation } from 'react-i18next'; +import { Flexbox } from 'react-layout-kit'; + +import { MAX_WIDTH } from '@/const/layoutTokens'; + +import { type ErrorType, sentryCaptureException } from './sentryCaptureException'; + +interface PageErrorProps { + error: ErrorType; + reset: () => void; +} + +const PageError = memo(({ reset, error }) => { + const { t } = useTranslation('error'); + + useLayoutEffect(() => { + sentryCaptureException(error); + }, [error]); + + return ( + +

+ ERROR +

+ +

+ {t('error.title')} +

+

{t('error.desc')}

+ + + + + + +
+ ); +}); + +export default PageError; diff --git a/src/components/Error/sentryCaptureException.ts b/src/components/Error/sentryCaptureException.ts new file mode 100644 index 000000000000..d17e11643c0e --- /dev/null +++ b/src/components/Error/sentryCaptureException.ts @@ -0,0 +1,11 @@ +import { getClientConfig } from '@/config/client'; + +const { ENABLE_SENTRY } = getClientConfig(); + +export type ErrorType = Error & { digest?: string }; + +export const sentryCaptureException = async (error: Error & { digest?: string }) => { + if (!ENABLE_SENTRY) return; + const { captureException } = await import('@sentry/nextjs'); + return captureException(error); +}; diff --git a/src/config/client.ts b/src/config/client.ts index 8dedf8d61578..b7479b50d2c3 100644 --- a/src/config/client.ts +++ b/src/config/client.ts @@ -55,6 +55,9 @@ export const getClientConfig = () => ({ process.env.NEXT_PUBLIC_UMAMI_SCRIPT_URL || 'https://analytics.umami.is/script.js', UMAMI_WEBSITE_ID: process.env.NEXT_PUBLIC_UMAMI_WEBSITE_ID, + // Sentry + ENABLE_SENTRY: !!process.env.NEXT_PUBLIC_SENTRY_DSN, + // i18n debug mode I18N_DEBUG: process.env.NEXT_PUBLIC_I18N_DEBUG === '1', I18N_DEBUG_BROWSER: process.env.NEXT_PUBLIC_I18N_DEBUG_BROWSER === '1', diff --git a/src/locales/default/error.ts b/src/locales/default/error.ts index 7b9ccb874a9f..d942f9e95f26 100644 --- a/src/locales/default/error.ts +++ b/src/locales/default/error.ts @@ -1,4 +1,15 @@ export default { + error: { + backHome: '返回首页', + desc: '待会来试试,或者回到已知的世界', + retry: '重新加载', + title: '页面遇到一点问题..', + }, + notFound: { + backHome: '返回首页', + desc: '我们找不到你正在寻找的页面,请检查链接是否正确', + title: '进入了未知领域?', + }, pluginSettings: { desc: '完成以下配置,即可开始使用该插件', title: '{{name}} 插件配置', @@ -115,6 +126,7 @@ export default { addProxyUrl: '添加 OpenAI 代理地址(可选)', closeMessage: '关闭提示', confirm: '确认并重试', + oauth: { description: '管理员已开启统一登录认证,点击下方按钮登录,即可解锁应用', success: '登录成功',