feat: add My Uploads listing with card and table views

This commit is contained in:
2026-06-18 21:22:44 +05:30
parent dff9e2222f
commit a18fff4d6f
28 changed files with 1060 additions and 127 deletions

View File

@@ -73,6 +73,7 @@ export interface DataTableProps<TData, TValue> {
sorting?: SortingState;
onSortingChange?: (sorting: SortingState) => void;
enableColumnControls?: boolean;
onRowClick?: (row: TData) => void;
/** Minimum width (px) for every column unless overridden in the column def. */
minColumnSize?: number;
}
@@ -111,6 +112,7 @@ function DataTableContent<TData, TValue>({
emptyTitle = 'No results found.',
emptyDescription = 'Try adjusting your filters or search terms.',
pagination,
onRowClick,
sorting: controlledSorting,
onSortingChange,
enableColumnControls = true,
@@ -281,6 +283,8 @@ function DataTableContent<TData, TValue>({
<TableRow
key={row.id}
data-state={row.getIsSelected() && 'selected'}
onClick={() => onRowClick?.(row.original)}
className={cn(onRowClick && 'cursor-pointer')}
>
{row.getVisibleCells().map((cell) => {
const truncate = shouldTruncateCell(cell.column);

View File

@@ -1,5 +1,6 @@
'use client';
import type { RefObject } from 'react';
import { useMemo, useState } from 'react';
import { Check, ChevronDown } from 'lucide-react';
@@ -27,6 +28,7 @@ interface SelectPopoverProps {
emptyMessage?: string;
disabled?: boolean;
align?: 'start' | 'center' | 'end';
portalContainer?: RefObject<HTMLDivElement | null>;
}
export function SelectPopover({
@@ -38,6 +40,7 @@ export function SelectPopover({
emptyMessage = 'No options found.',
disabled = false,
align = 'start',
portalContainer,
}: SelectPopoverProps) {
const [open, setOpen] = useState(false);
const [search, setSearch] = useState('');
@@ -70,7 +73,11 @@ export function SelectPopover({
<ChevronDown className="size-4 opacity-60" />
</Button>
</PopoverTrigger>
<PopoverContent align={align} className="w-72 p-0 shadow-none">
<PopoverContent
align={align}
container={portalContainer}
className="w-72 p-0 shadow-none"
>
<div className="border-b p-3">
<Input
value={search}

View File

@@ -21,10 +21,18 @@ function PopoverContent({
className,
align = 'center',
sideOffset = 4,
container,
...props
}: React.ComponentProps<typeof PopoverPrimitive.Content>) {
}: React.ComponentProps<typeof PopoverPrimitive.Content> & {
container?:
| React.ComponentProps<typeof PopoverPrimitive.Portal>['container']
| React.RefObject<HTMLElement | null>;
}) {
const portalContainer =
container && 'current' in container ? container.current : container;
return (
<PopoverPrimitive.Portal>
<PopoverPrimitive.Portal container={portalContainer}>
<PopoverPrimitive.Content
data-slot="popover-content"
align={align}