first commit

This commit is contained in:
“dongming”
2026-01-21 16:08:49 +08:00
commit ea72dd0c3c
57 changed files with 11884 additions and 0 deletions

45
src/i18n/I18nProvider.tsx Normal file
View File

@@ -0,0 +1,45 @@
import React, { useCallback, useEffect, useMemo, useState } from 'react'
import { DEFAULT_LOCALE, TRANSLATIONS, type Locale } from './translations'
import { I18nContext, type I18nContextValue } from './context'
const STORAGE_KEY = 'locale'
export const I18nProvider: React.FC<React.PropsWithChildren> = ({ children }) => {
const [locale, setLocaleState] = useState<Locale>(() => {
const fromStorage = window.localStorage.getItem(STORAGE_KEY)
if (fromStorage === 'th' || fromStorage === 'zh') return fromStorage
return DEFAULT_LOCALE
})
const setLocale = useCallback((next: Locale) => {
setLocaleState(next)
window.localStorage.setItem(STORAGE_KEY, next)
}, [])
const t = useCallback(
(key: string) => {
return TRANSLATIONS[locale][key] ?? TRANSLATIONS[DEFAULT_LOCALE][key] ?? key
},
[locale],
)
useEffect(() => {
document.documentElement.lang = locale
document.title =
locale === 'zh'
? '湘味小馆 | 正宗湘菜在泰国'
: 'Xiang Hunan Kitchen | อาหารหูหนานแท้ในไทย'
}, [locale])
const value = useMemo<I18nContextValue>(
() => ({
locale,
setLocale,
t,
}),
[locale, setLocale, t],
)
return <I18nContext.Provider value={value}>{children}</I18nContext.Provider>
}

10
src/i18n/context.ts Normal file
View File

@@ -0,0 +1,10 @@
import { createContext } from 'react'
import type { Locale } from './translations'
export type I18nContextValue = {
locale: Locale
setLocale: (locale: Locale) => void
t: (key: string) => string
}
export const I18nContext = createContext<I18nContextValue | null>(null)

174
src/i18n/translations.ts Normal file
View File

