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 (
+
+
+
+
+
Login to your account
+ Enter your details to access your account
+
+
+
+
+
+ )
+}
+
+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',
},
},