From 9137f41537c8d84a92be7539a26824a19928c4df Mon Sep 17 00:00:00 2001 From: curo1305 Date: Fri, 22 May 2026 20:09:05 +0200 Subject: [PATCH] feat(02-05): admin tab components and AdminView - AdminView.vue: tabbed layout (Users | Quotas | AI Config) with UI-SPEC tab strip classes - AdminUsersTab.vue: user table with create form (crypto.getRandomValues password), inline deactivation confirmation, reactivate, reset-password, row-level spinner, empty state - AdminQuotasTab.vue: quota inline edit with MB display, usage %, warning when limit < usage - AdminAiConfigTab.vue: AI provider/model per-user with 1.5s "Saved" confirmation - client.js: fix adminDeactivateUser/adminReactivateUser to use PATCH /status endpoint, fix adminResetUserPassword to /password-reset, fix adminUpdateAiConfig to send ai_provider/ai_model, add adminGetUserQuota - No impersonation UI in any admin component (T-02-31) --- frontend/src/api/client.js | 20 +- .../src/components/admin/AdminAiConfigTab.vue | 135 +++++++ .../src/components/admin/AdminQuotasTab.vue | 182 +++++++++ .../src/components/admin/AdminUsersTab.vue | 379 ++++++++++++++++++ frontend/src/views/AdminView.vue | 19 +- 5 files changed, 722 insertions(+), 13 deletions(-) create mode 100644 frontend/src/components/admin/AdminAiConfigTab.vue create mode 100644 frontend/src/components/admin/AdminQuotasTab.vue create mode 100644 frontend/src/components/admin/AdminUsersTab.vue diff --git a/frontend/src/api/client.js b/frontend/src/api/client.js index 774d00a..6855396 100644 --- a/frontend/src/api/client.js +++ b/frontend/src/api/client.js @@ -225,15 +225,27 @@ export function adminCreateUser(body) { } export function adminDeactivateUser(id) { - return request(`/api/admin/users/${id}/deactivate`, { method: 'POST' }) + return request(`/api/admin/users/${id}/status`, { + method: 'PATCH', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ is_active: false }), + }) } export function adminReactivateUser(id) { - return request(`/api/admin/users/${id}/reactivate`, { method: 'POST' }) + return request(`/api/admin/users/${id}/status`, { + method: 'PATCH', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ is_active: true }), + }) } export function adminResetUserPassword(id) { - return request(`/api/admin/users/${id}/reset-password`, { method: 'POST' }) + return request(`/api/admin/users/${id}/password-reset`, { method: 'POST' }) +} + +export function adminGetUserQuota(id) { + return request(`/api/admin/users/${id}/quota`) } export function adminUpdateQuota(id, limitBytes) { @@ -248,6 +260,6 @@ export function adminUpdateAiConfig(id, provider, model) { return request(`/api/admin/users/${id}/ai-config`, { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ provider, model }), + body: JSON.stringify({ ai_provider: provider, ai_model: model }), }) } diff --git a/frontend/src/components/admin/AdminAiConfigTab.vue b/frontend/src/components/admin/AdminAiConfigTab.vue new file mode 100644 index 0000000..afee257 --- /dev/null +++ b/frontend/src/components/admin/AdminAiConfigTab.vue @@ -0,0 +1,135 @@ + + + diff --git a/frontend/src/components/admin/AdminQuotasTab.vue b/frontend/src/components/admin/AdminQuotasTab.vue new file mode 100644 index 0000000..7babeb4 --- /dev/null +++ b/frontend/src/components/admin/AdminQuotasTab.vue @@ -0,0 +1,182 @@ + + + diff --git a/frontend/src/components/admin/AdminUsersTab.vue b/frontend/src/components/admin/AdminUsersTab.vue new file mode 100644 index 0000000..ce37f28 --- /dev/null +++ b/frontend/src/components/admin/AdminUsersTab.vue @@ -0,0 +1,379 @@ + + + diff --git a/frontend/src/views/AdminView.vue b/frontend/src/views/AdminView.vue index 0ddcc53..ae6720c 100644 --- a/frontend/src/views/AdminView.vue +++ b/frontend/src/views/AdminView.vue @@ -1,8 +1,8 @@