'use client';
/**
* Small shared client helpers for the admin tables: a clickable sortable
* column header and a CSV-download trigger. Kept dependency-free and
* dark-theme consistent with globals.css.
*/
export type SortOrder = 'asc' | 'desc';
export function SortHeader({
label,
col,
sort,
order,
onSort,
className,
}: {
label: string;
col: string;
sort: string;
order: SortOrder;
onSort: (col: string) => void;
className?: string;
}) {
const active = sort === col;
const indicator = active ? (order === 'asc' ? '▲' : '▼') : '↕';
return (
onSort(col)}
role="button"
tabIndex={0}
aria-sort={active ? (order === 'asc' ? 'ascending' : 'descending') : 'none'}
onKeyDown={(e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
onSort(col);
}
}}
>
{label}
{indicator}
|
);
}
/**
* Triggers a browser download of a same-origin URL. The server sets
* Content-Disposition: attachment, so the cookie-authenticated GET streams the
* CSV straight to a file.
*/
export function downloadUrl(url: string): void {
const a = document.createElement('a');
a.href = url;
a.rel = 'noopener';
document.body.appendChild(a);
a.click();
a.remove();
}