Skip to content

Commit b1d12f5

Browse files
Add Turkish translations for various commands, manuals, and game elements
- Updated translations for terminal commands and editor messages in Turkish. - Added new game-related translations for the Doom and Chess games. - Included detailed usage instructions for commands in the manuals section. - Enhanced user interface translations for better clarity and consistency. - Added placeholder content for files and scripts to improve user experience.
1 parent 23f8568 commit b1d12f5

File tree

7 files changed

+671
-393
lines changed

7 files changed

+671
-393
lines changed

src/components/ContactForm.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ export default function ContactForm({ labels }: { labels: Labels }) {
4444
const data = await response.json();
4545

4646
if (!response.ok || !data.ok) {
47-
throw new Error("Request failed");
47+
throw new Error(labels.error);
4848
}
4949

5050
setStatus("success");

src/components/HomeClient.tsx

Lines changed: 78 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,14 @@ function slugify(value: string) {
328328
.replace(/(^-|-$)/g, "");
329329
}
330330

331+
function formatTemplate(value: string, vars: Record<string, string | number>) {
332+
return Object.entries(vars).reduce(
333+
(acc, [key, replacement]) =>
334+
acc.replaceAll(`{${key}}`, String(replacement)),
335+
value,
336+
);
337+
}
338+
331339
type LocalizedProject = {
332340
title: string;
333341
year: string;
@@ -1333,7 +1341,8 @@ export default function HomeClient({
13331341
}, [latestProjects, t.projects.latestTitle]);
13341342

13351343
const files = useMemo(() => {
1336-
const terminalUser = profile.terminal.prompt.split("@")[0] || "user";
1344+
const terminalUser =
1345+
profile.terminal.prompt.split("@")[0] || t.terminal.system.userFallback;
13371346
const homeDir = `/home/${terminalUser}`;
13381347
const docsDir = `${homeDir}/docs`;
13391348
const scriptsDir = `${homeDir}/scripts`;
@@ -1342,7 +1351,9 @@ export default function HomeClient({
13421351
return [
13431352
{
13441353
path: `${homeDir}/README.md`,
1345-
content: `# ${profile.fullName}\n\nWelcome to KININ-TERM.\n\nQuick links:\n- docs/about.md\n- docs/projects.md\n- docs/contact.md\n`,
1354+
content: formatTemplate(t.terminal.files.readme, {
1355+
name: profile.fullName,
1356+
}),
13461357
},
13471358
{
13481359
path: `${docsDir}/title.md`,
@@ -1366,250 +1377,225 @@ export default function HomeClient({
13661377
},
13671378
{
13681379
path: `${homeDir}/notes/todo.txt`,
1369-
content:
1370-
"- finalize terminal sim\n- tune hero camera\n- deploy to cloud run\n- add new 3d scene\n",
1380+
content: t.terminal.files.notesTodo,
13711381
},
13721382
{
13731383
path: `${homeDir}/notes/ideas.txt`,
1374-
content:
1375-
"Ideas:\n- retro mini games\n- hardware blog posts\n- terminal theme switch\n",
1384+
content: t.terminal.files.notesIdeas,
13761385
},
13771386
{
13781387
path: `${scriptsDir}/calc.py`,
1379-
content:
1380-
"# SciCalc demo\nimport math\nexpr = 'sin(pi/2) + cos(0)'\nallowed = {k: getattr(math, k) for k in ['sin','cos','tan','sqrt','log','pi','e']}\nallowed['pow'] = pow\nresult = eval(expr, {'__builtins__': {}}, allowed)\nprint('SciCalc demo:', expr, '=', result)\nprint('Tip: use calc command for interactive mode.')\n",
1388+
content: t.terminal.files.scriptsCalc,
13811389
},
13821390
{
13831391
path: `${scriptsDir}/snake.py`,
1384-
content:
1385-
"# Snake demo\nboard = [\n '###########',\n '#.........#',\n '#..S....@..#',\n '#.........#',\n '###########',\n]\nprint('Controls: run `snake` in terminal for full game.')\nprint('\n'.join(board))\n",
1392+
content: t.terminal.files.scriptsSnake,
13861393
},
13871394
{
13881395
path: `${scriptsDir}/pacman.py`,
1389-
content:
1390-
"# Pacman demo\nmaze = [\n '############',\n '#C....##....#',\n '#.##..##..##.#',\n '#....G.....o#',\n '############',\n]\nprint('Controls: run `pacman` in terminal for full game.')\nprint('\n'.join(maze))\n",
1396+
content: t.terminal.files.scriptsPacman,
13911397
},
13921398
{
13931399
path: `${scriptsDir}/pong.py`,
1394-
content:
1395-
"# Pong demo\nprint('Controls: run `pong` in terminal for full game.')\nprint('Scoreboard: PLAYER 0 - 0 AI')\nprint('Left/Right to move paddle')\n",
1400+
content: t.terminal.files.scriptsPong,
13961401
},
13971402
{
13981403
path: `${scriptsDir}/chess.py`,
1399-
content:
1400-
"# Chess demo\nprint('Controls: run `chess` in terminal for full game.')\nprint('Tips: 1/2/3 difficulty, B bot, P pvp, C bot color')\n",
1404+
content: t.terminal.files.scriptsChess,
14011405
},
14021406
{
14031407
path: `${scriptsDir}/solitaire.py`,
1404-
content:
1405-
"# Solitaire demo\nprint('Controls: run `solitaire` in terminal for full game.')\nprint('Keys: D draw, W waste, 1-7 tableau, F foundation')\n",
1408+
content: t.terminal.files.scriptsSolitaire,
14061409
},
14071410
{
14081411
path: `${scriptsDir}/dice_roll.py`,
1409-
content:
1410-
"import random\nprint('Dice roll:', random.randint(1, 6))\nprint('Try again for a new roll.')\n",
1412+
content: t.terminal.files.scriptsDiceRoll,
14111413
},
14121414
{
14131415
path: `${scriptsDir}/hello_world.py`,
1414-
content:
1415-
"import datetime\nprint('Hello, world!')\nprint('UTC time:', datetime.datetime.utcnow().isoformat())\n",
1416+
content: t.terminal.files.scriptsHelloWorld,
14161417
},
14171418
{
14181419
path: `${scriptsDir}/media_demo.py`,
1419-
content:
1420-
"print('Media demo:')\nprint('image -> random retro ASCII')\nprint('video -> random loop')\nprint('mp3 -> random chiptune')\nprint('Tip: image ~/media/nebula.txt')\n",
1420+
content: t.terminal.files.scriptsMediaDemo,
14211421
},
14221422
{
14231423
path: `${scriptsDir}/ascii_image.py`,
1424-
content:
1425-
"art = [\n ' .-.',\n ' (o o)',\n ' | = |',\n ' (__|__)',\n 'RETRO BOT',\n]\nprint('\\n'.join(art))\n",
1424+
content: t.terminal.files.scriptsAsciiImage,
14261425
},
14271426
{
14281427
path: `${scriptsDir}/starfield.py`,
1429-
content:
1430-
"import random\nfor _ in range(6):\n line = ''.join(random.choice('.*') if random.random() > 0.7 else ' ' for _ in range(48))\n print(line)\n",
1428+
content: t.terminal.files.scriptsStarfield,
14311429
},
14321430
{
14331431
path: `${scriptsDir}/quote_bot.py`,
1434-
content:
1435-
"import random\nquotes = [\n 'Focus beats luck.',\n 'Ship it.',\n 'Keep it simple.',\n 'Small steps, big wins.',\n]\nprint(random.choice(quotes))\n",
1432+
content: t.terminal.files.scriptsQuoteBot,
14361433
},
14371434
{
14381435
path: `${mediaDir}/nebula.txt`,
1439-
content:
1440-
" . . .\n . * . . * .\n . . . .***. . . .\n . .*' * '*. .\n . . * . . * . .\n . '*. .*' .\n . . . '***' . . .\n . * . . * .\n . . .\n",
1436+
content: t.terminal.files.mediaNebula,
14411437
},
14421438
{
14431439
path: `${mediaDir}/grid.txt`,
1444-
content:
1445-
"|‾‾‾‾‾‾‾‾‾‾‾|\n| RETRO |\n| GRID |\n|_________|\n\\\\\\\\\\\\\\\n/ / / / / /\n\\\\\\\\\\\\\\\n",
1440+
content: t.terminal.files.mediaGrid,
14461441
},
14471442
{
14481443
path: `${mediaDir}/city.txt`,
1449-
content:
1450-
" | | | | | |\n ___|_|_|_|_|_|___\n /__ NEON SKYLINE __\\\n|_|_|_|_|_|_|_|_|_|_|\n /_/ /_/ /_/ /_/ /_\n",
1444+
content: t.terminal.files.mediaCity,
14511445
},
14521446
{
14531447
path: `${mediaDir}/arcade.txt`,
1454-
content:
1455-
" .--------------.\n / ARCADE 88 /|\n /______________/ |\n | .----------. | |\n | | READY! | | |\n | '----------' |/\n '--------------'\n",
1448+
content: t.terminal.files.mediaArcade,
14561449
},
14571450
{
14581451
path: `${mediaDir}/loop.vid`,
1459-
content:
1460-
"[frame 1]\n (o)\n /|\\\n / \\\n\n---\n[frame 2]\n (o)\n /|\\\n /\\ \\\n\n---\n[frame 3]\n (o)\n /|\\\n / \\\n\n",
1452+
content: t.terminal.files.mediaLoop1,
14611453
},
14621454
{
14631455
path: `${mediaDir}/loop2.vid`,
1464-
content:
1465-
"[frame 1]\n [#] \n /|_|\\\n / \\\n\n---\n[frame 2]\n [#] \n /|_|\\\n /\\ \\\n\n---\n[frame 3]\n [#] \n /|_|\\\n / \\\n\n",
1456+
content: t.terminal.files.mediaLoop2,
14661457
},
14671458
{
14681459
path: `${mediaDir}/loop3.vid`,
1469-
content:
1470-
"[frame 1]\n <o> \n /|\\\n / \\\n\n---\n[frame 2]\n <o> \n /|\\\n /\\ \\\n\n---\n[frame 3]\n <o> \n /|\\\n / \\\n\n",
1460+
content: t.terminal.files.mediaLoop3,
14711461
},
14721462
{
14731463
path: `${mediaDir}/loop4.vid`,
1474-
content:
1475-
"[frame 1]\n /\\_/\\ \n ( o.o )\n > ^ <\n\n---\n[frame 2]\n /\\_/\\ \n ( o.o )\n > ~ <\n\n---\n[frame 3]\n /\\_/\\ \n ( o.o )\n > ^ <\n\n",
1464+
content: t.terminal.files.mediaLoop4,
14761465
},
14771466
{
14781467
path: `${mediaDir}/loop5.vid`,
1479-
content:
1480-
"[frame 1]\n [==] \n | | \n |__| \n\n---\n[frame 2]\n [==] \n |~~| \n |__| \n\n---\n[frame 3]\n [==] \n | | \n |__| \n\n",
1468+
content: t.terminal.files.mediaLoop5,
14811469
},
14821470
{
14831471
path: `${mediaDir}/neon_grid.png`,
1484-
content:
1485-
"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='64' height='64'><rect width='64' height='64' fill='%230b0f0e'/><path d='M0 48 L64 32' stroke='%236fd1ff' stroke-width='2'/><path d='M0 56 L64 40' stroke='%237ef2b2' stroke-width='2'/><circle cx='48' cy='20' r='10' fill='%23ffb36b'/></svg>",
1472+
content: t.terminal.files.mediaNeonGrid,
14861473
},
14871474
{
14881475
path: `${mediaDir}/neon_sun.jpg`,
1489-
content:
1490-
"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='64' height='64'><rect width='64' height='64' fill='%23061110'/><rect y='36' width='64' height='28' fill='%23121f2a'/><circle cx='32' cy='30' r='14' fill='%23ff7ad9'/><path d='M0 48 L64 34' stroke='%23ffb36b' stroke-width='2'/></svg>",
1476+
content: t.terminal.files.mediaNeonSun,
14911477
},
14921478
{
14931479
path: `${mediaDir}/circuit_chip.png`,
1494-
content:
1495-
"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='64' height='64'><rect width='64' height='64' fill='%230b0f0e'/><rect x='14' y='14' width='36' height='36' rx='4' fill='%231a2b2a' stroke='%236fd1ff' stroke-width='2'/><path d='M8 20h8M8 32h8M8 44h8M48 8v8M32 8v8M20 8v8M56 20h-8M56 32h-8M56 44h-8M20 56v-8M32 56v-8M44 56v-8' stroke='%237ef2b2' stroke-width='2'/></svg>",
1480+
content: t.terminal.files.mediaCircuitChip,
14961481
},
14971482
{
14981483
path: `${mediaDir}/sunrise.png`,
1499-
content:
1500-
"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='80' height='64'><rect width='80' height='64' fill='%23070b12'/><rect y='34' width='80' height='30' fill='%23111f2a'/><circle cx='40' cy='30' r='14' fill='%23ffb36b'/><path d='M0 44 L80 32' stroke='%23ff7ad9' stroke-width='2'/><path d='M0 52 L80 38' stroke='%236fd1ff' stroke-width='2'/></svg>",
1484+
content: t.terminal.files.mediaSunrise,
15011485
},
15021486
{
15031487
path: `${mediaDir}/neon_rain.jpg`,
1504-
content:
1505-
"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='80' height='64'><rect width='80' height='64' fill='%230a0f14'/><path d='M8 0v64M20 0v64M32 0v64M44 0v64M56 0v64M68 0v64' stroke='%236fd1ff' stroke-width='2' opacity='0.7'/><circle cx='62' cy='20' r='8' fill='%23ff7ad9'/></svg>",
1488+
content: t.terminal.files.mediaNeonRain,
15061489
},
15071490
{
15081491
path: `${mediaDir}/grid_horizon.jpg`,
1509-
content:
1510-
"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='80' height='64'><rect width='80' height='64' fill='%230b0f0e'/><path d='M0 44 L80 28' stroke='%237ef2b2' stroke-width='2'/><path d='M0 54 L80 36' stroke='%236fd1ff' stroke-width='2'/><path d='M0 64 L80 44' stroke='%23ffb36b' stroke-width='2'/></svg>",
1492+
content: t.terminal.files.mediaGridHorizon,
15111493
},
15121494
{
15131495
path: `${mediaDir}/synth.mp3`,
1514-
content: "MP3DATA",
1496+
content: t.terminal.files.mediaSynth1,
15151497
},
15161498
{
15171499
path: `${mediaDir}/synth2.mp3`,
1518-
content: "MP3DATA_2",
1500+
content: t.terminal.files.mediaSynth2,
15191501
},
15201502
{
15211503
path: `${mediaDir}/synth3.mp3`,
1522-
content: "MP3DATA_3",
1504+
content: t.terminal.files.mediaSynth3,
15231505
},
15241506
{
15251507
path: `${mediaDir}/neon_drive.mp3`,
1526-
content: "MP3DATA_4",
1508+
content: t.terminal.files.mediaNeonDrive,
15271509
},
15281510
{
15291511
path: `${mediaDir}/circuit_beat.mp3`,
1530-
content: "MP3DATA_5",
1512+
content: t.terminal.files.mediaCircuitBeat,
15311513
},
15321514
{
15331515
path: `${mediaDir}/glow_shift.mp3`,
1534-
content: "MP3DATA_6",
1516+
content: t.terminal.files.mediaGlowShift,
15351517
},
15361518
{
15371519
path: `${mediaDir}/horizon_chords.mp3`,
1538-
content: "MP3DATA_7",
1520+
content: t.terminal.files.mediaHorizonChords,
15391521
},
15401522
{
15411523
path: `${mediaDir}/pulse_echo.mp3`,
1542-
content: "MP3DATA_8",
1524+
content: t.terminal.files.mediaPulseEcho,
15431525
},
15441526
{
15451527
path: `${mediaDir}/retro_wave.mp3`,
1546-
content: "MP3DATA_9",
1528+
content: t.terminal.files.mediaRetroWave,
15471529
},
15481530
{
15491531
path: `${projectsDir}/kinin-portfolio/README.md`,
1550-
content:
1551-
"# Kinin Portfolio\n\nStatus: active\nStack: Next.js, Three.js, WebGL\n",
1532+
content: t.terminal.files.projectPortfolio,
15521533
},
15531534
{
15541535
path: `${projectsDir}/kinin-os/README.md`,
1555-
content:
1556-
"# Kinin OS\n\nExperimenting with terminal UX and CRT shaders.\n",
1536+
content: t.terminal.files.projectKininOs,
15571537
},
15581538
{
15591539
path: `${homeDir}/.bashrc`,
1560-
content: "alias ll='ls -al'\nalias la='ls -a'\n",
1540+
content: t.terminal.files.bashrc,
15611541
},
15621542
{
15631543
path: `${homeDir}/.profile`,
1564-
content: "export LANG=en_US.UTF-8\nexport TERM=kinin-term\n",
1544+
content: t.terminal.files.profile,
15651545
},
15661546
{
15671547
path: "/etc/os-release",
1568-
content:
1569-
'NAME=KininOS\nVERSION=0.9.4\nID=kininos\nPRETTY_NAME="KininOS 0.9.4"\n',
1548+
content: t.terminal.files.osRelease,
15701549
},
15711550
{
15721551
path: "/var/log/boot.log",
1573-
content: "boot: ok\nservices: ready\n",
1552+
content: t.terminal.files.bootLog,
15741553
},
15751554
{
15761555
path: "/usr/bin/python",
1577-
content: "ELF...",
1556+
content: t.terminal.files.elfPlaceholder,
15781557
},
15791558
{
15801559
path: "/usr/bin/pacman",
1581-
content: "ELF...",
1560+
content: t.terminal.files.elfPlaceholder,
15821561
},
15831562
{
15841563
path: "/usr/bin/snake",
1585-
content: "ELF...",
1564+
content: t.terminal.files.elfPlaceholder,
15861565
},
15871566
{
15881567
path: "/usr/bin/pong",
1589-
content: "ELF...",
1568+
content: t.terminal.files.elfPlaceholder,
15901569
},
15911570
{
15921571
path: "/usr/bin/chess",
1593-
content: "ELF...",
1572+
content: t.terminal.files.elfPlaceholder,
15941573
},
15951574
{
15961575
path: "/usr/bin/solitaire",
1597-
content: "ELF...",
1576+
content: t.terminal.files.elfPlaceholder,
15981577
},
15991578
{
16001579
path: "/usr/bin/mp3",
1601-
content: "ELF...",
1580+
content: t.terminal.files.elfPlaceholder,
16021581
},
16031582
{
16041583
path: "/usr/bin/video",
1605-
content: "ELF...",
1584+
content: t.terminal.files.elfPlaceholder,
16061585
},
16071586
{
16081587
path: "/usr/bin/image",
1609-
content: "ELF...",
1588+
content: t.terminal.files.elfPlaceholder,
16101589
},
16111590
];
1612-
}, [localizedPages, profile.fullName, profile.terminal.prompt, projectsMd]);
1591+
}, [
1592+
localizedPages,
1593+
profile.fullName,
1594+
profile.terminal.prompt,
1595+
projectsMd,
1596+
t.terminal.files,
1597+
t.terminal.system.userFallback,
1598+
]);
16131599

16141600
const scrollToSection = (id: string) => {
16151601
const element = document.getElementById(id);
@@ -2844,10 +2830,10 @@ export default function HomeClient({
28442830
<p className="footer-name">{profile.fullName}</p>
28452831
<p className="footer-role">{profile.jobTitle[language]}</p>
28462832
<p className="footer-copy">
2847-
© 2026 {profile.fullName}.{" "}
2848-
{language === "tr"
2849-
? "Tum haklari saklidir."
2850-
: "All rights reserved."}
2833+
{formatTemplate(t.ui.footerRights, {
2834+
year: new Date().getFullYear(),
2835+
name: profile.fullName,
2836+
})}
28512837
</p>
28522838
</div>
28532839
<div className="footer-links">

0 commit comments

Comments
 (0)