feat: implement toast notifications for delete actions in dashboard pages
This commit is contained in:
parent
36b22d3f4a
commit
7ab83a4f66
@ -11,6 +11,8 @@ const buttonVariants = cva(
|
||||
variant: {
|
||||
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',
|
||||
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:
|
||||
@ -21,7 +23,7 @@ const buttonVariants = cva(
|
||||
size: {
|
||||
default: 'h-[50px] w-[150px]',
|
||||
block: 'h-[50px] w-full',
|
||||
icon: 'h-9 w-9',
|
||||
icon: 'h-9 w-9 rounded-full',
|
||||
sm: 'h-8 rounded-md px-3 text-xs',
|
||||
lg: 'h-10 rounded-md px-8',
|
||||
fit: 'w-fit',
|
||||
|
||||
@ -1,7 +1,18 @@
|
||||
import {
|
||||
Description,
|
||||
Dialog,
|
||||
DialogBackdrop,
|
||||
DialogPanel,
|
||||
DialogTitle,
|
||||
} from '@headlessui/react'
|
||||
import { PencilSquareIcon, TrashIcon } from '@heroicons/react/20/solid'
|
||||
import type { ConfigColumns } from 'datatables.net-dt'
|
||||
import type { DataTableSlots } from 'datatables.net-react'
|
||||
import { Link, useRouteLoaderData } from 'react-router'
|
||||
import { useEffect, useState } from 'react'
|
||||
import toast from 'react-hot-toast'
|
||||
import { Link, useFetcher, useRouteLoaderData } from 'react-router'
|
||||
|
||||
import type { TAdResponse } from '~/apis/common/get-ads'
|
||||
import { Button } from '~/components/ui/button'
|
||||
import { UiTable } from '~/components/ui/table'
|
||||
import { TitleDashboard } from '~/components/ui/title-dashboard'
|
||||
@ -12,6 +23,22 @@ export const AdvertisementsPage = () => {
|
||||
'routes/_admin.lg-admin._dashboard.advertisements._index',
|
||||
)
|
||||
const { adsData: dataTable } = loaderData || {}
|
||||
const [selectedId, setSelectedId] = useState<TAdResponse>()
|
||||
const fetcher = useFetcher()
|
||||
|
||||
useEffect(() => {
|
||||
if (fetcher.data?.success === false) {
|
||||
toast.error(fetcher.data?.message)
|
||||
return
|
||||
}
|
||||
|
||||
if (fetcher.data?.success === true) {
|
||||
setSelectedId(undefined)
|
||||
toast.success('Banner iklan berhasil dihapus!')
|
||||
return
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [fetcher.data])
|
||||
|
||||
const dataColumns: ConfigColumns[] = [
|
||||
{
|
||||
@ -42,15 +69,25 @@ export const AdvertisementsPage = () => {
|
||||
/>
|
||||
)
|
||||
},
|
||||
3: (value: string) => (
|
||||
3: (value: string, _type: unknown, data: TAdResponse) => (
|
||||
<div className="flex space-x-2">
|
||||
<Button
|
||||
as={Link}
|
||||
to={`/lg-admin/advertisements/update/${value}`}
|
||||
className="text-md rounded-md"
|
||||
size="sm"
|
||||
as="a"
|
||||
href={`/lg-admin/advertisements/update/${value}`}
|
||||
className=""
|
||||
size="icon"
|
||||
>
|
||||
Update Banner Iklan
|
||||
<PencilSquareIcon className="h-4 w-4" />
|
||||
</Button>
|
||||
<Button
|
||||
type="button"
|
||||
size="icon"
|
||||
variant="newsDanger"
|
||||
onClick={() => setSelectedId(data)}
|
||||
>
|
||||
<TrashIcon className="h-4 w-4" />
|
||||
</Button>
|
||||
</div>
|
||||
),
|
||||
}
|
||||
|
||||
@ -76,6 +113,60 @@ export const AdvertisementsPage = () => {
|
||||
slots={dataSlot}
|
||||
title="Daftar Banner Iklan"
|
||||
/>
|
||||
|
||||
<Dialog
|
||||
open={!!selectedId}
|
||||
onClose={() => setSelectedId(undefined)}
|
||||
className="relative z-50"
|
||||
transition
|
||||
>
|
||||
<DialogBackdrop
|
||||
className="fixed inset-0 bg-black/50 duration-300 ease-out data-[closed]:opacity-0"
|
||||
transition
|
||||
/>
|
||||
<div className="fixed inset-0 flex w-screen justify-center overflow-y-auto p-0 max-sm:bg-white sm:items-center sm:p-4">
|
||||
<DialogPanel
|
||||
transition
|
||||
className="max-w-lg space-y-6 rounded-lg bg-white p-8 duration-300 ease-out data-[closed]:scale-95 data-[closed]:opacity-0 sm:shadow-lg"
|
||||
>
|
||||
<DialogTitle className="relative flex justify-start text-xl font-bold">
|
||||
Anda akan menghapus banner berikut?
|
||||
</DialogTitle>
|
||||
<Description className="space-y-1 text-center text-[#565658]">
|
||||
<img
|
||||
src={selectedId?.image_url}
|
||||
alt={selectedId?.image_url}
|
||||
className="aspect-[150/1] h-[50px] rounded object-contain"
|
||||
/>
|
||||
<Button
|
||||
as={Link}
|
||||
to={selectedId?.url || ''}
|
||||
variant="link"
|
||||
size="fit"
|
||||
>
|
||||
{selectedId?.url}
|
||||
</Button>
|
||||
</Description>
|
||||
<div className="flex justify-end">
|
||||
<fetcher.Form
|
||||
method="POST"
|
||||
action={`/actions/admin/advertisements/delete/${selectedId?.id}`}
|
||||
className="grid"
|
||||
>
|
||||
<Button
|
||||
type="submit"
|
||||
variant="newsDanger"
|
||||
className="text-md h-[42px] rounded-md"
|
||||
disabled={fetcher.state !== 'idle'}
|
||||
isLoading={fetcher.state !== 'idle'}
|
||||
>
|
||||
Hapus
|
||||
</Button>
|
||||
</fetcher.Form>
|
||||
</div>
|
||||
</DialogPanel>
|
||||
</div>
|
||||
</Dialog>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@ -56,8 +56,8 @@ export const CategoriesPage = () => {
|
||||
),
|
||||
3: (value: string) => (
|
||||
<Button
|
||||
as={Link}
|
||||
to={`/lg-admin/categories/update/${value}`}
|
||||
as="a"
|
||||
href={`/lg-admin/categories/update/${value}`}
|
||||
className="text-md rounded-md"
|
||||
size="sm"
|
||||
>
|
||||
|
||||
@ -83,8 +83,8 @@ export const ContentsPage = () => {
|
||||
),
|
||||
7: (value: string) => (
|
||||
<Button
|
||||
as={Link}
|
||||
to={`/lg-admin/contents/update/${encodeURIComponent(value)}`}
|
||||
as="a"
|
||||
href={`/lg-admin/contents/update/${encodeURIComponent(value)}`}
|
||||
className="text-md rounded-md"
|
||||
size="sm"
|
||||
>
|
||||
|
||||
@ -67,8 +67,8 @@ export const SubscribePlanPage = () => {
|
||||
),
|
||||
6: (value: string) => (
|
||||
<Button
|
||||
as={Link}
|
||||
to={`/lg-admin/subscribe-plan/update/${value}`}
|
||||
as="a"
|
||||
href={`/lg-admin/subscribe-plan/update/${value}`}
|
||||
className="text-md rounded-md"
|
||||
size="sm"
|
||||
>
|
||||
|
||||
@ -42,8 +42,8 @@ export const TagsPage = () => {
|
||||
const dataSlot: DataTableSlots = {
|
||||
3: (value: string) => (
|
||||
<Button
|
||||
as={Link}
|
||||
to={`/lg-admin/tags/update/${value}`}
|
||||
as="a"
|
||||
href={`/lg-admin/tags/update/${value}`}
|
||||
className="text-md rounded-md"
|
||||
size="sm"
|
||||
>
|
||||
|
||||
@ -42,11 +42,13 @@ export const FormTagPage = (properties: TProperties) => {
|
||||
useEffect(() => {
|
||||
if (fetcher.data?.success === false) {
|
||||
toast.error(fetcher.data?.message)
|
||||
return
|
||||
}
|
||||
|
||||
if (fetcher.data?.success === true) {
|
||||
toast.success(`Tag berhasil ${tagData ? 'diupdate' : 'dibuat'}!`)
|
||||
navigate('/lg-admin/tags')
|
||||
return
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [fetcher.data])
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user