Enhance frontend styling and accessibility features

- Updated .dockerignore to exclude backup directory with root-only permissions from build context.
- Added new CSS variables for card radius and transition duration in app.css.
- Implemented consistent focus ring styles for interactive elements to improve accessibility.
- Refactored card components across various pages to utilize a unified card style, enhancing visual consistency.
- Improved button styles with touch manipulation support for better user interaction on mobile devices.
This commit is contained in:
2026-03-01 22:19:51 +03:00
parent 225aaa36e7
commit d27eb2651e
9 changed files with 71 additions and 31 deletions

View File

@@ -3,7 +3,7 @@
<h1 class="text-2xl font-bold mb-6">Admin</h1>
<template v-if="loading">
<div class="card bg-base-200 shadow-xl mb-6">
<div class="card card-app card-bg-base-200 mb-6">
<div class="card-body">
<Skeleton class="h-6 w-24 mb-4" />
<div class="flex flex-col gap-2">
@@ -12,7 +12,7 @@
</div>
</div>
</div>
<div class="card bg-base-200 shadow-xl mb-6">
<div class="card card-app card-bg-base-200 mb-6">
<div class="card-body">
<Skeleton class="h-6 w-20 mb-4" />
<div class="overflow-x-auto">
@@ -20,7 +20,7 @@
</div>
</div>
</div>
<div class="card bg-base-200 shadow-xl mb-6">
<div class="card card-app card-bg-base-200 mb-6">
<div class="card-body">
<Skeleton class="h-6 w-16 mb-4" />
<div class="flex flex-col gap-3">
@@ -45,7 +45,7 @@
</div>
</div>
<div class="card bg-base-200 shadow-xl mb-6 transition-all duration-200">
<div class="card card-app card-bg-base-200 mb-6 transition-all duration-200">
<div class="card-body">
<h2 class="card-title gap-2">
<icons-icon-users />
@@ -88,7 +88,7 @@
</div>
</div>
<div class="card bg-base-200 shadow-xl mb-6 transition-all duration-200">
<div class="card card-app card-bg-base-200 mb-6 transition-all duration-200">
<div class="card-body">
<h2 class="card-title gap-2">
<icons-icon-map-pin />
@@ -145,7 +145,7 @@
</div>
</div>
<div class="card bg-base-200 shadow-xl mb-6 transition-all duration-200">
<div class="card card-app card-bg-base-200 mb-6 transition-all duration-200">
<div class="card-body">
<h2 class="card-title gap-2">
<icons-icon-settings />
@@ -191,7 +191,7 @@
</div>
</div>
<div class="card bg-base-200 shadow-xl mb-6 transition-all duration-200">
<div class="card card-app card-bg-base-200 mb-6 transition-all duration-200">
<div class="card-body">
<h2 class="card-title gap-2">
<icons-icon-alert-triangle />
@@ -226,8 +226,8 @@
</button>
</form>
</div>
<div class="border-t border-red-500/30 pt-4 mt-1 bg-error/5 rounded-lg p-3 -mx-1">
<p class="text-sm font-medium text-error/90 mb-2">Danger zone</p>
<div class="border-t border-error/30 pt-4 mt-1 bg-error/5 rounded-lg p-3 -mx-1">
<p class="text-sm font-medium text-error mb-2">Danger zone</p>
<button class="btn btn-sm btn-error min-h-11 touch-manipulation" :disabled="wiping" @click="confirmWipe">
<span v-if="wiping" class="loading loading-spinner loading-sm" />
<span v-else>Wipe all data</span>

View File

@@ -1,11 +1,11 @@
<template>
<div class="container mx-auto p-4 max-w-lg">
<div class="container mx-auto p-4 max-w-2xl min-w-0">
<h1 class="text-2xl font-bold mb-6">Edit map {{ id }}</h1>
<form v-if="map" @submit.prevent="submit" class="flex flex-col gap-4">
<fieldset class="fieldset">
<label class="label" for="name">Name</label>
<input id="name" v-model="form.name" type="text" class="input" required />
<input id="name" v-model="form.name" type="text" class="input min-h-11 touch-manipulation" required />
</fieldset>
<fieldset class="fieldset">
<label class="label cursor-pointer gap-2">
@@ -21,16 +21,16 @@
</fieldset>
<p v-if="error" class="text-error text-sm">{{ error }}</p>
<div class="flex gap-2">
<button type="submit" class="btn btn-primary" :disabled="loading">
<button type="submit" class="btn btn-primary min-h-11 touch-manipulation" :disabled="loading">
<span v-if="loading" class="loading loading-spinner loading-sm" />
<span v-else>Save</span>
</button>
<NuxtLink to="/admin" class="btn btn-ghost">Back</NuxtLink>
<NuxtLink to="/admin" class="btn btn-ghost min-h-11 touch-manipulation">Back</NuxtLink>
</div>
</form>
<template v-else-if="mapsLoaded">
<p class="text-base-content/70">Map not found.</p>
<NuxtLink to="/admin" class="btn btn-ghost mt-2">Back to Admin</NuxtLink>
<NuxtLink to="/admin" class="btn btn-ghost mt-2 min-h-11 touch-manipulation">Back to Admin</NuxtLink>
</template>
<p v-else class="text-base-content/70">Loading</p>
</div>

View File

