diff --git a/src/app/v2/login/page.tsx b/src/app/v2/login/page.tsx new file mode 100644 index 00000000..502e85c9 --- /dev/null +++ b/src/app/v2/login/page.tsx @@ -0,0 +1,12 @@ +import LoginBox from '@/components/organism/Login/LoginBox' +import React from 'react' + +const Login = () => { + return ( +
+ +
+ ) +} + +export default Login diff --git a/src/assets/Logo Circle.svg b/src/assets/Logo Circle.svg new file mode 100644 index 00000000..a4beb110 --- /dev/null +++ b/src/assets/Logo Circle.svg @@ -0,0 +1,6 @@ + + + diff --git a/src/components/atoms/Input/InputBox.tsx b/src/components/atoms/Input/InputBox.tsx new file mode 100644 index 00000000..44254497 --- /dev/null +++ b/src/components/atoms/Input/InputBox.tsx @@ -0,0 +1,22 @@ +import React, { forwardRef } from 'react' + +type Props = { + placeholder?: string + className?: string + type: string +} +const InputBox = forwardRef(({ placeholder, className, type, ...rest }, ref) => { + return ( + + ) +}) + +InputBox.displayName = 'InputBox' // for React DevTools + +export default InputBox diff --git a/src/components/atoms/InputWarningText/index.tsx b/src/components/atoms/InputWarningText/index.tsx new file mode 100644 index 00000000..c58789b9 --- /dev/null +++ b/src/components/atoms/InputWarningText/index.tsx @@ -0,0 +1,13 @@ +import React, { ReactNode, HTMLAttributes } from 'react' + +interface InputWarningTextProps extends HTMLAttributes { + children: ReactNode +} + +export default function InputWarningText({ children, className = '', ...rest }: InputWarningTextProps) { + return ( + + {children} + + ) +} diff --git a/src/components/atoms/LoginButtons/index.tsx b/src/components/atoms/LoginButtons/index.tsx new file mode 100644 index 00000000..f6ab9c39 --- /dev/null +++ b/src/components/atoms/LoginButtons/index.tsx @@ -0,0 +1,24 @@ +import React from 'react' + +interface LoginButtonProps extends React.ButtonHTMLAttributes { + className?: string + variant?: 'primary' | 'secondary' | 'danger' | 'shade' +} + +const LoginButtons: React.FC = ({ className = '', variant = 'primary', children, ...props }) => { + const variantClasses = { + primary: 'bg-primary-500 text-white', + secondary: 'bg-gray-500 text-white', + danger: 'bg-red-500 text-white', + shade: 'bg-secondary border border-shade-button-border text-primary-500 drop-shadow-sm', + } + + const variantClass = variantClasses[variant] + return ( + + ) +} + +export default LoginButtons diff --git a/src/components/atoms/SupportingText/index.tsx b/src/components/atoms/SupportingText/index.tsx new file mode 100644 index 00000000..e3a98091 --- /dev/null +++ b/src/components/atoms/SupportingText/index.tsx @@ -0,0 +1,13 @@ +import React, { ReactNode, HTMLAttributes } from 'react' + +interface TitleProps extends HTMLAttributes { + children: ReactNode +} + +export default function SupportingText({ children, className = '', ...rest }: TitleProps) { + return ( +

+ {children} +

+ ) +} diff --git a/src/components/organism/Login/LoginBox.tsx b/src/components/organism/Login/LoginBox.tsx new file mode 100644 index 00000000..0d2828e5 --- /dev/null +++ b/src/components/organism/Login/LoginBox.tsx @@ -0,0 +1,102 @@ +'use client' +import React, { useEffect, useState } from 'react' +import logo from '@/assets/Logo Circle.svg' +import InputBox from '@/components/atoms/Input/InputBox' +import { AiOutlineEye } from 'react-icons/ai' +import { AiOutlineEyeInvisible } from 'react-icons/ai' +import Title from '@/components/atoms/Title' +import SupportingText from '@/components/atoms/SupportingText' +import LoginButtons from '@/components/atoms/LoginButtons' +import { useForm } from 'react-hook-form' +import { LoginForm } from '@/models/auth' +import InputWarningText from '@/components/atoms/InputWarningText' +import { useHandleLogin } from '@/services/auth' +import { useRouter } from 'next/navigation' + +const LoginBox = () => { + const [showPassword, setShowPassword] = useState(false) + const router = useRouter() + const { + register: registerLogin, + handleSubmit: handleSubmitLogin, + formState: { errors: loginErrors }, + } = useForm() + + const { mutate: mutateLogin, isSuccess } = useHandleLogin() + + const onSubmit = async (data: LoginForm) => { + await mutateLogin(data) + } + + useEffect(() => { + if (isSuccess) { + router.push(`/timeline`) + } + }, [isSuccess]) + + return ( +
+
+ lgog +
+ Login to your account + Enter your details to access your account +
+
+
+ + + + {loginErrors.email && ( + {loginErrors.email.message ? loginErrors.email.message : 'Please enter your email!'} + )} +
+
+ + +
+ {showPassword ? ( + setShowPassword(!showPassword)} /> + ) : ( + setShowPassword(!showPassword)} /> + )} +
+ {loginErrors.password && Please enter your password!} + +
+ +
+ +

Remember device for 30 days

+
+ Log in +
+
+ +
+ ) +} + +export default LoginBox diff --git a/tailwind.config.js b/tailwind.config.js index a944d6eb..d23c1e21 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -44,6 +44,7 @@ module.exports = { 'gray-light': '#d3dce6', 'gray-1': '#737373', 'border': '#D4D4D4', + 'shade-button-border': '#E9E8FF', }, },