diff --git a/app/apis/admin/delete-subscribe-plan.ts b/app/apis/admin/delete-subscribe-plan.ts index 6a82d57..fc6a5d9 100644 --- a/app/apis/admin/delete-subscribe-plan.ts +++ b/app/apis/admin/delete-subscribe-plan.ts @@ -9,14 +9,12 @@ const subscribePlanResponseSchema = z.object({ }), }) -type TTSubscribePlanId = Pick type TParameters = { - payload: TTSubscribePlanId + id: TSubscribePlanSchema['id'] } & THttpServer export const deleteSubscribePlanRequest = async (parameters: TParameters) => { - const { payload, ...restParameters } = parameters - const { id } = payload + const { id, ...restParameters } = parameters try { const { data } = await HttpServer(restParameters).delete( `/api/subscribe-plan/${id}/delete`, diff --git a/app/components/ui/button.tsx b/app/components/ui/button.tsx index c4fc7e5..ffd5e69 100644 --- a/app/components/ui/button.tsx +++ b/app/components/ui/button.tsx @@ -12,7 +12,7 @@ const buttonVariants = cva( newsPrimary: 'bg-[#2E2F7C] text-white text-lg hover:bg-[#4C5CA0] hover:shadow transition active:bg-[#6970B4]', newsDanger: - 'bg-red-500 text-white text-lg hover:bg-red-600 hover:shadow transition active:bg-red-700', + 'bg-[#EF4444] text-white text-lg hover:shadow transition active:bg-[#FEE2E2] hover:bg-[#FCA5A5]', newsPrimaryOutline: 'border-[3px] bg-[#2E2F7C] border-white text-white text-lg hover:bg-[#4C5CA0] hover:shadow-lg active:shadow-2xl transition active:bg-[#6970B4]', newsSecondary: diff --git a/app/pages/dashboard-advertisements/dialog-delete.tsx b/app/pages/dashboard-advertisements/dialog-delete.tsx index 4da1a44..4a149c2 100644 --- a/app/pages/dashboard-advertisements/dialog-delete.tsx +++ b/app/pages/dashboard-advertisements/dialog-delete.tsx @@ -13,12 +13,12 @@ import type { TAdResponse } from '~/apis/common/get-ads' import { Button } from '~/components/ui/button' type TProperties = { - selectedAds?: TAdResponse - setSelectedAds: Dispatch> + selectedItem?: TAdResponse + setSelectedItem: Dispatch> } export const DialogDelete = (properties: TProperties) => { - const { selectedAds, setSelectedAds } = properties || {} + const { selectedItem, setSelectedItem } = properties || {} const fetcher = useFetcher() useEffect(() => { @@ -28,7 +28,7 @@ export const DialogDelete = (properties: TProperties) => { } if (fetcher.data?.success === true) { - setSelectedAds(undefined) + setSelectedItem(undefined) toast.success('Banner iklan berhasil dihapus!') return } @@ -37,10 +37,10 @@ export const DialogDelete = (properties: TProperties) => { return ( { if (fetcher.state === 'idle') { - setSelectedAds(undefined) + setSelectedItem(undefined) } }} className="relative z-50" @@ -60,23 +60,23 @@ export const DialogDelete = (properties: TProperties) => { {selectedAds?.image_url}
@@ -99,8 +99,8 @@ export const AdvertisementsPage = () => { />
) diff --git a/app/pages/dashboard-categories/index.tsx b/app/pages/dashboard-categories/index.tsx index 653d3f8..fc1c09b 100644 --- a/app/pages/dashboard-categories/index.tsx +++ b/app/pages/dashboard-categories/index.tsx @@ -81,8 +81,8 @@ export const CategoriesPage = () => { diff --git a/app/pages/dashboard-contents/index.tsx b/app/pages/dashboard-contents/index.tsx index 68af6e0..057c574 100644 --- a/app/pages/dashboard-contents/index.tsx +++ b/app/pages/dashboard-contents/index.tsx @@ -107,8 +107,8 @@ export const ContentsPage = () => { diff --git a/app/pages/dashboard-subscribe-plan/dialog-delete.tsx b/app/pages/dashboard-subscribe-plan/dialog-delete.tsx new file mode 100644 index 0000000..c62ae78 --- /dev/null +++ b/app/pages/dashboard-subscribe-plan/dialog-delete.tsx @@ -0,0 +1,90 @@ +import { + Description, + Dialog, + DialogBackdrop, + DialogPanel, + DialogTitle, +} from '@headlessui/react' +import { useEffect, type Dispatch, type SetStateAction } from 'react' +import toast from 'react-hot-toast' +import { useFetcher } from 'react-router' + +import type { TSubscribePlanResponse } from '~/apis/common/get-subscribe-plan' +import { Button } from '~/components/ui/button' +import { formatNumberWithPeriods } from '~/utils/formatter' + +type TProperties = { + selectedItem?: TSubscribePlanResponse + setSelectedItem: Dispatch> +} + +export const DialogDelete = (properties: TProperties) => { + const { selectedItem, setSelectedItem } = properties || {} + const fetcher = useFetcher() + + useEffect(() => { + if (fetcher.data?.success === false) { + toast.error(fetcher.data?.message) + return + } + + if (fetcher.data?.success === true) { + setSelectedItem(undefined) + toast.success('Subscribe plan berhasil dihapus!') + return + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [fetcher.data]) + + return ( + { + if (fetcher.state === 'idle') { + setSelectedItem(undefined) + } + }} + className="relative z-50" + transition + > + +
+ + + Anda akan menghapus subscribe plan berikut? + + +

{selectedItem?.name}

+

Length: {selectedItem?.length}

+

+ Harga: Rp. {formatNumberWithPeriods(selectedItem?.price || 0)} +

+
+
+ + + +
+
+
+
+ ) +} diff --git a/app/pages/dashboard-subscribe-plan/index.tsx b/app/pages/dashboard-subscribe-plan/index.tsx index a94c300..c475155 100644 --- a/app/pages/dashboard-subscribe-plan/index.tsx +++ b/app/pages/dashboard-subscribe-plan/index.tsx @@ -1,5 +1,11 @@ +import { + PencilSquareIcon, + PlusIcon, + TrashIcon, +} from '@heroicons/react/20/solid' import DT from 'datatables.net-dt' import DataTable from 'datatables.net-react' +import { useState } from 'react' import { Link, useRouteLoaderData } from 'react-router' import type { TSubscribePlanResponse } from '~/apis/common/get-subscribe-plan' @@ -10,10 +16,14 @@ import { TitleDashboard } from '~/components/ui/title-dashboard' import type { loader } from '~/routes/_admin.lg-admin._dashboard.subscribe-plan._index' import { formatNumberWithPeriods } from '~/utils/formatter' +import { DialogDelete } from './dialog-delete' + export const SubscribePlanPage = () => { const loaderData = useRouteLoaderData( 'routes/_admin.lg-admin._dashboard.subscribe-plan._index', ) + const [selectedSubscribePlan, setSelectedSubscribePlan] = + useState() DataTable.use(DT) const { subscribePlanData: dataTable } = loaderData || {} @@ -43,7 +53,7 @@ export const SubscribePlanPage = () => { data: 'length', }, { - title: 'Price', + title: 'Harga', data: 'price', }, { @@ -70,14 +80,25 @@ export const SubscribePlanPage = () => { data.code === 'basic' ? ( '' ) : ( - +
+ + +
), } return ( @@ -88,10 +109,10 @@ export const SubscribePlanPage = () => { @@ -107,6 +128,11 @@ export const SubscribePlanPage = () => { }} title=" Daftar Subscribe Plan" /> + + ) } diff --git a/app/pages/dashboard-tags/index.tsx b/app/pages/dashboard-tags/index.tsx index 06225ed..82e5785 100644 --- a/app/pages/dashboard-tags/index.tsx +++ b/app/pages/dashboard-tags/index.tsx @@ -66,8 +66,8 @@ export const TagsPage = () => { diff --git a/app/routes/actions.admin.subscribe-plan.delete.$id.ts b/app/routes/actions.admin.subscribe-plan.delete.$id.ts new file mode 100644 index 0000000..1728fb1 --- /dev/null +++ b/app/routes/actions.admin.subscribe-plan.delete.$id.ts @@ -0,0 +1,48 @@ +import { data } from 'react-router' +import { XiorError } from 'xior' + +import { deleteSubscribePlanRequest } from '~/apis/admin/delete-subscribe-plan' +import { handleCookie } from '~/libs/cookies' + +import type { Route } from './+types/actions.admin.advertisements.create' + +export const action = async ({ request, params }: Route.ActionArgs) => { + const { staffToken: accessToken } = await handleCookie(request) + const { id } = params + try { + const { data: subscribePlanData } = await deleteSubscribePlanRequest({ + accessToken, + id, + }) + + return data( + { + success: true, + subscribePlanData, + }, + { + status: 200, + statusText: 'OK', + }, + ) + } catch (error) { + if (error instanceof XiorError) { + return data( + { + success: false, + message: error?.response?.data?.error?.message || error.message, + }, + { + status: error?.response?.status || 500, + }, + ) + } + return data( + { + success: false, + message: 'Internal server error', + }, + { status: 500 }, + ) + } +}