diff --git a/app/components/dialog/delete.tsx b/app/components/dialog/delete.tsx index b83a055..f8b066e 100644 --- a/app/components/dialog/delete.tsx +++ b/app/components/dialog/delete.tsx @@ -23,12 +23,12 @@ export const DialogDelete = (properties: TProperties) => { const fetcher = useFetcher() useEffect(() => { - if (fetcher.data?.success === false) { - toast.error(fetcher.data?.message) + if (!fetcher.data?.success && fetcher.data?.message) { + toast.error(fetcher.data.message) return } - if (fetcher.data?.success === true) { + if (fetcher.data?.success) { close() toast.success(`${title} berhasil dihapus!`) return diff --git a/app/layouts/admin/dashboard.tsx b/app/layouts/admin/dashboard.tsx index 8c9c3a4..387e35b 100644 --- a/app/layouts/admin/dashboard.tsx +++ b/app/layouts/admin/dashboard.tsx @@ -1,5 +1,6 @@ import type { PropsWithChildren } from 'react' +import { DialogProfile } from './dialog-profile' import { DialogUpload } from './dialog-upload' import { Navbar } from './navbar' import { Sidebar } from './sidebar' @@ -15,6 +16,7 @@ export const AdminDashboardLayout = (properties: PropsWithChildren) => { + ) } diff --git a/app/layouts/admin/dialog-profile.tsx b/app/layouts/admin/dialog-profile.tsx new file mode 100644 index 0000000..d4b4b7a --- /dev/null +++ b/app/layouts/admin/dialog-profile.tsx @@ -0,0 +1,77 @@ +import { Dialog, DialogBackdrop, DialogPanel } from '@headlessui/react' +import { zodResolver } from '@hookform/resolvers/zod' +import { useEffect } from 'react' +import toast from 'react-hot-toast' +import { useFetcher } from 'react-router' +import { RemixFormProvider, useRemixForm } from 'remix-hook-form' +import { z } from 'zod' + +import { useAdminContext } from '~/contexts/admin' + +const profileSchema = z.object({ + name: z.string().min(1, 'Name is required'), + email: z.string().email('Invalid email address'), + profile_picture: z.string().optional(), +}) + +type TProfileSchema = z.infer + +export const DialogProfile = () => { + const { editProfile, setEditProfile } = useAdminContext() + const fetcher = useFetcher() + + const formMethods = useRemixForm({ + mode: 'onSubmit', + fetcher, + resolver: zodResolver(profileSchema), + }) + + const { handleSubmit } = formMethods + + useEffect(() => { + if (!fetcher.data?.success && fetcher.data?.message) { + toast.error(fetcher.data.message) + return + } + + if (fetcher.data?.success) { + setEditProfile(false) + return + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [fetcher.data]) + + return ( + { + if (fetcher.state === 'idle') { + setEditProfile(false) + } + }} + className="relative z-50" + transition + > + +
+ + + + + +
+
+ ) +} diff --git a/app/layouts/admin/dialog-upload.tsx b/app/layouts/admin/dialog-upload.tsx index 2ff72c0..2c5604c 100644 --- a/app/layouts/admin/dialog-upload.tsx +++ b/app/layouts/admin/dialog-upload.tsx @@ -1,6 +1,7 @@ import { Dialog, DialogBackdrop, DialogPanel, Input } from '@headlessui/react' import { zodResolver } from '@hookform/resolvers/zod' -import { useEffect, useState, type ChangeEvent } from 'react' +import { useEffect, type ChangeEvent } from 'react' +import toast from 'react-hot-toast' import { useFetcher } from 'react-router' import { RemixFormProvider, useRemixForm } from 'remix-hook-form' import { z } from 'zod' @@ -18,7 +19,6 @@ export type TUploadSchema = z.infer export const DialogUpload = () => { const { isUploadOpen, setUploadedFile, setIsUploadOpen } = useAdminContext() const fetcher = useFetcher() - const [error, setError] = useState() const maxFileSize = 10 * 1024 // 10MB const formMethods = useRemixForm({ @@ -30,14 +30,12 @@ export const DialogUpload = () => { const { handleSubmit, register, setValue } = formMethods useEffect(() => { - if (!fetcher.data?.success) { - setError(fetcher.data?.message) + if (!fetcher.data?.success && fetcher.data?.message) { + toast.error(fetcher.data.message) return } setUploadedFile(fetcher.data.uploadData.data.file_url) - - setError(undefined) // eslint-disable-next-line react-hooks/exhaustive-deps }, [fetcher]) @@ -58,12 +56,12 @@ export const DialogUpload = () => { const img = new Image() if (!file.type.startsWith('image/')) { - setError('Please upload an image file.') + toast.error('Please upload an image file.') return } if (file.size > maxFileSize * 1024) { - setError(`File size is too big!`) + toast.error(`File size is too big!`) return } @@ -110,9 +108,6 @@ export const DialogUpload = () => { action="/actions/admin/upload" encType="multipart/form-data" > - {error && ( -
{error}
- )} { const { handleSubmit } = formMethods useEffect(() => { - if (fetcher.data?.success === false) { - toast.error(fetcher.data?.message) + if (!fetcher.data?.success && fetcher.data?.message) { + toast.error(fetcher.data.message) return } - if (fetcher.data?.success === true) { + if (fetcher.data?.success) { toast.success(`Banner iklan berhasil ${adData ? 'diupdate' : 'dibuat'}!`) navigate('/lg-admin/advertisements') return diff --git a/app/pages/form-category/index.tsx b/app/pages/form-category/index.tsx index a4bed97..19b6617 100644 --- a/app/pages/form-category/index.tsx +++ b/app/pages/form-category/index.tsx @@ -44,12 +44,12 @@ export const FormCategoryPage = (properties: TProperties) => { const watchName = watch('name') useEffect(() => { - if (fetcher.data?.success === false) { - toast.error(fetcher.data?.message) + if (!fetcher.data?.success && fetcher.data?.message) { + toast.error(fetcher.data.message) return } - if (fetcher.data?.success === true) { + if (fetcher.data?.success) { toast.success( `Kategori berhasil ${categoryData ? 'diupdate' : 'dibuat'}!`, ) diff --git a/app/pages/form-contents/index.tsx b/app/pages/form-contents/index.tsx index 62ca7e8..da881c0 100644 --- a/app/pages/form-contents/index.tsx +++ b/app/pages/form-contents/index.tsx @@ -96,12 +96,12 @@ export const FormContentsPage = (properties: TProperties) => { const watchTags = watch('tags') useEffect(() => { - if (fetcher.data?.success === false) { - toast.error(fetcher.data?.message) + if (!fetcher.data?.success && fetcher.data?.message) { + toast.error(fetcher.data.message) return } - if (fetcher.data?.success === true) { + if (fetcher.data?.success) { toast.success(`Artikel berhasil ${newsData ? 'diupdate' : 'dibuat'}!`) navigate('/lg-admin/contents') return diff --git a/app/pages/form-subscribe-plan/index.tsx b/app/pages/form-subscribe-plan/index.tsx index db76c0b..c932b34 100644 --- a/app/pages/form-subscribe-plan/index.tsx +++ b/app/pages/form-subscribe-plan/index.tsx @@ -48,12 +48,12 @@ export const FormSubscribePlanPage = (properties: TProperties) => { const watchName = watch('name') useEffect(() => { - if (fetcher.data?.success === false) { - toast.error(fetcher.data?.message) + if (!fetcher.data?.success && fetcher.data?.message) { + toast.error(fetcher.data.message) return } - if (fetcher.data?.success === true) { + if (fetcher.data?.success) { toast.success( `Subscribe Plan berhasil ${subscribePlanData ? 'diupdate' : 'dibuat'}!`, ) diff --git a/app/pages/form-tag/index.tsx b/app/pages/form-tag/index.tsx index d0037fa..26845ea 100644 --- a/app/pages/form-tag/index.tsx +++ b/app/pages/form-tag/index.tsx @@ -40,12 +40,12 @@ export const FormTagPage = (properties: TProperties) => { const watchName = watch('name') useEffect(() => { - if (fetcher.data?.success === false) { - toast.error(fetcher.data?.message) + if (!fetcher.data?.success && fetcher.data?.message) { + toast.error(fetcher.data.message) return } - if (fetcher.data?.success === true) { + if (fetcher.data?.success) { toast.success(`Tag berhasil ${tagData ? 'diupdate' : 'dibuat'}!`) navigate('/lg-admin/tags') return