feat: custom hook for add gacha roll item

- Buat custom hook untuk add item
This commit is contained in:
Hafid Nur
2025-04-05 06:41:11 +07:00
parent 2746af0b3f
commit 885d156833
2 changed files with 133 additions and 81 deletions
@@ -1,6 +1,7 @@
import { Button } from '@imphnen-frontend-service/ui/atoms';
import { InputField, Modal } from '@imphnen-frontend-service/ui/molecules';
import { useState } from 'react';
import { Modal } from '@imphnen-frontend-service/ui/molecules';
import { ControlledInputField } from '@imphnen-frontend-service/ui/organisms';
import { useAddItem, useConfirmAddItem } from '../_hook/use-add-item';
interface IModalAddItem {
isOpen: boolean;
@@ -49,9 +50,7 @@ interface IStepOneProps {
}
const StepOne = ({ nextStep }: IStepOneProps) => {
const [itemName, setItemName] = useState('');
const [quantity, setQuantity] = useState('');
const [chanceRate, setChanceRate] = useState('');
const { form, onSubmit } = useAddItem(nextStep);
return (
<>
@@ -63,45 +62,42 @@ const StepOne = ({ nextStep }: IStepOneProps) => {
Lengkapi detal di bawah ini, untuk menambahkan item gacha
</p>
</Modal.Header>
<Modal.Content className="flex flex-col gap-8">
<div className="flex flex-col gap-4">
<InputField
label="Pilih Item"
type="text"
placeholder="Pilih item yang dimasukkan ke roll"
value={itemName}
onChange={(e) => setItemName(e.target.value)}
size="lg"
className="w-full"
/>
<InputField
label="Quantity"
type="text"
placeholder="Masukkan Kuantitas Item"
value={quantity}
onChange={(e) => setQuantity(e.target.value)}
size="lg"
className="w-full"
/>
<InputField
label="Chance Rate"
type="text"
placeholder="Masukkan Chance Rate (0.1 - 1)"
value={chanceRate}
onChange={(e) => setChanceRate(e.target.value)}
size="lg"
className="w-full"
/>
</div>
<Modal.Content>
<form onSubmit={onSubmit} className="flex flex-col gap-8">
<div className="flex flex-col gap-4">
<ControlledInputField
control={form.control}
label="Pilih Item"
name="itemName"
type="text"
placeholder="Pilih item yang dimasukkan ke roll"
size="lg"
className="w-full"
/>
<ControlledInputField
control={form.control}
label="Quantity"
name="quantity"
type="text"
placeholder="Masukkan Kuantitas Item"
size="lg"
className="w-full"
/>
<ControlledInputField
control={form.control}
label="Chance Rate"
name="chanceRate"
type="text"
placeholder="Masukkan Chance Rate (0.1 - 1)"
size="lg"
className="w-full"
/>
</div>
<Button
variant="primary"
size="lg"
className="w-full"
onClick={nextStep}
>
Tambahkan Item
</Button>
<Button variant="primary" size="lg" className="w-full" type="submit">
Tambahkan Item
</Button>
</form>
</Modal.Content>
</>
);
@@ -113,43 +109,40 @@ interface IStepTwoProps {
resetStep: () => void;
}
const StepTwo = ({ onClose, handleAddItem, resetStep }: IStepTwoProps) => (
<>
<Modal.Header className="mb-0 text-center items-center">
<h2 className="text-p1 font-semibold text-primary-500 mb-3">
Tambah ke Roll Gacha
</h2>
<p className="text-p3 text-neutral-400">
Apakah kamu yakin ingin
<br /> menambahkan item ini ke roll gacha?
</p>
</Modal.Header>
<Modal.Content className="flex gap-4">
<Button
variant="bordered"
size="lg"
className="w-full"
onClick={() => {
onClose();
resetStep();
}}
>
Batal
</Button>
<Button
variant="primary"
size="lg"
className="w-full"
onClick={() => {
handleAddItem && handleAddItem();
onClose();
resetStep();
}}
>
Tambahkan
</Button>
</Modal.Content>
</>
);
const StepTwo = ({ onClose, handleAddItem, resetStep }: IStepTwoProps) => {
const { onConfirm, onCancel } = useConfirmAddItem(onClose, resetStep);
return (
<>
<Modal.Header className="mb-0 text-center items-center">
<h2 className="text-p1 font-semibold text-primary-500 mb-3">
Tambah ke Roll Gacha
</h2>
<p className="text-p3 text-neutral-400">
Apakah kamu yakin ingin
<br /> menambahkan item ini ke roll gacha?
</p>
</Modal.Header>
<Modal.Content className="flex gap-4">
<Button
variant="bordered"
size="lg"
className="w-full"
onClick={onCancel}
>
Batal
</Button>
<Button
variant="primary"
size="lg"
className="w-full"
onClick={onConfirm}
>
Tambahkan
</Button>
</Modal.Content>
</>
);
};
export default ModalAddItem;
@@ -0,0 +1,59 @@
import { useForm } from 'react-hook-form';
import { z } from 'zod';
import { zodResolver } from '@hookform/resolvers/zod';
const addItemSchema = z.object({
itemName: z.string().min(1, 'Item name is required'),
quantity: z.string().min(1, 'Quantity is required'),
chanceRate: z
.string()
.min(1, 'Chance rate is required')
.refine(
(val) => {
const num = parseFloat(val);
return num >= 0.1 && num <= 1;
},
{ message: 'Chance rate must be between 0.1 and 1' }
),
});
type TAddItemForm = z.infer<typeof addItemSchema>;
export const useAddItem = (nextStep: () => void) => {
const form = useForm<TAddItemForm>({
resolver: zodResolver(addItemSchema),
mode: 'all',
});
const onSubmit = form.handleSubmit((data) => {
console.log('Form data:', data);
nextStep();
});
return {
form,
onSubmit,
};
};
export const useConfirmAddItem = (
onClose: () => void,
resetStep: () => void,
handleAddItem?: () => void,
) => {
const onConfirm = () => {
handleAddItem?.();
onClose();
resetStep();
};
const onCancel = () => {
onClose();
resetStep();
};
return {
onConfirm,
onCancel,
};
};