Refactor frontend components and enhance API integration
- Updated frontend-nuxt.mdc to specify usage of composables for API calls. - Added new AuthCard and ConfirmModal components for improved UI consistency. - Introduced UserAvatar component for user profile display, replacing previous Gravatar implementation. - Implemented useFormSubmit composable for handling form submissions with loading and error states. - Enhanced vitest.config.ts to include coverage reporting for composables and components. - Removed deprecated useAdminApi and useAuth composables to streamline API interactions. - Updated login and setup pages to utilize new components and composables for better user experience.
This commit is contained in:
@@ -37,23 +37,7 @@
|
||||
<div class="dropdown dropdown-end flex items-center">
|
||||
<details ref="userDropdownRef" class="dropdown group">
|
||||
<summary class="btn btn-ghost btn-sm gap-2 flex items-center min-h-9 h-9 cursor-pointer list-none [&::-webkit-details-marker]:hidden">
|
||||
<div class="avatar">
|
||||
<div class="rounded-full w-8 h-8 overflow-hidden flex items-center justify-center">
|
||||
<img
|
||||
v-if="me.email && !gravatarErrorDesktop"
|
||||
:src="useGravatarUrl(me.email, 32)"
|
||||
alt=""
|
||||
class="w-full h-full object-cover"
|
||||
@error="gravatarErrorDesktop = true"
|
||||
>
|
||||
<div
|
||||
v-else
|
||||
class="bg-primary text-primary-content rounded-full w-8 h-8 flex items-center justify-center"
|
||||
>
|
||||
<span class="text-sm font-medium">{{ (me.username || '?')[0].toUpperCase() }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<UserAvatar :username="me.username" :email="me.email" :size="32" />
|
||||
<span class="max-w-[8rem] truncate font-medium">{{ me.username }}</span>
|
||||
<svg class="size-4 opacity-70 shrink-0 transition-transform group-open:rotate-180" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
|
||||
@@ -128,23 +112,7 @@
|
||||
<aside class="bg-base-200/95 backdrop-blur-xl min-h-full w-72 p-4 flex flex-col">
|
||||
<!-- Mobile: user + live when logged in -->
|
||||
<div v-if="!isLogin && me" class="flex items-center gap-3 pb-4 mb-2 border-b border-base-300/50">
|
||||
<div class="avatar">
|
||||
<div class="rounded-full w-10 h-10 overflow-hidden flex items-center justify-center">
|
||||
<img
|
||||
v-if="me.email && !gravatarErrorDrawer"
|
||||
:src="useGravatarUrl(me.email, 40)"
|
||||
alt=""
|
||||
class="w-full h-full object-cover"
|
||||
@error="gravatarErrorDrawer = true"
|
||||
>
|
||||
<div
|
||||
v-else
|
||||
class="bg-primary text-primary-content rounded-full w-10 h-10 flex items-center justify-center"
|
||||
>
|
||||
<span class="text-sm font-medium">{{ (me.username || '?')[0].toUpperCase() }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<UserAvatar :username="me.username" :email="me.email" :size="40" />
|
||||
<div class="flex-1 min-w-0">
|
||||
<p class="font-medium truncate">{{ me.username }}</p>
|
||||
<p class="text-xs flex items-center gap-1.5" :class="live ? 'text-success' : 'text-base-content/60'">
|
||||
@@ -227,8 +195,6 @@ const dark = ref(false)
|
||||
/** Live when at least one of current user's characters is on the map (set by MapView). */
|
||||
const live = useState<boolean>('mapLive', () => false)
|
||||
const me = useState<MeResponse | null>('me', () => null)
|
||||
const gravatarErrorDesktop = ref(false)
|
||||
const gravatarErrorDrawer = ref(false)
|
||||
const userDropdownRef = ref<HTMLDetailsElement | null>(null)
|
||||
const drawerCheckboxRef = ref<HTMLInputElement | null>(null)
|
||||
|
||||
@@ -281,14 +247,6 @@ watch(
|
||||
{ immediate: true }
|
||||
)
|
||||
|
||||
watch(
|
||||
() => me.value?.email,
|
||||
() => {
|
||||
gravatarErrorDesktop.value = false
|
||||
gravatarErrorDrawer.value = false
|
||||
}
|
||||
)
|
||||
|
||||
function onThemeToggle() {
|
||||
dark.value = !dark.value
|
||||
applyTheme()
|
||||
|
||||
Reference in New Issue
Block a user