feat(ui): integrate Nuxt UI and rebuild layout and login pages

Wrap application in UApp and apply base UI styles
Build responsive default layout with navigation and footer
Implement staff login form with validation and toast notifications
Restructure index page routing
This commit is contained in:
2026-04-12 18:26:36 +08:00
parent 4288c98e21
commit a649c509c2
8 changed files with 360 additions and 197 deletions

View File

@@ -1,13 +1,81 @@
<template>
<div>
</div>
<UContainer class="py-10">
<div class="mx-auto max-w-md">
<UCard class="border border-default bg-default">
<template #header>
<h1 class="text-2xl font-bold text-highlighted">
Staff Login
</h1>
</template>
<UForm :state="form" :validate="validateLogin" class="space-y-5" @submit="onSubmit">
<UFormField name="username" label="Username" required>
<UInput
v-model="form.username"
type="text"
size="xl"
class="w-full"
placeholder="Enter your username"
/>
</UFormField>
<UFormField name="password" label="Password" required>
<UInput
v-model="form.password"
type="password"
size="xl"
class="w-full"
placeholder="Enter your password"
/>
</UFormField>
<UCheckbox v-model="form.remember" label="Remember this device" />
<UButton
type="submit"
label="Sign In"
size="xl"
class="w-full justify-center"
/>
</UForm>
</UCard>
</div>
</UContainer>
</template>
<script lang="ts" setup>
import type { FormError, FormSubmitEvent } from '@nuxt/ui'
const toast = useToast()
const form = reactive({
username: '',
password: '',
remember: true
})
function validateLogin(state: typeof form): FormError[] {
const errors: FormError[] = []
if (!state.username.trim()) {
errors.push({ name: 'username', message: 'Please enter your username.' })
}
if (!state.password.trim()) {
errors.push({ name: 'password', message: 'Please enter your password.' })
}
return errors
}
function onSubmit(event: FormSubmitEvent<typeof form>) {
toast.add({
title: 'Authentication is not wired yet',
description: 'This page is ready for backend integration, but sign-in is still a placeholder.',
color: 'warning',
icon: 'i-lucide-info'
})
event.preventDefault()
}
</script>
<style>
</style>