feat: integeration register modal

This commit is contained in:
egagofur
2025-04-03 23:32:44 +07:00
parent 585ad482f2
commit 9aff9e2dc8
5 changed files with 151 additions and 17 deletions
@@ -1,6 +1,8 @@
import { Button } from '@imphnen-frontend-service/ui/atoms';
import { InputField, Modal } from '@imphnen-frontend-service/ui/molecules';
import { useQueryState } from '@imphnen-frontend-service/utils';
import { useRegister } from '../../_hooks/use-register';
import { ControlledInputField } from '@imphnen-frontend-service/ui/organisms';
interface IModalFormRegisterProps {
isOpen: boolean;
@@ -8,6 +10,8 @@ interface IModalFormRegisterProps {
}
const ModalFormRegister = ({ isOpen, onClose }: IModalFormRegisterProps) => {
const { form, onSubmit } = useRegister();
const {
step: currentStep,
nextStep,
@@ -37,45 +41,58 @@ const ModalFormRegister = ({ isOpen, onClose }: IModalFormRegisterProps) => {
{currentStep === 1 ? 'Info Akun' : 'Informasi Pengiriman Hadiah'}
</h2>
</Modal.Header>
<Modal.Content className="space-y-6">
{currentStep === 1 && <StepOne nextStep={nextStep} onClose={onClose} />}
{currentStep === 2 && (
<StepTwo nextStep={nextStep} prevStep={prevStep} />
)}
<Modal.Content>
<form onSubmit={onSubmit} className="space-y-6">
{currentStep === 1 && (
<StepOne form={form} nextStep={nextStep} onClose={onClose} />
)}
{currentStep === 2 && (
<StepTwo form={form} nextStep={nextStep} prevStep={prevStep} />
)}
</form>
</Modal.Content>
</Modal>
);
};
interface IStepOneProps {
form: any;
nextStep: () => void;
onClose: () => void;
}
const StepOne = ({ nextStep, onClose }: IStepOneProps) => (
const StepOne = ({ form, nextStep, onClose }: IStepOneProps) => (
<>
<InputField
<ControlledInputField
control={form.control}
name="fullname"
label="Nama Lengkap"
placeholder="Masukkan Nama Lengkap"
type="text"
size="lg"
className="w-full"
/>
<InputField
<ControlledInputField
control={form.control}
label="Email"
placeholder="Masukkan Email Anda"
type="email"
name="email"
size="lg"
className="w-full"
/>
<InputField
<ControlledInputField
control={form.control}
name="password"
label="Password"
placeholder="Masukkan Password"
type="password"
size="lg"
className="w-full"
/>
<InputField
<ControlledInputField
control={form.control}
name="confirm_password"
label="Ulangi Password"
placeholder="Masukkan Ulang Password"
type="password"
@@ -89,22 +106,45 @@ const StepOne = ({ nextStep, onClose }: IStepOneProps) => (
);
interface IStepTwoProps {
form: any;
nextStep: () => void;
prevStep: () => void;
}
const StepTwo = ({ nextStep, prevStep }: IStepTwoProps) => (
const StepTwo = ({ form, nextStep, prevStep }: IStepTwoProps) => (
<>
<InputField
<ControlledInputField
control={form.control}
name="phone_number"
label="Nomor Telepon"
placeholder="Masukkan Nomor Telepon Aktif"
type="text"
size="lg"
className="w-full"
/>
<InputField
label="Alamat Pengiriman"
placeholder="Masukkan Alamat Pengiriman"
<ControlledInputField
control={form.control}
name="referral_code"
label="Kode Referral"
placeholder="Masukkan Kode Referral"
type="text"
size="lg"
className="w-full"
/>
<ControlledInputField
control={form.control}
name="referred_by"
label="Referral By"
placeholder="Masukkan Referral By"
type="text"
size="lg"
className="w-full"
/>
<ControlledInputField
control={form.control}
name="student_type"
label="Tipe Pelajar"
placeholder="Masukkan Tipe Pelajar"
type="text"
size="lg"
className="w-full"
@@ -113,7 +153,7 @@ const StepTwo = ({ nextStep, prevStep }: IStepTwoProps) => (
<Button size="md" variant="text" className="w-[40%]" onClick={prevStep}>
Kembali
</Button>
<Button size="md" className="w-full" onClick={nextStep}>
<Button size="md" className="w-full" type='submit'>
Gacha Sekarang
</Button>
</div>
+28
View File
@@ -0,0 +1,28 @@
import { useForm } from 'react-hook-form';
import {
authRegisterSchema,
TRegisterRequest,
usePostRegister,
} from '@imphnen-frontend-service/service';
import { zodResolver } from '@hookform/resolvers/zod';
import { toast } from 'sonner';
export const useRegister = () => {
const postRegister = usePostRegister();
const form = useForm<TRegisterRequest>({
resolver: zodResolver(authRegisterSchema),
mode: 'all',
});
const onSubmit = form.handleSubmit((data) => {
postRegister.mutate(data, {
onSuccess: (data) => toast.success(data.message),
onError: (error) => toast.error(error.message),
});
});
return {
form,
onSubmit,
};
};
+2
View File
@@ -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(
<StrictMode>
<QueryProvider>
<Toaster />
<RouterProvider router={router} />
</QueryProvider>
</StrictMode>
+59
View File
@@ -15,3 +15,62 @@ export const authLoginSchema = z.object({
})
.min(1, 'Password tidak boleh kosong'),
});
export const authRegisterSchema = z
.object({
email: z
.string({
required_error: 'Email tidak boleh kosong',
invalid_type_error: 'Email harus berupa string',
})
.min(1, 'Email tidak boleh kosong')
.email('Email harus valid'),
fullname: z
.string({
required_error: 'Nama tidak boleh kosong',
invalid_type_error: 'Nama harus berupa string',
})
.min(1, 'Nama tidak boleh kosong')
.max(50, 'Nama tidak boleh lebih dari 50 karakter'),
password: z
.string({
required_error: 'Password tidak boleh kosong',
invalid_type_error: 'Password harus berupa string',
})
.min(1, 'Password tidak boleh kosong')
.min(8, 'Password harus lebih dari 8 karakter')
.max(50, 'Password tidak boleh lebih dari 50 karakter'),
phone_number: z
.string({
required_error: 'Nomor telepon tidak boleh kosong',
invalid_type_error: 'Nomor telepon harus berupa string',
})
.min(1, 'Nomor telepon tidak boleh kosong')
.max(15, 'Nomor telepon tidak boleh lebih dari 15 karakter'),
referral_code: z
.string()
.min(1, 'Kode referral tidak boleh kosong')
.max(4, 'Kode referral tidak boleh lebih dari 4 karakter')
.optional(),
referred_by: z
.string()
.min(1, 'Kode referral tidak boleh kosong')
.max(50, 'Kode referral tidak boleh lebih dari 50 karakter')
.optional(),
student_type: z.string(),
confirm_password: z
.string({
required_error: 'Konfirmasi password tidak boleh kosong',
})
.min(1, 'Konfirmasi password tidak boleh kosong')
.max(50, 'Konfirmasi password tidak boleh lebih dari 50 karakter'),
})
.superRefine((val, ctx) => {
if (val.password !== val.confirm_password) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
path: ['confirm_password'],
message: `No duplicates allowed.`,
});
}
});
+6 -1
View File
@@ -16,9 +16,14 @@ export type TLoginResponse = {
};
export type TRegisterRequest = {
fullname: string;
email: string;
fullname: string;
password: string;
phone_number: string;
referral_code?: string;
referred_by?: string;
student_type: string;
confirm_password: string;
};
export type TVerifyEmailRequest = {