finished reset password & other changes

This commit is contained in:
2024-04-24 22:37:55 +03:00
parent b1ad7b5c3e
commit 53cadc289a
58 changed files with 1520 additions and 349 deletions

View File

@@ -3,6 +3,8 @@ import { Card, CardContent, CardFooter, CardHeader } from '@/components/ui/card'
import { Header } from '@/components/auth/header'
import { Social } from '@/components/auth/social'
import { BackButton } from '@/components/auth/back-button'
import { Suspense } from 'react'
import { Loading } from '@/components/loading'
type Props = {
children: React.ReactNode
@@ -24,32 +26,31 @@ export const CardWrapper = ({
continueWithLabel,
}: Props) => {
return (
<Card
className={`max-w-[430px] w-[100%] shadow-md md:min-w-[430px] sm:w-full`}>
<CardHeader>
<Header label={headerLabel} title={headerTitle}/>
</CardHeader>
<CardContent>
{children}
</CardContent>
{showSocial && <CardFooter className="flex-wrap">
<div className="relative flex-none w-[100%] mb-4"
style={{ display: 'block' }}>
<div className="absolute inset-0 flex items-center">
<span className="w-full border-t"></span>
</div>
<div className="relative flex justify-center text-xs uppercase">
<Suspense fallback={<Loading/>}>
<Card
className="border-8 border-muted shadow-2xl max-w-[430px] w-full sm:min-w-[430px]">
<CardHeader>
<Header label={headerLabel} title={headerTitle}/>
</CardHeader>
<CardContent>
{children}
</CardContent>
{showSocial && <CardFooter className="flex-wrap">
<div className="relative flex-none w-[100%] mb-4" style={{ background: 'block' }}>
<div className="absolute inset-0 flex items-center">
<span className="w-full border-t"></span>
</div>
<div className="relative flex justify-center text-xs uppercase">
<span
className="bg-background px-2 text-muted-foreground">{continueWithLabel}</span>
</div>
</div>
</div>
{/*<Separator className="my-4"/>*/}
<Social/>
</CardFooter>}
<CardFooter>
<BackButton label={backButtonLabel} href={backButtonHref}/>
</CardFooter>
</Card>
<Social/>
</CardFooter>}
<CardFooter>
<BackButton label={backButtonLabel} href={backButtonHref}/>
</CardFooter>
</Card>
</Suspense>
)
}

View File

@@ -14,9 +14,9 @@ const ErrorCard = () => {
backButtonLabel={t('auth.form.error.back_button_label')}
backButtonHref={AUTH_LOGIN_URL}
>
<div className="w-full flex items-center justify-center">
<TriangleAlert className="w-4 h-4 text-destructive"/>
<p>ssss</p>
<div className="w-full flex items-center justify-center text-destructive">
<TriangleAlert className="w-4 h-4 mr-1.5"/>
<p>Hush little baby... this is prohibited zone!</p>
</div>
</CardWrapper>
)

View File

@@ -21,7 +21,8 @@ import FormError from '@/components/form-error'
import FormSuccess from '@/components/form-success'
import { login } from '@/actions/login'
import { LoginSchema } from '@/schemas'
import { AUTH_REGISTER_URL } from '@/config/routes'
import { AUTH_REGISTER_URL, AUTH_RESET_PASSWORD_URL } from '@/config/routes'
import Link from 'next/link'
export const LoginForm = () => {
const t = useI18n()
@@ -61,12 +62,12 @@ export const LoginForm = () => {
backButtonLabel={t('auth.form.login.back_button_label')}
backButtonHref={AUTH_REGISTER_URL}
showSocial
continueWithLabel={t('form.label.continue_with')}
continueWithLabel={t('auth.form.label.continue_with')}
>
<Form {...form}>
<form
onSubmit={form.handleSubmit(onSubmit)}
className="space-y-6"
className="space-y-0"
>
<div className="space-y-4">
<FormField control={form.control} name="email"
@@ -78,7 +79,7 @@ export const LoginForm = () => {
disabled={isPending}
placeholder={t('form.placeholder.email')}
type="email"
autoComplete="username"
autoComplete="email"
/>
</FormControl>
<FormMessage className="text-xs"/>
@@ -96,9 +97,14 @@ export const LoginForm = () => {
autoComplete="current-password"
/>
</FormControl>
<Button variant="link" size="sm" asChild
className="mt-0 p-0 items-start font-light text-sky-900">
<Link href={AUTH_RESET_PASSWORD_URL}>{t('auth.form.login.reset_password_link_text')}</Link>
</Button>
<FormMessage className="text-xs"/>
</FormItem>)}/>
</div>
<FormSuccess message={success}/>
<FormError message={error || urlError}/>
<Button type="submit" className="w-full" disabled={isPending}>
@@ -107,6 +113,4 @@ export const LoginForm = () => {
</form>
</Form>
</CardWrapper>)
}
//1:30:00
}

View File

@@ -0,0 +1,88 @@
'use client'
import { infer as zInfer } from 'zod'
import { useState, useTransition } from 'react'
import { useForm } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from '@/components/ui/form'
import { Input } from '@/components/ui/input'
import { CardWrapper } from '@/components/auth/card-wrapper'
import { useI18n } from '@/locales/client'
import { Button } from '@/components/ui/button'
import FormError from '@/components/form-error'
import FormSuccess from '@/components/form-success'
import { NewPasswordSchema } from '@/schemas'
import { AUTH_LOGIN_URL } from '@/config/routes'
import { newPassword } from '@/actions/new-password'
export const NewPasswordForm = ({ token }: { token: string }) => {
const t = useI18n()
const [error, setError] = useState<string | undefined>('')
const [success, setSuccess] = useState<string | undefined>('')
const [isPending, startTransition] = useTransition()
const form = useForm<zInfer<typeof NewPasswordSchema>>({
resolver: zodResolver(NewPasswordSchema), defaultValues: {
password: '',
},
})
const onSubmit = (values: zInfer<typeof NewPasswordSchema>) => {
setError('')
setSuccess('')
startTransition(() => {
newPassword(values, token).then((data) => {
// @ts-ignore
setError(t(data?.error))
// @ts-ignore
setSuccess(t(data?.success))
})
})
}
return (<CardWrapper
headerTitle={t('auth.title')}
headerLabel={t('auth.form.new_password.header_label')}
backButtonLabel={t('auth.form.new_password.back_button_label')}
backButtonHref={AUTH_LOGIN_URL}
>
<Form {...form}>
<form
onSubmit={form.handleSubmit(onSubmit)}
className="space-y-4"
>
<div className="space-y-4">
<FormField control={form.control} name="password"
render={({ field }) => (<FormItem>
<FormLabel>{t('form.label.password')}</FormLabel>
<FormControl>
<Input
{...field}
disabled={isPending}
type="password"
placeholder="******"
autoComplete="new-password"
/>
</FormControl>
<FormMessage className="text-xs"/>
</FormItem>)}/>
</div>
<FormSuccess message={success}/>
<FormError message={error}/>
<Button type="submit" className="w-full" disabled={isPending}>
{t('auth.form.new_password.button')}
</Button>
</form>
</Form>
</CardWrapper>)
}

View File

@@ -24,6 +24,7 @@ import { RegisterSchema } from '@/schemas'
import { AUTH_LOGIN_URL } from '@/config/routes'
export const RegisterForm = () => {
// TODO: create repeat password field
// const [currentPassword, setCurrentPassword] = useState('')
// const [password, setPassword] = useState('')
// const [passwordConfirmation, setPasswordConfirmation] = useState('')
@@ -59,7 +60,7 @@ export const RegisterForm = () => {
backButtonLabel={t('auth.form.register.back_button_label')}
backButtonHref={AUTH_LOGIN_URL}
showSocial
continueWithLabel={t('form.label.continue_with')}
continueWithLabel={t('auth.form.label.continue_with')}
>
<Form {...form}>
<form
@@ -91,7 +92,7 @@ export const RegisterForm = () => {
disabled={isPending}
placeholder={t('form.placeholder.email')}
type="email"
autoComplete="username"
autoComplete="email"
/>
</FormControl>
<FormMessage className="text-xs"/>
@@ -115,7 +116,7 @@ export const RegisterForm = () => {
<FormSuccess message={success}/>
<FormError message={error}/>
<Button type="submit" className="w-full" disabled={isPending}>
{t('form.label.register')}
{t('auth.form.register.button')}
</Button>
</form>
</Form>

View File

@@ -0,0 +1,88 @@
'use client'
import { infer as zInfer } from 'zod'
import { useState, useTransition } from 'react'
import { useForm } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from '@/components/ui/form'
import { Input } from '@/components/ui/input'
import { CardWrapper } from '@/components/auth/card-wrapper'
import { useI18n } from '@/locales/client'
import { Button } from '@/components/ui/button'
import FormError from '@/components/form-error'
import FormSuccess from '@/components/form-success'
import { ResetSchema } from '@/schemas'
import { AUTH_LOGIN_URL } from '@/config/routes'
import { reset } from '@/actions/reset'
export const ResetForm = () => {
const t = useI18n()
const [error, setError] = useState<string | undefined>('')
const [success, setSuccess] = useState<string | undefined>('')
const [isPending, startTransition] = useTransition()
const form = useForm<zInfer<typeof ResetSchema>>({
resolver: zodResolver(ResetSchema), defaultValues: {
email: '',
},
})
const onSubmit = (values: zInfer<typeof ResetSchema>) => {
setError('')
setSuccess('')
startTransition(() => {
reset(values).then((data) => {
// @ts-ignore
setError(t(data?.error))
// @ts-ignore
setSuccess(t(data?.success))
})
})
}
return (<CardWrapper
headerTitle={t('auth.title')}
headerLabel={t('auth.form.reset.header_label')}
backButtonLabel={t('auth.form.reset.back_button_label')}
backButtonHref={AUTH_LOGIN_URL}
>
<Form {...form}>
<form
onSubmit={form.handleSubmit(onSubmit)}
className="space-y-4"
>
<div className="space-y-4">
<FormField control={form.control} name="email"
render={({ field }) => (<FormItem>
<FormLabel>{t('form.label.email')}</FormLabel>
<FormControl>
<Input
{...field}
disabled={isPending}
placeholder={t('form.placeholder.email')}
type="email"
autoComplete="email"
/>
</FormControl>
<FormMessage className="text-xs"/>
</FormItem>)}/>
</div>
<FormSuccess message={success}/>
<FormError message={error}/>
<Button type="submit" className="w-full" disabled={isPending}>
{t('auth.form.reset.button')}
</Button>
</form>
</Form>
</CardWrapper>)
}

View File

@@ -11,12 +11,12 @@ export const Social = () => {
return (
<div className="flex items-center w-full gap-x-2">
<Button size="lg" className="w-full" variant="outline"
onClick={() => SignInProvider('google')}>
<Button size="lg" className="w-full" variant="outline" role="button"
onClick={() => SignInProvider('google')} aria-label="Sign in with Google">
<FcGoogle className="w-5 h-5"/>
</Button>
<Button size="lg" className="w-full" variant="outline"
onClick={() => SignInProvider('github')}>
<Button size="lg" className="w-full" variant="outline" role="button"
onClick={() => SignInProvider('github')} aria-label="Sign in with Github">
<FaGithub className="w-5 h-5"/>
</Button>
{/*<Button size="lg" className="w-full" variant="outline" onClick={() => {}}>