瀏覽代碼

feat: add box sign in page

satnaing 2 年之前
父節點
當前提交
42b6ef9b7c
共有 4 個文件被更改,包括 135 次插入5 次删除
  1. 7 0
      src/data/sidelinks.tsx
  2. 71 5
      src/pages/auth/components/user-auth-form.tsx
  3. 55 0
      src/pages/auth/sign-in-2.tsx
  4. 2 0
      src/router.tsx

+ 7 - 0
src/data/sidelinks.tsx

@@ -2,6 +2,7 @@ import {
   IconBoxSeam,
   IconChartHistogram,
   IconHexagonNumber1,
+  IconHexagonNumber2,
   IconLayoutDashboard,
   IconMessages,
   IconRouteAltLeft,
@@ -46,6 +47,12 @@ export const sidelinks: SideLink[] = [
         href: 'sign-in',
         icon: <IconHexagonNumber1 size={18} />,
       },
+      {
+        title: 'Sign In (Box)',
+        label: '',
+        href: 'sign-in-2',
+        icon: <IconHexagonNumber2 size={18} />,
+      },
     ],
   },
   {

+ 71 - 5
src/pages/auth/components/user-auth-form.tsx

@@ -1,4 +1,4 @@
-import { HTMLAttributes } from 'react'
+import { HTMLAttributes, useState } from 'react'
 import { cn } from '@/lib/utils'
 import { zodResolver } from '@hookform/resolvers/zod'
 import { useForm } from 'react-hook-form'
@@ -13,6 +13,12 @@ import {
   FormMessage,
 } from '@/components/ui/form'
 import { Input } from '@/components/ui/input'
+import { Link } from 'react-router-dom'
+import {
+  IconBrandFacebook,
+  IconBrandGithub,
+  IconLoader2,
+} from '@tabler/icons-react'
 
 interface UserAuthFormProps extends HTMLAttributes<HTMLDivElement> {}
 
@@ -32,6 +38,8 @@ const formSchema = z.object({
 })
 
 export function UserAuthForm({ className, ...props }: UserAuthFormProps) {
+  const [isLoading, setIsLoading] = useState(false)
+
   const form = useForm<z.infer<typeof formSchema>>({
     resolver: zodResolver(formSchema),
     defaultValues: {
@@ -40,8 +48,13 @@ export function UserAuthForm({ className, ...props }: UserAuthFormProps) {
     },
   })
 
-  function onSubmit(variables: z.infer<typeof formSchema>) {
-    console.log(variables)
+  function onSubmit(data: z.infer<typeof formSchema>) {
+    setIsLoading(true)
+    console.log(data)
+
+    setTimeout(() => {
+      setIsLoading(false)
+    }, 3000)
   }
 
   return (
@@ -67,7 +80,15 @@ export function UserAuthForm({ className, ...props }: UserAuthFormProps) {
               name='password'
               render={({ field }) => (
                 <FormItem className='space-y-1'>
-                  <FormLabel>Password</FormLabel>
+                  <div className='flex items-center justify-between'>
+                    <FormLabel>Password</FormLabel>
+                    <Link
+                      to='/forgot-password'
+                      className='text-sm font-medium text-muted-foreground hover:opacity-75'
+                    >
+                      Forgot password?
+                    </Link>
+                  </div>
                   <FormControl>
                     <Input placeholder='********' {...field} type='password' />
                   </FormControl>
@@ -75,7 +96,52 @@ export function UserAuthForm({ className, ...props }: UserAuthFormProps) {
                 </FormItem>
               )}
             />
-            <Button className='mt-2'>Login</Button>
+            <Button className='mt-2' disabled={isLoading}>
+              {isLoading && (
+                <IconLoader2 className='mr-2 h-4 w-4 animate-spin' />
+              )}
+              Login
+            </Button>
+
+            <div className='relative my-2'>
+              <div className='absolute inset-0 flex items-center'>
+                <span className='w-full border-t' />
+              </div>
+              <div className='relative flex justify-center text-xs uppercase'>
+                <span className='bg-background px-2 text-muted-foreground'>
+                  Or continue with
+                </span>
+              </div>
+            </div>
+
+            <div className='flex items-center gap-2'>
+              <Button
+                variant='outline'
+                className='w-full'
+                type='button'
+                disabled={isLoading}
+              >
+                {isLoading ? (
+                  <IconLoader2 className='mr-2 h-4 w-4 animate-spin' />
+                ) : (
+                  <IconBrandGithub className='mr-2 h-4 w-4' />
+                )}{' '}
+                GitHub
+              </Button>
+              <Button
+                variant='outline'
+                className='w-full'
+                type='button'
+                disabled={isLoading}
+              >
+                {isLoading ? (
+                  <IconLoader2 className='mr-2 h-4 w-4 animate-spin' />
+                ) : (
+                  <IconBrandFacebook className='mr-2 h-4 w-4' />
+                )}{' '}
+                Facebook
+              </Button>
+            </div>
           </div>
         </form>
       </Form>

+ 55 - 0
src/pages/auth/sign-in-2.tsx

@@ -0,0 +1,55 @@
+import { Card } from '@/components/ui/card'
+import { UserAuthForm } from './components/user-auth-form'
+
+export default function SignIn2() {
+  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='flex flex-col space-y-2 text-left'>
+              <h1 className='text-2xl font-semibold tracking-tight'>Login</h1>
+              <p className='text-sm text-muted-foreground'>
+                Enter your email and password below <br />
+                to log into your account
+              </p>
+            </div>
+            <UserAuthForm />
+            <p className='mt-4 px-8 text-center text-sm text-muted-foreground'>
+              By clicking login, you agree to our{' '}
+              <a
+                href='/terms'
+                className='underline underline-offset-4 hover:text-primary'
+              >
+                Terms of Service
+              </a>{' '}
+              and{' '}
+              <a
+                href='/privacy'
+                className='underline underline-offset-4 hover:text-primary'
+              >
+                Privacy Policy
+              </a>
+              .
+            </p>
+          </Card>
+        </div>
+      </div>
+    </>
+  )
+}

+ 2 - 0
src/router.tsx

@@ -4,6 +4,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'))
 
 export default function Router() {
   return (
@@ -11,6 +12,7 @@ export default function Router() {
       <Routes>
         <Route path='/' element={<Dashboard />} />
         <Route path='/sign-in' element={<SignIn />} />
+        <Route path='/sign-in-2' element={<SignIn2 />} />
       </Routes>
     </Suspense>
   )