feat(i18n): add Spanish localization support with Flask-Babel
- Add Flask-Babel for internationalization - Configure app for Spanish (default) and English - Add language switcher in navigation - Wrap all UI text in templates with gettext() - Create translation directory structure - Add complete Spanish translations (58 strings) - Add English translations (template) - Compile .po to .mo files - Add extract_translations.py script for future updates - Add compile_translations.py script Spanish is now the default language, with English available via ?lang=en Translated strings include: - Navigation (Home, Add Tablet, Add User, etc.) - User Loans interface (Search, Filter, Status, etc.) - Table headers (User, Tablet, Serial Number, etc.) - Buttons (Loan, Return, Search, etc.) - Messages (No users found, No active loans, etc.) - All UI text across all templates
This commit is contained in:
parent
db7e9591e1
commit
34dd3ca937
13 changed files with 1020 additions and 110 deletions
|
|
@ -1,9 +1,9 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<html lang="{{ language or 'en' }}">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Tablet Management System</title>
|
||||
<title>{{ _('Tablet Management System') }}</title>
|
||||
|
||||
<!-- Tailwind CSS via CDN -->
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
|
|
@ -48,16 +48,16 @@
|
|||
extend: {
|
||||
colors: {
|
||||
primary: {
|
||||
50: '#f0fdf4',
|
||||
100: '#dcfce7',
|
||||
200: '#bbf7d0',
|
||||
300: '#86efac',
|
||||
400: '#4ade80',
|
||||
500: '#22c55e',
|
||||
600: '#16a34a',
|
||||
700: '#15803d',
|
||||
800: '#166534',
|
||||
900: '#14532d',
|
||||
50: '#ecfdf5',
|
||||
100: '#d1fae5',
|
||||
200: '#a7f3d0',
|
||||
300: '#6ee7b7',
|
||||
400: '#34d399',
|
||||
500: '#10b981',
|
||||
600: '#059669',
|
||||
700: '#047857',
|
||||
800: '#065f46',
|
||||
900: '#064e3b',
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -65,25 +65,68 @@
|
|||
}
|
||||
</script>
|
||||
</head>
|
||||
<body class="bg-gray-50 min-h-screen">
|
||||
<div class="max-w-7xl mx-auto p-4 sm:p-6 lg:p-8">
|
||||
<body class="bg-gray-50 text-gray-900">
|
||||
<!-- Skip to main content -->
|
||||
<a href="#main-content" class="sr-only focus:not-sr-only">Skip to main content</a>
|
||||
|
||||
<!-- Container -->
|
||||
<div class="min-h-screen">
|
||||
<!-- Header -->
|
||||
<header class="mb-8">
|
||||
<h1 class="text-2xl sm:text-3xl font-bold text-gray-800 text-center mb-6">
|
||||
Tablet Management System
|
||||
</h1>
|
||||
|
||||
<header class="bg-primary-600 text-white shadow-lg">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="flex items-center justify-between h-16">
|
||||
<!-- Logo / Title -->
|
||||
<div class="flex items-center gap-3">
|
||||
<svg class="w-8 h-8" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
d="M12 19l9 2-9-18-9 18 9-2zm0 0v-8"></path>
|
||||
</svg>
|
||||
<h1 class="text-xl font-bold">{{ _('Tablet Management System') }}</h1>
|
||||
</div>
|
||||
|
||||
<!-- Language Switcher -->
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="text-sm opacity-80">{{ _('Language') }}:</span>
|
||||
{% for lang_code, lang_name in config['LANGUAGES'].items() %}
|
||||
<a
|
||||
href="?lang={{ lang_code }}"
|
||||
class="px-2 py-1 text-sm rounded hover:bg-white/20 transition-colors
|
||||
{% if language == lang_code %}bg-white/30 font-medium{% endif %}"
|
||||
>
|
||||
{{ lang_name }}
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- Main Content -->
|
||||
<main id="main-content" class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
||||
<!-- Flash Messages -->
|
||||
{% with messages = get_flashed_messages(with_categories=true) %}
|
||||
{% if messages %}
|
||||
<div class="mb-6 space-y-3">
|
||||
{% for category, message in messages %}
|
||||
<div class="p-4 rounded-md
|
||||
{% if category == 'success' %}bg-green-100 text-green-800 border border-green-200
|
||||
{% elif category == 'error' %}bg-red-100 text-red-800 border border-red-200
|
||||
{% else %}bg-blue-100 text-blue-800 border border-blue-200
|
||||
{% endif %}">
|
||||
{{ message }}
|
||||
<div class="p-4 rounded-lg
|
||||
{% if category == 'success' %}bg-green-100 text-green-800
|
||||
{% elif category == 'error' %}bg-red-100 text-red-800
|
||||
{% elif category == 'warning' %}bg-yellow-100 text-yellow-800
|
||||
{% else %}bg-blue-100 text-blue-800{% endif %}">
|
||||
<div class="flex items-center gap-2">
|
||||
{% if category == 'success' %}
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
d="M5 13l4 4L19 7"></path>
|
||||
</svg>
|
||||
{% elif category == 'error' %}
|
||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
|
||||
</svg>
|
||||
{% endif %}
|
||||
<span>{{ _(message) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
|
@ -91,50 +134,55 @@
|
|||
{% endwith %}
|
||||
|
||||
<!-- Navigation -->
|
||||
<nav class="bg-green-600 rounded-lg shadow-md mb-6">
|
||||
<nav class="bg-primary-600 rounded-lg shadow-md mb-6" aria-label="Main navigation">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="flex flex-wrap justify-center sm:justify-start gap-1 sm:gap-2 py-3">
|
||||
<a href="/"
|
||||
class="px-3 py-2 text-sm sm:text-base text-white rounded hover:bg-green-700 transition-colors whitespace-nowrap">
|
||||
Home
|
||||
class="px-3 py-2 text-sm sm:text-base text-white rounded hover:bg-primary-700 transition-colors whitespace-nowrap">
|
||||
{{ _('Home') }}
|
||||
</a>
|
||||
<a href="/add_tablet"
|
||||
class="px-3 py-2 text-sm sm:text-base text-white rounded hover:bg-green-700 transition-colors whitespace-nowrap">
|
||||
Add Tablet
|
||||
class="px-3 py-2 text-sm sm:text-base text-white rounded hover:bg-primary-700 transition-colors whitespace-nowrap">
|
||||
{{ _('Add Tablet') }}
|
||||
</a>
|
||||
<a href="/add_user"
|
||||
class="px-3 py-2 text-sm sm:text-base text-white rounded hover:bg-green-700 transition-colors whitespace-nowrap">
|
||||
Add User
|
||||
class="px-3 py-2 text-sm sm:text-base text-white rounded hover:bg-primary-700 transition-colors whitespace-nowrap">
|
||||
{{ _('Add User') }}
|
||||
</a>
|
||||
<a href="/loan_tablet"
|
||||
class="px-3 py-2 text-sm sm:text-base text-white rounded hover:bg-green-700 transition-colors whitespace-nowrap">
|
||||
Loan Tablet
|
||||
class="px-3 py-2 text-sm sm:text-base text-white rounded hover:bg-primary-700 transition-colors whitespace-nowrap">
|
||||
{{ _('Loan Tablet') }}
|
||||
</a>
|
||||
<a href="/history"
|
||||
class="px-3 py-2 text-sm sm:text-base text-white rounded hover:bg-green-700 transition-colors whitespace-nowrap">
|
||||
Loan History
|
||||
class="px-3 py-2 text-sm sm:text-base text-white rounded hover:bg-primary-700 transition-colors whitespace-nowrap">
|
||||
{{ _('History') }}
|
||||
</a>
|
||||
<a href="/user_loans"
|
||||
class="px-3 py-2 text-sm sm:text-base text-white rounded hover:bg-green-700 transition-colors whitespace-nowrap">
|
||||
User Loans
|
||||
class="px-3 py-2 text-sm sm:text-base text-white rounded hover:bg-primary-700 transition-colors whitespace-nowrap">
|
||||
{{ _('User Loans') }}
|
||||
</a>
|
||||
<a href="/non_loanable_devices"
|
||||
class="px-3 py-2 text-sm sm:text-base text-white rounded hover:bg-green-700 transition-colors whitespace-nowrap">
|
||||
Non-Loanable Devices
|
||||
class="px-3 py-2 text-sm sm:text-base text-white rounded hover:bg-primary-700 transition-colors whitespace-nowrap">
|
||||
{{ _('Non-Loanable Devices') }}
|
||||
</a>
|
||||
<a href="/project_management"
|
||||
class="px-3 py-2 text-sm sm:text-base text-white rounded hover:bg-green-700 transition-colors whitespace-nowrap">
|
||||
Project Management
|
||||
class="px-3 py-2 text-sm sm:text-base text-white rounded hover:bg-primary-700 transition-colors whitespace-nowrap">
|
||||
{{ _('Project Management') }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<!-- Main Content -->
|
||||
<main>
|
||||
|
||||
<!-- Page Content -->
|
||||
{% block content %}{% endblock %}
|
||||
</main>
|
||||
|
||||
<!-- Footer -->
|
||||
<footer class="mt-12 py-6 border-t border-gray-200">
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 text-center text-sm text-gray-500">
|
||||
<p>{{ _('Tablet Management System - Internal Tool') }}</p>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue