Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
<script setup lang="ts">
|
||||
definePageMeta({ layout: false })
|
||||
|
||||
const { t } = useI18n()
|
||||
const auth = useAuthStore()
|
||||
const toast = useToast()
|
||||
|
||||
const mode = ref<'login' | 'register'>('login')
|
||||
const form = reactive({ name: '', email: '', password: '' })
|
||||
const loading = ref(false)
|
||||
|
||||
onMounted(() => {
|
||||
if (auth.isAuthed) navigateTo('/')
|
||||
})
|
||||
|
||||
async function submit() {
|
||||
loading.value = true
|
||||
try {
|
||||
if (mode.value === 'login') {
|
||||
await auth.login(form.email, form.password)
|
||||
} else {
|
||||
await auth.register(form.name, form.email, form.password)
|
||||
}
|
||||
await navigateTo('/')
|
||||
} catch (e: unknown) {
|
||||
const msg = (e as { data?: { message?: string } })?.data?.message || t('common.error')
|
||||
toast.add({ title: msg, color: 'error' })
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="min-h-dvh flex flex-col items-center justify-center px-6 gap-6">
|
||||
<div class="flex flex-col items-center gap-3 text-center">
|
||||
<SfLogo :size="80" />
|
||||
<h1 class="text-3xl font-black tracking-tight">
|
||||
<span class="sf-flame-text">Streak</span><span>Fit</span>
|
||||
</h1>
|
||||
<p class="text-sm text-zinc-500">{{ t('app.tagline') }}</p>
|
||||
</div>
|
||||
|
||||
<UCard class="w-full max-w-sm">
|
||||
<form class="space-y-4" @submit.prevent="submit">
|
||||
<UFormField v-if="mode === 'register'" :label="t('auth.name')">
|
||||
<UInput v-model="form.name" size="lg" class="w-full" icon="i-lucide-user" required />
|
||||
</UFormField>
|
||||
<UFormField :label="t('auth.email')">
|
||||
<UInput v-model="form.email" type="email" size="lg" class="w-full" icon="i-lucide-mail" required />
|
||||
</UFormField>
|
||||
<UFormField :label="t('auth.password')">
|
||||
<UInput v-model="form.password" type="password" size="lg" class="w-full" icon="i-lucide-lock" required />
|
||||
</UFormField>
|
||||
|
||||
<UButton type="submit" block size="lg" color="primary" class="font-bold" :loading="loading">
|
||||
{{ mode === 'login' ? t('auth.signIn') : t('auth.signUp') }}
|
||||
</UButton>
|
||||
</form>
|
||||
|
||||
<USeparator :label="t('auth.or')" class="my-4" />
|
||||
|
||||
<UButton
|
||||
block
|
||||
size="lg"
|
||||
color="neutral"
|
||||
variant="subtle"
|
||||
icon="i-lucide-key-round"
|
||||
:label="t('auth.loginWithPocketId')"
|
||||
@click="auth.loginWithPocketId()"
|
||||
/>
|
||||
|
||||
<template #footer>
|
||||
<button
|
||||
class="w-full text-center text-sm text-flame-600 dark:text-flame-400 hover:underline"
|
||||
@click="mode = mode === 'login' ? 'register' : 'login'"
|
||||
>
|
||||
{{ mode === 'login' ? t('auth.noAccount') + ' ' + t('auth.signUp') : t('auth.haveAccount') + ' ' + t('auth.signIn') }}
|
||||
</button>
|
||||
</template>
|
||||
</UCard>
|
||||
</div>
|
||||
</template>
|
||||
Reference in New Issue
Block a user