feat: integrate all backend APIs into frontend apps

- Fix API service paths to use /v1/iam/, /v1/dimentorin/, /v1/gacha/, /v1/hackathon/ prefixes
- Add roles, permissions, events, testimonials, sessions API services and hooks
- Rewrite gacha service with full CRUD + roll/claim endpoints
- Replace all mock data in backoffice pages with real API calls (accounts, roles, permissions, gacha-roll, dashboard, sessions, users-dimentorin, feedback-review, settings)
- Wire dimentorin mentoring list to useMentorList with search + pagination
- Wire dimentorin mentor detail page to useMentorById, pass real data to all sections
- Wire appointment modal to useBookSession with controlled schedule inputs
- Wire gacha app Spin Now to useExecuteGachaRoll, show credits and real items

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
maulanasdqn
2026-04-05 17:08:58 +07:00
co-authored by Claude Sonnet 4.6
parent 8d2aaf5188
commit 53ad40f3fd
74 changed files with 3028 additions and 1942 deletions
@@ -11,6 +11,7 @@ interface IModalAddItem {
nextStep: () => void;
prevStep: () => void;
resetStep: () => void;
onDataCapture?: (data: any) => void;
}
const ModalAddItem = ({
@@ -20,6 +21,7 @@ const ModalAddItem = ({
nextStep,
resetStep,
handleAddItem,
onDataCapture,
}: IModalAddItem) => {
return (
<Modal
@@ -31,7 +33,7 @@ const ModalAddItem = ({
}}
disableEscapeKeyDown={true}
>
{currentStep === 1 && <StepOne nextStep={nextStep} onClose={onClose} />}
{currentStep === 1 && <StepOne nextStep={nextStep} onClose={onClose} onDataCapture={onDataCapture} />}
{currentStep === 2 && (
<StepTwo
onClose={onClose}
@@ -46,10 +48,11 @@ const ModalAddItem = ({
interface IStepOneProps {
nextStep: () => void;
onClose: () => void;
onDataCapture?: (data: any) => void;
}
const StepOne = ({ nextStep }: IStepOneProps) => {
const { form, onSubmit } = useItem(nextStep);
const StepOne = ({ nextStep, onDataCapture }: IStepOneProps) => {
const { form, onSubmit } = useItem(nextStep, undefined, onDataCapture);
return (
<>
@@ -4,7 +4,7 @@ import { Modal } from '@imphnen-frontend-service/ui/molecules';
interface IModalDeleteItem {
isOpen: boolean;
onClose: () => void;
handleDeleteItem?: () => void;
handleDeleteItem?: () => Promise<void>;
}
const ModalDeleteItem = ({
@@ -48,8 +48,9 @@ const ModalDeleteItem = ({
variant="danger"
size="lg"
className="w-full"
onClick={() => {
handleDeleteItem && handleDeleteItem();
onClick={async () => {
if (handleDeleteItem) await handleDeleteItem();
onClose();
}}
>
Hapus Item
@@ -11,6 +11,8 @@ interface IModalUpdateItem {
nextStep: () => void;
prevStep: () => void;
resetStep: () => void;
initialValues?: { itemName?: string; quantity?: number; chanceRate?: number };
onDataCapture?: (data: any) => void;
}
const ModalUpdateItem = ({
@@ -20,6 +22,8 @@ const ModalUpdateItem = ({
nextStep,
resetStep,
handleUpdateItem,
initialValues,
onDataCapture,
}: IModalUpdateItem) => {
return (
<Modal
@@ -31,7 +35,7 @@ const ModalUpdateItem = ({
}}
disableEscapeKeyDown={true}
>
{currentStep === 1 && <StepOne nextStep={nextStep} onClose={onClose} />}
{currentStep === 1 && <StepOne nextStep={nextStep} onClose={onClose} initialValues={initialValues} onDataCapture={onDataCapture} />}
{currentStep === 2 && (
<StepTwo
onClose={onClose}
@@ -46,16 +50,12 @@ const ModalUpdateItem = ({
interface IStepOneProps {
nextStep: () => void;
onClose: () => void;
initialValues?: { itemName?: string; quantity?: number; chanceRate?: number };
onDataCapture?: (data: any) => void;
}
const StepOne = ({ nextStep }: IStepOneProps) => {
const initialValues = {
itemName: 'Hoodie IMPHNEN Official 2025',
quantity: 10,
chanceRate: 0.1,
};
const { form, onSubmit } = useItem(nextStep, initialValues);
const StepOne = ({ nextStep, initialValues, onDataCapture }: IStepOneProps) => {
const { form, onSubmit } = useItem(nextStep, initialValues as any, onDataCapture);
return (
<>
@@ -105,7 +105,7 @@ const StepOne = ({ nextStep }: IStepOneProps) => {
variant="primary"
size="lg"
className="w-full"
onClick={nextStep}
type="submit"
>
Perbarui Item
</Button>