Ver Fonte

feat: add forgot-password page

satnaing há 2 anos atrás
pai
commit
0875a9871a

+ 10 - 3
src/data/sidelinks.tsx

@@ -3,6 +3,7 @@ import {
   IconChartHistogram,
   IconHexagonNumber1,
   IconHexagonNumber2,
+  IconHexagonNumber3,
   IconLayoutDashboard,
   IconMessages,
   IconRouteAltLeft,
@@ -38,21 +39,27 @@ export const sidelinks: SideLink[] = [
   {
     title: 'Authentication',
     label: '',
-    href: 'authentication',
+    href: '',
     icon: <IconUserShield size={18} />,
     sub: [
       {
         title: 'Sign In (email + password)',
         label: '',
-        href: 'sign-in',
+        href: '/sign-in',
         icon: <IconHexagonNumber1 size={18} />,
       },
       {
         title: 'Sign In (Box)',
         label: '',
-        href: 'sign-in-2',
+        href: '/sign-in-2',
         icon: <IconHexagonNumber2 size={18} />,
       },
+      {
+        title: 'Forgot Password',
+        label: '',
+        href: '/forgot-password',
+        icon: <IconHexagonNumber3 size={18} />,
+      },
     ],
   },
   {

+ 73 - 0
src/pages/auth/components/forgot-form.tsx

@@ -0,0 +1,73 @@
+import { HTMLAttributes, useState } from 'react'
+import { cn } from '@/lib/utils'
+import { zodResolver } from '@hookform/resolvers/zod'
+import { useForm } from 'react-hook-form'
+import { z } from 'zod'
+import { Button } from '@/components/ui/button'
+import {
+  Form,
+  FormControl,
+  FormField,
+  FormItem,
+  FormLabel,
+  FormMessage,
+} from '@/components/ui/form'
+import { Input } from '@/components/ui/input'
+import { IconLoader2 } from '@tabler/icons-react'
+
+interface ForgotFormProps extends HTMLAttributes<HTMLDivElement> {}
+
+const formSchema = z.object({
+  email: z
+    .string()
+    .min(1, { message: 'Please enter your email' })
+    .email({ message: 'Invalid email address' }),
+})
+
+export function ForgotForm({ className, ...props }: ForgotFormProps) {
+  const [isLoading, setIsLoading] = useState(false)
+
+  const form = useForm<z.infer<typeof formSchema>>({
+    resolver: zodResolver(formSchema),
+    defaultValues: { email: '' },
+  })
+
+  function onSubmit(data: z.infer<typeof formSchema>) {
+    setIsLoading(true)
+    console.log(data)
+
+    setTimeout(() => {
+      setIsLoading(false)
+    }, 3000)
+  }
+
+  return (
+    <div className={cn('grid gap-6', className)} {...props}>
+      <Form {...form}>
+        <form onSubmit={form.handleSubmit(onSubmit)}>
+          <div className='grid gap-2'>
+            <FormField
+              control={form.control}
+              name='email'
+              render={({ field }) => (
+                <FormItem className='space-y-1'>
+                  <FormLabel>Email</FormLabel>
+                  <FormControl>
+                    <Input placeholder='name@example.com' {...field} />
+                  </FormControl>
+                  <FormMessage />
+                </FormItem>
+              )}
+            />
+            <Button className='mt-2' disabled={isLoading}>
+              {isLoading && (
+                <IconLoader2 className='mr-2 h-4 w-4 animate-spin' />
+              )}
+              Continue
+            </Button>
+          </div>
+        </form>
+      </Form>
+    </div>
+  )
+}

+ 51 - 0
src/pages/auth/forgot-password.tsx

@@ -0,0 +1,51 @@
+import { Card } from '@/components/ui/card'
+import { ForgotForm } from './components/forgot-form'
+import { Link } from 'react-router-dom'
+
+export default function ForgotPassword() {
+  return (
+    <>
+      <div className='container grid h-svh flex-col items-center justify-center bg-primary-foreground lg:max-w-none lg:px-0'>
+        <div className='mx-auto flex w-full flex-col justify-center space-y-2 sm:w-[480px] lg:p-8'>
+          <div className='mb-4 flex items-center justify-center'>
+            <svg
+              xmlns='http://www.w3.org/2000/svg'
+              viewBox='0 0 24 24'
+              fill='none'
+              stroke='currentColor'
+              strokeWidth='2'
+              strokeLinecap='round'
+              strokeLinejoin='round'
+              className='mr-2 h-6 w-6'
+            >
+              <path d='M15 6v12a3 3 0 1 0 3-3H6a3 3 0 1 0 3 3V6a3 3 0 1 0-3 3h12a3 3 0 1 0-3-3' />
+            </svg>
+            <h1 className='text-xl font-medium'>Admin Dashboard</h1>
+          </div>
+          <Card className='p-6'>
+            <div className='mb-2 flex flex-col space-y-2 text-left'>
+              <h1 className='text-md font-semibold tracking-tight'>
+                Forgot Password
+              </h1>
+              <p className='text-sm text-muted-foreground'>
+                Enter your registered email and <br /> we will send you a link
+                to reset your password.
+              </p>
+            </div>
+            <ForgotForm />
+            <p className='mt-4 px-8 text-center text-sm text-muted-foreground'>
+              Don't have an account?{' '}
+              <Link
+                to='/sign-up'
+                className='underline underline-offset-4 hover:text-primary'
+              >
+                Sign up
+              </Link>
+              .
+            </p>
+          </Card>
+        </div>
+      </div>
+    </>
+  )
+}

+ 2 - 0
src/router.tsx

@@ -5,6 +5,7 @@ import Loader from '@/components/loader'
 const Dashboard = lazy(() => import('@/pages/dashboard'))
 const SignIn = lazy(() => import('@/pages/auth/sign-in'))
 const SignIn2 = lazy(() => import('@/pages/auth/sign-in-2'))
+const ForgotPassword = lazy(() => import('@/pages/auth/forgot-password'))
 
 export default function Router() {
   return (
@@ -13,6 +14,7 @@ export default function Router() {
         <Route path='/' element={<Dashboard />} />
         <Route path='/sign-in' element={<SignIn />} />
         <Route path='/sign-in-2' element={<SignIn2 />} />
+        <Route path='/forgot-password' element={<ForgotPassword />} />
       </Routes>
     </Suspense>
   )