chore(history): import initial web product snapshot
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
import { createContext, useContext, useEffect, useMemo, useState, type ReactNode } from 'react'
|
||||
import { UI_LOCALES, type UiLocale } from '@/config/languages'
|
||||
import { zh, type LocaleDict } from './locales/zh'
|
||||
import { en } from './locales/en'
|
||||
import { ar } from './locales/ar'
|
||||
|
||||
const DICTS: Record<UiLocale, LocaleDict> = { zh, en, ar }
|
||||
|
||||
interface I18nContextValue {
|
||||
locale: UiLocale
|
||||
dir: 'ltr' | 'rtl'
|
||||
setLocale: (l: UiLocale) => void
|
||||
t: (key: keyof LocaleDict) => string
|
||||
}
|
||||
|
||||
const I18nContext = createContext<I18nContextValue | null>(null)
|
||||
|
||||
const STORAGE_KEY = 'lx-locale'
|
||||
|
||||
export function I18nProvider({ children }: { children: ReactNode }) {
|
||||
const [locale, setLocaleState] = useState<UiLocale>(() => {
|
||||
const saved = localStorage.getItem(STORAGE_KEY)
|
||||
return (saved === 'en' || saved === 'ar' || saved === 'zh' ? saved : 'zh') as UiLocale
|
||||
})
|
||||
|
||||
const dir: 'ltr' | 'rtl' = UI_LOCALES.find((l) => l.code === locale)?.rtl ? 'rtl' : 'ltr'
|
||||
|
||||
useEffect(() => {
|
||||
document.documentElement.lang = locale === 'zh' ? 'zh-CN' : locale
|
||||
document.documentElement.dir = dir
|
||||
localStorage.setItem(STORAGE_KEY, locale)
|
||||
}, [locale, dir])
|
||||
|
||||
const value = useMemo<I18nContextValue>(
|
||||
() => ({
|
||||
locale,
|
||||
dir,
|
||||
setLocale: setLocaleState,
|
||||
t: (key) => DICTS[locale][key] ?? zh[key] ?? String(key),
|
||||
}),
|
||||
[locale, dir],
|
||||
)
|
||||
|
||||
return <I18nContext.Provider value={value}>{children}</I18nContext.Provider>
|
||||
}
|
||||
|
||||
export function useI18n(): I18nContextValue {
|
||||
const ctx = useContext(I18nContext)
|
||||
if (!ctx) throw new Error('useI18n must be used within I18nProvider')
|
||||
return ctx
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
import type { LocaleDict } from './zh'
|
||||
|
||||
/** 阿拉伯语(RTL 布局演示) */
|
||||
export const ar: LocaleDict = {
|
||||
'app.name': 'لينغشي عبر الحدود',
|
||||
'app.slogan': 'نجعل التواصل عبر الحدود أبسط',
|
||||
'app.company': 'شركة شوزو أوهوي للتكنولوجيا',
|
||||
|
||||
'nav.dashboard': 'لوحة العمل',
|
||||
'nav.inbox': 'الرسائل الموحدة',
|
||||
'nav.customers': 'إدارة العملاء',
|
||||
'nav.opportunities': 'الفرص والمتابعة',
|
||||
'nav.translate': 'الترجمة الذكية',
|
||||
'nav.interpret': 'الترجمة الفورية',
|
||||
'nav.risks': 'تنبيهات المخاطر',
|
||||
'nav.knowledge': 'قاعدة المعرفة',
|
||||
'nav.analytics': 'تحليل البيانات',
|
||||
'nav.channels': 'مركز القنوات',
|
||||
'nav.team': 'فريق العمل',
|
||||
'nav.billing': 'الباقات والفواتير',
|
||||
'nav.settings': 'إعدادات النظام',
|
||||
'nav.help': 'المساعدة والتدريب',
|
||||
|
||||
'common.search': 'بحث',
|
||||
'common.save': 'حفظ',
|
||||
'common.cancel': 'إلغاء',
|
||||
'common.confirm': 'تأكيد',
|
||||
'common.delete': 'حذف',
|
||||
'common.edit': 'تعديل',
|
||||
'common.create': 'جديد',
|
||||
'common.close': 'إغلاق',
|
||||
'common.loading': 'جارٍ التحميل…',
|
||||
'common.all': 'الكل',
|
||||
'common.back': 'رجوع',
|
||||
'common.export': 'تصدير',
|
||||
'common.import': 'استيراد',
|
||||
'common.more': 'المزيد',
|
||||
'common.submit': 'إرسال',
|
||||
'common.reset': 'إعادة تعيين',
|
||||
'common.optional': 'اختياري',
|
||||
'common.required': 'مطلوب',
|
||||
'common.demoData': 'بيانات تجريبية',
|
||||
|
||||
'topbar.searchPlaceholder': 'ابحث عن العملاء والمحادثات والمعرفة والمهام…',
|
||||
'topbar.notifications': 'الإشعارات',
|
||||
'topbar.help': 'المساعدة',
|
||||
'topbar.switchRole': 'تبديل الدور التجريبي',
|
||||
'topbar.logout': 'تسجيل الخروج',
|
||||
'topbar.profile': 'الملف الشخصي',
|
||||
|
||||
'sidebar.currentPlan': 'الباقة الحالية',
|
||||
'sidebar.usage': 'استخدام الباقة',
|
||||
'sidebar.collapse': 'طي القائمة',
|
||||
'sidebar.expand': 'توسيع القائمة',
|
||||
|
||||
'login.title': 'تسجيل الدخول إلى لينغشي',
|
||||
'login.subtitle': 'منصة الأعمال الذكية عبر الحدود',
|
||||
'login.phoneTab': 'رمز التحقق',
|
||||
'login.passwordTab': 'كلمة المرور',
|
||||
'login.accountPlaceholder': 'الهاتف أو البريد الإلكتروني',
|
||||
'login.codePlaceholder': 'رمز مكون من 6 أرقام',
|
||||
'login.passwordPlaceholder': 'كلمة المرور',
|
||||
'login.getCode': 'إرسال الرمز',
|
||||
'login.remember': 'تذكرني',
|
||||
'login.forgot': 'نسيت كلمة المرور؟',
|
||||
'login.submit': 'تسجيل الدخول',
|
||||
'login.register': 'تسجيل شركة جديدة',
|
||||
'login.quick': 'دخول تجريبي بنقرة واحدة',
|
||||
'login.agreementPrefix': 'بتسجيل الدخول فأنت توافق على',
|
||||
'login.privacy': 'سياسة الخصوصية',
|
||||
'login.terms': 'شروط الخدمة',
|
||||
'login.and': 'و',
|
||||
|
||||
'dashboard.goodMorning': 'صباح الخير',
|
||||
'dashboard.goodAfternoon': 'مساء الخير',
|
||||
'dashboard.goodEvening': 'مساء الخير',
|
||||
'dashboard.updatedAt': 'آخر تحديث',
|
||||
|
||||
'lang.name': 'اللغة',
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
import type { LocaleDict } from './zh'
|
||||
|
||||
export const en: LocaleDict = {
|
||||
'app.name': 'Lingxi Cross-border',
|
||||
'app.slogan': 'Make cross-border communication simple',
|
||||
'app.company': 'Xuzhou Ouhui Technology Co., Ltd.',
|
||||
|
||||
'nav.dashboard': 'Workspace',
|
||||
'nav.inbox': 'Unified Inbox',
|
||||
'nav.customers': 'Customers',
|
||||
'nav.opportunities': 'Deals & Follow-ups',
|
||||
'nav.translate': 'AI Translation',
|
||||
'nav.interpret': 'Interpretation',
|
||||
'nav.risks': 'Risk Alerts',
|
||||
'nav.knowledge': 'Knowledge Base',
|
||||
'nav.analytics': 'Analytics',
|
||||
'nav.channels': 'Channels',
|
||||
'nav.team': 'Team',
|
||||
'nav.billing': 'Plans & Billing',
|
||||
'nav.settings': 'Settings',
|
||||
'nav.help': 'Help & Training',
|
||||
|
||||
'common.search': 'Search',
|
||||
'common.save': 'Save',
|
||||
'common.cancel': 'Cancel',
|
||||
'common.confirm': 'Confirm',
|
||||
'common.delete': 'Delete',
|
||||
'common.edit': 'Edit',
|
||||
'common.create': 'New',
|
||||
'common.close': 'Close',
|
||||
'common.loading': 'Loading…',
|
||||
'common.all': 'All',
|
||||
'common.back': 'Back',
|
||||
'common.export': 'Export',
|
||||
'common.import': 'Import',
|
||||
'common.more': 'More',
|
||||
'common.submit': 'Submit',
|
||||
'common.reset': 'Reset',
|
||||
'common.optional': 'Optional',
|
||||
'common.required': 'Required',
|
||||
'common.demoData': 'Demo data',
|
||||
|
||||
'topbar.searchPlaceholder': 'Search customers, chats, knowledge, tasks…',
|
||||
'topbar.notifications': 'Notifications',
|
||||
'topbar.help': 'Help',
|
||||
'topbar.switchRole': 'Switch demo role',
|
||||
'topbar.logout': 'Sign out',
|
||||
'topbar.profile': 'Profile',
|
||||
|
||||
'sidebar.currentPlan': 'Current plan',
|
||||
'sidebar.usage': 'Plan usage',
|
||||
'sidebar.collapse': 'Collapse',
|
||||
'sidebar.expand': 'Expand',
|
||||
|
||||
'login.title': 'Sign in to Lingxi',
|
||||
'login.subtitle': 'Cross-border AI business platform',
|
||||
'login.phoneTab': 'Code sign-in',
|
||||
'login.passwordTab': 'Password',
|
||||
'login.accountPlaceholder': 'Phone or email',
|
||||
'login.codePlaceholder': '6-digit code',
|
||||
'login.passwordPlaceholder': 'Password',
|
||||
'login.getCode': 'Get code',
|
||||
'login.remember': 'Remember me',
|
||||
'login.forgot': 'Forgot password?',
|
||||
'login.submit': 'Sign in',
|
||||
'login.register': 'Register company',
|
||||
'login.quick': 'One-click demo login',
|
||||
'login.agreementPrefix': 'By signing in you agree to',
|
||||
'login.privacy': 'Privacy Policy',
|
||||
'login.terms': 'Terms of Service',
|
||||
'login.and': 'and',
|
||||
|
||||
'dashboard.goodMorning': 'Good morning',
|
||||
'dashboard.goodAfternoon': 'Good afternoon',
|
||||
'dashboard.goodEvening': 'Good evening',
|
||||
'dashboard.updatedAt': 'Updated at',
|
||||
|
||||
'lang.name': 'Language',
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
export const zh = {
|
||||
'app.name': '灵犀跨境',
|
||||
'app.slogan': '让跨境沟通更简单',
|
||||
'app.company': '徐州欧汇科技有限公司',
|
||||
|
||||
'nav.dashboard': '工作台',
|
||||
'nav.inbox': '统一消息',
|
||||
'nav.customers': '客户管理',
|
||||
'nav.opportunities': '商机与跟进',
|
||||
'nav.translate': 'AI翻译',
|
||||
'nav.interpret': '同声传译',
|
||||
'nav.risks': '风险预警',
|
||||
'nav.knowledge': '企业知识库',
|
||||
'nav.analytics': '数据分析',
|
||||
'nav.channels': '渠道中心',
|
||||
'nav.team': '团队协作',
|
||||
'nav.billing': '套餐与账单',
|
||||
'nav.settings': '系统设置',
|
||||
'nav.help': '帮助与培训',
|
||||
|
||||
'common.search': '搜索',
|
||||
'common.save': '保存',
|
||||
'common.cancel': '取消',
|
||||
'common.confirm': '确认',
|
||||
'common.delete': '删除',
|
||||
'common.edit': '编辑',
|
||||
'common.create': '新建',
|
||||
'common.close': '关闭',
|
||||
'common.loading': '加载中…',
|
||||
'common.all': '全部',
|
||||
'common.back': '返回',
|
||||
'common.export': '导出',
|
||||
'common.import': '导入',
|
||||
'common.more': '更多',
|
||||
'common.submit': '提交',
|
||||
'common.reset': '重置',
|
||||
'common.optional': '选填',
|
||||
'common.required': '必填',
|
||||
'common.demoData': '演示数据',
|
||||
|
||||
'topbar.searchPlaceholder': '搜索客户、会话、知识、任务…',
|
||||
'topbar.notifications': '通知',
|
||||
'topbar.help': '帮助',
|
||||
'topbar.switchRole': '切换演示角色',
|
||||
'topbar.logout': '退出登录',
|
||||
'topbar.profile': '个人中心',
|
||||
|
||||
'sidebar.currentPlan': '当前套餐',
|
||||
'sidebar.usage': '套餐使用量',
|
||||
'sidebar.collapse': '收起导航',
|
||||
'sidebar.expand': '展开导航',
|
||||
|
||||
'login.title': '登录灵犀跨境',
|
||||
'login.subtitle': '跨境AI经营服务平台',
|
||||
'login.phoneTab': '验证码登录',
|
||||
'login.passwordTab': '密码登录',
|
||||
'login.accountPlaceholder': '手机号或邮箱',
|
||||
'login.codePlaceholder': '6位验证码',
|
||||
'login.passwordPlaceholder': '密码',
|
||||
'login.getCode': '获取验证码',
|
||||
'login.remember': '记住登录状态',
|
||||
'login.forgot': '忘记密码?',
|
||||
'login.submit': '登 录',
|
||||
'login.register': '注册新企业',
|
||||
'login.quick': '演示角色一键登录',
|
||||
'login.agreementPrefix': '登录即代表同意',
|
||||
'login.privacy': '《隐私政策》',
|
||||
'login.terms': '《服务协议》',
|
||||
'login.and': '和',
|
||||
|
||||
'dashboard.goodMorning': '早上好',
|
||||
'dashboard.goodAfternoon': '下午好',
|
||||
'dashboard.goodEvening': '晚上好',
|
||||
'dashboard.updatedAt': '数据更新于',
|
||||
|
||||
'lang.name': '语言',
|
||||
}
|
||||
export type LocaleDict = typeof zh
|
||||
Reference in New Issue
Block a user