@@ -1,5 +1,5 @@
<template>
<div class="container mx-auto p-4 max-w-lg">
<div class="container mx-auto p-4 max-w-2xl min-w-0">
<h1 class="text-2xl font-bold mb-6">{{ isNew ? 'New user' : `Edit ${username}` }}</h1>
<form @submit.prevent="submit" class="flex flex-col gap-4">
@@ -9,7 +9,7 @@
id="user"
v-model="form.user"
type="text"
class="input"
class="input min-h-11 touch-manipulation"
required
:readonly="!isNew"
/>
@@ -30,15 +30,15 @@
</fieldset>
<p v-if="error" class="text-error text-sm">{{ error }}</p>
<div class="flex gap-2">
<button type="submit" class="btn btn-primary" :disabled="loading">
<button type="submit" class="btn btn-primary min-h-11 touch-manipulation" :disabled="loading">
<span v-if="loading" class="loading loading-spinner loading-sm" />
<span v-else>Save</span>
</button>
<NuxtLink to="/admin" class="btn btn-ghost">Back</NuxtLink>
<NuxtLink to="/admin" class="btn btn-ghost min-h-11 touch-manipulation">Back</NuxtLink>
<button
v-if="!isNew"
type="button"
class="btn btn-error btn-outline ml-auto"
class="btn btn-error btn-outline ml-auto min-h-11 touch-manipulation"
:disabled="loading"
@click="confirmDelete"
>

View File

@@ -1,6 +1,6 @@
<template>
<div class="min-h-screen flex flex-col items-center justify-center bg-gradient-to-br from-base-200 via-base-300 to-primary/10 p-4 overflow-hidden">
<div class="card w-full max-w-sm bg-base-100 shadow-2xl ring-1 ring-base-300 login-card">
<div class="card card-app w-full max-w-sm login-card">
<div class="card-body">
<h1 class="card-title justify-center text-2xl">HnH Map</h1>
<p class="text-center text-base-content/70 text-sm">Log in to continue</p>
@@ -23,7 +23,7 @@
id="user"
v-model="user"
type="text"
class="input"
class="input min-h-11 touch-manipulation"
required
autocomplete="username"
/>
@@ -35,7 +35,7 @@
autocomplete="current-password"
/>
<p v-if="error" class="text-error text-sm">{{ error }}</p>
<button type="submit" class="btn btn-primary transition-all duration-200 hover:scale-[1.02]" :disabled="loading">
<button type="submit" class="btn btn-primary min-h-11 touch-manipulation" :disabled="loading">
<span v-if="loading" class="loading loading-spinner loading-sm" />
<span v-else>Log in</span>
</button>

View File

@@ -3,7 +3,7 @@
<h1 class="text-2xl font-bold mb-6">Profile</h1>
<!-- User info card -->
<div class="card bg-base-200 shadow-xl mb-6 transition-all duration-200">
<div class="card card-app card-bg-base-200 mb-6 transition-all duration-200">
<div class="card-body">
<template v-if="initialLoad">
<div class="flex items-center gap-4">
@@ -80,7 +80,7 @@
</div>
<!-- Upload tokens -->
<div class="card bg-base-200 shadow-xl mb-6 transition-all duration-200">
<div class="card card-app card-bg-base-200 mb-6 transition-all duration-200">
<div class="card-body">
<template v-if="initialLoad">
<Skeleton class="h-6 w-32 mb-2" />
@@ -116,14 +116,14 @@
</ul>
<p v-else class="text-sm mt-2">No tokens yet.</p>
<p v-if="tokenError" class="text-error text-sm mt-2">{{ tokenError }}</p>
<button class="btn btn-primary btn-sm mt-2 min-h-11 touch-manipulation transition-all duration-200 hover:scale-[1.02]" :disabled="loadingTokens" @click="generateToken">
<button class="btn btn-primary btn-sm mt-2 min-h-11 touch-manipulation" :disabled="loadingTokens" @click="generateToken">
{{ loadingTokens ? '' : 'Generate token' }}
</button>
</template>
</div>
</div>
<div class="card bg-base-200 shadow-xl mb-6 transition-all duration-200">
<div class="card card-app card-bg-base-200 mb-6 transition-all duration-200">
<div class="card-body">
<h2 class="card-title gap-2">
<icons-icon-settings />
@@ -136,7 +136,7 @@
autocomplete="new-password"
/>
<p v-if="passMsg" class="text-sm" :class="passOk ? 'text-success' : 'text-error'">{{ passMsg }}</p>
<button type="submit" class="btn btn-sm min-h-11 touch-manipulation transition-all duration-200 hover:scale-[1.02]" :disabled="loadingPass">Save password</button>
<button type="submit" class="btn btn-sm min-h-11 touch-manipulation" :disabled="loadingPass">Save password</button>
</form>
</div>
</div>

View File

@@ -1,6 +1,6 @@
<template>
<div class="min-h-screen flex flex-col items-center justify-center bg-base-200 p-4">
<div class="card w-full max-w-sm bg-base-100 shadow-xl">
<div class="min-h-screen flex flex-col items-center justify-center bg-gradient-to-br from-base-200 via-base-300 to-primary/10 p-4 overflow-hidden">
<div class="card card-app w-full max-w-sm login-card">
<div class="card-body">
<h1 class="card-title justify-center">First-time setup</h1>
<p class="text-sm text-base-content/80">
@@ -15,7 +15,7 @@
autocomplete="current-password"
/>
<p v-if="error" class="text-error text-sm">{{ error }}</p>
<button type="submit" class="btn btn-primary" :disabled="loading">
<button type="submit" class="btn btn-primary min-h-11 touch-manipulation" :disabled="loading">
<span v-if="loading" class="loading loading-spinner loading-sm" />
<span v-else>Create and log in</span>
</button>