modules/frontend/Write-Frontend-I18n.ps1
|
param( [string]$ProjectName, [string]$OutputPath, [string]$FrontendMode, [bool]$I18n = $false, [string]$Language = 'tr' ) if (-not $I18n) { return } if ($FrontendMode -eq "NextJS") { return } . (Join-Path (Split-Path $MyInvocation.MyCommand.Path) "..\core\Utils.ps1") $base = Join-Path $OutputPath "frontend" function Write-File($rel, $content) { Write-CoreFile (Join-Path $base $rel) $content } $isTS = ($FrontendMode -eq "ReactTS") $extTs = if ($isTS) { "ts" } else { "js" } # ─── i18n init ──────────────────────────────────────────────── Write-File "i18n.$extTs" @" import i18n from 'i18next'; import { initReactI18next } from 'react-i18next'; import LanguageDetector from 'i18next-browser-languagedetector'; import HttpBackend from 'i18next-http-backend'; i18n .use(HttpBackend) .use(LanguageDetector) .use(initReactI18next) .init({ lng: '$Language', fallbackLng: 'en', supportedLngs: ['en', 'tr'], ns: ['common'], defaultNS: 'common', backend: { loadPath: '/locales/{{lng}}/{{ns}}.json' }, detection: { order: ['localStorage', 'navigator'], caches: ['localStorage'], }, interpolation: { escapeValue: false }, }); export default i18n; "@ # ─── Locale files ───────────────────────────────────────────── Write-File "public\locales\en\common.json" @" { "app": { "brand": "$ProjectName", "logout": "Logout", "loading": "Loading...", "error": "An error occurred.", "noData": "No records found." }, "auth": { "login": "Login", "username": "Username", "password": "Password", "loginTitle": "Sign in to your account" }, "pagination": { "previous": "Previous", "next": "Next", "page": "Page {{current}} / {{total}}" }, "actions": { "add": "Add", "delete": "Delete", "save": "Save", "cancel": "Cancel" } } "@ Write-File "public\locales\tr\common.json" @" { "app": { "brand": "$ProjectName", "logout": "Cikis", "loading": "Yukleniyor...", "error": "Bir hata olustu.", "noData": "Kayit bulunamadi." }, "auth": { "login": "Giris Yap", "username": "Kullanici Adi", "password": "Sifre", "loginTitle": "Hesabiniza giris yapin" }, "pagination": { "previous": "Onceki", "next": "Sonraki", "page": "Sayfa {{current}} / {{total}}" }, "actions": { "add": "Ekle", "delete": "Sil", "save": "Kaydet", "cancel": "Iptal" } } "@ # ─── Language switcher component ────────────────────────────── $ext = if ($isTS) { "tsx" } else { "jsx" } Write-File "components\common\LanguageSwitcher.$ext" @' import { useTranslation } from 'react-i18next'; const LANGS = [ { code: 'en', label: 'EN' }, { code: 'tr', label: 'TR' }, ]; export function LanguageSwitcher() { const { i18n } = useTranslation(); return ( <div style={{ display: 'flex', gap: 6 }}> {LANGS.map(l => ( <button key={l.code} onClick={() => i18n.changeLanguage(l.code)} style={{ padding: '3px 8px', borderRadius: 4, border: 'none', cursor: 'pointer', fontWeight: i18n.language === l.code ? 700 : 400, background: i18n.language === l.code ? '#fff' : 'transparent', color: i18n.language === l.code ? '#0f3460' : 'rgba(255,255,255,0.7)', }} > {l.label} </button> ))} </div> ); } '@ # ─── Wire i18n import into main entry ───────────────────────── $mainFile = Join-Path $base "main.$ext" if (-not $Global:DryRun -and (Test-Path $mainFile)) { $mainContent = Get-Content $mainFile -Raw if ($mainContent -notmatch "i18n") { $mainContent = "import './i18n';`n" + $mainContent Set-Content $mainFile $mainContent -Encoding UTF8 } } elseif ($Global:DryRun) { Write-Host " [DRY] i18n import added to main.$ext" -ForegroundColor DarkGray } |