import type { Row, Table } from '@tanstack/react-table' import { Database } from 'lucide-react' /* 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 * as React from 'react' import { useTranslation } from 'react-i18next' import { Empty, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle, } from '@/components/ui/empty' import { Skeleton } from '@/components/ui/skeleton' import { cn } from '@/lib/utils' import { tableHasCompactMeta } from './card-cell-utils' import { CardRowContent } from './card-row-content' interface MobileCardListProps { table: Table isLoading?: boolean emptyTitle?: string emptyDescription?: string getRowKey?: (row: Row) => string | number getRowClassName?: (row: Row) => string | undefined } function ListSkeleton() { return (
{[1, 2, 3, 4, 5].map((i) => (
))}
) } function FallbackListSkeleton() { return (
{[1, 2, 3, 4, 5].map((i) => (
{[1, 2, 3].map((j) => (
))}
))}
) } /** * Mobile-optimized list view for table data. * * Renders rows inside a single bordered container with dividers — * a Vercel/Stripe-style list rather than individual cards. * * Per-row content is shared with the desktop card view via * {@link CardRowContent}; see `card-row-content.tsx` for the column-meta * extensions (`mobileTitle`, `mobileBadge`, `mobileHidden`). */ export function MobileCardList(props: MobileCardListProps) { const { table, isLoading = false, emptyTitle, emptyDescription, getRowKey, getRowClassName, } = props const { t } = useTranslation() const resolvedEmptyTitle = emptyTitle ?? t('No Data') const resolvedEmptyDescription = emptyDescription ?? t('No data available') const visibleColumns = table.getVisibleLeafColumns() const hasCompactMeta = React.useMemo( () => tableHasCompactMeta(table), // eslint-disable-next-line react-hooks/exhaustive-deps [visibleColumns] ) if (isLoading) { return hasCompactMeta ? : } const rows = table.getRowModel().rows if (!rows || rows.length === 0) { return (
{resolvedEmptyTitle} {resolvedEmptyDescription}
) } return (
{rows.map((row) => { const key = getRowKey ? getRowKey(row) : row.id return (
) })}
) }