diff --git a/apps/backoffice/src/routes/_authenticated/_components/accounts/modal-edit-account.tsx b/apps/backoffice/src/routes/_authenticated/_components/accounts/modal-edit-account.tsx deleted file mode 100644 index c533680..0000000 --- a/apps/backoffice/src/routes/_authenticated/_components/accounts/modal-edit-account.tsx +++ /dev/null @@ -1,162 +0,0 @@ -import { Button } from '@imphnen-frontend-service/ui/atoms'; -import { InputField, Modal } from '@imphnen-frontend-service/ui/molecules'; -import { useEffect, useState } from 'react'; - -interface IModalEditAccount { - isOpen: boolean; - onClose: () => void; - handleEditAccount?: () => Promise; - currentStep?: number; - nextStep: () => void; - prevStep: () => void; - resetStep: () => void; - initialValues?: { fullname?: string; email?: string }; - onDataCapture?: (data: any) => void; -} - -const ModalEditAccount = ({ - isOpen, - onClose, - currentStep, - nextStep, - resetStep, - handleEditAccount, - initialValues, - onDataCapture, -}: IModalEditAccount) => { - return ( - { - onClose(); - resetStep(); - }} - disableEscapeKeyDown={true} - > - {currentStep === 1 && ( - - )} - {currentStep === 2 && ( - - )} - - ); -}; - -interface IStepOneProps { - nextStep: () => void; - onClose: () => void; - initialValues?: { fullname?: string; email?: string }; - onDataCapture?: (data: any) => void; -} - -const StepOne = ({ nextStep, initialValues, onDataCapture }: IStepOneProps) => { - const [fullName, setFullName] = useState(initialValues?.fullname ?? ''); - const [email, setEmail] = useState(initialValues?.email ?? ''); - - useEffect(() => { - setFullName(initialValues?.fullname ?? ''); - setEmail(initialValues?.email ?? ''); - }, [initialValues]); - - return ( - <> - -

- Edit Data Akun -

-
- -
- setFullName(e.target.value)} - size="lg" - className="w-full" - /> - setEmail(e.target.value)} - size="lg" - className="w-full" - /> -
- - -
- - ); -}; - -interface IStepTwoProps { - onClose: () => void; - handleEditAccount?: () => Promise; - resetStep: () => void; -} - -const StepTwo = ({ onClose, handleEditAccount, resetStep }: IStepTwoProps) => ( - <> - -

- Update Data -

-

- Apakah kamu yakin dengan -
perubahan yang dilakukan? -

-
- - - - - -); - -export default ModalEditAccount; diff --git a/apps/backoffice/src/routes/_authenticated/_components/cms-events/modal-add-event.tsx b/apps/backoffice/src/routes/_authenticated/_components/cms-events/modal-add-event.tsx deleted file mode 100644 index b8b987a..0000000 --- a/apps/backoffice/src/routes/_authenticated/_components/cms-events/modal-add-event.tsx +++ /dev/null @@ -1,202 +0,0 @@ -import { Button } from '@imphnen-frontend-service/ui/atoms'; -import { Modal } from '@imphnen-frontend-service/ui/molecules'; -import { ControlledInputField } from '@imphnen-frontend-service/ui/organisms'; -import { useItem, useConfirmItem } from '../../_hooks/cms-events/use-item'; - -interface IModalAddEvent { - isOpen: boolean; - onClose: () => void; - handleAdd?: () => Promise; - currentStep?: number; - nextStep: () => void; - prevStep: () => void; - resetStep: () => void; - onDataCapture?: (data: any) => void; -} - -const ModalAddEvent = ({ - isOpen, - onClose, - currentStep, - nextStep, - resetStep, - handleAdd, - onDataCapture, -}: IModalAddEvent) => { - return ( - { - onClose(); - resetStep(); - }} - disableEscapeKeyDown={true} - > - {currentStep === 1 && } - {currentStep === 2 && ( - - )} - - ); -}; - -interface IStepOneProps { - nextStep: () => void; - onClose: () => void; - onDataCapture?: (data: any) => void; -} - -const StepOne = ({ nextStep, onDataCapture }: IStepOneProps) => { - const { form, onSubmit } = useItem(nextStep, undefined, onDataCapture); - - return ( - <> - -

- Tambah Event -

-
- -
-
- - - - - - - -
- - -
-
- - -
-
- - ); -}; - -interface IStepTwoProps { - onClose: () => void; - handleAdd?: () => Promise; - resetStep: () => void; -} - -const StepTwo = ({ onClose, handleAdd, resetStep }: IStepTwoProps) => { - const { onConfirm, onCancel } = useConfirmItem( - onClose, - resetStep, - handleAdd, - { - success: 'Data event berhasil ditambahkan', - error: 'Data event gagal ditambahkan', - } - ); - - return ( - <> - -

- Tambah Event -

-

- Apakah kamu yakin ingin -
menambahkan event ini? -

-
- - - - - - ); -}; - -export default ModalAddEvent; diff --git a/apps/backoffice/src/routes/_authenticated/_components/cms-events/modal-delete-event.tsx b/apps/backoffice/src/routes/_authenticated/_components/cms-events/modal-delete-event.tsx deleted file mode 100644 index 396feed..0000000 --- a/apps/backoffice/src/routes/_authenticated/_components/cms-events/modal-delete-event.tsx +++ /dev/null @@ -1,72 +0,0 @@ -import { Button } from '@imphnen-frontend-service/ui/atoms'; -import { Modal } from '@imphnen-frontend-service/ui/molecules'; -import { useConfirmItem } from '../../_hooks/cms-events/use-item'; - -interface IModalDeleteEvent { - isOpen: boolean; - onClose: () => void; - handleDelete?: () => Promise; - currentStep?: number; - nextStep: () => void; - prevStep: () => void; - resetStep: () => void; -} - -const ModalDeleteEvent = ({ - isOpen, - onClose, - resetStep, - handleDelete, -}: IModalDeleteEvent) => { - const { onConfirm } = useConfirmItem(onClose, resetStep, handleDelete, { - success: 'Data event berhasil dihapus', - error: 'Data event gagal dihapus', - }); - - return ( - - - Delete? -
-

- Delete Event -

-

- Apakah kamu yakin untuk menghapus event ini? Menghapus data ini - mungkin akan mempengaruhi fungsional sistem -

-
-
- - - - -
- ); -}; - -export default ModalDeleteEvent; diff --git a/apps/backoffice/src/routes/_authenticated/_components/cms-events/modal-update-event.tsx b/apps/backoffice/src/routes/_authenticated/_components/cms-events/modal-update-event.tsx deleted file mode 100644 index 1844d0e..0000000 --- a/apps/backoffice/src/routes/_authenticated/_components/cms-events/modal-update-event.tsx +++ /dev/null @@ -1,166 +0,0 @@ -import { useEffect } from 'react'; -import { useForm } from 'react-hook-form'; -import { toast } from 'sonner'; -import { Button } from '@imphnen-frontend-service/ui/atoms'; -import { Modal } from '@imphnen-frontend-service/ui/molecules'; -import { ControlledInputField } from '@imphnen-frontend-service/ui/organisms'; - -interface IModalUpdateEvent { - isOpen: boolean; - onClose: () => void; - handleUpdate?: () => Promise; - currentStep?: number; - nextStep: () => void; - prevStep: () => void; - resetStep: () => void; - initialValues?: { - name?: string; - description?: string; - detail_link?: string; - location?: string; - price?: number; - start_date?: string; - end_date?: string; - is_online?: boolean; - }; - onDataCapture?: (data: any) => void; -} - -const ModalUpdateEvent = ({ - isOpen, - onClose, - resetStep, - handleUpdate, - initialValues, - onDataCapture, -}: IModalUpdateEvent) => { - const form = useForm({ - mode: 'all', - defaultValues: initialValues, - }); - - useEffect(() => { - if (isOpen) { - form.reset(initialValues); - } - }, [isOpen, initialValues]); - - const onSubmit = form.handleSubmit(async (data) => { - try { - onDataCapture?.(data); - if (handleUpdate) await handleUpdate(); - toast.success('Perubahan event berhasil dilakukan'); - onClose(); - resetStep(); - } catch (error) { - console.log(error); - toast.error('Perubahan event gagal dilakukan'); - } - }); - - return ( - - -

- Update Event -

-
- -
-
- - - - - - - -
- - -
-
- - -
-
-
- ); -}; - -export default ModalUpdateEvent; diff --git a/apps/backoffice/src/routes/_authenticated/_components/cms-testimonials/modal-add-testimonial.tsx b/apps/backoffice/src/routes/_authenticated/_components/cms-testimonials/modal-add-testimonial.tsx deleted file mode 100644 index 0fbe819..0000000 --- a/apps/backoffice/src/routes/_authenticated/_components/cms-testimonials/modal-add-testimonial.tsx +++ /dev/null @@ -1,146 +0,0 @@ -import { Button } from '@imphnen-frontend-service/ui/atoms'; -import { Modal } from '@imphnen-frontend-service/ui/molecules'; -import { ControlledInputField } from '@imphnen-frontend-service/ui/organisms'; -import { useItem, useConfirmItem } from '../../_hooks/cms-testimonials/use-item'; - -interface IModalAddTestimonial { - isOpen: boolean; - onClose: () => void; - handleAdd?: () => Promise; - currentStep?: number; - nextStep: () => void; - prevStep: () => void; - resetStep: () => void; - onDataCapture?: (data: any) => void; -} - -const ModalAddTestimonial = ({ - isOpen, - onClose, - currentStep, - nextStep, - resetStep, - handleAdd, - onDataCapture, -}: IModalAddTestimonial) => { - return ( - { - onClose(); - resetStep(); - }} - disableEscapeKeyDown={true} - > - {currentStep === 1 && } - {currentStep === 2 && ( - - )} - - ); -}; - -interface IStepOneProps { - nextStep: () => void; - onClose: () => void; - onDataCapture?: (data: any) => void; -} - -const StepOne = ({ nextStep, onDataCapture }: IStepOneProps) => { - const { form, onSubmit } = useItem(nextStep, undefined, onDataCapture); - - return ( - <> - -

- Tambah Testimonial -

-
- -
-
- - -
- - -
-
- - ); -}; - -interface IStepTwoProps { - onClose: () => void; - handleAdd?: () => Promise; - resetStep: () => void; -} - -const StepTwo = ({ onClose, handleAdd, resetStep }: IStepTwoProps) => { - const { onConfirm, onCancel } = useConfirmItem( - onClose, - resetStep, - handleAdd, - { - success: 'Data testimonial berhasil ditambahkan', - error: 'Data testimonial gagal ditambahkan', - } - ); - - return ( - <> - -

- Tambah Testimonial -

-

- Apakah kamu yakin ingin -
menambahkan testimonial ini? -

-
- - - - - - ); -}; - -export default ModalAddTestimonial; diff --git a/apps/backoffice/src/routes/_authenticated/_components/cms-testimonials/modal-delete-testimonial.tsx b/apps/backoffice/src/routes/_authenticated/_components/cms-testimonials/modal-delete-testimonial.tsx deleted file mode 100644 index f4d8a5c..0000000 --- a/apps/backoffice/src/routes/_authenticated/_components/cms-testimonials/modal-delete-testimonial.tsx +++ /dev/null @@ -1,72 +0,0 @@ -import { Button } from '@imphnen-frontend-service/ui/atoms'; -import { Modal } from '@imphnen-frontend-service/ui/molecules'; -import { useConfirmItem } from '../../_hooks/cms-testimonials/use-item'; - -interface IModalDeleteTestimonial { - isOpen: boolean; - onClose: () => void; - handleDelete?: () => Promise; - currentStep?: number; - nextStep: () => void; - prevStep: () => void; - resetStep: () => void; -} - -const ModalDeleteTestimonial = ({ - isOpen, - onClose, - resetStep, - handleDelete, -}: IModalDeleteTestimonial) => { - const { onConfirm } = useConfirmItem(onClose, resetStep, handleDelete, { - success: 'Data testimonial berhasil dihapus', - error: 'Data testimonial gagal dihapus', - }); - - return ( - - - Delete? -
-

- Delete Testimonial -

-

- Apakah kamu yakin untuk menghapus testimonial ini? Menghapus data ini - mungkin akan mempengaruhi fungsional sistem -

-
-
- - - - -
- ); -}; - -export default ModalDeleteTestimonial; diff --git a/apps/backoffice/src/routes/_authenticated/_components/cms-testimonials/modal-update-testimonial.tsx b/apps/backoffice/src/routes/_authenticated/_components/cms-testimonials/modal-update-testimonial.tsx deleted file mode 100644 index bdcdb3e..0000000 --- a/apps/backoffice/src/routes/_authenticated/_components/cms-testimonials/modal-update-testimonial.tsx +++ /dev/null @@ -1,104 +0,0 @@ -import { useEffect } from 'react'; -import { useForm } from 'react-hook-form'; -import { toast } from 'sonner'; -import { Button } from '@imphnen-frontend-service/ui/atoms'; -import { Modal } from '@imphnen-frontend-service/ui/molecules'; -import { ControlledInputField } from '@imphnen-frontend-service/ui/organisms'; - -interface IModalUpdateTestimonial { - isOpen: boolean; - onClose: () => void; - handleUpdate?: () => Promise; - currentStep?: number; - nextStep: () => void; - prevStep: () => void; - resetStep: () => void; - initialValues?: { - role?: string; - content?: string; - }; - onDataCapture?: (data: any) => void; -} - -const ModalUpdateTestimonial = ({ - isOpen, - onClose, - resetStep, - handleUpdate, - initialValues, - onDataCapture, -}: IModalUpdateTestimonial) => { - const form = useForm({ - mode: 'all', - defaultValues: initialValues, - }); - - useEffect(() => { - if (isOpen) { - form.reset(initialValues); - } - }, [isOpen, initialValues]); - - const onSubmit = form.handleSubmit(async (data) => { - try { - onDataCapture?.(data); - if (handleUpdate) await handleUpdate(); - toast.success('Perubahan testimonial berhasil dilakukan'); - onClose(); - resetStep(); - } catch (error) { - console.log(error); - toast.error('Perubahan testimonial gagal dilakukan'); - } - }); - - return ( - - -

- Update Testimonial -

-
- -
-
- - -
- - -
-
-
- ); -}; - -export default ModalUpdateTestimonial; diff --git a/apps/backoffice/src/routes/_authenticated/_components/dashboard/modal-add-item.tsx b/apps/backoffice/src/routes/_authenticated/_components/dashboard/modal-add-item.tsx deleted file mode 100644 index bbe767b..0000000 --- a/apps/backoffice/src/routes/_authenticated/_components/dashboard/modal-add-item.tsx +++ /dev/null @@ -1,164 +0,0 @@ -import { Button } from '@imphnen-frontend-service/ui/atoms'; -import { Modal } from '@imphnen-frontend-service/ui/molecules'; -import { useConfirmItem, useItem } from '../../_hooks/dashboard/use-item'; -import { ControlledInputField } from '@imphnen-frontend-service/ui/organisms'; - -interface IModalAddItem { - isOpen: boolean; - onClose: () => void; - handleAddItem?: () => Promise; - currentStep?: number; - nextStep: () => void; - prevStep: () => void; - resetStep: () => void; - onDataCapture?: (data: any) => void; -} - -const ModalAddItem = ({ - isOpen, - onClose, - currentStep, - nextStep, - resetStep, - handleAddItem, - onDataCapture, -}: IModalAddItem) => { - return ( - { - onClose(); - resetStep(); - }} - disableEscapeKeyDown={true} - > - {currentStep === 1 && } - {currentStep === 2 && ( - - )} - - ); -}; - -interface IStepOneProps { - nextStep: () => void; - onClose: () => void; - onDataCapture?: (data: any) => void; -} - -const StepOne = ({ nextStep, onDataCapture }: IStepOneProps) => { - const { form, onSubmit } = useItem(nextStep, undefined, onDataCapture); - - return ( - <> - -

- Tambah Item Gacha -

-

- Lengkapi detail di bawah ini untuk menambahkan item gacha -

-
- -
-
- - - -
- - -
-
- - ); -}; - -interface IStepTwoProps { - onClose: () => void; - handleAddItem?: () => Promise; - resetStep: () => void; -} - -const StepTwo = ({ onClose, handleAddItem, resetStep }: IStepTwoProps) => { - const { onConfirm, onCancel } = useConfirmItem( - onClose, - resetStep, - handleAddItem, - { - success: 'Item ditambahkan ke gacha item', - error: 'Item gagal ditambahkan ke gacha item', - } - ); - - return ( - <> - -

- Tambah Item -

-

- Apakah kamu yakin ingin -
menambahkan item ini? -

-
- - - - - - ); -}; - -export default ModalAddItem; diff --git a/apps/backoffice/src/routes/_authenticated/_components/dashboard/modal-delete-item.tsx b/apps/backoffice/src/routes/_authenticated/_components/dashboard/modal-delete-item.tsx deleted file mode 100644 index 75c14f4..0000000 --- a/apps/backoffice/src/routes/_authenticated/_components/dashboard/modal-delete-item.tsx +++ /dev/null @@ -1,63 +0,0 @@ -import { Button } from '@imphnen-frontend-service/ui/atoms'; -import { Modal } from '@imphnen-frontend-service/ui/molecules'; - -interface IModalDeleteItem { - isOpen: boolean; - onClose: () => void; - handleDeleteItem?: () => Promise; -} - -const ModalDeleteItem = ({ - isOpen, - onClose, - handleDeleteItem, -}: IModalDeleteItem) => { - return ( - - - Delete item? -
-

- Delete Item -

-

- Apakah kamu yakin untuk menghapus item ini? -

-
-
- - - - -
- ); -}; - -export default ModalDeleteItem; diff --git a/apps/backoffice/src/routes/_authenticated/_components/dashboard/modal-edit-item.tsx b/apps/backoffice/src/routes/_authenticated/_components/dashboard/modal-edit-item.tsx deleted file mode 100644 index c76e146..0000000 --- a/apps/backoffice/src/routes/_authenticated/_components/dashboard/modal-edit-item.tsx +++ /dev/null @@ -1,165 +0,0 @@ -import { Button } from '@imphnen-frontend-service/ui/atoms'; -import { InputField, Modal } from '@imphnen-frontend-service/ui/molecules'; -import { useConfirmItem, useItem } from '../../_hooks/dashboard/use-item'; -import { ControlledInputField } from '@imphnen-frontend-service/ui/organisms'; - -interface IModalEditItem { - isOpen: boolean; - onClose: () => void; - handleEditItem?: () => Promise; - currentStep?: number; - nextStep: () => void; - prevStep: () => void; - resetStep: () => void; - initialValues?: { itemName?: string; quantity?: number }; - onDataCapture?: (data: any) => void; -} - -const ModalEditItem = ({ - isOpen, - onClose, - currentStep, - nextStep, - resetStep, - handleEditItem, - initialValues, - onDataCapture, -}: IModalEditItem) => { - return ( - { - onClose(); - resetStep(); - }} - disableEscapeKeyDown={true} - > - {currentStep === 1 && } - {currentStep === 2 && ( - - )} - - ); -}; - -interface IStepOneProps { - nextStep: () => void; - onClose: () => void; - initialValues?: { itemName?: string; quantity?: number }; - onDataCapture?: (data: any) => void; -} - -const StepOne = ({ nextStep, initialValues, onDataCapture }: IStepOneProps) => { - const { form, onSubmit } = useItem(nextStep, initialValues as any, onDataCapture); - - return ( - <> - -

- Edit Item Gacha -

-

- Silakan mengubah detail dari item yang diperlukan -

-
- -
-
- - - -
- - -
-
- - ); -}; - -interface IStepTwoProps { - onClose: () => void; - handleEditItem?: () => Promise; - resetStep: () => void; -} - -const StepTwo = ({ onClose, handleEditItem, resetStep }: IStepTwoProps) => { - const { onConfirm, onCancel } = useConfirmItem( - onClose, - resetStep, - handleEditItem, - { - success: 'Perubahan item berhasil dilakukan', - error: 'Perubahan item gagal dilakukan', - } - ); - return ( - <> - -

- Update Item -

-

- Apakah kamu yakin dengan -
perubahan yang dilakukan? -

-
- - - - - - ); -}; - -export default ModalEditItem; diff --git a/apps/backoffice/src/routes/_authenticated/_components/gacha-roll/modal-add-item.tsx b/apps/backoffice/src/routes/_authenticated/_components/gacha-roll/modal-add-item.tsx deleted file mode 100644 index b8f91ed..0000000 --- a/apps/backoffice/src/routes/_authenticated/_components/gacha-roll/modal-add-item.tsx +++ /dev/null @@ -1,163 +0,0 @@ -import { Button } from '@imphnen-frontend-service/ui/atoms'; -import { Modal } from '@imphnen-frontend-service/ui/molecules'; -import { ControlledInputField } from '@imphnen-frontend-service/ui/organisms'; -import { useItem, useConfirmItem } from '../../_hooks/gacha-roll/use-item'; - -interface IModalAddItem { - isOpen: boolean; - onClose: () => void; - handleAddItem?: () => Promise; - currentStep?: number; - nextStep: () => void; - prevStep: () => void; - resetStep: () => void; - onDataCapture?: (data: any) => void; -} - -const ModalAddItem = ({ - isOpen, - onClose, - currentStep, - nextStep, - resetStep, - handleAddItem, - onDataCapture, -}: IModalAddItem) => { - return ( - { - onClose(); - resetStep(); - }} - disableEscapeKeyDown={true} - > - {currentStep === 1 && } - {currentStep === 2 && ( - - )} - - ); -}; - -interface IStepOneProps { - nextStep: () => void; - onClose: () => void; - onDataCapture?: (data: any) => void; -} - -const StepOne = ({ nextStep, onDataCapture }: IStepOneProps) => { - const { form, onSubmit } = useItem(nextStep, undefined, onDataCapture); - - return ( - <> - -

- Tambah Item Roll Gacha -

-

- Lengkapi detal di bawah ini, untuk menambahkan item gacha -

-
- -
-
- - - -
- - -
-
- - ); -}; - -interface IStepTwoProps { - onClose: () => void; - handleAddItem?: () => Promise; - resetStep: () => void; -} - -const StepTwo = ({ onClose, handleAddItem, resetStep }: IStepTwoProps) => { - const { onConfirm, onCancel } = useConfirmItem( - onClose, - resetStep, - handleAddItem, - { - success: 'Item ditambahkan ke roll gacha', - error: 'Item gagal ditambahkan ke roll gacha', - } - ); - - return ( - <> - -

- Tambah ke Roll Gacha -

-

- Apakah kamu yakin ingin -
menambahkan item ini ke roll gacha? -

-
- - - - - - ); -}; - -export default ModalAddItem; diff --git a/apps/backoffice/src/routes/_authenticated/_components/gacha-roll/modal-delete-item.tsx b/apps/backoffice/src/routes/_authenticated/_components/gacha-roll/modal-delete-item.tsx deleted file mode 100644 index cfc6075..0000000 --- a/apps/backoffice/src/routes/_authenticated/_components/gacha-roll/modal-delete-item.tsx +++ /dev/null @@ -1,63 +0,0 @@ -import { Button } from '@imphnen-frontend-service/ui/atoms'; -import { Modal } from '@imphnen-frontend-service/ui/molecules'; - -interface IModalDeleteItem { - isOpen: boolean; - onClose: () => void; - handleDeleteItem?: () => Promise; -} - -const ModalDeleteItem = ({ - isOpen, - onClose, - handleDeleteItem, -}: IModalDeleteItem) => { - return ( - - - Delete item? -
-

- Delete Item -

-

- Apakah kamu yakin untuk menghapus item ini? -

-
-
- - - - -
- ); -}; - -export default ModalDeleteItem; diff --git a/apps/backoffice/src/routes/_authenticated/_components/gacha-roll/modal-update-item.tsx b/apps/backoffice/src/routes/_authenticated/_components/gacha-roll/modal-update-item.tsx deleted file mode 100644 index 3b5265f..0000000 --- a/apps/backoffice/src/routes/_authenticated/_components/gacha-roll/modal-update-item.tsx +++ /dev/null @@ -1,168 +0,0 @@ -import { Button } from '@imphnen-frontend-service/ui/atoms'; -import { Modal } from '@imphnen-frontend-service/ui/molecules'; -import { useConfirmItem, useItem } from '../../_hooks/gacha-roll/use-item'; -import { ControlledInputField } from '@imphnen-frontend-service/ui/organisms'; - -interface IModalUpdateItem { - isOpen: boolean; - onClose: () => void; - handleUpdateItem?: () => Promise; - currentStep?: number; - nextStep: () => void; - prevStep: () => void; - resetStep: () => void; - initialValues?: { itemName?: string; quantity?: number; chanceRate?: number }; - onDataCapture?: (data: any) => void; -} - -const ModalUpdateItem = ({ - isOpen, - onClose, - currentStep, - nextStep, - resetStep, - handleUpdateItem, - initialValues, - onDataCapture, -}: IModalUpdateItem) => { - return ( - { - onClose(); - resetStep(); - }} - disableEscapeKeyDown={true} - > - {currentStep === 1 && } - {currentStep === 2 && ( - - )} - - ); -}; - -interface IStepOneProps { - nextStep: () => void; - onClose: () => void; - initialValues?: { itemName?: string; quantity?: number; chanceRate?: number }; - onDataCapture?: (data: any) => void; -} - -const StepOne = ({ nextStep, initialValues, onDataCapture }: IStepOneProps) => { - const { form, onSubmit } = useItem(nextStep, initialValues as any, onDataCapture); - - return ( - <> - -

- Update Item Roll Gacha -

-
- -
-
- - - -
- - -
-
- - ); -}; - -interface IStepTwoProps { - onClose: () => void; - handleUpdateItem?: () => Promise; - resetStep: () => void; -} - -const StepTwo = ({ onClose, handleUpdateItem, resetStep }: IStepTwoProps) => { - const { onConfirm, onCancel } = useConfirmItem( - onClose, - resetStep, - handleUpdateItem, - { - success: 'Perubahan item roll berhasil dilakukan', - error: 'Perubahan item roll gagal dilakukan', - } - ); - - return ( - <> - -

- Update Item -

-

- Apakah kamu yakin dengan -
perubahan yang dilakukan? -

-
- - - - - - ); -}; - -export default ModalUpdateItem; diff --git a/apps/backoffice/src/routes/_authenticated/_components/permissions/modal-add-permission.tsx b/apps/backoffice/src/routes/_authenticated/_components/permissions/modal-add-permission.tsx deleted file mode 100644 index e7857c8..0000000 --- a/apps/backoffice/src/routes/_authenticated/_components/permissions/modal-add-permission.tsx +++ /dev/null @@ -1,135 +0,0 @@ -import { Button } from '@imphnen-frontend-service/ui/atoms'; -import { Modal } from '@imphnen-frontend-service/ui/molecules'; -import { ControlledInputField } from '@imphnen-frontend-service/ui/organisms'; -import { useItem, useConfirmItem } from '../../_hooks/permissions/use-item'; - -interface IModalAddPermission { - isOpen: boolean; - onClose: () => void; - handleAddItem?: () => Promise; - currentStep?: number; - nextStep: () => void; - prevStep: () => void; - resetStep: () => void; - onDataCapture?: (data: any) => void; -} - -const ModalAddPermission = ({ - isOpen, - onClose, - currentStep, - nextStep, - resetStep, - handleAddItem, - onDataCapture, -}: IModalAddPermission) => { - return ( - { - onClose(); - resetStep(); - }} - disableEscapeKeyDown={true} - > - {currentStep === 1 && } - {currentStep === 2 && ( - - )} - - ); -}; - -interface IStepOneProps { - nextStep: () => void; - onClose: () => void; - onDataCapture?: (data: any) => void; -} - -const StepOne = ({ nextStep, onDataCapture }: IStepOneProps) => { - const { form, onSubmit } = useItem(nextStep, undefined, onDataCapture); - - return ( - <> - -

- Tambah Permissions -

-
- -
- - - - -
- - ); -}; - -interface IStepTwoProps { - onClose: () => void; - handleAddItem?: () => Promise; - resetStep: () => void; -} - -const StepTwo = ({ onClose, handleAddItem, resetStep }: IStepTwoProps) => { - const { onConfirm, onCancel } = useConfirmItem( - onClose, - resetStep, - handleAddItem, - { - success: 'Data permissions berhasil ditambahkan', - error: 'Data permissions gagal ditambahkan', - } - ); - - return ( - <> - -

- Tambah Permissions -

-

- Apakah kamu yakin ingin -
menambahkan permission ini? -

-
- - - - - - ); -}; - -export default ModalAddPermission; diff --git a/apps/backoffice/src/routes/_authenticated/_components/permissions/modal-delete-permission.tsx b/apps/backoffice/src/routes/_authenticated/_components/permissions/modal-delete-permission.tsx deleted file mode 100644 index e4d3be3..0000000 --- a/apps/backoffice/src/routes/_authenticated/_components/permissions/modal-delete-permission.tsx +++ /dev/null @@ -1,72 +0,0 @@ -import { Button } from '@imphnen-frontend-service/ui/atoms'; -import { Modal } from '@imphnen-frontend-service/ui/molecules'; -import { useConfirmItem } from '../../_hooks/permissions/use-item'; - -interface IModalDeletePermission { - isOpen: boolean; - onClose: () => void; - handleDelete?: () => Promise; - currentStep?: number; - nextStep: () => void; - prevStep: () => void; - resetStep: () => void; -} - -const ModalDeletePermission = ({ - isOpen, - onClose, - resetStep, - handleDelete, -}: IModalDeletePermission) => { - const { onConfirm } = useConfirmItem(onClose, resetStep, handleDelete, { - success: 'Data permissions berhasil dihapus', - error: 'Data permissions gagal dihapus', - }); - - return ( - - - Delete? -
-

- Delete Permissions -

-

- Apakah kamu yakin untuk menghapus permission ini? Menghapus data ini - mungkin akan mempengaruhi fungsional sistem -

-
-
- - - - -
- ); -}; - -export default ModalDeletePermission; diff --git a/apps/backoffice/src/routes/_authenticated/_components/permissions/modal-update-permission.tsx b/apps/backoffice/src/routes/_authenticated/_components/permissions/modal-update-permission.tsx deleted file mode 100644 index 03ba03a..0000000 --- a/apps/backoffice/src/routes/_authenticated/_components/permissions/modal-update-permission.tsx +++ /dev/null @@ -1,90 +0,0 @@ -import { useEffect } from 'react'; -import { useForm } from 'react-hook-form'; -import { toast } from 'sonner'; -import { Button } from '@imphnen-frontend-service/ui/atoms'; -import { Modal } from '@imphnen-frontend-service/ui/molecules'; -import { ControlledInputField } from '@imphnen-frontend-service/ui/organisms'; - -interface IModalUpdatePermission { - isOpen: boolean; - onClose: () => void; - handleUpdate?: () => Promise; - currentStep?: number; - nextStep: () => void; - prevStep: () => void; - resetStep: () => void; - initialValues?: { name?: string }; - onDataCapture?: (data: any) => void; -} - -const ModalUpdatePermission = ({ - isOpen, - onClose, - resetStep, - handleUpdate, - initialValues, - onDataCapture, -}: IModalUpdatePermission) => { - const form = useForm<{ name: string }>({ - mode: 'all', - defaultValues: initialValues, - }); - - useEffect(() => { - if (isOpen) { - form.reset(initialValues); - } - }, [isOpen, initialValues]); - - const onSubmit = form.handleSubmit(async (data) => { - try { - onDataCapture?.(data); - if (handleUpdate) await handleUpdate(); - toast.success('Perubahan permissions berhasil dilakukan'); - onClose(); - resetStep(); - } catch (error) { - console.log(error); - toast.error('Perubahan permissions gagal dilakukan'); - } - }); - - return ( - - -

- Update Permissions -

-
- -
- - - - -
-
- ); -}; - -export default ModalUpdatePermission; diff --git a/apps/backoffice/src/routes/_authenticated/_components/roles/modal-add-role.tsx b/apps/backoffice/src/routes/_authenticated/_components/roles/modal-add-role.tsx deleted file mode 100644 index 15b96e0..0000000 --- a/apps/backoffice/src/routes/_authenticated/_components/roles/modal-add-role.tsx +++ /dev/null @@ -1,188 +0,0 @@ -import { Button } from '@imphnen-frontend-service/ui/atoms'; -import { Modal } from '@imphnen-frontend-service/ui/molecules'; -import { ControlledInputField } from '@imphnen-frontend-service/ui/organisms'; -import { useItem, useConfirmItem } from '../../_hooks/roles/use-item'; - -interface IModalAddRole { - isOpen: boolean; - onClose: () => void; - handleAdd?: () => Promise; - currentStep?: number; - nextStep: () => void; - prevStep: () => void; - resetStep: () => void; - onDataCapture?: (data: any) => void; -} - -const ModalAddRole = ({ - isOpen, - onClose, - currentStep, - nextStep, - resetStep, - handleAdd, - onDataCapture, -}: IModalAddRole) => { - return ( - { - onClose(); - resetStep(); - }} - disableEscapeKeyDown={true} - > - {currentStep === 1 && } - {currentStep === 2 && ( - - )} - - ); -}; - -interface IStepOneProps { - nextStep: () => void; - onClose: () => void; - onDataCapture?: (data: any) => void; -} - -const StepOne = ({ nextStep, onDataCapture }: IStepOneProps) => { - const { form, onSubmit } = useItem(nextStep, undefined, onDataCapture); - - return ( - <> - -

- Tambah Roles -

-
- -
-
- -
- -
- - Permissions - -
- {[ - 'Gacha Items', - 'Gacha Roll', - 'Roll', - 'Users', - 'Gacha Claim', - ].map((title) => ( -
- {title} -
- - -
-
-
-
- - -
-
- - -
-
- - -
-
- - -
-
-
- ))} -
-
- - -
-
- - ); -}; - -interface IStepTwoProps { - onClose: () => void; - handleAdd?: () => Promise; - resetStep: () => void; -} - -const StepTwo = ({ onClose, handleAdd, resetStep }: IStepTwoProps) => { - const { onConfirm, onCancel } = useConfirmItem( - onClose, - resetStep, - handleAdd, - { - success: 'Data role berhasil ditambahkan', - error: 'Data role gagal ditambahkan', - } - ); - - return ( - <> - -

- Tambah Roles -

-

- Apakah kamu yakin ingin -
menambahkan role ini? -

-
- - - - - - ); -}; - -export default ModalAddRole; diff --git a/apps/backoffice/src/routes/_authenticated/_components/roles/modal-delete-role.tsx b/apps/backoffice/src/routes/_authenticated/_components/roles/modal-delete-role.tsx deleted file mode 100644 index 39a61e9..0000000 --- a/apps/backoffice/src/routes/_authenticated/_components/roles/modal-delete-role.tsx +++ /dev/null @@ -1,72 +0,0 @@ -import { Button } from '@imphnen-frontend-service/ui/atoms'; -import { Modal } from '@imphnen-frontend-service/ui/molecules'; -import { useConfirmItem } from '../../_hooks/roles/use-item'; - -interface IModalDeletePermission { - isOpen: boolean; - onClose: () => void; - handleDelete?: () => Promise; - currentStep?: number; - nextStep: () => void; - prevStep: () => void; - resetStep: () => void; -} - -const ModalDeletePermission = ({ - isOpen, - onClose, - resetStep, - handleDelete, -}: IModalDeletePermission) => { - const { onConfirm } = useConfirmItem(onClose, resetStep, handleDelete, { - success: 'Data roles berhasil dihapus', - error: 'Data roles gagal dihapus', - }); - - return ( - - - Delete? -
-

- Delete Roles -

-

- Apakah kamu yakin untuk menghapus role ini? Menghapus data ini - mungkin akan mempengaruhi fungsional sistem -

-
-
- - - - -
- ); -}; - -export default ModalDeletePermission; diff --git a/apps/backoffice/src/routes/_authenticated/_components/roles/modal-update-role.tsx b/apps/backoffice/src/routes/_authenticated/_components/roles/modal-update-role.tsx deleted file mode 100644 index 791a3d9..0000000 --- a/apps/backoffice/src/routes/_authenticated/_components/roles/modal-update-role.tsx +++ /dev/null @@ -1,139 +0,0 @@ -import { useEffect } from 'react'; -import { useForm } from 'react-hook-form'; -import { toast } from 'sonner'; -import { Button } from '@imphnen-frontend-service/ui/atoms'; -import { Modal } from '@imphnen-frontend-service/ui/molecules'; -import { ControlledInputField } from '@imphnen-frontend-service/ui/organisms'; - -interface IModalUpdateRole { - isOpen: boolean; - onClose: () => void; - handleUpdate?: () => Promise; - currentStep?: number; - nextStep: () => void; - prevStep: () => void; - resetStep: () => void; - initialValues?: { name?: string }; - onDataCapture?: (data: any) => void; -} - -const ModalUpdateRole = ({ - isOpen, - onClose, - resetStep, - handleUpdate, - initialValues, - onDataCapture, -}: IModalUpdateRole) => { - const form = useForm<{ name: string }>({ - mode: 'all', - defaultValues: initialValues, - }); - - useEffect(() => { - if (isOpen) { - form.reset(initialValues); - } - }, [isOpen, initialValues]); - - const onSubmit = form.handleSubmit(async (data) => { - try { - onDataCapture?.(data); - if (handleUpdate) await handleUpdate(); - toast.success('Perubahan roles berhasil dilakukan'); - onClose(); - resetStep(); - } catch (error) { - console.log(error); - toast.error('Perubahan roles gagal dilakukan'); - } - }); - - return ( - - -

- Update Roles -

-
- -
-
- -
- -
- - Permissions - -
- {['Gacha Items', 'Gacha Roll', 'Roll', 'Users', 'Gacha Claim'].map( - (title) => ( -
- {title} -
- - -
-
-
-
- - -
-
- - -
-
- - -
-
- - -
-
-
- ) - )} -
-
- - -
-
-
- ); -}; - -export default ModalUpdateRole; diff --git a/apps/backoffice/src/routes/_authenticated/accounts.tsx b/apps/backoffice/src/routes/_authenticated/accounts.tsx index 9ceba49..fba1fad 100644 --- a/apps/backoffice/src/routes/_authenticated/accounts.tsx +++ b/apps/backoffice/src/routes/_authenticated/accounts.tsx @@ -1,6 +1,6 @@ -import { createFileRoute } from '@tanstack/react-router' +import { createFileRoute, useNavigate } from '@tanstack/react-router' import * as React from 'react' -import { FC, Fragment, ReactElement, useRef, useState } from 'react' +import { Fragment, useState } from 'react' import { FilterOutlined, SearchOutlined, @@ -16,11 +16,8 @@ import { useReactTable, RowSelectionState, } from '@tanstack/react-table' -import ModalEditAccount from './_components/accounts/modal-edit-account' -import { useQueryState } from '@imphnen-frontend-service/utils' import { useUserList, - useUpdateUserById, TUsersListItem, } from '@imphnen-frontend-service/service' @@ -29,21 +26,8 @@ export const Route = createFileRoute('/_authenticated/accounts')({ }) function AccountsPage() { - const [showModalEditAccount, setShowModalEditAccount] = useState(false) - const [selectedUser, setSelectedUser] = useState(null) + const navigate = useNavigate() const [search, setSearch] = useState('') - const pendingFormData = useRef(null) - - const { - step: currentStep, - nextStep, - prevStep, - resetStep, - } = useQueryState('step', { - defaultValue: 1, - maxValue: 2, - minValue: 1, - }) const [pagination, setPagination] = React.useState({ pageIndex: 0, @@ -58,17 +42,10 @@ function AccountsPage() { page: pagination.pageIndex + 1, per_page: pagination.pageSize, }) - const updateUser = useUpdateUserById() const users: TUsersListItem[] = usersData?.data ?? [] const totalItems = usersData?.meta?.total ?? users.length - const handleEditAccount = async () => { - if (selectedUser && pendingFormData.current) { - await updateUser.mutateAsync({ id: selectedUser.id, data: pendingFormData.current }) - } - } - const columns: ColumnDef[] = [ { id: 'select', @@ -122,8 +99,7 @@ function AccountsPage() { size="sm" onClick={(e) => { e.stopPropagation() - setSelectedUser(row.original) - setShowModalEditAccount(true) + navigate({ to: '/accounts/$id', params: { id: row.original.id } }) }} className="flex items-center gap-2" > @@ -193,18 +169,6 @@ function AccountsPage() { )} - - setShowModalEditAccount(false)} - handleEditAccount={handleEditAccount} - nextStep={nextStep} - prevStep={prevStep} - resetStep={resetStep} - initialValues={selectedUser ? { fullname: selectedUser.fullname, email: selectedUser.email } : undefined} - onDataCapture={(data) => { pendingFormData.current = data }} - /> ) } diff --git a/apps/backoffice/src/routes/_authenticated/accounts_/$id.tsx b/apps/backoffice/src/routes/_authenticated/accounts_/$id.tsx new file mode 100644 index 0000000..9b66c5e --- /dev/null +++ b/apps/backoffice/src/routes/_authenticated/accounts_/$id.tsx @@ -0,0 +1,110 @@ +import { createFileRoute, useNavigate } from '@tanstack/react-router' +import { useEffect, useState } from 'react' +import { toast } from 'sonner' +import { ArrowLeftOutlined } from '@ant-design/icons' +import { Button } from '@imphnen-frontend-service/ui/atoms' +import { InputField } from '@imphnen-frontend-service/ui/molecules' +import { + useUserList, + useUpdateUserById, +} from '@imphnen-frontend-service/service' + +export const Route = createFileRoute('/_authenticated/accounts/$id')({ + component: AccountsEditPage, +}) + +function AccountsEditPage() { + const { id } = Route.useParams() + const navigate = useNavigate() + const updateUser = useUpdateUserById() + + const { data: usersData, isLoading } = useUserList({ search: '', per_page: 100 }) + const user = usersData?.data?.find((u) => u.id === id) + + const [fullName, setFullName] = useState('') + const [email, setEmail] = useState('') + + useEffect(() => { + if (user) { + setFullName(user.fullname) + setEmail(user.email) + } + }, [user]) + + const handleSubmit = async () => { + try { + await updateUser.mutateAsync({ id, data: { fullname: fullName, email } }) + toast.success('Data akun berhasil diperbarui') + navigate({ to: '/accounts' }) + } catch (error) { + console.log(error) + toast.error('Data akun gagal diperbarui') + } + } + + if (isLoading) { + return ( +
+
Loading...
+
+ ) + } + + return ( +
+
+
+ +

Edit Data Akun

+
+ +
+
+ setFullName(e.target.value)} + size="lg" + className="w-full" + /> + setEmail(e.target.value)} + size="lg" + className="w-full" + /> + +
+ + +
+
+
+
+
+ ) +} diff --git a/apps/backoffice/src/routes/_authenticated/cms-events.tsx b/apps/backoffice/src/routes/_authenticated/cms-events.tsx index 6f30977..99563ad 100644 --- a/apps/backoffice/src/routes/_authenticated/cms-events.tsx +++ b/apps/backoffice/src/routes/_authenticated/cms-events.tsx @@ -1,5 +1,5 @@ -import { createFileRoute } from '@tanstack/react-router' -import { FC, Fragment, ReactElement, useRef, useState } from 'react' +import { createFileRoute, useNavigate } from '@tanstack/react-router' +import { Fragment, useState } from 'react' import { SearchOutlined, EditOutlined, @@ -16,41 +16,22 @@ import { RowSelectionState, useReactTable, } from '@tanstack/react-table' -import ModalAddEvent from './_components/cms-events/modal-add-event' -import ModalUpdateEvent from './_components/cms-events/modal-update-event' -import ModalDeleteEvent from './_components/cms-events/modal-delete-event' -import { useQueryState } from '@imphnen-frontend-service/utils' import { useEventList, - useCreateEvent, - useUpdateEvent, useDeleteEvent, TEventsListItem, } from '@imphnen-frontend-service/service' import React from 'react' +import { toast } from 'sonner' export const Route = createFileRoute('/_authenticated/cms-events')({ component: CmsEventsPage, }) function CmsEventsPage() { - const [showModalAddItem, setShowModalAddItem] = useState(false) - const [showModalUpdateItem, setShowModalUpdateItem] = useState(false) - const [showModalDeleteItem, setShowModalDeleteItem] = useState(false) - const [selectedEvent, setSelectedEvent] = useState(null) + const navigate = useNavigate() const [search, setSearch] = useState('') - const pendingFormData = useRef(null) - - const { - step: currentStep, - nextStep, - prevStep, - resetStep, - } = useQueryState('step', { - defaultValue: 1, - maxValue: 2, - minValue: 1, - }) + const [deleteId, setDeleteId] = useState(null) const [pagination, setPagination] = React.useState({ pageIndex: 0, @@ -64,32 +45,20 @@ function CmsEventsPage() { page: pagination.pageIndex + 1, per_page: pagination.pageSize, }) - const createEvent = useCreateEvent() - const updateEvent = useUpdateEvent() const deleteEvent = useDeleteEvent() const events: TEventsListItem[] = eventsData?.data ?? [] const totalItems = eventsData?.meta?.total ?? events.length - const handleAdd = async (): Promise => { - if (pendingFormData.current) { - await createEvent.mutateAsync(pendingFormData.current) + const handleDelete = async (id: string) => { + try { + await deleteEvent.mutateAsync(id) + toast.success('Data event berhasil dihapus') + setDeleteId(null) + } catch (error) { + console.log(error) + toast.error('Data event gagal dihapus') } - return true - } - - const handleUpdate = async (): Promise => { - if (selectedEvent && pendingFormData.current) { - await updateEvent.mutateAsync({ id: selectedEvent.id, data: pendingFormData.current }) - } - return true - } - - const handleDelete = async (): Promise => { - if (selectedEvent) { - await deleteEvent.mutateAsync(selectedEvent.id) - } - return true } const columns: ColumnDef[] = [ @@ -163,25 +132,49 @@ function CmsEventsPage() { size="sm" onClick={(e) => { e.stopPropagation() - setSelectedEvent(row.original) - setShowModalUpdateItem(true) + navigate({ to: '/cms-events/$id', params: { id: row.original.id } }) }} className="flex items-center gap-2" > Update - + {deleteId === row.original.id ? ( +
+ Yakin? + + +
+ ) : ( + + )} ), }, @@ -228,7 +221,7 @@ function CmsEventsPage() { variant="primary" size="md" className="flex gap-3 text-nowrap" - onClick={() => setShowModalAddItem(true)} + onClick={() => navigate({ to: '/cms-events/create' })} > Tambah Event @@ -248,44 +241,6 @@ function CmsEventsPage() { )} - - setShowModalAddItem(false)} - nextStep={nextStep} - prevStep={prevStep} - resetStep={resetStep} - handleAdd={handleAdd} - onDataCapture={(data) => { pendingFormData.current = data }} - /> - setShowModalUpdateItem(false)} - nextStep={nextStep} - prevStep={prevStep} - resetStep={resetStep} - handleUpdate={handleUpdate} - initialValues={selectedEvent ? { - name: selectedEvent.name, - description: selectedEvent.description, - detail_link: selectedEvent.detail_link, - location: selectedEvent.location, - price: selectedEvent.price, - start_date: selectedEvent.start_date, - end_date: selectedEvent.end_date, - is_online: selectedEvent.is_online, - } : undefined} - onDataCapture={(data) => { pendingFormData.current = data }} - /> - setShowModalDeleteItem(false)} - nextStep={nextStep} - prevStep={prevStep} - resetStep={resetStep} - handleDelete={handleDelete} - /> ) } diff --git a/apps/backoffice/src/routes/_authenticated/cms-events_/$id.tsx b/apps/backoffice/src/routes/_authenticated/cms-events_/$id.tsx new file mode 100644 index 0000000..6e5cac2 --- /dev/null +++ b/apps/backoffice/src/routes/_authenticated/cms-events_/$id.tsx @@ -0,0 +1,195 @@ +import { createFileRoute, useNavigate } from '@tanstack/react-router' +import { useEffect } from 'react' +import { useForm } from 'react-hook-form' +import { toast } from 'sonner' +import { ArrowLeftOutlined } from '@ant-design/icons' +import { Button } from '@imphnen-frontend-service/ui/atoms' +import { ControlledInputField } from '@imphnen-frontend-service/ui/organisms' +import { + useEventList, + useUpdateEvent, +} from '@imphnen-frontend-service/service' + +export const Route = createFileRoute('/_authenticated/cms-events/$id')({ + component: CmsEventsEditPage, +}) + +function CmsEventsEditPage() { + const { id } = Route.useParams() + const navigate = useNavigate() + const updateEvent = useUpdateEvent() + + const { data: eventsData, isLoading } = useEventList({ search: '', per_page: 100 }) + const event = eventsData?.data?.find((e) => e.id === id) + + const form = useForm<{ + name: string + description: string + detail_link: string + location: string + price: number + start_date: string + end_date: string + is_online: boolean + }>({ + mode: 'all', + defaultValues: { + name: '', + description: '', + detail_link: '', + location: '', + price: 0, + start_date: '', + end_date: '', + is_online: false, + }, + }) + + useEffect(() => { + if (event) { + form.reset({ + name: event.name, + description: event.description, + detail_link: event.detail_link, + location: event.location, + price: event.price, + start_date: event.start_date, + end_date: event.end_date, + is_online: event.is_online, + }) + } + }, [event]) + + const onSubmit = form.handleSubmit(async (data) => { + try { + await updateEvent.mutateAsync({ id, data }) + toast.success('Perubahan event berhasil dilakukan') + navigate({ to: '/cms-events' }) + } catch (error) { + console.log(error) + toast.error('Perubahan event gagal dilakukan') + } + }) + + if (isLoading) { + return ( +
+
Loading...
+
+ ) + } + + return ( +
+
+
+ +

Edit Event

+
+ +
+
+ + + + + + + +
+ + +
+ +
+ + +
+ +
+
+
+ ) +} diff --git a/apps/backoffice/src/routes/_authenticated/cms-events_/create.tsx b/apps/backoffice/src/routes/_authenticated/cms-events_/create.tsx new file mode 100644 index 0000000..3a48019 --- /dev/null +++ b/apps/backoffice/src/routes/_authenticated/cms-events_/create.tsx @@ -0,0 +1,164 @@ +import { createFileRoute, useNavigate } from '@tanstack/react-router' +import { useForm } from 'react-hook-form' +import { toast } from 'sonner' +import { ArrowLeftOutlined } from '@ant-design/icons' +import { Button } from '@imphnen-frontend-service/ui/atoms' +import { ControlledInputField } from '@imphnen-frontend-service/ui/organisms' +import { useCreateEvent } from '@imphnen-frontend-service/service' + +export const Route = createFileRoute('/_authenticated/cms-events/create')({ + component: CmsEventsCreatePage, +}) + +function CmsEventsCreatePage() { + const navigate = useNavigate() + const createEvent = useCreateEvent() + + const form = useForm<{ + name: string + description: string + detail_link: string + location: string + price: number + start_date: string + end_date: string + is_online: boolean + }>({ + mode: 'all', + defaultValues: { + name: '', + description: '', + detail_link: '', + location: '', + price: 0, + start_date: '', + end_date: '', + is_online: false, + }, + }) + + const onSubmit = form.handleSubmit(async (data) => { + try { + await createEvent.mutateAsync(data) + toast.success('Data event berhasil ditambahkan') + navigate({ to: '/cms-events' }) + } catch (error) { + console.log(error) + toast.error('Data event gagal ditambahkan') + } + }) + + return ( +
+
+
+ +

Tambah Event

+
+ +
+
+ + + + + + + +
+ + +
+ +
+ + +
+ +
+
+
+ ) +} diff --git a/apps/backoffice/src/routes/_authenticated/cms-testimonials.tsx b/apps/backoffice/src/routes/_authenticated/cms-testimonials.tsx index 7122624..6702a6d 100644 --- a/apps/backoffice/src/routes/_authenticated/cms-testimonials.tsx +++ b/apps/backoffice/src/routes/_authenticated/cms-testimonials.tsx @@ -1,5 +1,5 @@ -import { createFileRoute } from '@tanstack/react-router' -import { FC, Fragment, ReactElement, useRef, useState } from 'react' +import { createFileRoute, useNavigate } from '@tanstack/react-router' +import { Fragment, useState } from 'react' import { SearchOutlined, EditOutlined, @@ -16,41 +16,22 @@ import { RowSelectionState, useReactTable, } from '@tanstack/react-table' -import ModalAddTestimonial from './_components/cms-testimonials/modal-add-testimonial' -import ModalUpdateTestimonial from './_components/cms-testimonials/modal-update-testimonial' -import ModalDeleteTestimonial from './_components/cms-testimonials/modal-delete-testimonial' -import { useQueryState } from '@imphnen-frontend-service/utils' import { useTestimonialList, - useCreateTestimonial, - useUpdateTestimonial, useDeleteTestimonial, TTestimonialsListItem, } from '@imphnen-frontend-service/service' import React from 'react' +import { toast } from 'sonner' export const Route = createFileRoute('/_authenticated/cms-testimonials')({ component: CmsTestimonialsPage, }) function CmsTestimonialsPage() { - const [showModalAddItem, setShowModalAddItem] = useState(false) - const [showModalUpdateItem, setShowModalUpdateItem] = useState(false) - const [showModalDeleteItem, setShowModalDeleteItem] = useState(false) - const [selectedTestimonial, setSelectedTestimonial] = useState(null) + const navigate = useNavigate() const [search, setSearch] = useState('') - const pendingFormData = useRef(null) - - const { - step: currentStep, - nextStep, - prevStep, - resetStep, - } = useQueryState('step', { - defaultValue: 1, - maxValue: 2, - minValue: 1, - }) + const [deleteId, setDeleteId] = useState(null) const [pagination, setPagination] = React.useState({ pageIndex: 0, @@ -64,32 +45,20 @@ function CmsTestimonialsPage() { page: pagination.pageIndex + 1, per_page: pagination.pageSize, }) - const createTestimonial = useCreateTestimonial() - const updateTestimonial = useUpdateTestimonial() const deleteTestimonial = useDeleteTestimonial() const testimonials: TTestimonialsListItem[] = testimonialsData?.data ?? [] const totalItems = testimonialsData?.meta?.total ?? testimonials.length - const handleAdd = async (): Promise => { - if (pendingFormData.current) { - await createTestimonial.mutateAsync(pendingFormData.current) + const handleDelete = async (id: string) => { + try { + await deleteTestimonial.mutateAsync(id) + toast.success('Data testimonial berhasil dihapus') + setDeleteId(null) + } catch (error) { + console.log(error) + toast.error('Data testimonial gagal dihapus') } - return true - } - - const handleUpdate = async (): Promise => { - if (selectedTestimonial && pendingFormData.current) { - await updateTestimonial.mutateAsync({ id: selectedTestimonial.id, data: pendingFormData.current }) - } - return true - } - - const handleDelete = async (): Promise => { - if (selectedTestimonial) { - await deleteTestimonial.mutateAsync(selectedTestimonial.id) - } - return true } const columns: ColumnDef[] = [ @@ -147,25 +116,49 @@ function CmsTestimonialsPage() { size="sm" onClick={(e) => { e.stopPropagation() - setSelectedTestimonial(row.original) - setShowModalUpdateItem(true) + navigate({ to: '/cms-testimonials/$id', params: { id: row.original.id } }) }} className="flex items-center gap-2" > Update - + {deleteId === row.original.id ? ( +
+ Yakin? + + +
+ ) : ( + + )} ), }, @@ -212,7 +205,7 @@ function CmsTestimonialsPage() { variant="primary" size="md" className="flex gap-3 text-nowrap" - onClick={() => setShowModalAddItem(true)} + onClick={() => navigate({ to: '/cms-testimonials/create' })} > Tambah Testimonial @@ -232,38 +225,6 @@ function CmsTestimonialsPage() { )} - - setShowModalAddItem(false)} - nextStep={nextStep} - prevStep={prevStep} - resetStep={resetStep} - handleAdd={handleAdd} - onDataCapture={(data) => { pendingFormData.current = data }} - /> - setShowModalUpdateItem(false)} - nextStep={nextStep} - prevStep={prevStep} - resetStep={resetStep} - handleUpdate={handleUpdate} - initialValues={selectedTestimonial ? { - role: selectedTestimonial.role, - content: selectedTestimonial.content, - } : undefined} - onDataCapture={(data) => { pendingFormData.current = data }} - /> - setShowModalDeleteItem(false)} - nextStep={nextStep} - prevStep={prevStep} - resetStep={resetStep} - handleDelete={handleDelete} - /> ) } diff --git a/apps/backoffice/src/routes/_authenticated/cms-testimonials_/$id.tsx b/apps/backoffice/src/routes/_authenticated/cms-testimonials_/$id.tsx new file mode 100644 index 0000000..65000f8 --- /dev/null +++ b/apps/backoffice/src/routes/_authenticated/cms-testimonials_/$id.tsx @@ -0,0 +1,115 @@ +import { createFileRoute, useNavigate } from '@tanstack/react-router' +import { useEffect } from 'react' +import { useForm } from 'react-hook-form' +import { toast } from 'sonner' +import { ArrowLeftOutlined } from '@ant-design/icons' +import { Button } from '@imphnen-frontend-service/ui/atoms' +import { ControlledInputField } from '@imphnen-frontend-service/ui/organisms' +import { + useTestimonialList, + useUpdateTestimonial, +} from '@imphnen-frontend-service/service' + +export const Route = createFileRoute('/_authenticated/cms-testimonials/$id')({ + component: CmsTestimonialsEditPage, +}) + +function CmsTestimonialsEditPage() { + const { id } = Route.useParams() + const navigate = useNavigate() + const updateTestimonial = useUpdateTestimonial() + + const { data: testimonialsData, isLoading } = useTestimonialList({ search: '', per_page: 100 }) + const testimonial = testimonialsData?.data?.find((t) => t.id === id) + + const form = useForm<{ role: string; content: string }>({ + mode: 'all', + defaultValues: { role: '', content: '' }, + }) + + useEffect(() => { + if (testimonial) { + form.reset({ + role: testimonial.role, + content: testimonial.content, + }) + } + }, [testimonial]) + + const onSubmit = form.handleSubmit(async (data) => { + try { + await updateTestimonial.mutateAsync({ id, data }) + toast.success('Perubahan testimonial berhasil dilakukan') + navigate({ to: '/cms-testimonials' }) + } catch (error) { + console.log(error) + toast.error('Perubahan testimonial gagal dilakukan') + } + }) + + if (isLoading) { + return ( +
+
Loading...
+
+ ) + } + + return ( +
+
+
+ +

Edit Testimonial

+
+ +
+
+ + + +
+ + +
+ +
+
+
+ ) +} diff --git a/apps/backoffice/src/routes/_authenticated/cms-testimonials_/create.tsx b/apps/backoffice/src/routes/_authenticated/cms-testimonials_/create.tsx new file mode 100644 index 0000000..fb7fd78 --- /dev/null +++ b/apps/backoffice/src/routes/_authenticated/cms-testimonials_/create.tsx @@ -0,0 +1,90 @@ +import { createFileRoute, useNavigate } from '@tanstack/react-router' +import { useForm } from 'react-hook-form' +import { toast } from 'sonner' +import { ArrowLeftOutlined } from '@ant-design/icons' +import { Button } from '@imphnen-frontend-service/ui/atoms' +import { ControlledInputField } from '@imphnen-frontend-service/ui/organisms' +import { useCreateTestimonial } from '@imphnen-frontend-service/service' + +export const Route = createFileRoute('/_authenticated/cms-testimonials/create')({ + component: CmsTestimonialsCreatePage, +}) + +function CmsTestimonialsCreatePage() { + const navigate = useNavigate() + const createTestimonial = useCreateTestimonial() + + const form = useForm<{ role: string; content: string }>({ + mode: 'all', + defaultValues: { role: '', content: '' }, + }) + + const onSubmit = form.handleSubmit(async (data) => { + try { + await createTestimonial.mutateAsync(data) + toast.success('Data testimonial berhasil ditambahkan') + navigate({ to: '/cms-testimonials' }) + } catch (error) { + console.log(error) + toast.error('Data testimonial gagal ditambahkan') + } + }) + + return ( +
+
+
+ +

Tambah Testimonial

+
+ +
+
+ + + +
+ + +
+ +
+
+
+ ) +} diff --git a/apps/backoffice/src/routes/_authenticated/dashboard.tsx b/apps/backoffice/src/routes/_authenticated/dashboard.tsx index c830069..1e45a52 100644 --- a/apps/backoffice/src/routes/_authenticated/dashboard.tsx +++ b/apps/backoffice/src/routes/_authenticated/dashboard.tsx @@ -1,92 +1,46 @@ -import { createFileRoute } from '@tanstack/react-router' +import { createFileRoute, useNavigate } from '@tanstack/react-router' import { PlusOutlined, ReloadOutlined, UsergroupAddOutlined, UsergroupDeleteOutlined, UserSwitchOutlined, + DeleteOutlined, } from '@ant-design/icons' import { Button } from '@imphnen-frontend-service/ui/atoms' -import { FC, Fragment, ReactElement, useRef, useState } from 'react' -import ModalAddItem from './_components/dashboard/modal-add-item' -import ModalEditItem from './_components/dashboard/modal-edit-item' -import ModalDeleteItem from './_components/dashboard/modal-delete-item' -import { useQueryState } from '@imphnen-frontend-service/utils' +import { Fragment, useState } from 'react' import { useUserList, useGachaItemList, - useCreateGachaItem, - useUpdateGachaItem, useDeleteGachaItem, TGachaItemDto, } from '@imphnen-frontend-service/service' +import { toast } from 'sonner' export const Route = createFileRoute('/_authenticated/dashboard')({ component: DashboardPage, }) function DashboardPage() { - const [showModalAddItem, setShowModalAddItem] = useState(false) - const [showModalEditItem, setShowModalEditItem] = useState(false) - const [showModalDeleteItem, setShowModalDeleteItem] = useState(false) - const [selectedItem, setSelectedItem] = useState(null) - const pendingFormData = useRef(null) - - const { - step: currentStep, - nextStep, - prevStep, - resetStep, - } = useQueryState('step', { - defaultValue: 1, - maxValue: 2, - minValue: 1, - }) + const navigate = useNavigate() + const [deleteId, setDeleteId] = useState(null) const { data: usersData } = useUserList({ per_page: 1 }) const { data: gachaItemsData } = useGachaItemList({ per_page: 9 }) - const createItem = useCreateGachaItem() - const updateItem = useUpdateGachaItem() const deleteItem = useDeleteGachaItem() const totalUsers = usersData?.meta?.total ?? 0 const gachaItems: TGachaItemDto[] = gachaItemsData?.data ?? [] - const handleAdd = async (): Promise => { - if (pendingFormData.current) { - const { itemName, quantity } = pendingFormData.current - await createItem.mutateAsync({ - item_code: (itemName as string).toLowerCase().replace(/\s+/g, '-'), - name: itemName, - description: '', - rarity: 'common', - type_: 'physical', - category: 'merchandise', - value: 0, - weight: 1, - stock: quantity ?? 1, - is_limited: false, - }) + const handleDelete = async (id: string) => { + try { + await deleteItem.mutateAsync(id) + toast.success('Item berhasil dihapus') + setDeleteId(null) + } catch (error) { + console.log(error) + toast.error('Item gagal dihapus') } - return true - } - - const handleEdit = async (): Promise => { - if (selectedItem && pendingFormData.current) { - const { itemName, quantity } = pendingFormData.current - await updateItem.mutateAsync({ - id: selectedItem.id, - data: { name: itemName, stock: quantity }, - }) - } - return true - } - - const handleDelete = async (): Promise => { - if (selectedItem) { - await deleteItem.mutateAsync(selectedItem.id) - } - return true } return ( @@ -158,7 +112,7 @@ function DashboardPage() { variant="primary" size="sm" className="items-end gap-3" - onClick={() => setShowModalAddItem(true)} + onClick={() => navigate({ to: '/dashboard/create' })} > Tambah Item @@ -185,24 +139,40 @@ function DashboardPage() { variant="text" size="sm" className="text-[10px] text-neutral-500 p-0 font-normal hover:bg-transparent hover:text-primary-500" - onClick={() => { - setSelectedItem(item) - setShowModalEditItem(true) - }} + onClick={() => navigate({ to: '/dashboard/$id', params: { id: item.id } })} > Edit - + {deleteId === item.id ? ( +
+ Yakin? + + +
+ ) : ( + + )} @@ -220,35 +190,6 @@ function DashboardPage() { /> - - setShowModalAddItem(false)} - nextStep={nextStep} - prevStep={prevStep} - resetStep={resetStep} - handleAddItem={handleAdd} - onDataCapture={(data) => { pendingFormData.current = data }} - /> - - setShowModalEditItem(false)} - nextStep={nextStep} - prevStep={prevStep} - resetStep={resetStep} - handleEditItem={handleEdit} - initialValues={selectedItem ? { itemName: selectedItem.name } : undefined} - onDataCapture={(data) => { pendingFormData.current = data }} - /> - - setShowModalDeleteItem(false)} - handleDeleteItem={async () => { await handleDelete(); return true }} - /> ) } diff --git a/apps/backoffice/src/routes/_authenticated/dashboard_/$id.tsx b/apps/backoffice/src/routes/_authenticated/dashboard_/$id.tsx new file mode 100644 index 0000000..29344e5 --- /dev/null +++ b/apps/backoffice/src/routes/_authenticated/dashboard_/$id.tsx @@ -0,0 +1,124 @@ +import { createFileRoute, useNavigate } from '@tanstack/react-router' +import { useEffect } from 'react' +import { useForm } from 'react-hook-form' +import { toast } from 'sonner' +import { ArrowLeftOutlined } from '@ant-design/icons' +import { Button } from '@imphnen-frontend-service/ui/atoms' +import { ControlledInputField } from '@imphnen-frontend-service/ui/organisms' +import { + useGachaItemList, + useUpdateGachaItem, +} from '@imphnen-frontend-service/service' + +export const Route = createFileRoute('/_authenticated/dashboard/$id')({ + component: DashboardEditPage, +}) + +function DashboardEditPage() { + const { id } = Route.useParams() + const navigate = useNavigate() + const updateItem = useUpdateGachaItem() + + const { data: gachaItemsData, isLoading } = useGachaItemList({ per_page: 100 }) + const item = gachaItemsData?.data?.find((i) => i.id === id) + + const form = useForm<{ itemName: string; quantity: number; foto?: FileList }>({ + mode: 'all', + defaultValues: { itemName: '', quantity: 1 }, + }) + + useEffect(() => { + if (item) { + form.reset({ itemName: item.name, quantity: item.stock }) + } + }, [item]) + + const onSubmit = form.handleSubmit(async (data) => { + try { + await updateItem.mutateAsync({ + id, + data: { name: data.itemName, stock: data.quantity }, + }) + toast.success('Perubahan item berhasil dilakukan') + navigate({ to: '/dashboard' }) + } catch (error) { + console.log(error) + toast.error('Perubahan item gagal dilakukan') + } + }) + + if (isLoading) { + return ( +
+
Loading...
+
+ ) + } + + return ( +
+
+
+ +

Edit Item Gacha

+
+ +
+
+ + + + +
+ + +
+ +
+
+
+ ) +} diff --git a/apps/backoffice/src/routes/_authenticated/dashboard_/create.tsx b/apps/backoffice/src/routes/_authenticated/dashboard_/create.tsx new file mode 100644 index 0000000..e8d0d1a --- /dev/null +++ b/apps/backoffice/src/routes/_authenticated/dashboard_/create.tsx @@ -0,0 +1,111 @@ +import { createFileRoute, useNavigate } from '@tanstack/react-router' +import { useForm } from 'react-hook-form' +import { toast } from 'sonner' +import { ArrowLeftOutlined } from '@ant-design/icons' +import { Button } from '@imphnen-frontend-service/ui/atoms' +import { ControlledInputField } from '@imphnen-frontend-service/ui/organisms' +import { useCreateGachaItem } from '@imphnen-frontend-service/service' + +export const Route = createFileRoute('/_authenticated/dashboard/create')({ + component: DashboardCreatePage, +}) + +function DashboardCreatePage() { + const navigate = useNavigate() + const createItem = useCreateGachaItem() + + const form = useForm<{ itemName: string; quantity: number; foto?: FileList }>({ + mode: 'all', + defaultValues: { itemName: '', quantity: 1 }, + }) + + const onSubmit = form.handleSubmit(async (data) => { + try { + await createItem.mutateAsync({ + item_code: (data.itemName as string).toLowerCase().replace(/\s+/g, '-'), + name: data.itemName, + description: '', + rarity: 'common', + type_: 'physical', + category: 'merchandise', + value: 0, + weight: 1, + stock: data.quantity ?? 1, + is_limited: false, + }) + toast.success('Item ditambahkan ke gacha item') + navigate({ to: '/dashboard' }) + } catch (error) { + console.log(error) + toast.error('Item gagal ditambahkan ke gacha item') + } + }) + + return ( +
+
+
+ +

Tambah Item Gacha

+
+ +
+
+ + + + +
+ + +
+ +
+
+
+ ) +} diff --git a/apps/backoffice/src/routes/_authenticated/gacha-roll.tsx b/apps/backoffice/src/routes/_authenticated/gacha-roll.tsx index f281214..b4fb439 100644 --- a/apps/backoffice/src/routes/_authenticated/gacha-roll.tsx +++ b/apps/backoffice/src/routes/_authenticated/gacha-roll.tsx @@ -1,6 +1,6 @@ -import { createFileRoute } from '@tanstack/react-router' +import { createFileRoute, useNavigate } from '@tanstack/react-router' import * as React from 'react' -import { FC, Fragment, ReactElement, useRef, useState } from 'react' +import { Fragment, useState } from 'react' import { SearchOutlined, EditOutlined, @@ -17,40 +17,21 @@ import { useReactTable, RowSelectionState, } from '@tanstack/react-table' -import ModalAddItem from './_components/gacha-roll/modal-add-item' -import ModalUpdateItem from './_components/gacha-roll/modal-update-item' -import ModalDeleteItem from './_components/gacha-roll/modal-delete-item' -import { useQueryState } from '@imphnen-frontend-service/utils' import { useGachaItemList, - useCreateGachaItem, - useUpdateGachaItem, useDeleteGachaItem, TGachaItemDto, } from '@imphnen-frontend-service/service' +import { toast } from 'sonner' export const Route = createFileRoute('/_authenticated/gacha-roll')({ component: GachaRollPage, }) function GachaRollPage() { - const [showModalAddItem, setShowModalAddItem] = useState(false) - const [showModalUpdateItem, setShowModalUpdateItem] = useState(false) - const [showModalDeleteItem, setShowModalDeleteItem] = useState(false) - const [selectedItem, setSelectedItem] = useState(null) + const navigate = useNavigate() const [search, setSearch] = useState('') - const pendingFormData = useRef(null) - - const { - step: currentStep, - nextStep, - prevStep, - resetStep, - } = useQueryState('step', { - defaultValue: 1, - maxValue: 2, - minValue: 1, - }) + const [deleteId, setDeleteId] = useState(null) const [pagination, setPagination] = React.useState({ pageIndex: 0, @@ -64,52 +45,20 @@ function GachaRollPage() { page: pagination.pageIndex + 1, per_page: pagination.pageSize, }) - const createItem = useCreateGachaItem() - const updateItem = useUpdateGachaItem() const deleteItem = useDeleteGachaItem() const items: TGachaItemDto[] = itemsData?.data ?? [] const totalItems = itemsData?.meta?.total ?? items.length - const handleAdd = async (): Promise => { - if (pendingFormData.current) { - const { itemName, quantity, chanceRate } = pendingFormData.current - await createItem.mutateAsync({ - item_code: (itemName as string).toLowerCase().replace(/\s+/g, '-'), - name: itemName, - description: '', - rarity: 'common', - type_: 'physical', - category: 'merchandise', - value: 0, - weight: chanceRate ?? 1, - stock: quantity ?? 1, - is_limited: false, - }) + const handleDelete = async (id: string) => { + try { + await deleteItem.mutateAsync(id) + toast.success('Item berhasil dihapus') + setDeleteId(null) + } catch (error) { + console.log(error) + toast.error('Item gagal dihapus') } - return true - } - - const handleUpdate = async (): Promise => { - if (selectedItem && pendingFormData.current) { - const { itemName, quantity, chanceRate } = pendingFormData.current - await updateItem.mutateAsync({ - id: selectedItem.id, - data: { - name: itemName, - weight: chanceRate, - stock: quantity, - }, - }) - } - return true - } - - const handleDelete = async () => { - if (selectedItem) { - await deleteItem.mutateAsync(selectedItem.id) - } - setShowModalDeleteItem(false) } const columns: ColumnDef[] = [ @@ -149,25 +98,49 @@ function GachaRollPage() { size="sm" onClick={(e) => { e.stopPropagation() - setSelectedItem(row.original) - setShowModalUpdateItem(true) + navigate({ to: '/gacha-roll/$id', params: { id: row.original.id } }) }} className="flex items-center gap-2" > Update - + {deleteId === row.original.id ? ( +
+ Yakin? + + +
+ ) : ( + + )} ), }, @@ -214,7 +187,7 @@ function GachaRollPage() { variant="primary" size="md" className="flex gap-3 text-nowrap" - onClick={() => setShowModalAddItem(true)} + onClick={() => navigate({ to: '/gacha-roll/create' })} > Tambah Item @@ -229,33 +202,6 @@ function GachaRollPage() { )} - - setShowModalAddItem(false)} - nextStep={nextStep} - prevStep={prevStep} - resetStep={resetStep} - handleAddItem={handleAdd} - onDataCapture={(data) => { pendingFormData.current = data }} - /> - setShowModalUpdateItem(false)} - nextStep={nextStep} - prevStep={prevStep} - resetStep={resetStep} - handleUpdateItem={handleUpdate} - initialValues={selectedItem ? { itemName: selectedItem.name } : undefined} - onDataCapture={(data) => { pendingFormData.current = data }} - /> - setShowModalDeleteItem(false)} - handleDeleteItem={handleDelete} - /> ) } diff --git a/apps/backoffice/src/routes/_authenticated/gacha-roll_/$id.tsx b/apps/backoffice/src/routes/_authenticated/gacha-roll_/$id.tsx new file mode 100644 index 0000000..7b96864 --- /dev/null +++ b/apps/backoffice/src/routes/_authenticated/gacha-roll_/$id.tsx @@ -0,0 +1,136 @@ +import { createFileRoute, useNavigate } from '@tanstack/react-router' +import { useEffect } from 'react' +import { useForm } from 'react-hook-form' +import { toast } from 'sonner' +import { ArrowLeftOutlined } from '@ant-design/icons' +import { Button } from '@imphnen-frontend-service/ui/atoms' +import { ControlledInputField } from '@imphnen-frontend-service/ui/organisms' +import { + useGachaItemList, + useUpdateGachaItem, +} from '@imphnen-frontend-service/service' + +export const Route = createFileRoute('/_authenticated/gacha-roll/$id')({ + component: GachaRollEditPage, +}) + +function GachaRollEditPage() { + const { id } = Route.useParams() + const navigate = useNavigate() + const updateItem = useUpdateGachaItem() + + const { data: itemsData, isLoading } = useGachaItemList({ per_page: 100 }) + const item = itemsData?.data?.find((i) => i.id === id) + + const form = useForm<{ itemName: string; quantity: number; chanceRate: number }>({ + mode: 'all', + defaultValues: { itemName: '', quantity: 1, chanceRate: 0.1 }, + }) + + useEffect(() => { + if (item) { + form.reset({ + itemName: item.name, + quantity: item.stock, + chanceRate: item.weight, + }) + } + }, [item]) + + const onSubmit = form.handleSubmit(async (data) => { + try { + await updateItem.mutateAsync({ + id, + data: { + name: data.itemName, + weight: data.chanceRate, + stock: data.quantity, + }, + }) + toast.success('Perubahan item roll berhasil dilakukan') + navigate({ to: '/gacha-roll' }) + } catch (error) { + console.log(error) + toast.error('Perubahan item roll gagal dilakukan') + } + }) + + if (isLoading) { + return ( +
+
Loading...
+
+ ) + } + + return ( +
+
+
+ +

Edit Item Roll Gacha

+
+ +
+
+ + + + +
+ + +
+ +
+
+
+ ) +} diff --git a/apps/backoffice/src/routes/_authenticated/gacha-roll_/create.tsx b/apps/backoffice/src/routes/_authenticated/gacha-roll_/create.tsx new file mode 100644 index 0000000..81b70d5 --- /dev/null +++ b/apps/backoffice/src/routes/_authenticated/gacha-roll_/create.tsx @@ -0,0 +1,114 @@ +import { createFileRoute, useNavigate } from '@tanstack/react-router' +import { useForm } from 'react-hook-form' +import { toast } from 'sonner' +import { ArrowLeftOutlined } from '@ant-design/icons' +import { Button } from '@imphnen-frontend-service/ui/atoms' +import { ControlledInputField } from '@imphnen-frontend-service/ui/organisms' +import { useCreateGachaItem } from '@imphnen-frontend-service/service' + +export const Route = createFileRoute('/_authenticated/gacha-roll/create')({ + component: GachaRollCreatePage, +}) + +function GachaRollCreatePage() { + const navigate = useNavigate() + const createItem = useCreateGachaItem() + + const form = useForm<{ itemName: string; quantity: number; chanceRate: number }>({ + mode: 'all', + defaultValues: { itemName: '', quantity: 1, chanceRate: 0.1 }, + }) + + const onSubmit = form.handleSubmit(async (data) => { + try { + await createItem.mutateAsync({ + item_code: (data.itemName as string).toLowerCase().replace(/\s+/g, '-'), + name: data.itemName, + description: '', + rarity: 'common', + type_: 'physical', + category: 'merchandise', + value: 0, + weight: data.chanceRate ?? 1, + stock: data.quantity ?? 1, + is_limited: false, + }) + toast.success('Item ditambahkan ke roll gacha') + navigate({ to: '/gacha-roll' }) + } catch (error) { + console.log(error) + toast.error('Item gagal ditambahkan ke roll gacha') + } + }) + + return ( +
+
+
+ +

Tambah Item Roll Gacha

+
+ +
+
+ + + + +
+ + +
+ +
+
+
+ ) +} diff --git a/apps/backoffice/src/routes/_authenticated/permissions.tsx b/apps/backoffice/src/routes/_authenticated/permissions.tsx index 309eeea..cfe7c74 100644 --- a/apps/backoffice/src/routes/_authenticated/permissions.tsx +++ b/apps/backoffice/src/routes/_authenticated/permissions.tsx @@ -1,5 +1,5 @@ -import { createFileRoute } from '@tanstack/react-router' -import { FC, Fragment, ReactElement, useRef, useState } from 'react' +import { createFileRoute, useNavigate } from '@tanstack/react-router' +import { Fragment, useState } from 'react' import { SearchOutlined, EditOutlined, @@ -16,41 +16,22 @@ import { RowSelectionState, useReactTable, } from '@tanstack/react-table' -import ModalAddPermission from './_components/permissions/modal-add-permission' -import ModalUpdatePermission from './_components/permissions/modal-update-permission' -import ModalDeletePermission from './_components/permissions/modal-delete-permission' -import { useQueryState } from '@imphnen-frontend-service/utils' import { usePermissionList, - useCreatePermission, - useUpdatePermission, useDeletePermission, TPermissionItem, } from '@imphnen-frontend-service/service' import React from 'react' +import { toast } from 'sonner' export const Route = createFileRoute('/_authenticated/permissions')({ component: PermissionsPage, }) function PermissionsPage() { - const [showModalAddItem, setShowModalAddItem] = useState(false) - const [showModalUpdateItem, setShowModalUpdateItem] = useState(false) - const [showModalDeleteItem, setShowModalDeleteItem] = useState(false) - const [selectedItem, setSelectedItem] = useState(null) + const navigate = useNavigate() const [search, setSearch] = useState('') - const pendingFormData = useRef(null) - - const { - step: currentStep, - nextStep, - prevStep, - resetStep, - } = useQueryState('step', { - defaultValue: 1, - maxValue: 2, - minValue: 1, - }) + const [deleteId, setDeleteId] = useState(null) const [pagination, setPagination] = React.useState({ pageIndex: 0, @@ -64,32 +45,20 @@ function PermissionsPage() { page: pagination.pageIndex + 1, per_page: pagination.pageSize, }) - const createPermission = useCreatePermission() - const updatePermission = useUpdatePermission() const deletePermission = useDeletePermission() const permissions: TPermissionItem[] = permissionsData?.data ?? [] const totalItems = permissionsData?.meta?.total ?? permissions.length - const handleAdd = async (): Promise => { - if (pendingFormData.current) { - await createPermission.mutateAsync(pendingFormData.current) + const handleDelete = async (id: string) => { + try { + await deletePermission.mutateAsync(id) + toast.success('Data permissions berhasil dihapus') + setDeleteId(null) + } catch (error) { + console.log(error) + toast.error('Data permissions gagal dihapus') } - return true - } - - const handleUpdate = async (): Promise => { - if (selectedItem && pendingFormData.current) { - await updatePermission.mutateAsync({ id: selectedItem.id, data: pendingFormData.current }) - } - return true - } - - const handleDelete = async (): Promise => { - if (selectedItem) { - await deletePermission.mutateAsync(selectedItem.id) - } - return true } const columns: ColumnDef[] = [ @@ -129,25 +98,49 @@ function PermissionsPage() { size="sm" onClick={(e) => { e.stopPropagation() - setSelectedItem(row.original) - setShowModalUpdateItem(true) + navigate({ to: '/permissions/$id', params: { id: row.original.id } }) }} className="flex items-center gap-2" > Update - + {deleteId === row.original.id ? ( +
+ Yakin? + + +
+ ) : ( + + )} ), }, @@ -194,7 +187,7 @@ function PermissionsPage() { variant="primary" size="md" className="flex gap-3 text-nowrap" - onClick={() => setShowModalAddItem(true)} + onClick={() => navigate({ to: '/permissions/create' })} > Tambah Permissions @@ -214,35 +207,6 @@ function PermissionsPage() { )} - - setShowModalAddItem(false)} - nextStep={nextStep} - prevStep={prevStep} - resetStep={resetStep} - handleAddItem={handleAdd} - onDataCapture={(data) => { pendingFormData.current = data }} - /> - setShowModalUpdateItem(false)} - nextStep={nextStep} - prevStep={prevStep} - resetStep={resetStep} - handleUpdate={handleUpdate} - initialValues={selectedItem ? { name: selectedItem.name } : undefined} - onDataCapture={(data) => { pendingFormData.current = data }} - /> - setShowModalDeleteItem(false)} - nextStep={nextStep} - prevStep={prevStep} - resetStep={resetStep} - handleDelete={handleDelete} - /> ) } diff --git a/apps/backoffice/src/routes/_authenticated/permissions_/$id.tsx b/apps/backoffice/src/routes/_authenticated/permissions_/$id.tsx new file mode 100644 index 0000000..e6f9aea --- /dev/null +++ b/apps/backoffice/src/routes/_authenticated/permissions_/$id.tsx @@ -0,0 +1,103 @@ +import { createFileRoute, useNavigate } from '@tanstack/react-router' +import { useEffect } from 'react' +import { useForm } from 'react-hook-form' +import { toast } from 'sonner' +import { ArrowLeftOutlined } from '@ant-design/icons' +import { Button } from '@imphnen-frontend-service/ui/atoms' +import { ControlledInputField } from '@imphnen-frontend-service/ui/organisms' +import { + usePermissionList, + useUpdatePermission, +} from '@imphnen-frontend-service/service' + +export const Route = createFileRoute('/_authenticated/permissions/$id')({ + component: PermissionsEditPage, +}) + +function PermissionsEditPage() { + const { id } = Route.useParams() + const navigate = useNavigate() + const updatePermission = useUpdatePermission() + + const { data: permissionsData, isLoading } = usePermissionList({ search: '', per_page: 100 }) + const permission = permissionsData?.data?.find((p) => p.id === id) + + const form = useForm<{ name: string }>({ + mode: 'all', + defaultValues: { name: '' }, + }) + + useEffect(() => { + if (permission) { + form.reset({ name: permission.name }) + } + }, [permission]) + + const onSubmit = form.handleSubmit(async (data) => { + try { + await updatePermission.mutateAsync({ id, data }) + toast.success('Perubahan permissions berhasil dilakukan') + navigate({ to: '/permissions' }) + } catch (error) { + console.log(error) + toast.error('Perubahan permissions gagal dilakukan') + } + }) + + if (isLoading) { + return ( +
+
Loading...
+
+ ) + } + + return ( +
+
+
+ +

Edit Permission

+
+ +
+
+ + +
+ + +
+ +
+
+
+ ) +} diff --git a/apps/backoffice/src/routes/_authenticated/permissions_/create.tsx b/apps/backoffice/src/routes/_authenticated/permissions_/create.tsx new file mode 100644 index 0000000..3c200fc --- /dev/null +++ b/apps/backoffice/src/routes/_authenticated/permissions_/create.tsx @@ -0,0 +1,81 @@ +import { createFileRoute, useNavigate } from '@tanstack/react-router' +import { useForm } from 'react-hook-form' +import { toast } from 'sonner' +import { ArrowLeftOutlined } from '@ant-design/icons' +import { Button } from '@imphnen-frontend-service/ui/atoms' +import { ControlledInputField } from '@imphnen-frontend-service/ui/organisms' +import { useCreatePermission } from '@imphnen-frontend-service/service' + +export const Route = createFileRoute('/_authenticated/permissions/create')({ + component: PermissionsCreatePage, +}) + +function PermissionsCreatePage() { + const navigate = useNavigate() + const createPermission = useCreatePermission() + + const form = useForm<{ name: string }>({ + mode: 'all', + defaultValues: { name: '' }, + }) + + const onSubmit = form.handleSubmit(async (data) => { + try { + await createPermission.mutateAsync(data) + toast.success('Data permissions berhasil ditambahkan') + navigate({ to: '/permissions' }) + } catch (error) { + console.log(error) + toast.error('Data permissions gagal ditambahkan') + } + }) + + return ( +
+
+
+ +

Tambah Permission

+
+ +
+
+ + +
+ + +
+ +
+
+
+ ) +} diff --git a/apps/backoffice/src/routes/_authenticated/roles.tsx b/apps/backoffice/src/routes/_authenticated/roles.tsx index c4efd63..ee2011e 100644 --- a/apps/backoffice/src/routes/_authenticated/roles.tsx +++ b/apps/backoffice/src/routes/_authenticated/roles.tsx @@ -1,5 +1,5 @@ -import { createFileRoute } from '@tanstack/react-router' -import { FC, Fragment, ReactElement, useRef, useState } from 'react' +import { createFileRoute, useNavigate } from '@tanstack/react-router' +import { Fragment, useState } from 'react' import { SearchOutlined, EditOutlined, @@ -16,41 +16,22 @@ import { RowSelectionState, useReactTable, } from '@tanstack/react-table' -import ModalAddRole from './_components/roles/modal-add-role' -import ModalUpdateRole from './_components/roles/modal-update-role' -import ModalDeleteRole from './_components/roles/modal-delete-role' -import { useQueryState } from '@imphnen-frontend-service/utils' import { useRoleList, - useCreateRole, - useUpdateRole, useDeleteRole, TRolesListItem, } from '@imphnen-frontend-service/service' import React from 'react' +import { toast } from 'sonner' export const Route = createFileRoute('/_authenticated/roles')({ component: RolesPage, }) function RolesPage() { - const [showModalAddItem, setShowModalAddItem] = useState(false) - const [showModalUpdateItem, setShowModalUpdateItem] = useState(false) - const [showModalDeleteItem, setShowModalDeleteItem] = useState(false) - const [selectedRole, setSelectedRole] = useState(null) + const navigate = useNavigate() const [search, setSearch] = useState('') - const pendingFormData = useRef(null) - - const { - step: currentStep, - nextStep, - prevStep, - resetStep, - } = useQueryState('step', { - defaultValue: 1, - maxValue: 2, - minValue: 1, - }) + const [deleteId, setDeleteId] = useState(null) const [pagination, setPagination] = React.useState({ pageIndex: 0, @@ -64,32 +45,20 @@ function RolesPage() { page: pagination.pageIndex + 1, per_page: pagination.pageSize, }) - const createRole = useCreateRole() - const updateRole = useUpdateRole() const deleteRole = useDeleteRole() const roles: TRolesListItem[] = rolesData?.data ?? [] const totalItems = rolesData?.meta?.total ?? roles.length - const handleAdd = async (): Promise => { - if (pendingFormData.current) { - await createRole.mutateAsync(pendingFormData.current) + const handleDelete = async (id: string) => { + try { + await deleteRole.mutateAsync(id) + toast.success('Data role berhasil dihapus') + setDeleteId(null) + } catch (error) { + console.log(error) + toast.error('Data role gagal dihapus') } - return true - } - - const handleUpdate = async (): Promise => { - if (selectedRole && pendingFormData.current) { - await updateRole.mutateAsync({ id: selectedRole.id, data: pendingFormData.current }) - } - return true - } - - const handleDelete = async (): Promise => { - if (selectedRole) { - await deleteRole.mutateAsync(selectedRole.id) - } - return true } const columns: ColumnDef[] = [ @@ -129,25 +98,49 @@ function RolesPage() { size="sm" onClick={(e) => { e.stopPropagation() - setSelectedRole(row.original) - setShowModalUpdateItem(true) + navigate({ to: '/roles/$id', params: { id: row.original.id } }) }} className="flex items-center gap-2" > Update - + {deleteId === row.original.id ? ( +
+ Yakin? + + +
+ ) : ( + + )} ), }, @@ -194,7 +187,7 @@ function RolesPage() { variant="primary" size="md" className="flex gap-3 text-nowrap" - onClick={() => setShowModalAddItem(true)} + onClick={() => navigate({ to: '/roles/create' })} > Tambah Role @@ -214,35 +207,6 @@ function RolesPage() { )} - - setShowModalAddItem(false)} - nextStep={nextStep} - prevStep={prevStep} - resetStep={resetStep} - handleAdd={handleAdd} - onDataCapture={(data) => { pendingFormData.current = data }} - /> - setShowModalUpdateItem(false)} - nextStep={nextStep} - prevStep={prevStep} - resetStep={resetStep} - handleUpdate={handleUpdate} - initialValues={selectedRole ? { name: selectedRole.name } : undefined} - onDataCapture={(data) => { pendingFormData.current = data }} - /> - setShowModalDeleteItem(false)} - nextStep={nextStep} - prevStep={prevStep} - resetStep={resetStep} - handleDelete={handleDelete} - /> ) } diff --git a/apps/backoffice/src/routes/_authenticated/roles_/$id.tsx b/apps/backoffice/src/routes/_authenticated/roles_/$id.tsx new file mode 100644 index 0000000..8655ab9 --- /dev/null +++ b/apps/backoffice/src/routes/_authenticated/roles_/$id.tsx @@ -0,0 +1,150 @@ +import { createFileRoute, useNavigate } from '@tanstack/react-router' +import { useEffect } from 'react' +import { useForm } from 'react-hook-form' +import { toast } from 'sonner' +import { ArrowLeftOutlined } from '@ant-design/icons' +import { Button } from '@imphnen-frontend-service/ui/atoms' +import { ControlledInputField } from '@imphnen-frontend-service/ui/organisms' +import { + useRoleList, + useUpdateRole, +} from '@imphnen-frontend-service/service' + +export const Route = createFileRoute('/_authenticated/roles/$id')({ + component: RolesEditPage, +}) + +function RolesEditPage() { + const { id } = Route.useParams() + const navigate = useNavigate() + const updateRole = useUpdateRole() + + const { data: rolesData, isLoading } = useRoleList({ search: '', per_page: 100 }) + const role = rolesData?.data?.find((r) => r.id === id) + + const form = useForm<{ name: string }>({ + mode: 'all', + defaultValues: { name: '' }, + }) + + useEffect(() => { + if (role) { + form.reset({ name: role.name }) + } + }, [role]) + + const onSubmit = form.handleSubmit(async (data) => { + try { + await updateRole.mutateAsync({ id, data }) + toast.success('Perubahan role berhasil dilakukan') + navigate({ to: '/roles' }) + } catch (error) { + console.log(error) + toast.error('Perubahan role gagal dilakukan') + } + }) + + if (isLoading) { + return ( +
+
Loading...
+
+ ) + } + + return ( +
+
+
+ +

Edit Role

+
+ +
+
+ + +
+ + Permissions + +
+ {['Gacha Items', 'Gacha Roll', 'Roll', 'Users', 'Gacha Claim'].map( + (title) => ( +
+ {title} +
+ + +
+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+ ) + )} +
+
+ +
+ + +
+ +
+
+
+ ) +} diff --git a/apps/backoffice/src/routes/_authenticated/roles_/create.tsx b/apps/backoffice/src/routes/_authenticated/roles_/create.tsx new file mode 100644 index 0000000..27e2c52 --- /dev/null +++ b/apps/backoffice/src/routes/_authenticated/roles_/create.tsx @@ -0,0 +1,132 @@ +import { createFileRoute, useNavigate } from '@tanstack/react-router' +import { useForm } from 'react-hook-form' +import { toast } from 'sonner' +import { ArrowLeftOutlined } from '@ant-design/icons' +import { Button } from '@imphnen-frontend-service/ui/atoms' +import { ControlledInputField } from '@imphnen-frontend-service/ui/organisms' +import { useCreateRole } from '@imphnen-frontend-service/service' + +export const Route = createFileRoute('/_authenticated/roles/create')({ + component: RolesCreatePage, +}) + +function RolesCreatePage() { + const navigate = useNavigate() + const createRole = useCreateRole() + + const form = useForm<{ name: string }>({ + mode: 'all', + defaultValues: { name: '' }, + }) + + const onSubmit = form.handleSubmit(async (data) => { + try { + await createRole.mutateAsync(data) + toast.success('Data role berhasil ditambahkan') + navigate({ to: '/roles' }) + } catch (error) { + console.log(error) + toast.error('Data role gagal ditambahkan') + } + }) + + return ( +
+
+
+ +

Tambah Role

+
+ +
+
+ + +
+ + Permissions + +
+ {[ + 'Gacha Items', + 'Gacha Roll', + 'Roll', + 'Users', + 'Gacha Claim', + ].map((title) => ( +
+ {title} +
+ + +
+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+ ))} +
+
+ +
+ + +
+ +
+
+
+ ) +}