forked from BRETT/BRETT
Initial Commit
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
<script setup lang="ts">
|
||||
import type { CardBorderEffectKey } from '~~/shared/utils/cardBorderEffects'
|
||||
import type { CardEffectKey } from '~~/shared/utils/cardEffects'
|
||||
import CardBackgroundEffect from '@/components/effects/CardBackgroundEffect.vue'
|
||||
import CardBorderEffect from '@/components/effects/CardBorderEffect.vue'
|
||||
import CardVignette from '@/components/effects/CardVignette.vue'
|
||||
import { isCardBorderEffect } from '~~/shared/utils/cardBorderEffects'
|
||||
import { isCardEffect } from '~~/shared/utils/cardEffects'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
interface ListedUser {
|
||||
id: number
|
||||
name: string
|
||||
color: string | null
|
||||
avatarUrl: string | null
|
||||
cardEffect: string | null
|
||||
cardEffectColor: string | null
|
||||
cardVignette: boolean
|
||||
cardBorderEffect: string | null
|
||||
cardBorderEffectColor: string | null
|
||||
createdAt: string
|
||||
stats: {
|
||||
uploads: number
|
||||
comments: number
|
||||
}
|
||||
}
|
||||
|
||||
const { data: users } = await useFetch<ListedUser[]>('/api/users', {
|
||||
key: 'users-list',
|
||||
default: () => [],
|
||||
})
|
||||
|
||||
function cardEffect(user: ListedUser): CardEffectKey | null {
|
||||
return user.cardEffect && isCardEffect(user.cardEffect) ? user.cardEffect : null
|
||||
}
|
||||
|
||||
function cardBorderEffect(user: ListedUser): CardBorderEffectKey | null {
|
||||
return user.cardBorderEffect && isCardBorderEffect(user.cardBorderEffect) ? user.cardBorderEffect : null
|
||||
}
|
||||
|
||||
const GRID_COLS = 'grid-cols-[2.5rem_minmax(0,1fr)_3rem_2.5rem_2.5rem] sm:grid-cols-[2.5rem_minmax(0,1fr)_3.5rem_4.5rem_4.5rem_10rem]'
|
||||
|
||||
function joinDate(value: string) {
|
||||
return new Intl.DateTimeFormat('de-DE', { dateStyle: 'medium' }).format(new Date(value))
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="px-4 lg:px-6">
|
||||
<h1 class="mb-4 text-xl font-semibold">
|
||||
Benutzer
|
||||
</h1>
|
||||
|
||||
<p v-if="!users.length" class="text-sm text-muted-foreground">
|
||||
Noch keine Benutzer.
|
||||
</p>
|
||||
|
||||
<div v-else class="max-w-4xl overflow-x-auto">
|
||||
<div :class="cn('grid items-center gap-3 px-3 py-2 text-xs text-muted-foreground', GRID_COLS)">
|
||||
<span />
|
||||
<span>Name</span>
|
||||
<span class="text-right">ID</span>
|
||||
<span class="hidden text-right sm:block">Uploads</span>
|
||||
<span class="hidden text-right sm:block">Kommentare</span>
|
||||
<span class="hidden text-right sm:block">Dabei seit</span>
|
||||
</div>
|
||||
|
||||
<div class="mt-1 flex flex-col gap-2">
|
||||
<NuxtLink
|
||||
v-for="user in users"
|
||||
:key="user.id"
|
||||
:to="`/user/${user.id}`"
|
||||
:class="cn(
|
||||
'relative block overflow-hidden rounded-md border transition-colors',
|
||||
cardBorderEffect(user) ? 'border-transparent' : 'hover:border-primary/50',
|
||||
)"
|
||||
>
|
||||
<div v-if="cardEffect(user)" class="pointer-events-none absolute inset-0 overflow-hidden rounded-[inherit] [clip-path:inset(0_round_var(--radius-md))]">
|
||||
<CardBackgroundEffect :effect="cardEffect(user)!" :color="user.cardEffectColor ?? user.color ?? '#6366f1'" />
|
||||
<div class="absolute inset-0 bg-background/60" />
|
||||
<CardVignette v-if="user.cardVignette" surface="var(--color-background)" />
|
||||
</div>
|
||||
<CardBorderEffect v-if="cardBorderEffect(user)" :effect="cardBorderEffect(user)!" :color="user.cardBorderEffectColor ?? user.color ?? '#6366f1'" />
|
||||
|
||||
<div :class="cn('relative grid items-center gap-3 px-3 py-2.5', GRID_COLS)">
|
||||
<NuxtImg
|
||||
v-if="user.avatarUrl"
|
||||
:src="user.avatarUrl"
|
||||
:alt="user.name"
|
||||
width="40"
|
||||
height="40"
|
||||
fit="cover"
|
||||
class="size-10 shrink-0 rounded-sm"
|
||||
/>
|
||||
<span
|
||||
v-else
|
||||
class="flex size-10 shrink-0 items-center justify-center rounded-sm text-xs font-medium"
|
||||
:style="user.color ? { backgroundColor: user.color, color: '#fff' } : { backgroundColor: 'var(--color-muted)' }"
|
||||
>{{ user.name.slice(0, 2).toUpperCase() }}</span>
|
||||
<span
|
||||
class="truncate font-medium"
|
||||
:style="user.color ? { color: user.color } : undefined"
|
||||
>{{ user.name }}</span>
|
||||
<span class="text-right text-sm text-muted-foreground">{{ user.id }}</span>
|
||||
<span class="hidden text-right text-sm sm:block">{{ user.stats.uploads }}</span>
|
||||
<span class="hidden text-right text-sm sm:block">{{ user.stats.comments }}</span>
|
||||
<span class="hidden text-right text-sm text-muted-foreground sm:block">{{ joinDate(user.createdAt) }}</span>
|
||||
</div>
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
Reference in New Issue
Block a user