Files
boc/quixzoom-landing-fixed/i18n.js
T
Bernt aee0f09db8 landvex: Fixar och tester klara för alla komponenter
- Datafabrik: Dockerfile fix, agentorkestrering fungerar
- Vision: Identify-modell, FAISS, OCR alla testade
- API: Alla 7 integrationstester passerade
- Upplösare: Entitetsupplösning verifierad
2026-07-05 06:41:32 +00:00

98 lines
10 KiB
JavaScript

/**
* quiXzoom i18n — Frontend
* Detekterar OS/browser-språk automatiskt.
* Stöd: sv (svenska), en (engelska), th (thai)
* Användning: window.t('key') eller <span data-i18n="key">
*/
const STRINGS = {
'onboarding.welcome': { sv: 'Välkommen till quiXzoom', en: 'Welcome to quiXzoom', th: 'ยินดีต้อนรับสู่ quiXzoom' },
'onboarding.subtitle': { sv: 'Ta bilder. Tjäna pengar.', en: 'Take photos. Earn money.', th: 'ถ่ายรูป. สร้างรายได้.' },
'onboarding.continue': { sv: 'Fortsätt', en: 'Continue', th: 'ต่อไป' },
'onboarding.back': { sv: 'Tillbaka', en: 'Back', th: 'กลับ' },
'onboarding.skip': { sv: 'Hoppa över', en: 'Skip', th: 'ข้าม' },
'onboarding.done': { sv: 'Klart!', en: 'Done!', th: 'เสร็จแล้ว!' },
'onboarding.step_of': { sv: 'Steg {n} av {total}', en: 'Step {n} of {total}', th: 'ขั้นตอน {n} จาก {total}' },
'auth.email': { sv: 'E-post', en: 'Email', th: 'อีเมล' },
'auth.password': { sv: 'Lösenord', en: 'Password', th: 'รหัสผ่าน' },
'auth.first_name': { sv: 'Förnamn', en: 'First name', th: 'ชื่อ' },
'auth.last_name': { sv: 'Efternamn', en: 'Last name', th: 'นามสกุล' },
'auth.phone': { sv: 'Telefonnummer', en: 'Phone number', th: 'เบอร์โทรศัพท์' },
'auth.register': { sv: 'Skapa konto', en: 'Create account', th: 'สร้างบัญชี' },
'auth.login': { sv: 'Logga in', en: 'Sign in', th: 'เข้าสู่ระบบ' },
'auth.logout': { sv: 'Logga ut', en: 'Sign out', th: 'ออกจากระบบ' },
'auth.invalid_creds': { sv: 'Felaktigt e-post eller lösenord', en: 'Incorrect email or password', th: 'อีเมลหรือรหัสผ่านไม่ถูกต้อง' },
'auth.email_taken': { sv: 'E-postadressen är redan registrerad', en: 'Email already registered', th: 'อีเมลนี้ถูกใช้งานแล้ว' },
'mission.nearby': { sv: 'Uppdrag nära dig', en: 'Missions near you', th: 'ภารกิจใกล้คุณ' },
'mission.no_nearby': { sv: 'Inga uppdrag nära dig just nu', en: 'No missions near you right now', th: 'ไม่มีภารกิจใกล้คุณตอนนี้' },
'mission.loading': { sv: 'Hämtar uppdrag...', en: 'Loading missions...', th: 'กำลังโหลดภารกิจ...' },
'mission.claim': { sv: 'Ta uppdraget', en: 'Accept mission', th: 'รับภารกิจ' },
'mission.submit': { sv: 'Skicka in', en: 'Submit', th: 'ส่ง' },
'mission.complete': { sv: 'Slutför', en: 'Complete', th: 'เสร็จสิ้น' },
'mission.cancel': { sv: 'Avbryt uppdrag', en: 'Cancel mission', th: 'ยกเลิกภารกิจ' },
'mission.photos_required': { sv: '{n} bilder krävs', en: '{n} photos required', th: 'ต้องการ {n} รูป' },
'mission.reward': { sv: 'Ersättning', en: 'Reward', th: 'รางวัล' },
'mission.away': { sv: 'bort', en: 'away', th: 'ห่างออกไป' },
'kyc.verify_id': { sv: 'Verifiera din identitet', en: 'Verify your identity', th: 'ยืนยันตัวตนของคุณ' },
'kyc.upload_passport': { sv: 'Ladda upp pass', en: 'Upload passport', th: 'อัปโหลดหนังสือเดินทาง' },
'kyc.upload_selfie': { sv: 'Ta en selfie', en: 'Take a selfie', th: 'ถ่ายเซลฟี่' },
'kyc.take_photo': { sv: 'Ta foto', en: 'Take photo', th: 'ถ่ายรูป' },
'kyc.upload_photo': { sv: 'Ladda upp foto', en: 'Upload photo', th: 'อัปโหลดรูปภาพ' },
'kyc.processing': { sv: 'Verifierar...', en: 'Verifying...', th: 'กำลังตรวจสอบ...' },
'kyc.approved': { sv: 'Identitet verifierad ✓', en: 'Identity verified ✓', th: 'ยืนยันตัวตนแล้ว ✓' },
'kyc.rejected': { sv: 'Verifiering misslyckades', en: 'Verification failed', th: 'การยืนยันล้มเหลว' },
'kyc.action_blink': { sv: 'Blinka två gånger', en: 'Blink twice', th: 'กะพริบตาสองครั้ง' },
'kyc.action_turn_left': { sv: 'Vänd huvudet åt vänster', en: 'Turn head left', th: 'หันหัวไปทางซ้าย' },
'kyc.action_turn_right': { sv: 'Vänd huvudet åt höger', en: 'Turn head right', th: 'หันหัวไปทางขวา' },
'kyc.action_nod': { sv: 'Nicka', en: 'Nod', th: 'うなずく' },
'kyc.action_smile': { sv: 'Le', en: 'Smile', th: 'ยิ้ม' },
'wallet.balance': { sv: 'Saldo', en: 'Balance', th: 'ยอดเงิน' },
'wallet.earned': { sv: 'Totalt tjänat', en: 'Total earned', th: 'รายได้ทั้งหมด' },
'wallet.pending': { sv: 'Väntar på utbetalning', en: 'Pending payout', th: 'รอการจ่ายเงิน' },
'wallet.withdraw': { sv: 'Ta ut pengar', en: 'Withdraw', th: 'ถอนเงิน' },
'wallet.payout_setup': { sv: 'Sätt upp utbetalning', en: 'Set up payout', th: 'ตั้งค่าการจ่ายเงิน' },
'status.active': { sv: 'Aktiv', en: 'Active', th: 'ใช้งาน' },
'status.pending': { sv: 'Väntar', en: 'Pending', th: 'รอ' },
'status.completed': { sv: 'Slutfört', en: 'Completed', th: 'เสร็จสิ้น' },
'status.paid': { sv: 'Utbetalt', en: 'Paid', th: 'จ่ายแล้ว' },
'status.cancelled': { sv: 'Avbrutet', en: 'Cancelled', th: 'ยกเลิกแล้ว' },
'status.under_review': { sv: 'Granskas', en: 'Under review', th: 'กำลังตรวจสอบ' },
'error.generic': { sv: 'Något gick fel — försök igen', en: 'Something went wrong — try again', th: 'เกิดข้อผิดพลาด กรุณาลองใหม่' },
'error.no_gps': { sv: 'Platsbehörighet nekad', en: 'Location permission denied', th: 'ปฏิเสธการเข้าถึงตำแหน่ง' },
'error.network': { sv: 'Ingen nätverksanslutning', en: 'No network connection', th: 'ไม่มีการเชื่อมต่อเครือข่าย' },
'action.retry': { sv: 'Försök igen', en: 'Try again', th: 'ลองใหม่' },
'action.close': { sv: 'Stäng', en: 'Close', th: 'ปิด' },
'action.save': { sv: 'Spara', en: 'Save', th: 'บันทึก' },
'action.confirm': { sv: 'Bekräfta', en: 'Confirm', th: 'ยืนยัน' },
'action.allow': { sv: 'Tillåt', en: 'Allow', th: 'อนุญาต' },
};
function detectLang() {
const langs = (navigator.languages || [navigator.language || 'sv']).map(l => l.toLowerCase().slice(0,2));
for (const l of langs) { if (['sv','en','th'].includes(l)) return l; }
return 'sv';
}
const lang = detectLang();
function t(key, params = {}) {
const entry = STRINGS[key];
if (!entry) return key;
let str = entry[lang] || entry['sv'] || entry['en'] || key;
for (const [k, v] of Object.entries(params)) str = str.replace(new RegExp(`\\{${k}\\}`, 'g'), v);
return str;
}
function applyTranslations() {
document.querySelectorAll('[data-i18n]').forEach(el => { el.textContent = t(el.getAttribute('data-i18n')); });
document.querySelectorAll('[data-i18n-placeholder]').forEach(el => { el.placeholder = t(el.getAttribute('data-i18n-placeholder')); });
}
document.documentElement.lang = lang;
window.QZ_LANG = lang;
window.t = t;
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', applyTranslations);
else applyTranslations();