All checks were successful
Auto Tag Develop / tag (push) Successful in 9s
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
111 lines
3.7 KiB
Vue
111 lines
3.7 KiB
Vue
<template>
|
|
<div class="px-[86px]">
|
|
<div class="flex items-center justify-between">
|
|
<h1 class="text-4xl font-bold uppercase text-primary-500">Liste des utilisateurs</h1>
|
|
<NuxtLink
|
|
v-if="auth.isAdmin"
|
|
to="/admin/user"
|
|
class="inline-flex items-center justify-center text-xl text-white uppercase bg-primary-500 h-[50px] px-6 rounded hover:opacity-80 gap-2"
|
|
>
|
|
<Icon name="mdi:plus" size="28" />
|
|
Ajouter
|
|
</NuxtLink>
|
|
</div>
|
|
|
|
<div v-if="auth.isAdmin" class="mt-6 mb-16">
|
|
<UiDataTable
|
|
v-model:page="page"
|
|
v-model:per-page="perPage"
|
|
:columns="columns"
|
|
:items="items"
|
|
:total-items="totalItems"
|
|
:loading="loading"
|
|
row-clickable
|
|
@row-click="goToUser"
|
|
>
|
|
<template #header-username>
|
|
<UiTextInput
|
|
v-model="filters.username"
|
|
placeholder="Utilisateur"
|
|
size="compact"
|
|
/>
|
|
</template>
|
|
<template #header-roles>
|
|
<UiTextInput :model-value="''" placeholder="Role" size="compact" disabled />
|
|
</template>
|
|
<template #header-isLocked>
|
|
<UiSelect
|
|
v-model="filters.isLocked"
|
|
placeholder="Statut"
|
|
:options="statusOptions"
|
|
size="compact"
|
|
/>
|
|
</template>
|
|
<template #cell-roles="{ item }">
|
|
{{ getRoleLabels(item.roles) }}
|
|
</template>
|
|
<template #cell-isLocked="{ item }">
|
|
<span
|
|
v-if="item.isLocked"
|
|
class="inline-block px-2 py-0.5 text-xs font-semibold rounded bg-red-100 text-red-700"
|
|
>Verrouillé</span>
|
|
<span
|
|
v-else
|
|
class="inline-block px-2 py-0.5 text-xs font-semibold rounded bg-green-100 text-green-700"
|
|
>Actif</span>
|
|
</template>
|
|
</UiDataTable>
|
|
</div>
|
|
<div v-else class="mt-6 border border-slate-200 mb-16 px-4 py-6 text-slate-400">
|
|
Accès réservé aux administrateurs.
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
useHead({ title: 'Utilisateurs' })
|
|
|
|
import type { UserData } from '~/services/dto/user-data'
|
|
import { ROLE } from '~/utils/constants'
|
|
import { useAuthStore } from '~/stores/auth'
|
|
import { useDataTableServerState } from '~/composables/useDataTableServerState'
|
|
|
|
const router = useRouter()
|
|
const auth = useAuthStore()
|
|
const roleLabelByValue = new Map(ROLE.map(role => [role.value, role.label]))
|
|
|
|
const { items, totalItems, page, perPage, filters, loading, reload } =
|
|
useDataTableServerState<UserData>(
|
|
'admin/users',
|
|
{
|
|
username: '',
|
|
isLocked: ''
|
|
}
|
|
)
|
|
|
|
const statusOptions = [
|
|
{ value: 'false', label: 'Actif' },
|
|
{ value: 'true', label: 'Verrouillé' }
|
|
]
|
|
|
|
const columns = [
|
|
{ key: 'username', label: 'Utilisateur' },
|
|
{ key: 'roles', label: 'Role' },
|
|
{ key: 'isLocked', label: 'Statut', width: '160px' }
|
|
]
|
|
|
|
const getRoleLabels = (roles?: string[]) => {
|
|
if (!roles || roles.length === 0) return '---'
|
|
return roles.map(role => roleLabelByValue.get(role) ?? role).join(', ')
|
|
}
|
|
|
|
const goToUser = (user: UserData) => {
|
|
if (!auth.isAdmin) return
|
|
router.push(`/admin/user/${user.id}`)
|
|
}
|
|
|
|
onMounted(() => {
|
|
if (auth.isAdmin) reload()
|
|
})
|
|
</script>
|