feat: implement admin-users management with super admin restriction

- Add /admin/admin-users routes for managing admin users (super admin only)
- Remove vendor role from user creation form (vendors created via company hierarchy)
- Add admin-users.html and admin-user-detail.html templates
- Add admin-users.js and admin-user-detail.js for frontend logic
- Move database operations to admin_platform_service (list, get, create, delete, toggle status)
- Update sidebar to show Admin Users section only for super admins
- Add isSuperAdmin computed property to init-alpine.js
- Fix /api/v1 prefix issues in JS files (apiClient already adds prefix)
- Update architecture rule JS-012 to catch more variable patterns (url, endpoint, path)
- Replace inline SVGs with $icon() helper in select-platform.html

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-24 21:28:46 +01:00
parent 9d28210cf1
commit 7e68b93132
16 changed files with 1691 additions and 325 deletions

View File

@@ -15,6 +15,13 @@ function selectPlatform() {
async init() {
platformLog.info('=== PLATFORM SELECTION PAGE INITIALIZING ===');
// Prevent multiple initializations
if (window._platformSelectInitialized) {
platformLog.warn('Platform selection page already initialized, skipping...');
return;
}
window._platformSelectInitialized = true;
// Set theme
this.dark = localStorage.getItem('theme') === 'dark';
@@ -36,7 +43,7 @@ function selectPlatform() {
try {
platformLog.info('Fetching accessible platforms...');
const response = await apiClient.get('/api/v1/admin/auth/accessible-platforms');
const response = await apiClient.get('/admin/auth/accessible-platforms');
platformLog.debug('Platforms response:', response);
this.isSuperAdmin = response.is_super_admin;
@@ -83,7 +90,7 @@ function selectPlatform() {
try {
const response = await apiClient.post(
`/api/v1/admin/auth/select-platform?platform_id=${platform.id}`
`/admin/auth/select-platform?platform_id=${platform.id}`
);
platformLog.debug('Platform selection response:', response);
@@ -125,25 +132,20 @@ function selectPlatform() {
}
},
logout() {
async logout() {
platformLog.info('Logging out...');
fetch('/api/v1/admin/auth/logout', {
method: 'POST',
headers: {
'Authorization': `Bearer ${localStorage.getItem('admin_token')}`
}
})
.catch((error) => {
try {
await apiClient.post('/admin/auth/logout');
} catch (error) {
platformLog.error('Logout API error:', error);
})
.finally(() => {
} finally {
localStorage.removeItem('admin_token');
localStorage.removeItem('admin_user');
localStorage.removeItem('admin_platform');
localStorage.removeItem('token');
window.location.href = '/admin/login';
});
}
},
toggleDarkMode() {