/* Copyright (C) 2023-2026 QuantumNous This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . For commercial licensing, please contact support@quantumnous.com */ import { type ColumnDef } from '@tanstack/react-table' import { useTranslation } from 'react-i18next' import { formatQuota, formatTimestampToDate } from '@/lib/format' import { Checkbox } from '@/components/ui/checkbox' import { Tooltip, TooltipContent, TooltipTrigger, } from '@/components/ui/tooltip' import { DataTableColumnHeader } from '@/components/data-table' import { MaskedValueDisplay } from '@/components/masked-value-display' import { StatusBadge } from '@/components/status-badge' import { TableId } from '@/components/table-id' import { REDEMPTION_FILTER_EXPIRED, REDEMPTION_STATUSES } from '../constants' import { isRedemptionExpired, isTimestampExpired } from '../lib' import { type Redemption } from '../types' import { DataTableRowActions } from './data-table-row-actions' export function useRedemptionsColumns(): ColumnDef[] { const { t } = useTranslation() return [ { id: 'select', meta: { label: t('Select') }, header: ({ table }) => ( table.toggleAllPageRowsSelected(!!value)} aria-label={t('Select all')} className='translate-y-[2px]' /> ), cell: ({ row }) => ( row.toggleSelected(!!value)} aria-label={t('Select row')} className='translate-y-[2px]' /> ), enableSorting: false, enableHiding: false, size: 40, }, { accessorKey: 'id', meta: { label: t('ID'), mobileHidden: true }, header: ({ column }) => ( ), cell: ({ row }) => { return ( ) }, size: 80, }, { accessorKey: 'name', meta: { label: t('Name'), mobileTitle: true }, header: ({ column }) => ( ), cell: ({ row }) => { return (
{row.getValue('name')}
) }, size: 180, }, { accessorKey: 'status', meta: { label: t('Status'), mobileBadge: true }, header: ({ column }) => ( ), cell: ({ row }) => { const redemption = row.original const statusValue = row.getValue('status') as number // Check if expired if (isRedemptionExpired(redemption.expired_time, statusValue)) { return ( ) } const statusConfig = REDEMPTION_STATUSES[statusValue] if (!statusConfig) { return null } return ( ) }, filterFn: (row, id, value) => { const redemption = row.original const statusValue = row.getValue(id) as number // Check if expired status is being filtered if (value.includes(REDEMPTION_FILTER_EXPIRED)) { if (isRedemptionExpired(redemption.expired_time, statusValue)) { return true } } // Check regular status return value.includes(String(statusValue)) }, size: 120, }, { id: 'code', accessorKey: 'key', meta: { label: t('Code') }, header: ({ column }) => ( ), cell: function CodeCell({ row }) { const redemption = row.original const key = redemption.key const maskedKey = `${key.slice(0, 8)}${'*'.repeat(16)}${key.slice(-8)}` return ( ) }, enableSorting: false, size: 320, }, { accessorKey: 'quota', meta: { label: t('Quota') }, header: ({ column }) => ( ), cell: ({ row }) => { const quota = row.getValue('quota') as number return ( ) }, size: 120, }, { accessorKey: 'created_time', meta: { label: t('Created'), mobileHidden: true }, header: ({ column }) => ( ), cell: ({ row }) => { return (
{formatTimestampToDate(row.getValue('created_time'))}
) }, size: 180, }, { accessorKey: 'expired_time', meta: { label: t('Expires'), mobileHidden: true }, header: ({ column }) => ( ), cell: ({ row }) => { const expiredTime = row.getValue('expired_time') as number if (expiredTime === 0) { return ( ) } const isExpired = isTimestampExpired(expiredTime) return (
{formatTimestampToDate(expiredTime)}
) }, size: 180, }, { accessorKey: 'used_user_id', meta: { label: t('Redeemed By'), mobileHidden: true }, header: ({ column }) => ( ), cell: ({ row }) => { const userId = row.getValue('used_user_id') as number const redemption = row.original if (userId === 0) { return - } return ( } >
{t('User ID:')} {userId}
{redemption.redeemed_time > 0 && (
{t('Redeemed:')}{' '} {formatTimestampToDate(redemption.redeemed_time)}
)}
) }, size: 140, }, { id: 'actions', cell: ({ row }) => , size: 88, }, ] }