Auth Password Reset
block authFour-stage password reset surface in a single card: request (email form) -> sent (check-your-inbox confirmation with "Open reset form" demo button) -> reset (new password + confirm with match validation) -> done (success confirmation linking back to sign-in). Emits `request` (email) when the link is asked for and `reset` (password) when the new password is set; consumer wires the actual mail/db calls.
Also available for React ->Installation
$ pnpm dlx shadcn-vue@latest add https://uipkge.dev/r/vue/auth-password-reset.json$ npx shadcn-vue@latest add https://uipkge.dev/r/vue/auth-password-reset.json$ yarn dlx shadcn-vue@latest add https://uipkge.dev/r/vue/auth-password-reset.json$ bunx shadcn-vue@latest add https://uipkge.dev/r/vue/auth-password-reset.json
Or with the named registry:
npx shadcn-vue@latest add @uipkge/auth-password-reset
Examples
npm dependencies
Files (1)
-
app/components/blocks/AuthPasswordReset.vue 4.9 kB
<script setup lang="ts"> import { computed, ref } from 'vue' import { ArrowLeft, MailCheck } from 'lucide-vue-next' import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/components/ui/card' import { Input } from '@/components/ui/input' import { Label } from '@/components/ui/label' import { Button } from '@/components/ui/button' withDefaults( defineProps<{ signInHref?: string }>(), { signInHref: '/login' }, ) const emit = defineEmits<{ (e: 'request', email: string): void (e: 'reset', password: string): void }>() type Stage = 'request' | 'sent' | 'reset' | 'done' const stage = ref<Stage>('request') const email = ref('') const password = ref('') const confirm = ref('') const passwordsMatch = computed(() => !confirm.value || password.value === confirm.value) function submitRequest() { if (!email.value) return emit('request', email.value) stage.value = 'sent' } function submitReset() { if (!password.value || !passwordsMatch.value) return emit('reset', password.value) stage.value = 'done' } </script> <template> <div class="bg-background flex min-h-svh items-center justify-center p-6"> <Card class="w-full max-w-sm"> <template v-if="stage === 'request'"> <CardHeader class="text-center"> <CardTitle class="text-2xl">Forgot password?</CardTitle> <CardDescription>Enter your email and we'll send you a reset link.</CardDescription> </CardHeader> <CardContent> <form class="space-y-4" @submit.prevent="submitRequest"> <div class="grid gap-2"> <Label for="reset-email">Email</Label> <Input id="reset-email" v-model="email" type="email" placeholder="[email protected]" required /> </div> <Button type="submit" class="w-full">Send reset link</Button> </form> </CardContent> <CardFooter class="justify-center"> <a :href="signInHref" class="text-muted-foreground hover:text-foreground inline-flex items-center gap-1 text-sm" > <ArrowLeft class="size-3" />Back to sign in </a> </CardFooter> </template> <template v-else-if="stage === 'sent'"> <CardContent class="space-y-4 pt-6 text-center"> <div class="bg-primary/10 text-primary mx-auto flex size-12 items-center justify-center rounded-full"> <MailCheck class="size-6" /> </div> <div class="space-y-1"> <h3 class="text-lg font-semibold">Check your inbox</h3> <p class="text-muted-foreground text-sm"> We've sent a reset link to <span class="text-foreground font-medium">{{ email }}</span >. </p> </div> <Button variant="outline" class="w-full" @click="stage = 'reset'">Open reset form (demo)</Button> <button class="text-muted-foreground hover:text-foreground text-xs underline-offset-4 hover:underline" @click="stage = 'request'" > Wrong email? </button> </CardContent> </template> <template v-else-if="stage === 'reset'"> <CardHeader class="text-center"> <CardTitle class="text-2xl">Set new password</CardTitle> <CardDescription>Pick a strong password you haven't used before.</CardDescription> </CardHeader> <CardContent> <form class="space-y-4" @submit.prevent="submitReset"> <div class="grid gap-2"> <Label for="reset-pw">New password</Label> <Input id="reset-pw" v-model="password" type="password" autocomplete="new-password" required /> </div> <div class="grid gap-2"> <Label for="reset-confirm">Confirm password</Label> <Input id="reset-confirm" v-model="confirm" type="password" autocomplete="new-password" :aria-invalid="!passwordsMatch" required /> <p v-if="!passwordsMatch" class="text-destructive text-xs">Passwords don't match.</p> </div> <Button type="submit" class="w-full">Reset password</Button> </form> </CardContent> </template> <template v-else> <CardContent class="space-y-4 pt-6 text-center"> <div class="bg-success/10 text-success mx-auto flex size-12 items-center justify-center rounded-full"> <MailCheck class="size-6" /> </div> <div class="space-y-1"> <h3 class="text-lg font-semibold">All set</h3> <p class="text-muted-foreground text-sm"> Your password has been updated. You can now sign in with the new password. </p> </div> <a :href="signInHref"><Button class="w-full">Continue to sign in</Button></a> </CardContent> </template> </Card> </div> </template>
Raw manifest: https://uipkge.dev/r/vue/auth-password-reset.json