feat: took header out

This commit is contained in:
ivannoskov
2026-03-03 21:35:10 +03:00
parent 9b509df12f
commit ef903f1b23
3 changed files with 348 additions and 210 deletions

View File

@@ -0,0 +1,126 @@
"use client";
import { ArrowUpDown } from "lucide-react";
import { cn } from "@/lib/utils";
import { ALL_COLUMNS, getColumnStyle, type ColumnConfig } from "@/lib/config/placement-columns";
interface SortOption {
field: string;
direction: "asc" | "desc";
}
interface PlacementsTableHeaderProps {
visibleColumns: Set<string>;
sort?: SortOption | null;
onSort?: (field: string) => void;
}
const SORT_FIELD_TO_COLUMN: Record<string, string> = {
cost: "cost",
date: "planned_date",
cpm: "cpm",
cpf: "cpf",
subscribers: "subscriptions",
views: "views",
created: "created",
};
export function PlacementsTableHeader({
visibleColumns,
sort,
onSort,
}: PlacementsTableHeaderProps) {
const visibleColumnConfigs = ALL_COLUMNS.filter((c) =>
visibleColumns.has(c.id)
);
const handleSort = (column: ColumnConfig) => {
if (!column.sortable || !onSort) return;
const sortField = Object.entries(SORT_FIELD_TO_COLUMN).find(
([, colId]) => colId === column.id
)?.[0];
if (sortField) {
onSort(sortField);
}
};
const getSortDirection = (column: ColumnConfig): "asc" | "desc" | null => {
if (!sort || !column.sortable) return null;
const sortField = Object.entries(SORT_FIELD_TO_COLUMN).find(
([, colId]) => colId === column.id
)?.[0];
if (sortField && sort.field === sortField) {
return sort.direction;
}
return null;
};
return (
<div
className="sticky top-0 z-10 bg-background border-b"
>
<div
className="grid text-sm"
style={{
gridTemplateColumns: visibleColumnConfigs
.map((c) => getColumnStyle(c))
.join(" "),
}}
>
{visibleColumnConfigs.map((column) => {
const sortDir = getSortDirection(column);
return (
<div
key={column.id}
className={cn(
"py-2 px-3 font-medium text-muted-foreground flex items-center gap-1.5",
column.sortable && "cursor-pointer hover:text-foreground transition-colors"
)}
onClick={() => handleSort(column)}
title={column.sortable ? "Нажмите для сортировки" : undefined}
>
{column.editable && (
<span
className="flex items-center gap-0.5"
title={column.partialEdit ? "Частично редактируемое" : "Редактируемое"}
>
<span className="text-[10px] opacity-40 flex items-center gap-0.5">
(
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
className="h-3 w-3"
>
<path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" />
<path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" />
</svg>
)
</span>
</span>
)}
<span className="whitespace-nowrap">{column.label}</span>
{column.sortable && (
<ArrowUpDown
className={cn(
"h-3 w-3 opacity-40",
sortDir && "opacity-100 text-primary"
)}
/>
)}
</div>
);
})}
</div>
</div>
);
}