|
|
<!DOCTYPE html> |
|
|
<html lang="en"> |
|
|
<head> |
|
|
<meta charset="UTF-8"> |
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
|
<title>Localization Test | MedMIS</title> |
|
|
<script src="https://cdn.tailwindcss.com"></script> |
|
|
<script src="https://unpkg.com/feather-icons"></script> |
|
|
<script src="https://cdn.jsdelivr.net/npm/i18next@21.9.1/dist/umd/i18next.min.js"></script> |
|
|
<script src="https://cdn.jsdelivr.net/npm/i18next-http-backend@1.4.2/i18nextHttpBackend.min.js"></script> |
|
|
<script src="https://cdn.jsdelivr.net/npm/i18next-browser-languagedetector@6.1.3/i18nextBrowserLanguageDetector.min.js"></script> |
|
|
<style> |
|
|
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap'); |
|
|
body { |
|
|
font-family: 'Inter', sans-serif; |
|
|
} |
|
|
.language-card { |
|
|
transition: all 0.3s ease; |
|
|
border: 1px solid rgba(255,255,255,0.1); |
|
|
} |
|
|
.language-card:hover { |
|
|
transform: translateY(-3px); |
|
|
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); |
|
|
} |
|
|
.test-section { |
|
|
border: 1px dashed rgba(255,255,255,0.3); |
|
|
} |
|
|
</style> |
|
|
</head> |
|
|
<body class="bg-gray-900 text-white min-h-screen"> |
|
|
<div class="container mx-auto px-4 py-12"> |
|
|
<header class="mb-12"> |
|
|
<div class="flex items-center mb-8"> |
|
|
<button onclick="history.back()" class="mr-4 p-2 rounded-lg bg-gray-700 hover:bg-gray-600 transition"> |
|
|
<i data-feather="arrow-left" class="w-5 h-5"></i> |
|
|
</button> |
|
|
<div class="text-center flex-1"> |
|
|
<h1 class="text-4xl font-bold mb-4">Localization Test Interface</h1> |
|
|
<p class="text-xl text-gray-300 max-w-3xl mx-auto">Test all UI components across supported languages</p> |
|
|
</div> |
|
|
</div> |
|
|
</header> |
|
|
|
|
|
<div class="flex justify-center mb-12"> |
|
|
<div class="bg-gray-800 rounded-xl p-6 max-w-4xl w-full"> |
|
|
<h2 class="text-2xl font-semibold mb-6 text-center">Select Language</h2> |
|
|
<div class="grid grid-cols-1 md:grid-cols-4 gap-4"> |
|
|
<button class="language-card bg-gray-700 rounded-lg p-6 text-center hover:bg-blue-900 hover:border-blue-500" data-lang="ru"> |
|
|
<div class="text-4xl mb-2">🇷🇺</div> |
|
|
<h3 class="text-xl font-medium">Русский</h3> |
|
|
<p class="text-gray-400">Russian</p> |
|
|
</button> |
|
|
<button class="language-card bg-gray-700 rounded-lg p-6 text-center hover:bg-green-900 hover:border-green-500" data-lang="uz"> |
|
|
<div class="text-4xl mb-2">🇺🇿</div> |
|
|
<h3 class="text-xl font-medium">O'zbekcha</h3> |
|
|
<p class="text-gray-400">Uzbek</p> |
|
|
</button> |
|
|
<button class="language-card bg-gray-700 rounded-lg p-6 text-center hover:bg-yellow-900 hover:border-yellow-500" data-lang="tj"> |
|
|
<div class="text-4xl mb-2">🇹🇯</div> |
|
|
<h3 class="text-xl font-medium">Тоҷикӣ</h3> |
|
|
<p class="text-gray-400">Tajik</p> |
|
|
</button> |
|
|
<button class="language-card bg-gray-700 rounded-lg p-6 text-center hover:bg-red-900 hover:border-red-500" data-lang="kk"> |
|
|
<div class="text-4xl mb-2">🇰🇿</div> |
|
|
<h3 class="text-xl font-medium">Қазақша</h3> |
|
|
<p class="text-gray-400">Kazakh</p> |
|
|
</button> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="space-y-8 max-w-4xl mx-auto"> |
|
|
|
|
|
<div class="test-section bg-gray-800 rounded-xl p-6"> |
|
|
<h2 class="text-2xl font-semibold mb-4" data-i18n="test.navigation">Navigation Test</h2> |
|
|
<div class="flex flex-wrap gap-4"> |
|
|
<a href="#" class="px-4 py-2 bg-blue-600 rounded-lg hover:bg-blue-700 transition" data-i18n="nav.home">Home</a> |
|
|
<a href="#" class="px-4 py-2 bg-gray-700 rounded-lg hover:bg-gray-600 transition" data-i18n="nav.patients">Patients</a> |
|
|
<a href="#" class="px-4 py-2 bg-gray-700 rounded-lg hover:bg-gray-600 transition" data-i18n="nav.studies">Studies</a> |
|
|
<a href="#" class="px-4 py-2 bg-gray-700 rounded-lg hover:bg-gray-600 transition" data-i18n="nav.reports">Reports</a> |
|
|
<a href="#" class="px-4 py-2 bg-gray-700 rounded-lg hover:bg-gray-600 transition" data-i18n="nav.settings">Settings</a> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="test-section bg-gray-800 rounded-xl p-6"> |
|
|
<h2 class="text-2xl font-semibold mb-4" data-i18n="test.forms">Form Elements Test</h2> |
|
|
<form class="space-y-4"> |
|
|
<div> |
|
|
<label class="block mb-2" data-i18n="form.name">Full Name</label> |
|
|
<input type="text" class="w-full bg-gray-700 rounded-lg px-4 py-2"> |
|
|
</div> |
|
|
<div> |
|
|
<label class="block mb-2" data-i18n="form.email">Email Address</label> |
|
|
<input type="email" class="w-full bg-gray-700 rounded-lg px-4 py-2"> |
|
|
</div> |
|
|
<div> |
|
|
<label class="block mb-2" data-i18n="form.role">Role</label> |
|
|
<select class="w-full bg-gray-700 rounded-lg px-4 py-2"> |
|
|
<option value="" data-i18n="form.selectRole">Select Role</option> |
|
|
<option value="doctor" data-i18n="roles.doctor">Doctor</option> |
|
|
<option value="nurse" data-i18n="roles.nurse">Nurse</option> |
|
|
<option value="admin" data-i18n="roles.admin">Administrator</option> |
|
|
</select> |
|
|
</div> |
|
|
<div> |
|
|
<label class="inline-flex items-center"> |
|
|
<input type="checkbox" class="rounded bg-gray-700"> |
|
|
<span class="ml-2" data-i18n="form.agree">I agree to the terms</span> |
|
|
</label> |
|
|
</div> |
|
|
<button type="submit" class="px-6 py-2 bg-green-600 rounded-lg hover:bg-green-700 transition" data-i18n="form.submit">Submit Form</button> |
|
|
</form> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="test-section bg-gray-800 rounded-xl p-6"> |
|
|
<h2 class="text-2xl font-semibold mb-4" data-i18n="test.alerts">Alerts & Messages Test</h2> |
|
|
<div class="space-y-4"> |
|
|
<div class="p-4 bg-blue-900 rounded-lg"> |
|
|
<div class="flex items-center"> |
|
|
<i data-feather="info" class="w-5 h-5 mr-2 text-blue-300"></i> |
|
|
<span data-i18n="alert.info">This is an informational message.</span> |
|
|
</div> |
|
|
</div> |
|
|
<div class="p-4 bg-yellow-900 rounded-lg"> |
|
|
<div class="flex items-center"> |
|
|
<i data-feather="alert-triangle" class="w-5 h-5 mr-2 text-yellow-300"></i> |
|
|
<span data-i18n="alert.warning">Warning: Action required.</span> |
|
|
</div> |
|
|
</div> |
|
|
<div class="p-4 bg-red-900 rounded-lg"> |
|
|
<div class="flex items-center"> |
|
|
<i data-feather="alert-octagon" class="w-5 h-5 mr-2 text-red-300"></i> |
|
|
<span data-i18n="alert.error">Error: Something went wrong.</span> |
|
|
</div> |
|
|
</div> |
|
|
<div class="p-4 bg-green-900 rounded-lg"> |
|
|
<div class="flex items-center"> |
|
|
<i data-feather="check-circle" class="w-5 h-5 mr-2 text-green-300"></i> |
|
|
<span data-i18n="alert.success">Success! Operation completed.</span> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="test-section bg-gray-800 rounded-xl p-6"> |
|
|
<h2 class="text-2xl font-semibold mb-4" data-i18n="test.table">Data Table Test</h2> |
|
|
<div class="overflow-x-auto"> |
|
|
<table class="w-full"> |
|
|
<thead> |
|
|
<tr class="text-gray-300 border-b border-gray-700"> |
|
|
<th class="py-3 px-4 text-left" data-i18n="table.id">ID</th> |
|
|
<th class="py-3 px-4 text-left" data-i18n="table.name">Name</th> |
|
|
<th class="py-3 px-4 text-left" data-i18n="table.status">Status</th> |
|
|
<th class="py-3 px-4 text-left" data-i18n="table.date">Date</th> |
|
|
</tr> |
|
|
</thead> |
|
|
<tbody> |
|
|
<tr class="border-b border-gray-700"> |
|
|
<td class="py-3 px-4">P-123456</td> |
|
|
<td class="py-3 px-4" data-i18n="test.johnDoe">John Doe</td> |
|
|
<td class="py-3 px-4"><span class="bg-green-900 text-green-300 px-2 py-1 rounded text-xs" data-i18n="status.active">Active</span></td> |
|
|
<td class="py-3 px-4">15.06.2023</td> |
|
|
</tr> |
|
|
<tr class="border-b border-gray-700"> |
|
|
<td class="py-3 px-4">P-789012</td> |
|
|
<td class="py-3 px-4" data-i18n="test.janeSmith">Jane Smith</td> |
|
|
<td class="py-3 px-4"><span class="bg-yellow-900 text-yellow-300 px-2 py-1 rounded text-xs" data-i18n="status.pending">Pending</span></td> |
|
|
<td class="py-3 px-4">14.06.2023</td> |
|
|
</tr> |
|
|
</tbody> |
|
|
</table> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="test-section bg-gray-800 rounded-xl p-6"> |
|
|
<h2 class="text-2xl font-semibold mb-4" data-i18n="test.components">Complex Components Test</h2> |
|
|
|
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6"> |
|
|
|
|
|
<div class="bg-gray-700 rounded-lg p-4"> |
|
|
<div class="flex items-center mb-4"> |
|
|
<div class="p-3 bg-blue-500 rounded-lg mr-4"> |
|
|
<i data-feather="user" class="w-6 h-6"></i> |
|
|
</div> |
|
|
<h3 class="text-xl font-semibold" data-i18n="component.patient">Patient Card</h3> |
|
|
</div> |
|
|
<p class="text-gray-300 mb-4" data-i18n="component.patientDesc">Patient information and status</p> |
|
|
<button class="w-full bg-blue-600 hover:bg-blue-700 text-white py-2 px-4 rounded-lg transition" data-i18n="component.viewDetails"> |
|
|
View Details |
|
|
</button> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="bg-gray-700 rounded-lg p-4"> |
|
|
<h3 class="text-lg font-semibold mb-2" data-i18n="component.stats">Today's Statistics</h3> |
|
|
<div class="grid grid-cols-2 gap-2 text-sm"> |
|
|
<div> |
|
|
<span class="text-gray-400" data-i18n="stats.patients">Patients:</span> 8 |
|
|
</div> |
|
|
<div> |
|
|
<span class="text-gray-400" data-i18n="stats.studies">Studies:</span> 12 |
|
|
</div> |
|
|
<div> |
|
|
<span class="text-gray-400" data-i18n="stats.reports">Reports:</span> 9 |
|
|
</div> |
|
|
<div> |
|
|
<span class="text-gray-400" data-i18n="stats.avgTime">Avg Time:</span> 23m |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<script> |
|
|
|
|
|
i18next |
|
|
.use(i18nextHttpBackend) |
|
|
.use(i18nextBrowserLanguageDetector) |
|
|
.init({ |
|
|
fallbackLng: 'ru', |
|
|
lng: 'ru', |
|
|
debug: false, |
|
|
backend: { |
|
|
loadPath: '/locales/{{lng}}.json' |
|
|
}, |
|
|
detection: { |
|
|
order: ['querystring', 'cookie', 'localStorage', 'navigator', 'htmlTag'], |
|
|
caches: ['cookie'] |
|
|
} |
|
|
}) |
|
|
.then(function() { |
|
|
|
|
|
i18next.on('languageChanged', updateContent); |
|
|
updateContent(); |
|
|
|
|
|
|
|
|
document.querySelectorAll('.language-card').forEach(btn => { |
|
|
btn.addEventListener('click', async () => { |
|
|
const lang = btn.dataset.lang; |
|
|
await i18next.changeLanguage(lang); |
|
|
}); |
|
|
}); |
|
|
}); |
|
|
|
|
|
function updateContent() { |
|
|
|
|
|
document.querySelectorAll('[data-i18n]').forEach(el => { |
|
|
const key = el.dataset.i18n; |
|
|
if (el.tagName === 'INPUT' && el.type === 'text' || el.tagName === 'INPUT' && el.type === 'email') { |
|
|
el.placeholder = i18next.t(key); |
|
|
} else { |
|
|
el.textContent = i18next.t(key); |
|
|
} |
|
|
}); |
|
|
|
|
|
|
|
|
feather.replace(); |
|
|
} |
|
|
</script> |
|
|
</body> |
|
|
</html> |