Add internationalization support with English and Dutch translations

- Integrated i18next for language detection and translation support.
- Added English and Dutch JSON translation files for various app sections.
- Updated TweaksPanel and Workspace components to use translated strings.
- Imported i18n configuration in main entry file.
This commit is contained in:
LaurensBartelds committed 2026-04-26 21:19:47 +02:00
1 parent c64cdcd9e3
commit 6277826472
19 files changed
+1193 -369

No files matched your search

+14 -12
View File
@@ -1,5 +1,6 @@
import { useState, useEffect, useCallback } from 'react'
import { useNavigate, useParams, Navigate } from 'react-router-dom'
import { useTranslation } from 'react-i18next'
import { useAuth } from '../contexts/AuthContext'
import * as examApi from '../api/examApi'
import * as resultApi from '../api/resultApi'
@@ -9,13 +10,14 @@ import Settings from './Settings'
type TabKey = 'exams' | 'results' | 'settings'
const TABS: { key: TabKey; label: string; icon: string }[] = [
{ key: 'exams', label: 'My Exams', icon: '◇' },
{ key: 'results', label: 'Results', icon: '✦' },
{ key: 'settings', label: 'Settings', icon: '⚙' },
const TAB_KEYS: { key: TabKey; labelKey: string; icon: string }[] = [
{ key: 'exams', labelKey: 'workspace.myExams', icon: '◇' },
{ key: 'results', labelKey: 'workspace.results', icon: '✦' },
{ key: 'settings', labelKey: 'workspace.settings', icon: '⚙' },
]
export default function Workspace() {
const { t } = useTranslation()
const { user, loading: authLoading } = useAuth()
const navigate = useNavigate()
const { tab } = useParams<{ tab: string }>()
@@ -55,18 +57,18 @@ export default function Workspace() {
</div>
<nav className="workspace-nav">
{TABS.map((t) => (
{TAB_KEYS.map((tabItem) => (
<button
key={t.key}
className={`workspace-nav-item${activeTab === t.key ? ' active' : ''}`}
onClick={() => setTab(t.key)}
key={tabItem.key}
className={`workspace-nav-item${activeTab === tabItem.key ? ' active' : ''}`}
onClick={() => setTab(tabItem.key)}
>
<span className="workspace-nav-icon">{t.icon}</span>
<span className="workspace-nav-label">{t.label}</span>
{t.key === 'exams' && examCount > 0 && (
<span className="workspace-nav-icon">{tabItem.icon}</span>
<span className="workspace-nav-label">{t(tabItem.labelKey)}</span>
{tabItem.key === 'exams' && examCount > 0 && (
<span className="workspace-nav-badge">{examCount}</span>
)}
{t.key === 'results' && resultCount > 0 && (
{tabItem.key === 'results' && resultCount > 0 && (
<span className="workspace-nav-badge">{resultCount}</span>
)}
</button>