refactor(ui): redesign mobile card layout in Table component

- replace fixed column-slice layout with mobileHidden filter for flexible column visibility
- render primary column as prominent header with semantic styling
- display remaining columns in a responsive 2-column dl grid with label/value pairs
- update MobileSkeletonCard to reflect new grid structure based on visible column count
This commit is contained in:
2026-04-24 17:50:41 -04:00
parent 5743eb7f53
commit b90b4e7bcc
+37 -33
View File
@@ -101,49 +101,53 @@ const Table = ({
return value || '-'; return value || '-';
}; };
const MobileCard = ({ item }) => ( const MobileCard = ({ item }) => {
<div className={`${sizeClasses.mobile} space-y-3`}> const visible = columns.filter((col) => !col.mobileHidden);
<div className="flex items-start justify-between"> const [primary, ...rest] = visible;
<div className="flex-1"> return (
{columns.slice(0, 2).map((column) => ( <div className={`${sizeClasses.mobile} space-y-2.5`}>
<div key={column.key} className={column.key === columns[0]?.key ? 'mb-2' : ''}> {primary && (
<div className="text-sm font-medium text-neutral-900 dark:text-white">
{renderCellContent(item, primary)}
</div>
)}
{rest.length > 0 && (
<dl className="grid grid-cols-2 gap-x-4 gap-y-2.5">
{rest.map((column) => (
<div key={column.key}>
<dt className="text-[11px] font-medium uppercase tracking-[0.04em] text-neutral-400 dark:text-neutral-500">
{column.label}
</dt>
<dd className="mt-0.5 text-xs text-neutral-700 dark:text-neutral-300">
{renderCellContent(item, column)} {renderCellContent(item, column)}
</dd>
</div> </div>
))} ))}
</dl>
)}
</div> </div>
<div className="flex flex-col gap-2 ml-4"> );
{columns.slice(2, 4).map((column) => ( };
<div key={column.key}>{renderCellContent(item, column)}</div>
))} const MobileSkeletonCard = () => {
</div> const visibleCount = columns.filter((col) => !col.mobileHidden).length;
</div> const restCount = Math.min(Math.max(0, visibleCount - 1), 4);
{columns.length > 4 && ( return (
<div className="text-xs text-neutral-500 dark:text-neutral-400"> <div className={`${sizeClasses.mobile} space-y-2.5`}>
{columns.slice(4).map((column) => ( <Skeleton height="h-4" width="55%" />
<div key={column.key} className="mb-1"> {restCount > 0 && (
<span className="font-medium">{column.label}:</span> {renderCellContent(item, column)} <div className="grid grid-cols-2 gap-x-4 gap-y-3">
{Array.from({ length: restCount }).map((_, i) => (
<div key={i} className="space-y-1">
<Skeleton height="h-2.5" width="40%" />
<Skeleton height="h-3.5" width="70%" />
</div> </div>
))} ))}
</div> </div>
)} )}
</div> </div>
); );
};
const MobileSkeletonCard = () => (
<div className={`${sizeClasses.mobile} space-y-3`}>
<div className="flex items-start justify-between">
<div className="space-y-2 flex-1">
<Skeleton height="h-4" width="70%" />
<Skeleton height="h-3" width="40%" />
</div>
<div className="flex flex-col gap-2 ml-4">
<Skeleton cx="rounded-full" height="h-6" width="80px" />
<Skeleton cx="rounded-full" height="h-6" width="90px" />
</div>
</div>
<Skeleton height="h-3" width="50%" />
</div>
);
const getPageNumbers = () => { const getPageNumbers = () => {
const pages = []; const pages = [];