diff --git a/management/src/components/Layout.jsx b/management/src/components/Layout.jsx
index b14c254..94f250a 100644
--- a/management/src/components/Layout.jsx
+++ b/management/src/components/Layout.jsx
@@ -1,8 +1,9 @@
import React from 'react'
import { Outlet, NavLink, useLocation } from 'react-router-dom'
-import { useTranslation } from 'react-i18next'
+// import { useTranslation } from 'react-i18next' // Commented out until Docker rebuild
import { useAuth } from '../contexts/AuthContext'
import LanguageSelector from './common/LanguageSelector'
+import { t } from '../utils/tempTranslations' // Temporary translation system
import {
HomeIcon,
BuildingOfficeIcon,
@@ -12,15 +13,15 @@ import {
} from '@heroicons/react/24/outline'
const Layout = () => {
- const { t } = useTranslation()
+ // const { t } = useTranslation() // Commented out until Docker rebuild
const { user, logout } = useAuth()
const location = useLocation()
const navigation = [
- { name: t('navigation.dashboard'), href: '/dashboard', icon: HomeIcon },
- { name: t('navigation.tenants'), href: '/tenants', icon: BuildingOfficeIcon },
- { name: t('navigation.users'), href: '/users', icon: UsersIcon },
- { name: t('navigation.system'), href: '/system', icon: CogIcon },
+ { name: t('nav.dashboard'), href: '/dashboard', icon: HomeIcon },
+ { name: t('nav.tenants'), href: '/tenants', icon: BuildingOfficeIcon },
+ { name: t('nav.users'), href: '/users', icon: UsersIcon },
+ { name: t('nav.system'), href: '/system', icon: CogIcon },
]
return (
@@ -76,7 +77,7 @@ const Layout = () => {
diff --git a/management/src/pages/Dashboard.jsx b/management/src/pages/Dashboard.jsx
index 76cc52f..3871222 100644
--- a/management/src/pages/Dashboard.jsx
+++ b/management/src/pages/Dashboard.jsx
@@ -1,5 +1,6 @@
import React, { useState, useEffect } from 'react'
import api from '../services/api'
+import { t } from '../utils/tempTranslations' // Temporary translation system
import { BuildingOfficeIcon, UsersIcon, ServerIcon, ChartBarIcon } from '@heroicons/react/24/outline'
const Dashboard = () => {
@@ -38,26 +39,26 @@ const Dashboard = () => {
const statCards = [
{
- name: 'Total Tenants',
+ name: t('dashboard.totalTenants'),
value: stats.tenants,
icon: BuildingOfficeIcon,
color: 'bg-blue-500'
},
{
- name: 'Total Users',
+ name: t('dashboard.totalUsers'),
value: stats.users,
icon: UsersIcon,
color: 'bg-green-500'
},
{
- name: 'Active Sessions',
+ name: t('dashboard.activeSessions'),
value: stats.activeSessions,
icon: ChartBarIcon,
color: 'bg-yellow-500'
},
{
- name: 'System Health',
- value: stats.systemHealth === 'good' ? 'Good' : 'Issues',
+ name: t('dashboard.systemHealth'),
+ value: stats.systemHealth === 'good' ? t('dashboard.good') : t('dashboard.issues'),
icon: ServerIcon,
color: stats.systemHealth === 'good' ? 'bg-green-500' : 'bg-red-500'
}
@@ -74,8 +75,8 @@ const Dashboard = () => {
return (
-
Dashboard
-
Overview of your UAMILS system
+
{t('dashboard.title')}
+
{t('dashboard.description')}
{/* Stats Grid */}
diff --git a/management/src/pages/Tenants.jsx b/management/src/pages/Tenants.jsx
index 554ad29..565ac18 100644
--- a/management/src/pages/Tenants.jsx
+++ b/management/src/pages/Tenants.jsx
@@ -3,6 +3,7 @@ import { useNavigate } from 'react-router-dom'
import api from '../services/api'
import toast from 'react-hot-toast'
import TenantModal from '../components/TenantModal'
+import { t } from '../utils/tempTranslations' // Temporary translation system
import {
PlusIcon,
PencilIcon,
@@ -82,16 +83,16 @@ const Tenants = () => {
}
const deleteTenant = async (tenantId) => {
- if (!confirm('Are you sure you want to delete this tenant? This action cannot be undone.')) {
+ if (!confirm(t('tenants.confirmDelete'))) {
return
}
try {
await api.delete(`/management/tenants/${tenantId}`)
- toast.success('Tenant deleted successfully')
+ toast.success(t('tenants.deleteSuccess'))
loadTenants()
} catch (error) {
- toast.error('Failed to delete tenant')
+ toast.error(t('tenants.deleteError'))
console.error('Error deleting tenant:', error)
}
}
@@ -99,8 +100,8 @@ const Tenants = () => {
const toggleTenantStatus = async (tenant) => {
const action = tenant.is_active ? 'deactivate' : 'activate'
const confirmMessage = tenant.is_active
- ? `Are you sure you want to deactivate "${tenant.name}"? Users will not be able to access this tenant.`
- : `Are you sure you want to activate "${tenant.name}"?`
+ ? t('tenants.confirmDeactivate', { name: tenant.name })
+ : t('tenants.confirmActivate', { name: tenant.name })
if (!confirm(confirmMessage)) {
return
@@ -108,10 +109,10 @@ const Tenants = () => {
try {
await api.post(`/management/tenants/${tenant.id}/${action}`)
- toast.success(`Tenant ${action}d successfully`)
+ toast.success(t(`tenants.${action}Success`))
loadTenants()
} catch (error) {
- toast.error(`Failed to ${action} tenant`)
+ toast.error(t(`tenants.${action}Error`))
console.error(`Error ${action}ing tenant:`, error)
}
}
@@ -166,7 +167,7 @@ const Tenants = () => {
? 'bg-green-100 text-green-800'
: 'bg-red-100 text-red-800'
}`}>
- {isActive ? 'Active' : 'Inactive'}
+ {isActive ? t('common.active') : t('common.inactive')}
)
}
@@ -185,15 +186,15 @@ const Tenants = () => {
-
Tenants
-
Manage organizations and their configurations
+
{t('tenants.title')}
+
{t('tenants.description')}
@@ -204,7 +205,7 @@ const Tenants = () => {
{
|
- Tenant
+ {t('tenants.tenant')}
|
- Domain
+ {t('tenants.domain')}
|
- Auth Provider
+ {t('tenants.authProvider')}
|
- Subscription
+ {t('tenants.subscription')}
|
- Users
+ {t('tenants.users')}
|
- Created
+ {t('tenants.created')}
|
- Status
+ {t('tenants.status')}
|
- Actions
+ {t('tenants.actions')}
|
@@ -295,14 +296,14 @@ const Tenants = () => {
@@ -322,24 +323,24 @@ const Tenants = () => {
disabled={pagination.offset === 0}
className="relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 disabled:opacity-50"
>
- Previous
+ {t('common.previous')}
- Showing {pagination.offset + 1} to{' '}
-
- {Math.min(pagination.offset + pagination.limit, pagination.total)}
- {' '}
- of {pagination.total} results
+ {t('common.showingResults', {
+ start: pagination.offset + 1,
+ end: Math.min(pagination.offset + pagination.limit, pagination.total),
+ total: pagination.total
+ })}
@@ -349,15 +350,15 @@ const Tenants = () => {
{tenants.length === 0 && !loading && (
-
No tenants
-
Get started by creating a new tenant.
+
{t('tenants.noTenants')}
+
{t('tenants.noTenantsDescription')}
diff --git a/management/src/utils/tempTranslations.js b/management/src/utils/tempTranslations.js
new file mode 100644
index 0000000..663945e
--- /dev/null
+++ b/management/src/utils/tempTranslations.js
@@ -0,0 +1,279 @@
+// Temporary translation system for management portal until Docker rebuild
+const translations = {
+ en: {
+ nav: {
+ dashboard: 'Dashboard',
+ tenants: 'Tenants',
+ users: 'Users',
+ system: 'System'
+ },
+ navigation: {
+ dashboard: 'Dashboard',
+ tenants: 'Tenants',
+ users: 'Users',
+ system: 'System',
+ logout: 'Logout'
+ },
+ app: {
+ title: 'UAM-ILS Management Portal'
+ },
+ tenants: {
+ title: 'Tenants',
+ description: 'Manage organizations and their configurations',
+ noTenants: 'No tenants',
+ noTenantsDescription: 'Get started by creating a new tenant.',
+ loadingTenants: 'Loading tenants...',
+ addTenant: 'Create Tenant',
+ createTenant: 'Create Tenant',
+ editTenant: 'Edit Tenant',
+ deleteTenant: 'Delete Tenant',
+ searchPlaceholder: 'Search tenants...',
+ tenant: 'Tenant',
+ tenantName: 'Tenant Name',
+ tenantSlug: 'Tenant Slug',
+ domain: 'Domain',
+ authProvider: 'Auth Provider',
+ subscription: 'Subscription',
+ users: 'Users',
+ status: 'Status',
+ created: 'Created',
+ lastActivity: 'Last Activity',
+ actions: 'Actions',
+ active: 'Active',
+ inactive: 'Inactive',
+ suspended: 'Suspended',
+ edit: 'Edit',
+ delete: 'Delete',
+ viewUsers: 'View Users',
+ confirmDelete: 'Are you sure you want to delete this tenant? This action cannot be undone.',
+ confirmActivate: 'Are you sure you want to activate "{{name}}"?',
+ confirmDeactivate: 'Are you sure you want to deactivate "{{name}}"? Users will not be able to access this tenant.',
+ deleteSuccess: 'Tenant deleted successfully',
+ deleteError: 'Failed to delete tenant',
+ activateSuccess: 'Tenant activated successfully',
+ activateError: 'Failed to activate tenant',
+ deactivateSuccess: 'Tenant deactivated successfully',
+ deactivateError: 'Failed to deactivate tenant',
+ deleteWarning: 'This action cannot be undone and will remove all associated data.',
+ totalTenants: 'Total Tenants',
+ activeTenants: 'Active Tenants'
+ },
+ users: {
+ title: 'User Management',
+ noUsers: 'No users found',
+ addUser: 'Add User',
+ editUser: 'Edit User',
+ deleteUser: 'Delete User',
+ username: 'Username',
+ email: 'Email',
+ role: 'Role',
+ tenant: 'Tenant',
+ status: 'Status',
+ lastLogin: 'Last Login',
+ created: 'Created',
+ actions: 'Actions'
+ },
+ dashboard: {
+ title: 'Dashboard',
+ description: 'Overview of your UAMILS system',
+ totalTenants: 'Total Tenants',
+ activeTenants: 'Active Tenants',
+ totalUsers: 'Total Users',
+ activeSessions: 'Active Sessions',
+ systemHealth: 'System Health',
+ good: 'Good',
+ issues: 'Issues'
+ },
+ system: {
+ title: 'System Information',
+ serverInfo: 'Server Information',
+ databaseInfo: 'Database Information',
+ version: 'Version',
+ uptime: 'Uptime',
+ platform: 'Platform'
+ },
+ common: {
+ loading: 'Loading...',
+ error: 'Error',
+ success: 'Success',
+ cancel: 'Cancel',
+ save: 'Save',
+ delete: 'Delete',
+ edit: 'Edit',
+ add: 'Add',
+ search: 'Search',
+ filter: 'Filter',
+ refresh: 'Refresh',
+ previous: 'Previous',
+ next: 'Next',
+ active: 'Active',
+ inactive: 'Inactive',
+ showingResults: 'Showing {{start}} to {{end}} of {{total}} results',
+ yes: 'Yes',
+ no: 'No',
+ ok: 'OK',
+ close: 'Close'
+ },
+ auth: {
+ login: 'Login',
+ username: 'Username',
+ password: 'Password',
+ loginButton: 'Sign In',
+ logout: 'Logout'
+ }
+ },
+ sv: {
+ nav: {
+ dashboard: 'Översikt',
+ tenants: 'Hyresgäster',
+ users: 'Användare',
+ system: 'System'
+ },
+ navigation: {
+ dashboard: 'Översikt',
+ tenants: 'Hyresgäster',
+ users: 'Användare',
+ system: 'System',
+ logout: 'Logga ut'
+ },
+ app: {
+ title: 'UAM-ILS Förvaltningsportal'
+ },
+ tenants: {
+ title: 'Hyresgäster',
+ description: 'Hantera organisationer och deras konfigurationer',
+ noTenants: 'Inga hyresgäster',
+ noTenantsDescription: 'Kom igång genom att skapa en ny hyresgäst.',
+ loadingTenants: 'Laddar hyresgäster...',
+ addTenant: 'Skapa hyresgäst',
+ createTenant: 'Skapa hyresgäst',
+ editTenant: 'Redigera hyresgäst',
+ deleteTenant: 'Ta bort hyresgäst',
+ searchPlaceholder: 'Sök hyresgäster...',
+ tenant: 'Hyresgäst',
+ tenantName: 'Hyresgästnamn',
+ tenantSlug: 'Hyresgästslug',
+ domain: 'Domän',
+ authProvider: 'Auth-leverantör',
+ subscription: 'Prenumeration',
+ users: 'Användare',
+ status: 'Status',
+ created: 'Skapad',
+ lastActivity: 'Senaste aktivitet',
+ actions: 'Åtgärder',
+ active: 'Aktiv',
+ inactive: 'Inaktiv',
+ suspended: 'Avstängd',
+ edit: 'Redigera',
+ delete: 'Ta bort',
+ viewUsers: 'Visa användare',
+ confirmDelete: 'Är du säker på att du vill ta bort denna hyresgäst? Denna åtgärd kan inte ångras.',
+ confirmActivate: 'Är du säker på att du vill aktivera "{{name}}"?',
+ confirmDeactivate: 'Är du säker på att du vill deaktivera "{{name}}"? Användare kommer inte att kunna komma åt denna hyresgäst.',
+ deleteSuccess: 'Hyresgäst borttagen framgångsrikt',
+ deleteError: 'Misslyckades att ta bort hyresgäst',
+ activateSuccess: 'Hyresgäst aktiverad framgångsrikt',
+ activateError: 'Misslyckades att aktivera hyresgäst',
+ deactivateSuccess: 'Hyresgäst deaktiverad framgångsrikt',
+ deactivateError: 'Misslyckades att deaktivera hyresgäst',
+ deleteWarning: 'Denna åtgärd kan inte ångras och kommer att ta bort all associerad data.',
+ totalTenants: 'Totala hyresgäster',
+ activeTenants: 'Aktiva hyresgäster'
+ },
+ users: {
+ title: 'Användarhantering',
+ noUsers: 'Inga användare hittades',
+ addUser: 'Lägg till användare',
+ editUser: 'Redigera användare',
+ deleteUser: 'Ta bort användare',
+ username: 'Användarnamn',
+ email: 'E-post',
+ role: 'Roll',
+ tenant: 'Hyresgäst',
+ status: 'Status',
+ lastLogin: 'Senaste inloggning',
+ created: 'Skapad',
+ actions: 'Åtgärder'
+ },
+ dashboard: {
+ title: 'Instrumentpanel',
+ description: 'Översikt av ditt UAMILS-system',
+ totalTenants: 'Totala hyresgäster',
+ activeTenants: 'Aktiva hyresgäster',
+ totalUsers: 'Totala användare',
+ activeSessions: 'Aktiva sessioner',
+ systemHealth: 'Systemhälsa',
+ good: 'Bra',
+ issues: 'Problem'
+ },
+ system: {
+ title: 'Systeminformation',
+ serverInfo: 'Serverinformation',
+ databaseInfo: 'Databasinformation',
+ version: 'Version',
+ uptime: 'Drifttid',
+ platform: 'Plattform'
+ },
+ common: {
+ loading: 'Laddar...',
+ error: 'Fel',
+ success: 'Framgång',
+ cancel: 'Avbryt',
+ save: 'Spara',
+ delete: 'Ta bort',
+ edit: 'Redigera',
+ add: 'Lägg till',
+ search: 'Sök',
+ filter: 'Filtrera',
+ refresh: 'Uppdatera',
+ previous: 'Föregående',
+ next: 'Nästa',
+ active: 'Aktiv',
+ inactive: 'Inaktiv',
+ showingResults: 'Visar {{start}} till {{end}} av {{total}} resultat',
+ yes: 'Ja',
+ no: 'Nej',
+ ok: 'OK',
+ close: 'Stäng'
+ },
+ auth: {
+ login: 'Logga in',
+ username: 'Användarnamn',
+ password: 'Lösenord',
+ loginButton: 'Logga in',
+ logout: 'Logga ut'
+ }
+ }
+};
+
+let currentLanguage = localStorage.getItem('language') || 'en';
+
+export const t = (key, params = {}) => {
+ const keys = key.split('.');
+ let value = translations[currentLanguage];
+
+ for (const k of keys) {
+ value = value?.[k];
+ }
+
+ let result = value || key;
+
+ // Simple parameter interpolation
+ if (params && typeof params === 'object') {
+ Object.keys(params).forEach(param => {
+ const placeholder = `{{${param}}}`;
+ result = result.replace(new RegExp(placeholder, 'g'), params[param]);
+ });
+ }
+
+ return result;
+};
+
+export const changeLanguage = (lang) => {
+ currentLanguage = lang;
+ localStorage.setItem('language', lang);
+ // Trigger a page refresh to update all components
+ window.location.reload();
+};
+
+export const getCurrentLanguage = () => currentLanguage;
\ No newline at end of file