/* 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 { useMemo } from 'react' import { useTranslation } from 'react-i18next' import { BadgeCell } from '@/components/data-table' import { GroupBadge } from '@/components/group-badge' import { StatusBadge } from '@/components/status-badge' import { TableId } from '@/components/table-id' import { formatQuota } from '@/lib/format' import { formatDuration, formatResetPeriod } from '../lib' import type { PlanRecord } from '../types' import { DataTableRowActions } from './data-table-row-actions' export function useSubscriptionsColumns(): ColumnDef[] { const { t } = useTranslation() return useMemo( (): ColumnDef[] => [ { accessorFn: (row) => row.plan.id, id: 'id', header: t('ID'), meta: { mobileHidden: true }, cell: ({ row }) => , size: 60, }, { accessorFn: (row) => row.plan.title, id: 'title', header: t('Plan'), meta: { mobileTitle: true }, cell: ({ row }) => { const plan = row.original.plan return (
{plan.title}
{plan.subtitle && (
{plan.subtitle}
)}
) }, size: 200, }, { accessorFn: (row) => row.plan.price_amount, id: 'price', header: t('Price'), cell: ({ row }) => ( ${Number(row.original.plan.price_amount || 0).toFixed(2)} ), size: 100, }, { id: 'duration', header: t('Validity'), cell: ({ row }) => ( {formatDuration(row.original.plan, t)} ), size: 100, }, { id: 'reset', header: t('Quota Reset'), meta: { mobileHidden: true }, cell: ({ row }) => ( {formatResetPeriod(row.original.plan, t)} ), size: 100, }, { accessorFn: (row) => row.plan.sort_order, id: 'sort_order', header: t('Priority'), meta: { mobileHidden: true }, cell: ({ row }) => ( {row.original.plan.sort_order} ), size: 100, }, { accessorFn: (row) => row.plan.enabled, id: 'enabled', header: t('Status'), meta: { mobileBadge: true }, cell: ({ row }) => row.original.plan.enabled ? ( ) : ( ), size: 80, }, { id: 'payment', header: t('Payment Channel'), meta: { mobileHidden: true }, cell: ({ row }) => { const plan = row.original.plan return ( {plan.stripe_price_id && ( )} {plan.creem_product_id && ( )} {plan.waffo_pancake_product_id && ( )} ) }, size: 140, }, { id: 'total_amount', header: t('Plan Quota'), meta: { mobileHidden: true }, cell: ({ row }) => { const total = Number(row.original.plan.total_amount || 0) return ( {total > 0 ? formatQuota(total) : t('Unlimited')} ) }, size: 150, }, { id: 'upgrade_group', header: t('Upgrade Group'), meta: { mobileHidden: true }, cell: ({ row }) => { const group = row.original.plan.upgrade_group if (!group) { return ( {t('No Upgrade')} ) } return ( ) }, size: 120, }, { id: 'actions', header: () => t('Actions'), cell: ({ row }) => , meta: { pinned: 'right' as const }, }, ], [t] ) }