@@ -0,0 +1,174 @@
export type Locale = 'th' | 'zh'
export const DEFAULT_LOCALE: Locale = 'th'
export type Translations = Record<string, string>
export const TRANSLATIONS: Record<Locale, Translations> = {
th: {
'nav.home': 'หน้าแรก',
'nav.menu': 'เมนู',
'nav.about': 'เกี่ยวกับ',
'nav.contact': 'ติดต่อ',
'nav.news': 'ข่าวสาร',
'lang.th': 'ไทย',
'lang.zh': '中文',
'home.hero.title': 'อาหารหูหนาน (湘菜) รสจัด เผ็ดหอม กลมกล่อม',
'home.hero.desc':
'ร้านอาหารหูหนาน (湘菜) ที่เน้นรสเผ็ดหอม กลิ่นเครื่องเทศชัดเจน เหมาะกับทั้งมื้อครอบครัวและสังสรรค์กับเพื่อน',
'home.hero.cta.menu': 'ดูเมนู',
'home.hero.cta.contact': 'จองโต๊ะ / ติดต่อ',
'home.section.latestNews': 'ข่าวสารล่าสุด',
'home.section.latestNews.desc': 'โปรโมชั่น เมนูใหม่ และข่าวกิจกรรมของร้าน',
'home.section.latestNews.more': 'ดูทั้งหมด',
'home.emptyNews': 'ยังไม่มีข่าวสารในตอนนี้',
'home.cta.title': 'พร้อมชิมรสหูหนานแท้แล้วหรือยัง?',
'home.cta.desc':
'จองโต๊ะง่าย ๆ ผ่านโทรศัพท์หรือไลน์ แล้วมาสัมผัสความเผ็ดหอมแบบหูหนานได้เลย',
'home.cta.call': 'โทรจองโต๊ะ',
'home.cta.map': 'ดูแผนที่และเวลาเปิดร้าน',
'home.feature.1.title': 'เผ็ดหอมแบบหูหนาน',
'home.feature.1.desc': 'พริกแห้งและเครื่องเทศคั่วสด กลิ่นชัด รสมีมิติ',
'home.feature.2.title': 'เหมาะกับการแชร์',
'home.feature.2.desc': 'เมนูหลายจาน ทานร่วมกันได้ทั้งครอบครัวและเพื่อนฝูง',
'home.feature.3.title': 'จองโต๊ะง่าย',
'home.feature.3.desc': 'โทรหรือทักไลน์เพื่อจองโต๊ะและขอแนะนำเมนูได้ทันที',
'menu.title': 'เมนู',
'menu.subtitle':
'รสชาติหูหนานแท้ กลิ่นพริกแห้งและเครื่องเทศชัดเจน ปรับระดับความเผ็ดได้ตามชอบ',
'menu.allergy.title': 'มีอาการแพ้อาหาร?',
'menu.allergy.desc':
'แจ้งพนักงานก่อนสั่งอาหาร เราช่วยปรับสูตรและแนะนำเมนูที่เหมาะกับคุณได้',
'menu.allergy.call': 'โทรสอบถาม',
'menu.allergy.directions': 'ดูวิธีเดินทาง',
'about.title': 'เรื่องราวของเรา',
'about.subtitle':
'เราอยากให้ทุกคนได้สัมผัสเสน่ห์ของอาหารหูหนาน (湘菜) ที่โดดเด่นด้วยกลิ่นพริกแห้งและเครื่องเทศ รสเผ็ดหอมแต่กลมกล่อม พร้อมบริการเป็นกันเอง',
'about.occasions': 'เหมาะกับโอกาสไหน?',
'about.cta.title': 'อยากให้ช่วยแนะนำเมนู?',
'about.cta.desc':
'โทรหรือทักไลน์ได้เลย เราแนะนำเมนูตามจำนวนคนและระดับความเผ็ดที่ชอบ',
'about.cta.call': 'โทรจองโต๊ะ',
'about.cta.contact': 'ดูข้อมูลติดต่อ',
'contact.title': 'ติดต่อและการเดินทาง',
'contact.subtitle':
'จองโต๊ะ สอบถามเมนู หรือขอคำแนะนำระดับความเผ็ด ติดต่อเราได้ทุกช่องทาง',
'contact.shopInfo': 'ข้อมูลร้าน',
'contact.phone': 'โทร',
'contact.line': 'ไลน์',
'contact.address': 'ที่อยู่',
'contact.hours': 'เวลาเปิด-ปิด',
'contact.mapTitle': 'แผนที่ร้าน',
'contact.takeaway.title': 'อยากสั่งกลับบ้าน?',
'contact.takeaway.desc':
'โทรสั่งล่วงหน้าเพื่อความรวดเร็ว หรือทักไลน์แจ้งเวลารับได้เลย',
'contact.takeaway.call': 'โทรสั่งอาหาร',
'contact.takeaway.line': 'ทักไลน์',
'news.title': 'ข่าวสารและโปรโมชั่น',
'news.subtitle': 'อัปเดตเมนูใหม่ โปรโมชั่น และกิจกรรมของทางร้าน',
'news.empty': 'ยังไม่มีข่าวสารในตอนนี้',
'post.back': 'กลับหน้าข่าวสาร',
'notFound.title': 'ไม่พบหน้านี้',
'notFound.desc': 'ลิงก์อาจไม่ถูกต้อง หรือหน้านี้ถูกย้ายไปแล้ว',
'notFound.back': 'กลับหน้าแรก',
'card.more': 'ดูรายละเอียด',
'card.open': 'เปิด',
'common.phone': 'โทร',
'common.hours': 'เวลาเปิด-ปิด',
'common.call': 'โทร',
'common.contact': 'ติดต่อ',
'common.loadFailed': 'โหลดข้อมูลไม่สำเร็จ',
'footer.contact': 'ติดต่อ',
'footer.hours': 'เวลาเปิด-ปิด',
'home.hoursPreview': '11:0022:00',
},
zh: {
'nav.home': '首页',
'nav.menu': '菜单',
'nav.about': '关于我们',
'nav.contact': '联系/地址',
'nav.news': '新闻/活动',
'lang.th': 'ไทย',
'lang.zh': '中文',
'home.hero.title': '正宗湘菜(湘菜) 香辣鲜香,层次分明',
'home.hero.desc':
'面向泰国食客的湘菜餐厅:干辣椒与香辛料的香气突出,适合家庭聚餐与朋友小聚,辣度可按需调整。',
'home.hero.cta.menu': '查看菜单',
'home.hero.cta.contact': '订位/联系',
'home.section.latestNews': '最新新闻',
'home.section.latestNews.desc': '优惠活动、新菜上线与店内动态',
'home.section.latestNews.more': '查看全部',
'home.emptyNews': '暂无新闻',
'home.cta.title': '准备好来一口地道湘味了吗?',
'home.cta.desc': '电话或 Line 轻松订位,来体验香辣过瘾的湘菜。',
'home.cta.call': '电话订位',
'home.cta.map': '查看地图与营业时间',
'home.feature.1.title': '湘味重香重辣',
'home.feature.1.desc': '干辣椒与香辛料的复合香气突出,层次更丰富。',
'home.feature.2.title': '更适合分享',
'home.feature.2.desc': '多道菜拼桌更过瘾,适合家庭与朋友聚餐。',
'home.feature.3.title': '订位更方便',
'home.feature.3.desc': '电话或 Line 一键订位,也可按口味推荐菜品。',
'menu.title': '菜单',
'menu.subtitle': '湘菜重香重辣,干辣椒香气明显;可按口味调整辣度。',
'menu.allergy.title': '有过敏/忌口?',
'menu.allergy.desc': '下单前告知店员,我们可协助调整做法并推荐合适菜品。',
'menu.allergy.call': '电话咨询',
'menu.allergy.directions': '查看路线',
'about.title': '我们的故事',
'about.subtitle':
'我们希望让更多人体验湘菜的魅力:干辣椒与香辛料的复合香气,香辣但不失平衡,并以轻松友好的服务呈现。',
'about.occasions': '适合哪些场景?',
'about.cta.title': '不知道怎么点?',
'about.cta.desc': '电话或 Line 联系我们,按人数与辣度偏好帮你配菜。',
'about.cta.call': '电话订位',
'about.cta.contact': '查看联系方式',
'contact.title': '联系与到店',
'contact.subtitle': '订位、咨询菜单、辣度建议,都可以随时联系我们。',
'contact.shopInfo': '门店信息',
'contact.phone': '电话',
'contact.line': 'Line',
'contact.address': '地址',
'contact.hours': '营业时间',
'contact.mapTitle': '门店地图',
'contact.takeaway.title': '想打包带走?',
'contact.takeaway.desc': '建议提前电话下单,或 Line 告知取餐时间更省心。',
'contact.takeaway.call': '电话下单',
'contact.takeaway.line': 'Line 联系',
'news.title': '新闻与活动',
'news.subtitle': '更新优惠、活动与新品信息',
'news.empty': '暂无新闻',
'post.back': '返回新闻列表',
'notFound.title': '页面不存在',
'notFound.desc': '链接可能不正确,或页面已被移动。',
'notFound.back': '返回首页',
'card.more': '查看详情',
'card.open': '打开',
'common.phone': '电话',
'common.hours': '营业时间',
'common.call': '拨打电话',
'common.contact': '联系',
'common.loadFailed': '加载失败',
'footer.contact': '联系',
'footer.hours': '营业时间',
'home.hoursPreview': '11:0022:00',
},
}

10
src/i18n/useI18n.ts Normal file
View File

@@ -0,0 +1,10 @@
import { useContext } from 'react'
import { I18nContext } from './context'
export const useI18n = () => {
const ctx = useContext(I18nContext)
if (!ctx) {
throw new Error('useI18n must be used within I18nProvider')
}
return ctx
}