Rename hoard- to ui- and add UI components
Mass rename of CSS classes, tokens and animations from the hoard- namespace to ui- (classes, variables like --ui-*, and keyframes). Introduces new UI components: EmptyState, StatusPill, and UserAvatar and updates admin views to import and use them. Updates many route/layout components and global.css to use the new ui- patterns and responsive variables. Also updates Impressum contact emails and adds .claude/settings.local.json to allow running npm scripts in the Claude local settings.
This commit is contained in:
@@ -4,6 +4,9 @@ import { useRouter } from 'vue-router'
|
||||
import { fetchAdminUsers, type AdminUser } from '@/services/adminUsers'
|
||||
import { AuthRequestError } from '@/services/authSession'
|
||||
import { useAppBannersStore } from '@/stores/appBanners'
|
||||
import StatusPill from '@/components/ui/StatusPill.vue'
|
||||
import UserAvatar from '@/components/ui/UserAvatar.vue'
|
||||
import EmptyState from '@/components/ui/EmptyState.vue'
|
||||
|
||||
const router = useRouter()
|
||||
const appBannersStore = useAppBannersStore()
|
||||
@@ -111,15 +114,15 @@ onMounted(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<v-container fluid class="admin-users-page hoard-page">
|
||||
<header class="admin-users-header hoard-panel hoard-panel-gradient">
|
||||
<v-container fluid class="admin-users-page ui-page">
|
||||
<header class="admin-users-header ui-panel ui-panel-gradient">
|
||||
<div class="admin-users-header__copy">
|
||||
<p class="hoard-kicker hoard-kicker--wide">Adminbereich</p>
|
||||
<p class="ui-kicker ui-kicker--wide">Adminbereich</p>
|
||||
<h1>Benutzerverwaltung</h1>
|
||||
<p>Alle Hoard-Konten mit Rollen, Status und Passwortwechselpflicht – read-only.</p>
|
||||
</div>
|
||||
|
||||
<div class="admin-users-header__actions hoard-action-row">
|
||||
<div class="admin-users-header__actions ui-action-row">
|
||||
<v-text-field
|
||||
v-model="searchQuery"
|
||||
variant="outlined"
|
||||
@@ -144,7 +147,7 @@ onMounted(() => {
|
||||
|
||||
<section v-if="!isLoading && !errorMessage" class="admin-users-stats" aria-label="Benutzerübersicht">
|
||||
<article class="admin-users-stat">
|
||||
<span class="hoard-icon-tile">
|
||||
<span class="ui-icon-tile">
|
||||
<v-icon icon="mdi-account-group-outline" size="20" />
|
||||
</span>
|
||||
<div>
|
||||
@@ -153,7 +156,7 @@ onMounted(() => {
|
||||
</div>
|
||||
</article>
|
||||
<article class="admin-users-stat">
|
||||
<span class="hoard-icon-tile">
|
||||
<span class="ui-icon-tile">
|
||||
<v-icon icon="mdi-account-check-outline" size="20" />
|
||||
</span>
|
||||
<div>
|
||||
@@ -162,7 +165,7 @@ onMounted(() => {
|
||||
</div>
|
||||
</article>
|
||||
<article class="admin-users-stat">
|
||||
<span class="hoard-icon-tile">
|
||||
<span class="ui-icon-tile">
|
||||
<v-icon icon="mdi-shield-account-outline" size="20" />
|
||||
</span>
|
||||
<div>
|
||||
@@ -171,7 +174,7 @@ onMounted(() => {
|
||||
</div>
|
||||
</article>
|
||||
<article class="admin-users-stat">
|
||||
<span class="hoard-icon-tile">
|
||||
<span class="ui-icon-tile">
|
||||
<v-icon icon="mdi-lock-reset" size="20" />
|
||||
</span>
|
||||
<div>
|
||||
@@ -187,16 +190,16 @@ onMounted(() => {
|
||||
|
||||
<p v-else-if="isLoading" class="admin-users-loading">Benutzer werden geladen …</p>
|
||||
|
||||
<section v-else-if="!hasUsers" class="hoard-panel hoard-empty-state">
|
||||
<span class="hoard-icon-tile hoard-icon-tile--lg">
|
||||
<v-icon icon="mdi-account-question-outline" size="22" />
|
||||
</span>
|
||||
<h2>Keine Benutzer gefunden</h2>
|
||||
<p>Aktuell sind keine Konten vorhanden. Ein neuer Account muss vom Admin manuell angelegt werden.</p>
|
||||
</section>
|
||||
<EmptyState
|
||||
v-else-if="!hasUsers"
|
||||
icon="mdi-account-question-outline"
|
||||
title="Keine Benutzer gefunden"
|
||||
>
|
||||
Aktuell sind keine Konten vorhanden. Ein neuer Account muss vom Admin manuell angelegt werden.
|
||||
</EmptyState>
|
||||
|
||||
<section v-else class="admin-users-listing hoard-panel">
|
||||
<header class="admin-users-listing__head hoard-toolbar">
|
||||
<section v-else class="admin-users-listing ui-panel">
|
||||
<header class="admin-users-listing__head ui-toolbar">
|
||||
<div>
|
||||
<p class="admin-users-listing__title">Benutzer</p>
|
||||
<p class="admin-users-listing__meta">{{ filteredUsers.length }} von {{ users.length }} angezeigt</p>
|
||||
@@ -222,7 +225,7 @@ onMounted(() => {
|
||||
<tr v-for="user in filteredUsers" :key="user.id">
|
||||
<td>
|
||||
<div class="admin-users-cell-user">
|
||||
<span class="admin-users-cell-user__avatar">{{ userInitials(user) }}</span>
|
||||
<UserAvatar class="admin-users-cell-user__avatar" :initials="userInitials(user)" />
|
||||
<div>
|
||||
<p class="admin-users-cell-user__name">{{ user.userName || '(ohne Benutzername)' }}</p>
|
||||
<p class="admin-users-cell-user__id">{{ user.id }}</p>
|
||||
@@ -231,24 +234,14 @@ onMounted(() => {
|
||||
</td>
|
||||
<td>{{ formatRoles(user.roles) }}</td>
|
||||
<td>
|
||||
<span
|
||||
:class="[
|
||||
'hoard-status',
|
||||
user.isActive ? 'hoard-status--success' : 'hoard-status--danger',
|
||||
]"
|
||||
>
|
||||
<StatusPill :variant="user.isActive ? 'success' : 'danger'">
|
||||
{{ user.isActive ? 'Aktiv' : 'Inaktiv' }}
|
||||
</span>
|
||||
</StatusPill>
|
||||
</td>
|
||||
<td>
|
||||
<span
|
||||
:class="[
|
||||
'hoard-status',
|
||||
user.mustChangePassword ? 'hoard-status--warning' : 'hoard-status--info',
|
||||
]"
|
||||
>
|
||||
<StatusPill :variant="user.mustChangePassword ? 'warning' : 'info'">
|
||||
{{ user.mustChangePassword ? 'Erforderlich' : 'Aktuell' }}
|
||||
</span>
|
||||
</StatusPill>
|
||||
</td>
|
||||
<td class="admin-users-col-actions">
|
||||
<v-btn
|
||||
@@ -268,7 +261,7 @@ onMounted(() => {
|
||||
<div v-if="filteredUsers.length > 0" class="admin-users-mobile-list" aria-label="Benutzerliste">
|
||||
<article v-for="user in filteredUsers" :key="user.id" class="admin-users-mobile-card">
|
||||
<header class="admin-users-mobile-head">
|
||||
<span class="admin-users-mobile-avatar">{{ userInitials(user) }}</span>
|
||||
<UserAvatar class="admin-users-mobile-avatar" :initials="userInitials(user)" />
|
||||
<div>
|
||||
<p class="admin-users-mobile-label">Benutzer</p>
|
||||
<h2>{{ user.userName || '(ohne Benutzername)' }}</h2>
|
||||
@@ -284,27 +277,17 @@ onMounted(() => {
|
||||
<div>
|
||||
<dt>Aktiv</dt>
|
||||
<dd>
|
||||
<span
|
||||
:class="[
|
||||
'hoard-status',
|
||||
user.isActive ? 'hoard-status--success' : 'hoard-status--danger',
|
||||
]"
|
||||
>
|
||||
<StatusPill :variant="user.isActive ? 'success' : 'danger'">
|
||||
{{ user.isActive ? 'Aktiv' : 'Inaktiv' }}
|
||||
</span>
|
||||
</StatusPill>
|
||||
</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>Passwortwechsel</dt>
|
||||
<dd>
|
||||
<span
|
||||
:class="[
|
||||
'hoard-status',
|
||||
user.mustChangePassword ? 'hoard-status--warning' : 'hoard-status--info',
|
||||
]"
|
||||
>
|
||||
<StatusPill :variant="user.mustChangePassword ? 'warning' : 'info'">
|
||||
{{ user.mustChangePassword ? 'Erforderlich' : 'Nein' }}
|
||||
</span>
|
||||
</StatusPill>
|
||||
</dd>
|
||||
</div>
|
||||
</dl>
|
||||
@@ -325,15 +308,15 @@ onMounted(() => {
|
||||
|
||||
<style scoped>
|
||||
.admin-users-page {
|
||||
--hoard-page-width: 1200px;
|
||||
--ui-page-width: 1200px;
|
||||
}
|
||||
|
||||
/* ---------- Header ---------- */
|
||||
.admin-users-header {
|
||||
--hoard-gradient-angle: 120deg;
|
||||
--hoard-gradient-start: color-mix(in srgb, var(--color-primary-100) 55%, var(--color-surface) 45%);
|
||||
--hoard-gradient-end: var(--color-surface);
|
||||
--hoard-gradient-end-stop: 65%;
|
||||
--ui-gradient-angle: 120deg;
|
||||
--ui-gradient-start: color-mix(in srgb, var(--color-primary-100) 55%, var(--color-surface) 45%);
|
||||
--ui-gradient-end: var(--color-surface);
|
||||
--ui-gradient-end-stop: 65%;
|
||||
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
|
||||
@@ -505,7 +488,7 @@ onMounted(() => {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.hoard-empty-state {
|
||||
.ui-empty-state {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
@@ -516,7 +499,7 @@ onMounted(() => {
|
||||
.admin-users-header,
|
||||
.admin-users-stat,
|
||||
.admin-users-listing {
|
||||
animation: hoard-soft-enter 280ms both;
|
||||
animation: ui-soft-enter 280ms both;
|
||||
}
|
||||
|
||||
.admin-users-stat:nth-child(2) { animation-delay: 60ms; }
|
||||
|
||||
Reference in New Issue
Block a user