From 114a176c0ed78800976c427304d0b5fc43779e71 Mon Sep 17 00:00:00 2001 From: Kresna Date: Sun, 2 Aug 2026 14:42:01 +0700 Subject: [PATCH] feat(i18n): localize all 19 Dev tool UIs to Bahasa (wave 1) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Each Dev island now accepts the lang prop ToolHost forwards and renders Bahasa on /id/ via a local TR:{en,id} dictionary (LegacyLetter pattern). Covers JSON formatter/compare/converters (+ shared BiConverter), Base64, URL, JWT, UUID, password, hash, text-diff, CSV↔JSON, markdown, QR gen/read, timestamp, base & color convert. Logic untouched; brand/format/acronym terms kept; no 'alat'. Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_01Ubfx4XocHcECaL8twp9zsr --- src/components/dev/BiConverter.tsx | 39 +++++++++++-- src/islands/dev/Base64.tsx | 50 +++++++++++++--- src/islands/dev/BaseConvert.tsx | 32 +++++++++-- src/islands/dev/ColorConvert.tsx | 31 ++++++++-- src/islands/dev/CsvJson.tsx | 57 ++++++++++++++---- src/islands/dev/HashFile.tsx | 43 ++++++++++++-- src/islands/dev/JsonCompare.tsx | 71 ++++++++++++++++++----- src/islands/dev/JsonFormat.tsx | 55 ++++++++++++++---- src/islands/dev/JsonToml.tsx | 4 +- src/islands/dev/JsonXml.tsx | 4 +- src/islands/dev/JsonYaml.tsx | 4 +- src/islands/dev/JwtDecode.tsx | 58 ++++++++++++++++--- src/islands/dev/Markdown.tsx | 28 +++++++-- src/islands/dev/PasswordGen.tsx | 52 ++++++++++++++--- src/islands/dev/QrGen.tsx | 57 ++++++++++++++---- src/islands/dev/QrRead.tsx | 37 ++++++++++-- src/islands/dev/TextDiff.tsx | 71 ++++++++++++++++++----- src/islands/dev/Timestamp.tsx | 92 ++++++++++++++++++++++++------ src/islands/dev/UrlEncode.tsx | 42 +++++++++++--- src/islands/dev/UuidGen.tsx | 15 +++-- 20 files changed, 692 insertions(+), 150 deletions(-) diff --git a/src/components/dev/BiConverter.tsx b/src/components/dev/BiConverter.tsx index 8bdb4a5..3cb81e6 100644 --- a/src/components/dev/BiConverter.tsx +++ b/src/components/dev/BiConverter.tsx @@ -6,6 +6,30 @@ import { Alert } from '@/components/ui/Alert'; import { LoadFileButton, fileExt } from '@/components/ui/LoadFileButton'; import { CodeBlock, type CodeLanguage } from '@/components/ui/CodeBlock'; import { DownloadTextButton } from '@/components/ui/DownloadTextButton'; +import type { Lang } from '@/i18n/config'; + +const TR: Record string; + input: string; + clear: string; + result: string; + conversionFailed: string; +}> = { + en: { + loadFile: (left, right) => `Load ${left} / ${right} file`, + input: 'Input', + clear: 'Clear', + result: 'Result', + conversionFailed: 'Conversion failed', + }, + id: { + loadFile: (left, right) => `Muat file ${left} / ${right}`, + input: 'Input', + clear: 'Bersihkan', + result: 'Hasil', + conversionFailed: 'Konversi gagal', + }, +}; const MIME_BY_EXT: Record = { json: 'application/json', @@ -31,12 +55,15 @@ export interface BiConverterProps { rightExts?: string[]; /** highlight.js language for the right-hand format's output (left is JSON). */ rightLang?: CodeLanguage; + /** UI language; defaults to English. */ + lang?: Lang; } type Mode = 'toRight' | 'toLeft'; /** A two-way text converter: paste input, pick a direction, copy the result. */ -export function BiConverter({ leftLabel, rightLabel, toRight, toLeft, placeholder, fileAccept, rightExts = [], rightLang = 'plaintext' }: BiConverterProps) { +export function BiConverter({ leftLabel, rightLabel, toRight, toLeft, placeholder, fileAccept, rightExts = [], rightLang = 'plaintext', lang = 'en' }: BiConverterProps) { + const t = TR[lang] ?? TR.en; const [input, setInput] = useState(''); const [output, setOutput] = useState(''); const [error, setError] = useState(''); @@ -53,7 +80,7 @@ export function BiConverter({ leftLabel, rightLabel, toRight, toLeft, placeholde setOutput(next === 'toRight' ? toRight(source) : toLeft(source)); } catch (e) { setOutput(''); - setError(e instanceof Error ? e.message : 'Conversion failed'); + setError(e instanceof Error ? e.message : t.conversionFailed); } }; @@ -80,11 +107,11 @@ export function BiConverter({ leftLabel, rightLabel, toRight, toLeft, placeholde
{fileAccept && (
- +
)}