diff options
| author | joonhoekim <26rote@gmail.com> | 2025-10-15 21:38:21 +0900 |
|---|---|---|
| committer | joonhoekim <26rote@gmail.com> | 2025-10-15 21:38:21 +0900 |
| commit | a070f833d132e6370311c0bbdad03beb51d595df (patch) | |
| tree | 9184292e4c2631ee0c7a7247f9728fc26de790f1 /lib/email-whitelist/table/whitelist-table-columns.tsx | |
| parent | 280a2628df810dc157357e0e4d2ed8076d020a2c (diff) | |
(김준회) 이메일 화이트리스트 (SMS 우회) 기능 추가 및 기존 로그인 과정 통합
Diffstat (limited to 'lib/email-whitelist/table/whitelist-table-columns.tsx')
| -rw-r--r-- | lib/email-whitelist/table/whitelist-table-columns.tsx | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/lib/email-whitelist/table/whitelist-table-columns.tsx b/lib/email-whitelist/table/whitelist-table-columns.tsx new file mode 100644 index 00000000..2533d863 --- /dev/null +++ b/lib/email-whitelist/table/whitelist-table-columns.tsx @@ -0,0 +1,208 @@ +'use client'; + +/* IMPORT */ +import { Badge } from '@/components/ui/badge'; +import { Button } from '@/components/ui/button'; +import { Checkbox } from '@/components/ui/checkbox'; +import { MoreHorizontal, Trash, Pencil } from 'lucide-react'; +import { DataTableColumnHeaderSimple } from '@/components/data-table/data-table-column-simple-header'; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuSeparator, + DropdownMenuTrigger, +} from '@/components/ui/dropdown-menu'; +import { formatDate } from '@/lib/utils'; +import { type ColumnDef } from '@tanstack/react-table'; +import { type Dispatch, type SetStateAction } from 'react'; +import { type DataTableRowAction } from '@/types/table'; +import { type EmailWhitelist } from '../service'; + +// ---------------------------------------------------------------------------------------------------- + +/* TYPES */ +interface GetColumnsProps { + setRowAction: Dispatch<SetStateAction<DataTableRowAction<EmailWhitelist> | null>>; +} + +// ---------------------------------------------------------------------------------------------------- + +/* FUNCTION FOR GETTING COLUMNS SETTING */ +export function getColumns({ setRowAction }: GetColumnsProps): ColumnDef<EmailWhitelist>[] { + return [ + // [1] Checkbox Column + { + id: 'select', + header: ({ table }) => ( + <Checkbox + checked={ + table.getIsAllPageRowsSelected() || + (table.getIsSomePageRowsSelected() && 'indeterminate') + } + onCheckedChange={(value) => table.toggleAllPageRowsSelected(!!value)} + aria-label="Select all" + className="translate-y-0.5" + /> + ), + cell: ({ row }) => ( + <Checkbox + checked={row.getIsSelected()} + onCheckedChange={(value) => row.toggleSelected(!!value)} + aria-label="Select row" + className="translate-y-0.5" + /> + ), + enableSorting: false, + enableHiding: false, + }, + + // [2] ID Column + { + accessorKey: 'id', + header: ({ column }) => ( + <DataTableColumnHeaderSimple column={column} title="ID" /> + ), + cell: ({ row }) => <div>{row.getValue('id')}</div>, + enableSorting: false, + enableHiding: false, + size: 80, + }, + + // [3] Email/Domain Column + { + accessorKey: 'displayValue', + header: ({ column }) => ( + <DataTableColumnHeaderSimple column={column} title="이메일/도메인" /> + ), + cell: ({ row }) => { + const displayValue = row.getValue('displayValue') as string; + const isEmail = displayValue.includes('@'); + + return ( + <div className="flex space-x-2"> + <Badge variant={isEmail ? 'default' : 'outline'} className="font-mono"> + {isEmail ? displayValue : `@${displayValue}`} + </Badge> + </div> + ); + }, + enableSorting: false, + size: 220, + }, + + // [4] Description Column + { + accessorKey: 'description', + header: ({ column }) => ( + <DataTableColumnHeaderSimple column={column} title="설명" /> + ), + cell: ({ row }) => { + const description = row.getValue('description') as string; + return ( + <div className="truncate" title={description || ''}> + {description || '-'} + </div> + ); + }, + enableSorting: false, + size: 200, + }, + + // [5] Created At Column + { + accessorKey: 'createdAt', + header: ({ column }) => ( + <DataTableColumnHeaderSimple column={column} title="생성일" /> + ), + cell: ({ row }) => { + const date = row.getValue('createdAt') as Date; + return <div>{formatDate(date, "KR")}</div>; + }, + enableSorting: false, + size: 120, + }, + + // [6] Created By Column + { + accessorKey: 'createdByName', + header: ({ column }) => ( + <DataTableColumnHeaderSimple column={column} title="생성자" /> + ), + cell: ({ row }) => { + const name = row.getValue('createdByName') as string; + return <div>{name || '-'}</div>; + }, + enableSorting: false, + size: 100, + }, + + // [7] Updated At Column + { + accessorKey: 'updatedAt', + header: ({ column }) => ( + <DataTableColumnHeaderSimple column={column} title="수정일" /> + ), + cell: ({ row }) => { + const date = row.getValue('updatedAt') as Date; + return <div>{formatDate(date, "KR")}</div>; + }, + enableSorting: false, + size: 120, + }, + + // [8] Updated By Column + { + accessorKey: 'updatedByName', + header: ({ column }) => ( + <DataTableColumnHeaderSimple column={column} title="수정자" /> + ), + cell: ({ row }) => { + const name = row.getValue('updatedByName') as string; + return <div>{name || '-'}</div>; + }, + enableSorting: false, + size: 100, + }, + + // [9] Actions Column + { + id: 'actions', + cell: ({ row }) => ( + <DropdownMenu> + <DropdownMenuTrigger asChild> + <Button + aria-label="Open menu" + variant="ghost" + className="flex size-6 p-0 data-[state=open]:bg-muted" + > + <MoreHorizontal className="size-4" /> + </Button> + </DropdownMenuTrigger> + <DropdownMenuContent align="end" className="w-[160px]"> + <DropdownMenuItem + onSelect={() => setRowAction({ row, type: 'update' })} + > + <Pencil className="mr-2 size-4" /> + 수정 + </DropdownMenuItem> + <DropdownMenuSeparator /> + <DropdownMenuItem + onSelect={() => setRowAction({ row, type: 'delete' })} + className="text-destructive" + > + <Trash className="mr-2 size-4" /> + 삭제 + </DropdownMenuItem> + </DropdownMenuContent> + </DropdownMenu> + ), + enableSorting: false, + enableHiding: false, + enableResizing: false, + size: 80, + minSize: 80, + maxSize: 80, + }, + ]; +} |
