From 240e684b5377526946be2bc548d6af8a91e6109a Mon Sep 17 00:00:00 2001 From: Naufal Azmi <109430358+BoboiAzumi@users.noreply.github.com> Date: Wed, 9 Apr 2025 12:59:33 +0700 Subject: [PATCH] Dimentorin auth login responsive and implementation (#23) * feat: responsive * fix: success register * feat: auth login responsive && auth login implementation --- apps/dimentorin/src/app/_hooks/use-login.ts | 28 ++++++++ apps/dimentorin/src/app/auth/login/page.tsx | 71 +++++++++++-------- .../dimentorin/src/app/auth/register/page.tsx | 1 - .../src/app/auth/register/success/page.tsx | 3 +- apps/dimentorin/src/main.tsx | 2 + libs/ui/src/atoms/input/input.tsx | 5 +- .../src/organisms/auth-banner/auth-banner.tsx | 2 +- 7 files changed, 77 insertions(+), 35 deletions(-) create mode 100644 apps/dimentorin/src/app/_hooks/use-login.ts diff --git a/apps/dimentorin/src/app/_hooks/use-login.ts b/apps/dimentorin/src/app/_hooks/use-login.ts new file mode 100644 index 0000000..3c031d3 --- /dev/null +++ b/apps/dimentorin/src/app/_hooks/use-login.ts @@ -0,0 +1,28 @@ +import { useForm } from 'react-hook-form'; +import { + authLoginSchema, + TLoginRequest, + usePostLogin, +} from '@imphnen-frontend-service/service'; +import { zodResolver } from '@hookform/resolvers/zod'; +import { toast } from 'sonner'; + +export const useLogin = () => { + const postLogin = usePostLogin(); + const form = useForm({ + resolver: zodResolver(authLoginSchema), + mode: 'all', + }); + + const onSubmit = form.handleSubmit((data) => { + postLogin.mutate(data, { + onSuccess: () => toast.success("Login sukses"), + onError: (error) => toast.error(error.message), + }); + }); + + return { + form, + onSubmit, + }; +}; diff --git a/apps/dimentorin/src/app/auth/login/page.tsx b/apps/dimentorin/src/app/auth/login/page.tsx index 95440b3..3859aba 100644 --- a/apps/dimentorin/src/app/auth/login/page.tsx +++ b/apps/dimentorin/src/app/auth/login/page.tsx @@ -1,46 +1,50 @@ import { FC, ReactElement } from 'react'; -import { LoginBanner } from '@imphnen-frontend-service/ui/organisms'; +import { ControlledInputField, LoginBanner } from '@imphnen-frontend-service/ui/organisms'; import { Button } from '@imphnen-frontend-service/ui/atoms'; -import { useSearchParams } from 'react-router-dom'; -import { InputField } from '@imphnen-frontend-service/ui/molecules'; +import { useLogin } from '../../_hooks/use-login'; +import { ArrowLeftOutlined } from '@ant-design/icons'; export const Components: FC = (): ReactElement => { - const [searchParams] = useSearchParams(); - const error = searchParams.get('error'); // Ambil nilai ?error= + const { form, onSubmit } = useLogin(); return (
-
+
-
-
+
+

Hallo Minna-san

-
+
Welcome to Dimentorin by IMPHNEN
- - - - +
+ + + + + +
diff --git a/apps/dimentorin/src/app/auth/register/page.tsx b/apps/dimentorin/src/app/auth/register/page.tsx index a3933ce..79bcadf 100644 --- a/apps/dimentorin/src/app/auth/register/page.tsx +++ b/apps/dimentorin/src/app/auth/register/page.tsx @@ -37,7 +37,6 @@ export const Components: FC = (): ReactElement => {

OTP Code

{ diff --git a/apps/dimentorin/src/main.tsx b/apps/dimentorin/src/main.tsx index 7201952..4f9c907 100644 --- a/apps/dimentorin/src/main.tsx +++ b/apps/dimentorin/src/main.tsx @@ -8,6 +8,7 @@ import { convertPagesToRoute, QueryProvider, } from '@imphnen-frontend-service/utils'; +import { Toaster } from 'sonner'; import './index.css'; const files = import.meta.glob('./app/**/*(page|layout).tsx'); @@ -34,6 +35,7 @@ if (!rootElement) throw new Error('Failed to find the root element'); createRoot(rootElement).render( + diff --git a/libs/ui/src/atoms/input/input.tsx b/libs/ui/src/atoms/input/input.tsx index d8a6bf3..664169a 100644 --- a/libs/ui/src/atoms/input/input.tsx +++ b/libs/ui/src/atoms/input/input.tsx @@ -11,6 +11,7 @@ import { Button } from '../button'; type TInputType = 'text' | 'email' | 'number' | 'password' | 'file'; type TInputSize = 'sm' | 'md' | 'lg'; +type Width = 'standard' | 'custom' type TInputProps = Omit< DetailedHTMLProps, HTMLInputElement>, @@ -18,6 +19,7 @@ type TInputProps = Omit< > & { type?: TInputType; size?: TInputSize; + widthform?: Width; disabled?: boolean; }; @@ -34,6 +36,7 @@ export const Input: FC = ({ type = 'text', size = 'md', placeholder = 'Placeholder', + widthform='standard', disabled, className, ...rest @@ -46,7 +49,7 @@ export const Input: FC = ({ }; const mergedClassName = cn( - 'px-[12px] py-[8px] text-neutral-800 bg-white placeholder:text-neutral-300 border border-neutral-200 hover:border-blue-300 focus:outline-1 focus:outline-blue-500 rounded-md font-bai-jamjuree min-w-70', + `px-[12px] py-[8px] text-neutral-800 bg-white placeholder:text-neutral-300 border border-neutral-200 hover:border-blue-300 focus:outline-1 focus:outline-blue-500 rounded-md font-bai-jamjuree ${widthform === "standard" ? "min-w-70" : ""}`, sizeClasses[size].textSize, disabled && disabledClass, className diff --git a/libs/ui/src/organisms/auth-banner/auth-banner.tsx b/libs/ui/src/organisms/auth-banner/auth-banner.tsx index fbd5927..8b230b4 100644 --- a/libs/ui/src/organisms/auth-banner/auth-banner.tsx +++ b/libs/ui/src/organisms/auth-banner/auth-banner.tsx @@ -5,7 +5,7 @@ import { FC, ReactElement } from "react"; function AuthBanner({text, href}: {text: string, href: string}){ return ( -
+
Banner