feat: move Google login button above email/password form on login and register pages

This commit is contained in:
Paulo Castellano 2026-04-14 19:50:40 -03:00
parent 8caa3d55c7
commit 8e6e544ffe
2 changed files with 149 additions and 145 deletions

View file

@ -30,59 +30,61 @@ defineProps<{
{{ status }}
</div>
<Form v-bind="store.form()" :reset-on-success="['password']" v-slot="{ errors, processing }"
class="flex flex-col gap-6">
<input v-if="redirect" type="hidden" name="redirect" :value="redirect" />
<div class="grid gap-6">
<div class="grid gap-2">
<Label for="email">{{ $t('auth.login.email') }}</Label>
<Input id="email" type="email" name="email" autofocus :tabindex="1" autocomplete="email"
placeholder="email@example.com" :default-value="email ?? ''" />
<InputError :message="errors.email" />
</div>
<div class="grid gap-2">
<div class="flex items-center justify-between">
<Label for="password">{{ $t('auth.login.password') }}</Label>
<TextLink :href="request()" class="text-sm" :tabindex="5">
{{ $t('auth.login.forgot_password') }}
</TextLink>
</div>
<Input id="password" type="password" name="password" :tabindex="2"
autocomplete="current-password" :placeholder="$t('auth.login.password')" />
<InputError :message="errors.password" />
</div>
<div class="flex items-center justify-between">
<Label for="remember" class="flex items-center space-x-3">
<Checkbox id="remember" name="remember" :tabindex="3" />
<span>{{ $t('auth.login.remember_me') }}</span>
</Label>
</div>
<Button type="submit" class="mt-4 w-full" :tabindex="4" :disabled="processing" data-test="login-button">
<Spinner v-if="processing" />
{{ $t('auth.login.submit') }}
</Button>
</div>
<div class="flex flex-col gap-6">
<template v-if="$page.props.googleAuthEnabled">
<Button variant="outline" class="w-full" as="a" :href="googleRedirect.url()">
<img src="/images/social/google.svg" alt="Google" class="size-4" />
{{ $t('auth.google_login') }}
</Button>
<div
class="relative text-center text-sm after:absolute after:inset-0 after:top-1/2 after:z-0 after:flex after:items-center after:border-t after:border-border"
>
<span class="relative z-10 bg-background px-2 text-muted-foreground">{{ $t('auth.or_continue_with') }}</span>
</div>
<Button variant="outline" class="w-full" as="a" :href="googleRedirect.url()">
<img src="/images/social/google.svg" alt="Google" class="size-4" />
{{ $t('auth.google_login') }}
</Button>
</template>
<div class="text-center text-sm text-muted-foreground">
{{ $t('auth.login.no_account') }}
<TextLink :href="register()" :tabindex="5">{{ $t('auth.login.sign_up') }}</TextLink>
</div>
</Form>
<Form v-bind="store.form()" :reset-on-success="['password']" v-slot="{ errors, processing }"
class="flex flex-col gap-6">
<input v-if="redirect" type="hidden" name="redirect" :value="redirect" />
<div class="grid gap-6">
<div class="grid gap-2">
<Label for="email">{{ $t('auth.login.email') }}</Label>
<Input id="email" type="email" name="email" autofocus :tabindex="1" autocomplete="email"
placeholder="email@example.com" :default-value="email ?? ''" />
<InputError :message="errors.email" />
</div>
<div class="grid gap-2">
<div class="flex items-center justify-between">
<Label for="password">{{ $t('auth.login.password') }}</Label>
<TextLink :href="request()" class="text-sm" :tabindex="5">
{{ $t('auth.login.forgot_password') }}
</TextLink>
</div>
<Input id="password" type="password" name="password" :tabindex="2"
autocomplete="current-password" :placeholder="$t('auth.login.password')" />
<InputError :message="errors.password" />
</div>
<div class="flex items-center justify-between">
<Label for="remember" class="flex items-center space-x-3">
<Checkbox id="remember" name="remember" :tabindex="3" />
<span>{{ $t('auth.login.remember_me') }}</span>
</Label>
</div>
<Button type="submit" class="mt-4 w-full" :tabindex="4" :disabled="processing" data-test="login-button">
<Spinner v-if="processing" />
{{ $t('auth.login.submit') }}
</Button>
</div>
<div class="text-center text-sm text-muted-foreground">
{{ $t('auth.login.no_account') }}
<TextLink :href="register()" :tabindex="5">{{ $t('auth.login.sign_up') }}</TextLink>
</div>
</Form>
</div>
</AuthBase>
</template>

View file

@ -39,112 +39,114 @@ const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
>
<Head :title="$t('auth.register.page_title')" />
<Form
v-bind="store.form()"
:reset-on-success="['password']"
v-slot="{ errors, processing }"
class="flex flex-col gap-6"
>
<input v-if="redirect" type="hidden" name="redirect" :value="redirect" />
<input type="hidden" name="timezone" :value="timezone" />
<div class="grid gap-6">
<div class="grid gap-2">
<Label for="name">{{ $t('auth.register.name') }}</Label>
<Input
id="name"
type="text"
autofocus
:tabindex="1"
autocomplete="name"
name="name"
:placeholder="$t('auth.register.name_placeholder')"
/>
<InputError :message="errors.name" />
</div>
<div class="grid gap-2">
<Label for="email">{{ $t('auth.register.email') }}</Label>
<Input
id="email"
type="email"
:tabindex="2"
autocomplete="email"
name="email"
placeholder="email@example.com"
:default-value="email ?? ''"
/>
<InputError :message="errors.email" />
</div>
<div class="grid gap-2">
<Label for="password">{{ $t('auth.register.password') }}</Label>
<div class="relative">
<Input
id="password"
:type="showPassword ? 'text' : 'password'"
:tabindex="3"
autocomplete="new-password"
name="password"
:placeholder="$t('auth.register.password')"
/>
<div class="absolute inset-y-0 end-0 flex items-center pe-3">
<TooltipProvider>
<Tooltip>
<TooltipTrigger as-child>
<button
type="button"
:tabindex="-1"
class="cursor-pointer text-muted-foreground hover:text-foreground"
@click="showPassword = !showPassword"
>
<IconEyeOff v-if="showPassword" class="size-4" />
<IconEye v-else class="size-4" />
</button>
</TooltipTrigger>
<TooltipContent>
<p>{{ showPassword ? $t('auth.register.hide_password') : $t('auth.register.show_password') }}</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
</div>
</div>
<InputError :message="errors.password" />
</div>
<Button
type="submit"
class="mt-2 w-full"
tabindex="4"
:disabled="processing"
data-test="register-user-button"
>
<Spinner v-if="processing" />
{{ $t('auth.register.submit') }}
</Button>
</div>
<div class="flex flex-col gap-6">
<template v-if="$page.props.googleAuthEnabled">
<Button variant="outline" class="w-full" as="a" :href="googleRedirect.url()">
<img src="/images/social/google.svg" alt="Google" class="size-4" />
{{ $t('auth.google_signup') }}
</Button>
<div
class="relative text-center text-sm after:absolute after:inset-0 after:top-1/2 after:z-0 after:flex after:items-center after:border-t after:border-border"
>
<span class="relative z-10 bg-background px-2 text-muted-foreground">{{ $t('auth.or_continue_with') }}</span>
</div>
<Button variant="outline" class="w-full" as="a" :href="googleRedirect.url()">
<img src="/images/social/google.svg" alt="Google" class="size-4" />
{{ $t('auth.google_signup') }}
</Button>
</template>
<div class="text-center text-sm text-muted-foreground">
{{ $t('auth.register.has_account') }}
<TextLink
:href="login()"
class="underline underline-offset-4"
:tabindex="5"
>{{ $t('auth.register.log_in') }}</TextLink
>
</div>
</Form>
<Form
v-bind="store.form()"
:reset-on-success="['password']"
v-slot="{ errors, processing }"
class="flex flex-col gap-6"
>
<input v-if="redirect" type="hidden" name="redirect" :value="redirect" />
<input type="hidden" name="timezone" :value="timezone" />
<div class="grid gap-6">
<div class="grid gap-2">
<Label for="name">{{ $t('auth.register.name') }}</Label>
<Input
id="name"
type="text"
autofocus
:tabindex="1"
autocomplete="name"
name="name"
:placeholder="$t('auth.register.name_placeholder')"
/>
<InputError :message="errors.name" />
</div>
<div class="grid gap-2">
<Label for="email">{{ $t('auth.register.email') }}</Label>
<Input
id="email"
type="email"
:tabindex="2"
autocomplete="email"
name="email"
placeholder="email@example.com"
:default-value="email ?? ''"
/>
<InputError :message="errors.email" />
</div>
<div class="grid gap-2">
<Label for="password">{{ $t('auth.register.password') }}</Label>
<div class="relative">
<Input
id="password"
:type="showPassword ? 'text' : 'password'"
:tabindex="3"
autocomplete="new-password"
name="password"
:placeholder="$t('auth.register.password')"
/>
<div class="absolute inset-y-0 end-0 flex items-center pe-3">
<TooltipProvider>
<Tooltip>
<TooltipTrigger as-child>
<button
type="button"
:tabindex="-1"
class="cursor-pointer text-muted-foreground hover:text-foreground"
@click="showPassword = !showPassword"
>
<IconEyeOff v-if="showPassword" class="size-4" />
<IconEye v-else class="size-4" />
</button>
</TooltipTrigger>
<TooltipContent>
<p>{{ showPassword ? $t('auth.register.hide_password') : $t('auth.register.show_password') }}</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
</div>
</div>
<InputError :message="errors.password" />
</div>
<Button
type="submit"
class="mt-2 w-full"
tabindex="4"
:disabled="processing"
data-test="register-user-button"
>
<Spinner v-if="processing" />
{{ $t('auth.register.submit') }}
</Button>
</div>
<div class="text-center text-sm text-muted-foreground">
{{ $t('auth.register.has_account') }}
<TextLink
:href="login()"
class="underline underline-offset-4"
:tabindex="5"
>{{ $t('auth.register.log_in') }}</TextLink
>
</div>
</Form>
</div>
</AuthBase>
</template>