만들려는 것
다시 데이터 테이블 부터
- Data-table에 보여줄 column을 만든다.
'use client';
import { ColumnDef } from '@tanstack/react-table';
import CellAction from './cell-action';
// This type is used to define the shape of our data.
// You can use a Zod schema here if you want.
export type BillboardColumn = {
id: string;
label: string;
createdAt: string;
};
export const columns: ColumnDef<BillboardColumn>[] = [
{
accessorKey: 'label',
header: 'Label',
},
{
accessorKey: 'createdAt',
header: 'Date',
},
{
id: 'actions',
cell: ({ row }) => <CellAction data={row.original} />,
},
];
- Cell-Action 만든다.
'use client';
import { Button } from '@/components/ui/button';
import { BillboardColumn } from './columns';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import { Copy, Edit, MoreHorizontal, Trash } from 'lucide-react';
import { DropdownMenuLabel } from '@radix-ui/react-dropdown-menu';
import toast from 'react-hot-toast';
import { useParams, useRouter } from 'next/navigation';
import axios from 'axios';
import { useState } from 'react';
import AlertModal from '@/components/modals/alert-modal';
interface CellActionProps {
data: BillboardColumn;
}
export default function CellAction({ data }: CellActionProps) {
const router = useRouter();
const params = useParams();
const [loading, setLoading] = useState(false);
const [open, setOpen] = useState(false);
const onCopy = (id: string) => {
navigator.clipboard.writeText(id);
toast.success(`Billboard Id copied to the clipboard. id : ${id}`);
};
// billboard Form과는 조금 다른 onDelete 함수
const onDelete = async () => {
try {
setLoading(true);
await axios.delete(`/api/${params.storeId}/billboards/${data.id}`);
router.refresh();
// 리다이렉트 필요없음...
// router.push('/');
toast.success('Billboard Deleted');
} catch (error) {
toast.error(
'Make sure you removed all categories using this billboard first.'
);
} finally {
setLoading(false);
setOpen(false);
}
};
return (
<>
<AlertModal
isOpen={open}
onClonse={() => setOpen(false)}
onConfirm={onDelete}
loading={loading}
/>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant='ghost' className='h-8 w-8 p-0'>
<span className='sr-only'></span>
<MoreHorizontal className='h-4 w-4' />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align='end'>
<DropdownMenuLabel>Actions</DropdownMenuLabel>
<DropdownMenuItem onClick={() => onCopy(data.id)}>
<Copy className='mr-2 h-4 w-4' />
Copy Id
</DropdownMenuItem>
<DropdownMenuItem
onClick={() =>
router.push(`/${params.storeId}/billboards/${data.id}`)
}
>
<Edit className='mr-2 h-4 w-4' />
Update
</DropdownMenuItem>
<DropdownMenuItem onClick={() => setOpen(true)}>
<Trash className='mr-2 h-4 w-4' />
Delete
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</>
);
}
Cell Action이 조금 중요함
- update, delete 성공시 어디로
리다이렉트
시킬지 확인을 하자!
- update시
- router.push(
/${params.storeId}/billboards/${data.id}
)
- delete시
상단의 BillboardClient에서 컴포넌트 조합한다.
'use client';
import Heading from '@/components/ui/Heading';
import { Button } from '@/components/ui/button';
import { Separator } from '@/components/ui/separator';
import { Plus } from 'lucide-react';
import { useParams, useRouter } from 'next/navigation';
import { BillboardColumn, columns } from './columns';
import { DataTable } from '@/components/ui/data-table';
import ApiList from '@/components/ui/api-list';
interface BillboardClientProps {
data: BillboardColumn[];
}
export default function BillboardClient({ data }: BillboardClientProps) {
const router = useRouter();
const params = useParams();
return (
<>
<div className='flex items-center justify-between'>
<Heading
title={`Billboards (${data.length})`}
description='Mange billboards for your store'
/>
<Button
onClick={() => router.push(`/${params.storeId}/billboards/new`)}
>
<Plus className='mr-2 h-4 w-4' />
Add New
</Button>
</div>
<Separator />
// 데이터 테이블
<DataTable columns={columns} data={data} searchKey='label' />
<Heading title='API' description='API calls for Billboards' />
<Separator />
<ApiList entityName='billboards' entityIdName='billboardId' />
</>
);
}
필터를 걸어주기 위해서