diff --git a/admin/inertia/i18n/locales/en.json b/admin/inertia/i18n/locales/en.json index ed78f67..bf3ada5 100644 --- a/admin/inertia/i18n/locales/en.json +++ b/admin/inertia/i18n/locales/en.json @@ -39,7 +39,11 @@ "updateAvailable": "An update is available for Project N.O.M.A.D.!", "goToSettings": "Go to Settings", "startHere": "Start here!", - "poweredBy": "Powered by" + "poweredBy": "Powered by", + "easySetupDesc": "Not sure where to start? Use the setup wizard to quickly configure your N.O.M.A.D.!", + "installAppsDesc": "Not seeing your favorite app? Install it here!", + "docsDesc": "Read Project N.O.M.A.D. manuals and guides", + "settingsDesc": "Configure your N.O.M.A.D. settings" }, "menu": { "maps": "Maps", @@ -50,6 +54,7 @@ }, "maps": { "title": "Offline Maps", + "viewOffline": "View offline maps", "search": "Search locations...", "noResults": "No results found", "loadingMap": "Loading map...", @@ -69,10 +74,16 @@ "apps": "Apps", "models": "Models", "maps": "Maps", + "mapsManager": "Maps Manager", "benchmark": "Benchmark", "update": "Update", + "checkUpdates": "Check for Updates", "legal": "Legal", - "support": "Support" + "support": "Support", + "supportProject": "Support the Project", + "contentExplorer": "Content Explorer", + "contentManager": "Content Manager", + "serviceLogs": "Service Logs & Metrics" }, "system": { "title": "System Settings", diff --git a/admin/inertia/i18n/locales/zh.json b/admin/inertia/i18n/locales/zh.json index 540e199..23b7d49 100644 --- a/admin/inertia/i18n/locales/zh.json +++ b/admin/inertia/i18n/locales/zh.json @@ -39,7 +39,11 @@ "updateAvailable": "Project N.O.M.A.D. 有可用更新!", "goToSettings": "前往设置", "startHere": "从这里开始!", - "poweredBy": "技术支持" + "poweredBy": "技术支持", + "easySetupDesc": "不确定从哪里开始?使用设置向导快速配置您的 N.O.M.A.D.!", + "installAppsDesc": "没有看到您想要的应用?在这里安装!", + "docsDesc": "阅读 Project N.O.M.A.D. 手册和指南", + "settingsDesc": "配置您的 N.O.M.A.D. 设置" }, "menu": { "maps": "地图", @@ -50,6 +54,7 @@ }, "maps": { "title": "离线地图", + "viewOffline": "查看离线地图", "search": "搜索位置...", "noResults": "未找到结果", "loadingMap": "加载地图中...", @@ -69,10 +74,16 @@ "apps": "应用", "models": "模型", "maps": "地图", + "mapsManager": "地图管理器", "benchmark": "基准测试", "update": "更新", + "checkUpdates": "检查更新", "legal": "法律", - "support": "支持" + "support": "支持", + "supportProject": "支持项目", + "contentExplorer": "内容浏览器", + "contentManager": "内容管理器", + "serviceLogs": "服务日志和指标" }, "system": { "title": "系统设置", diff --git a/admin/inertia/layouts/SettingsLayout.tsx b/admin/inertia/layouts/SettingsLayout.tsx index 0ecad83..855a9ab 100644 --- a/admin/inertia/layouts/SettingsLayout.tsx +++ b/admin/inertia/layouts/SettingsLayout.tsx @@ -9,47 +9,67 @@ import { IconSettings, IconTerminal2, IconWand, - IconZoom + IconZoom, } from '@tabler/icons-react' import { usePage } from '@inertiajs/react' import StyledSidebar from '~/components/StyledSidebar' import { getServiceLink } from '~/lib/navigation' import useServiceInstalledStatus from '~/hooks/useServiceInstalledStatus' import { SERVICE_NAMES } from '../../constants/service_names' +import LanguageSwitcher from '~/components/LanguageSwitcher' +import { useTranslation } from 'react-i18next' export default function SettingsLayout({ children }: { children: React.ReactNode }) { + const { t } = useTranslation() const { aiAssistantName } = usePage<{ aiAssistantName: string }>().props const aiAssistantInstallStatus = useServiceInstalledStatus(SERVICE_NAMES.OLLAMA) const navigation = [ - ...(aiAssistantInstallStatus.isInstalled ? [{ name: aiAssistantName, href: '/settings/models', icon: IconWand, current: false }] : []), - { name: 'Apps', href: '/settings/apps', icon: IconTerminal2, current: false }, - { name: 'Benchmark', href: '/settings/benchmark', icon: IconChartBar, current: false }, - { name: 'Content Explorer', href: '/settings/zim/remote-explorer', icon: IconZoom, current: false }, - { name: 'Content Manager', href: '/settings/zim', icon: IconFolder, current: false }, - { name: 'Maps Manager', href: '/settings/maps', icon: IconMapRoute, current: false }, + ...(aiAssistantInstallStatus.isInstalled + ? [{ name: aiAssistantName, href: '/settings/models', icon: IconWand, current: false }] + : []), + { name: t('settings.apps'), href: '/settings/apps', icon: IconTerminal2, current: false }, { - name: 'Service Logs & Metrics', + name: t('settings.benchmark'), + href: '/settings/benchmark', + icon: IconChartBar, + current: false, + }, + { + name: t('settings.contentExplorer'), + href: '/settings/zim/remote-explorer', + icon: IconZoom, + current: false, + }, + { name: t('settings.contentManager'), href: '/settings/zim', icon: IconFolder, current: false }, + { name: t('settings.mapsManager'), href: '/settings/maps', icon: IconMapRoute, current: false }, + { + name: t('settings.serviceLogs'), href: getServiceLink('9999'), icon: IconDashboard, current: false, target: '_blank', }, { - name: 'Check for Updates', + name: t('settings.checkUpdates'), href: '/settings/update', icon: IconArrowBigUpLines, current: false, }, - { name: 'System', href: '/settings/system', icon: IconSettings, current: false }, - { name: 'Support the Project', href: '/settings/support', icon: IconHeart, current: false }, - { name: 'Legal Notices', href: '/settings/legal', icon: IconGavel, current: false }, + { name: t('settings.system'), href: '/settings/system', icon: IconSettings, current: false }, + { name: t('settings.support'), href: '/settings/support', icon: IconHeart, current: false }, + { name: t('settings.legal'), href: '/settings/legal', icon: IconGavel, current: false }, ] return (
- - {children} + +
+
+ +
+ {children} +
) } diff --git a/admin/inertia/pages/home.tsx b/admin/inertia/pages/home.tsx index 1feebb2..76a78b5 100644 --- a/admin/inertia/pages/home.tsx +++ b/admin/inertia/pages/home.tsx @@ -15,57 +15,57 @@ import { useUpdateAvailable } from '~/hooks/useUpdateAvailable' import { useSystemSetting } from '~/hooks/useSystemSetting' import Alert from '~/components/Alert' import { SERVICE_NAMES } from '../../constants/service_names' +import { useTranslation } from 'react-i18next' // Maps is a Core Capability (display_order: 4) -const MAPS_ITEM = { - label: 'Maps', +const getMapsItem = (t: (key: string) => string) => ({ + label: t('menu.maps'), to: '/maps', target: '', - description: 'View offline maps', + description: t('maps.viewOffline'), icon: , installed: true, displayOrder: 4, poweredBy: null, -} +}) // System items shown after all apps -const SYSTEM_ITEMS = [ +const getSystemItems = (t: (key: string) => string) => [ { - label: 'Easy Setup', + label: t('menu.easySetup'), to: '/easy-setup', target: '', - description: - 'Not sure where to start? Use the setup wizard to quickly configure your N.O.M.A.D.!', + description: t('home.easySetupDesc'), icon: , installed: true, displayOrder: 50, poweredBy: null, }, { - label: 'Install Apps', + label: t('menu.installApps'), to: '/settings/apps', target: '', - description: 'Not seeing your favorite app? Install it here!', + description: t('home.installAppsDesc'), icon: , installed: true, displayOrder: 51, poweredBy: null, }, { - label: 'Docs', + label: t('menu.docs'), to: '/docs/home', target: '', - description: 'Read Project N.O.M.A.D. manuals and guides', + description: t('home.docsDesc'), icon: , installed: true, displayOrder: 52, poweredBy: null, }, { - label: 'Settings', + label: t('menu.settings'), to: '/settings/system', target: '', - description: 'Configure your N.O.M.A.D. settings', + description: t('home.settingsDesc'), icon: , installed: true, displayOrder: 53, @@ -89,15 +89,18 @@ export default function Home(props: { services: ServiceSlim[] } }) { + const { t } = useTranslation() const items: DashboardItem[] = [] - const updateInfo = useUpdateAvailable(); + const updateInfo = useUpdateAvailable() const { aiAssistantName } = usePage<{ aiAssistantName: string }>().props // Check if user has visited Easy Setup const { data: easySetupVisited } = useSystemSetting({ - key: 'ui.hasVisitedEasySetup' + key: 'ui.hasVisitedEasySetup', }) - const shouldHighlightEasySetup = easySetupVisited?.value ? String(easySetupVisited.value) !== 'true' : false + const shouldHighlightEasySetup = easySetupVisited?.value + ? String(easySetupVisited.value) !== 'true' + : false // Add installed services (non-dependency services only) props.system.services @@ -105,7 +108,10 @@ export default function Home(props: { .forEach((service) => { items.push({ // Inject custom AI Assistant name if this is the chat service - label: service.service_name === SERVICE_NAMES.OLLAMA && aiAssistantName ? aiAssistantName : (service.friendly_name || service.service_name), + label: + service.service_name === SERVICE_NAMES.OLLAMA && aiAssistantName + ? aiAssistantName + : service.friendly_name || service.service_name, to: service.ui_location ? getServiceLink(service.ui_location) : '#', target: '_blank', description: @@ -123,38 +129,36 @@ export default function Home(props: { }) // Add Maps as a Core Capability - items.push(MAPS_ITEM) + items.push(getMapsItem(t)) // Add system items - items.push(...SYSTEM_ITEMS) + items.push(...getSystemItems(t)) // Sort all items by display order items.sort((a, b) => a.displayOrder - b.displayOrder) return ( - - { - updateInfo?.updateAvailable && ( -
- router.visit('/settings/update'), - }} - /> -
- ) - } + + {updateInfo?.updateAvailable && ( +
+ router.visit('/settings/update'), + }} + /> +
+ )}
{items.map((item) => { - const isEasySetup = item.label === 'Easy Setup' + const isEasySetup = item.label === t('menu.easySetup') const shouldHighlight = isEasySetup && shouldHighlightEasySetup const tileContent = ( @@ -166,13 +170,17 @@ export default function Home(props: { style={{ animationDuration: '1.5s' }} > - Start here! + {t('home.startHere')} )}
{item.icon}

{item.label}

- {item.poweredBy &&

Powered by {item.poweredBy}

} + {item.poweredBy && ( +

+ {t('home.poweredBy')} {item.poweredBy} +

+ )}

{item.description}

)