mirror of
https://github.com/rgrgogu/new_starr.git
synced 2026-09-27 00:12:54 +08:00
84 lines
2.7 KiB
React
84 lines
2.7 KiB
React
// config/library/lessons/columns.config.jsx
|
|
// Column definitions and pinning for the standalone Lesson Library table.
|
|
|
|
import { Badge } from "@/components/ui/badge";
|
|
import { Clock, Layers, Tag } from "lucide-react";
|
|
import * as LucideIcons from "lucide-react";
|
|
import { buildColumns } from "@/utils/table.util";
|
|
import { buildSelectionColumn } from "@/components/generic/Table/buildSelectionColumn";
|
|
import { buildRowActionsColumn } from "@/components/generic/Table/buildRowActionsColumn";
|
|
import { formatDuration } from "@/utils/timestamp.util";
|
|
import { resolveTierBadge } from "@/utils/tierBadge.util";
|
|
|
|
export const columnPinning = {
|
|
right: ["actions"],
|
|
left: [],
|
|
};
|
|
|
|
function buildCellOverrides(tierMap) {
|
|
return {
|
|
title: (info) => {
|
|
const inUnit = parseInt(info.row.original.unit_count ?? 0, 10) > 0;
|
|
return (
|
|
<div className="flex items-center gap-1.5 min-w-0">
|
|
{inUnit && (
|
|
<Badge variant="secondary" className="gap-1 text-[10px] font-medium shrink-0">
|
|
<Layers className="h-3 w-3" />
|
|
Unit
|
|
</Badge>
|
|
)}
|
|
<span className="block truncate max-w-56 text-sm" title={info.getValue()}>
|
|
{info.getValue()}
|
|
</span>
|
|
</div>
|
|
);
|
|
},
|
|
duration_seconds: (info) => {
|
|
const seconds = parseInt(info.getValue() ?? 0, 10);
|
|
return (
|
|
<div className="flex items-center gap-1.5">
|
|
<Clock className="h-3.5 w-3.5 text-muted-foreground" />
|
|
<Badge variant="secondary" className="text-xs font-medium tabular-nums">
|
|
{formatDuration(seconds)}
|
|
</Badge>
|
|
</div>
|
|
);
|
|
},
|
|
course_count: (info) => {
|
|
const n = parseInt(info.getValue() ?? 0, 10);
|
|
return (
|
|
<Badge variant="secondary" className="text-xs tabular-nums">
|
|
{n} course{n === 1 ? "" : "s"}
|
|
</Badge>
|
|
);
|
|
},
|
|
subscription: (info) => {
|
|
const own = info.getValue();
|
|
// Not gated directly — fall back to the tier(s) inherited from any
|
|
// affiliated course(s) instead of showing a bare "-".
|
|
const slug = own || info.row.original.course_subscription;
|
|
if (!slug) return <span className="text-muted-foreground/40">-</span>;
|
|
|
|
const { label, cls } = resolveTierBadge(slug, tierMap);
|
|
const Icon = LucideIcons[tierMap[slug]?.badge_icon] ?? Tag;
|
|
return (
|
|
<Badge className={cls}>
|
|
<Icon className="size-3" />
|
|
{label}
|
|
</Badge>
|
|
);
|
|
},
|
|
};
|
|
}
|
|
|
|
export function buildDataColumns(attributes, rowActions, tierMap = {}) {
|
|
const visibleAttributes = attributes.filter((a) => !a.hidden);
|
|
const cellOverrides = buildCellOverrides(tierMap);
|
|
|
|
return [
|
|
buildSelectionColumn(),
|
|
...buildColumns(visibleAttributes, { cellOverrides }),
|
|
buildRowActionsColumn(rowActions, { dropdownLabel: "Lesson Actions" }),
|
|
];
|
|
}
|