feat: login example

This commit is contained in:
Maulana Sodiqin
2025-04-03 12:21:10 +07:00
parent c05061becf
commit a6fea630a4
38 changed files with 942 additions and 755 deletions
@@ -1,11 +1,11 @@
import { Button } from '@imphnen-frontend-service/ui/atoms';
import {
InputForm,
InputField,
Modal,
Stepper,
} from '@imphnen-frontend-service/ui/molecules';
import { useQueryState } from '../../../hooks/use-query-state';
import { useQueryState } from '@imphnen-frontend-service/utils';
import { Fragment } from 'react/jsx-runtime';
interface IModalFormForgotPasswordProps {
isOpen: boolean;
onClose: () => void;
@@ -62,7 +62,7 @@ interface IStepOneProps {
const StepOne = ({ nextStep, onClose }: IStepOneProps) => (
<>
<InputForm
<InputField
label="Email"
placeholder="Masukkan Email yang Terdaftar"
type="email"
@@ -86,9 +86,8 @@ interface IStepTwoProps {
}
const StepTwo = ({ nextStep, prevStep }: IStepTwoProps) => (
<>
{/* TODO: Change component using OTP Input */}
<InputForm
<Fragment>
<InputField
label="Kode OTP"
placeholder="Masukkan Kode OTP"
type="text"
@@ -108,7 +107,7 @@ const StepTwo = ({ nextStep, prevStep }: IStepTwoProps) => (
Reset Password
</Button>
</div>
</>
</Fragment>
);
interface IStepThreeProps {
@@ -118,14 +117,14 @@ interface IStepThreeProps {
const StepThree = ({ onClose, resetStep }: IStepThreeProps) => (
<>
<InputForm
<InputField
label="Password Baru"
placeholder="Masukkan Password Baru"
type="password"
size="lg"
className="w-full"
/>
<InputForm
<InputField
label="Ulang Password"
placeholder="Masukkan Ulang Password"
type="password"
@@ -1,6 +1,8 @@
import { Button } from '@imphnen-frontend-service/ui/atoms';
import { InputForm, Modal } from '@imphnen-frontend-service/ui/molecules';
import { Modal } from '@imphnen-frontend-service/ui/molecules';
import { ControlledInputField } from '@imphnen-frontend-service/ui/organisms';
import { Link } from 'react-router-dom';
import { useLogin } from '../../_hooks/use-login';
interface IModalFormLogin {
isOpen: boolean;
@@ -13,6 +15,8 @@ const ModalFormLogin = ({
onClose,
onForgotPassword,
}: IModalFormLogin) => {
const { form, onSubmit } = useLogin();
return (
<Modal
className="py-[45px] min-w-[400px] lg:min-w-[455px] px-7"
@@ -25,38 +29,44 @@ const ModalFormLogin = ({
Login
</h1>
</Modal.Header>
<Modal.Content className="space-y-4">
<InputForm
label="Email"
placeholder="Masukkan Email"
type="email"
size="lg"
className="w-full"
/>
<InputForm
label="Password"
placeholder="Masukkan Password"
type="password"
size="lg"
className="w-full"
/>
<h1 className="text-end text-primary-500 text-xl font-medium">
<Button variant="text" onClick={onForgotPassword}>
Lupa Password?
<Modal.Content>
<form className="space-y-4" onSubmit={onSubmit}>
<ControlledInputField
control={form.control}
label="Email"
placeholder="Masukkan Email"
type="email"
name="email"
size="lg"
className="w-full"
/>
<ControlledInputField
control={form.control}
label="Password"
placeholder="Masukkan Password"
type="password"
name="password"
size="lg"
className="w-full"
/>
<h1 className="text-end text-primary-500 text-xl font-medium">
<Button variant="text" onClick={onForgotPassword}>
Lupa Password?
</Button>
</h1>
<Button type="submit" size="md" className="w-full">
Login
</Button>
</h1>
<Button size="md" className="w-full">
Login
</Button>
<div className="flex justify-center gap-2 pt-2.5 font-medium">
<p className="text-neutral-500">Belum punya akun?</p>
<Link
className="text-primary-500 hover:text-primary-600"
to="/register"
>
Daftar
</Link>
</div>
<div className="flex justify-center gap-2 pt-2.5 font-medium">
<p className="text-neutral-500">Belum punya akun?</p>
<Link
className="text-primary-500 hover:text-primary-600"
to="/register"
>
Daftar
</Link>
</div>
</form>
</Modal.Content>
</Modal>
);
@@ -1,6 +1,6 @@
import { Button } from '@imphnen-frontend-service/ui/atoms';
import { InputForm, Modal } from '@imphnen-frontend-service/ui/molecules';
import { useQueryState } from '../../../hooks/use-query-state';
import { InputField, Modal } from '@imphnen-frontend-service/ui/molecules';
import { useQueryState } from '@imphnen-frontend-service/utils';
interface IModalFormRegisterProps {
isOpen: boolean;
@@ -54,28 +54,28 @@ interface IStepOneProps {
const StepOne = ({ nextStep, onClose }: IStepOneProps) => (
<>
<InputForm
<InputField
label="Nama Lengkap"
placeholder="Masukkan Nama Lengkap"
type="text"
size="lg"
className="w-full"
/>
<InputForm
<InputField
label="Email"
placeholder="Masukkan Email Anda"
type="email"
size="lg"
className="w-full"
/>
<InputForm
<InputField
label="Password"
placeholder="Masukkan Password"
type="password"
size="lg"
className="w-full"
/>
<InputForm
<InputField
label="Ulangi Password"
placeholder="Masukkan Ulang Password"
type="password"
@@ -95,14 +95,14 @@ interface IStepTwoProps {
const StepTwo = ({ nextStep, prevStep }: IStepTwoProps) => (
<>
<InputForm
<InputField
label="Nomor Telepon"
placeholder="Masukkan Nomor Telepon Aktif"
type="text"
size="lg"
className="w-full"
/>
<InputForm
<InputField
label="Alamat Pengiriman"
placeholder="Masukkan Alamat Pengiriman"
type="text"
@@ -0,0 +1,29 @@
import { cn } from '@imphnen-frontend-service/utils';
import { FC, ReactElement } from 'react';
type TGachaItem = {
src: string;
label: string;
className?: string;
};
export const GachaItem: FC<TGachaItem> = ({
src,
label,
className,
}): ReactElement => {
return (
<div className="snap-center flex-auto justify-center items-center flex flex-col min-w-full overflow-hidden">
<div className="max-h-[180px] md:max-h-[270px] md:max-w-[500px] mb-2 md:mb-5 flex flex-1 justify-center items-center">
<img
src={src}
alt="Banner"
width={255}
height={255}
className={cn('h-[150px] md:h-[255px] object-contain', className)}
/>
</div>
<p className="font-semibold text-center md:text-p2">{label}</p>
</div>
);
};
+26
View File
@@ -0,0 +1,26 @@
import { useForm } from 'react-hook-form';
import {
authLoginSchema,
TLoginRequest,
usePostLogin,
} from '@imphnen-frontend-service/service';
import { zodResolver } from '@hookform/resolvers/zod';
export const useLogin = () => {
const postLogin = usePostLogin();
const form = useForm<TLoginRequest>({
resolver: zodResolver(authLoginSchema),
mode: 'all',
});
const onSubmit = form.handleSubmit((data) => {
postLogin.mutate(data, {
onSuccess: () => console.log('Success Login'),
});
});
return {
form,
onSubmit,
};
};
+1 -28
View File
@@ -1,37 +1,10 @@
import { ArrowDownOutlined } from '@ant-design/icons';
import { Button } from '@imphnen-frontend-service/ui/atoms';
import { cn } from '@imphnen-frontend-service/utils';
import { FC, Fragment, ReactElement, useState } from 'react';
import ModalFormForgotPassword from './_components/form/modal-form-forgot-password';
import ModalFormLogin from './_components/form/modal-form-login';
import ModalFormRegister from './_components/form/modal-form-register';
interface GachaItemProps {
src: string;
label: string;
className?: string;
}
const GachaItem: FC<GachaItemProps> = ({
src,
label,
className,
}): ReactElement => {
return (
<div className="snap-center flex-auto justify-center items-center flex flex-col min-w-full overflow-hidden">
<div className="max-h-[180px] md:max-h-[270px] md:max-w-[500px] mb-2 md:mb-5 flex flex-1 justify-center items-center">
<img
src={src}
alt="Banner"
width={255}
height={255}
className={cn('h-[150px] md:h-[255px] object-contain', className)}
/>
</div>
<p className="font-semibold text-center md:text-p2">{label}</p>
</div>
);
};
import { GachaItem } from './_components/item/gacha-item';
export const Components: FC = (): ReactElement => {
const [showModalForgotPassword, setShowModalForgotPassword] = useState(false);