import type { ColumnDef } from '@tanstack/vue-table' import { Icon } from '@iconify/vue' import { h } from 'vue' import type { Announcement } from '@/pages/developer/announcements/data/schema' import Badge from '@/components/ui/badge/Badge.vue' import Button from '@/components/ui/button/Button.vue' interface ColumnOptions { onToggleTop: (row: Announcement) => void onEdit: (row: Announcement) => void onDelete: (row: Announcement) => void } export function getColumns(options: ColumnOptions, t: (key: string) => string): ColumnDef[] { return [ { accessorKey: 'title', header: () => t('developer.announcements.columns.title'), cell: ({ row }) => { return h('div', { class: 'space-y-1' }, [ h('div', { class: 'font-medium' }, row.original.title), h('div', { class: 'text-xs text-muted-foreground truncate max-w-xs' }, row.original.content), ]) }, }, { accessorKey: 'application_name', header: () => t('developer.announcements.columns.application'), cell: ({ row }) => { const appName = row.original.application_name return appName ? h(Badge, { variant: 'secondary' }, () => appName) : '-' }, }, { accessorKey: 'type', header: () => t('developer.announcements.columns.type'), cell: ({ row }) => { const typeLabels: Record = { info: t('developer.announcements.types.info'), warning: t('developer.announcements.types.warning'), error: t('developer.announcements.types.error'), success: t('developer.announcements.types.success'), } const typeClasses: Record = { info: 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400', warning: 'bg-yellow-100 text-yellow-700 dark:bg-yellow-900/30 dark:text-yellow-400', error: 'bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400', success: 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400', } return h(Badge, { class: typeClasses[row.original.type] }, () => typeLabels[row.original.type]) }, }, { accessorKey: 'status', header: () => t('developer.announcements.columns.status'), cell: ({ row }) => { const statusLabels: Record = { active: t('developer.announcements.statuses.active'), inactive: t('developer.announcements.statuses.inactive'), } const statusClasses: Record = { active: 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400', inactive: 'bg-gray-100 text-gray-700 dark:bg-gray-900/30 dark:text-gray-400', } return h(Badge, { class: statusClasses[row.original.status] }, () => statusLabels[row.original.status]) }, }, { accessorKey: 'is_top', header: () => t('developer.announcements.columns.isTop'), cell: ({ row }) => { return h(Button, { variant: 'ghost', size: 'sm', onClick: () => options.onToggleTop(row.original), }, () => [ h(Icon, { icon: row.original.is_top ? 'lucide:pin' : 'lucide:pin-off', class: `h-4 w-4 ${row.original.is_top ? 'text-primary' : 'text-muted-foreground'}`, }), ]) }, }, { accessorKey: 'created_at', header: () => t('developer.announcements.columns.createdAt'), cell: ({ row }) => { return h('span', { class: 'text-sm text-muted-foreground' }, new Date(row.original.created_at).toLocaleString('zh-CN')) }, }, { id: 'actions', header: () => t('developer.announcements.columns.actions'), cell: ({ row }) => { return h('div', { class: 'flex items-center justify-end gap-1' }, [ h(Button, { variant: 'ghost', size: 'sm', onClick: () => options.onEdit(row.original), }, () => [ h(Icon, { icon: 'lucide:edit', class: 'h-4 w-4' }), ]), h(Button, { variant: 'ghost', size: 'sm', onClick: () => options.onDelete(row.original), }, () => [ h(Icon, { icon: 'lucide:trash-2', class: 'h-4 w-4 text-destructive' }), ]), ]) }, }, ] }