import type { ColumnDef } from "@tanstack/react-table"; import { ChevronRight } from "lucide-react"; import { SortableHeader } from "@/client/components/table/SortableHeader"; import { dateNullsLast, numericNullsLast, stringNullsLast, } from "@/client/components/table/nullSafeSort"; import { HeaderHelpLabel } from "@/client/features/keywords/components"; import { BacklinksSourceLink } from "./BacklinksPageLinks"; import type { BacklinksRow, GroupedBacklinkDomain } from "./backlinksPageTypes"; import { formatCompactDate, formatDecimal, formatNumber, } from "./backlinksPageUtils"; function BacklinkFlags({ row }: { row: BacklinksRow }) { return (
{row.isLost ? ( Lost ) : null} {row.isBroken ? ( Broken ) : null} {row.isDofollow === false ? ( Nofollow ) : null} {row.linksCount != null && row.linksCount > 1 ? ( {row.linksCount} links ) : null}
); } function DomainFlagBadges({ group }: { group: GroupedBacklinkDomain }) { const badges: Array<{ label: string; className: string }> = []; if (group.lostCount > 0) { badges.push({ label: `${group.lostCount} Lost`, className: "badge badge-sm badge-error badge-outline min-w-fit whitespace-nowrap", }); } if (group.brokenCount > 0) { badges.push({ label: `${group.brokenCount} Broken`, className: "badge badge-sm badge-warning badge-outline min-w-fit whitespace-nowrap", }); } if (group.nofollowCount > 0) { badges.push({ label: `${group.nofollowCount} Nofollow`, className: "badge badge-sm badge-outline min-w-fit whitespace-nowrap", }); } if (badges.length === 0) return null; return (
{badges.map((badge) => ( {badge.label} ))}
); } export const backlinksColumns: ColumnDef[] = [ { id: "source", accessorKey: "domain", header: ({ column }) => ( ), size: 250, minSize: 180, cell: ({ row }) => { if (row.depth > 0) { const child = row.original._backlink; return (
{child?.urlFrom ? ( ) : ( - )}
); } const group = row.original; return (
{group.domain}
{group.backlinkCount}{" "} {group.backlinkCount === 1 ? "backlink" : "backlinks"} ·{" "} {group.targetCount} {group.targetCount === 1 ? "page" : "pages"}
); }, sortingFn: stringNullsLast, }, { id: "target", header: () => ( ), size: 220, minSize: 150, enableSorting: false, cell: ({ row }) => { if (row.depth > 0) { const child = row.original._backlink; return (
{child?.urlTo ? ( ) : ( "-" )}
); } return null; }, }, { id: "anchor", header: () => ( ), size: 150, minSize: 100, enableSorting: false, cell: ({ row }) => { if (row.depth > 0) { const child = row.original._backlink; return (
{child?.anchor || "No anchor text"} {child?.itemType ? (
{child.itemType}
) : null}
); } return null; }, }, { id: "flags", header: () => ( ), size: 130, minSize: 80, enableSorting: false, cell: ({ row }) => { if (row.depth > 0) { const child = row.original._backlink; const hasFlags = child?.isLost || child?.isBroken || child?.isDofollow === false || (child?.linksCount != null && child.linksCount > 1); return hasFlags && child ? : null; } return ; }, }, { id: "linkAuthority", header: () => ( ), size: 70, minSize: 50, enableSorting: false, cell: ({ row }) => { if (row.depth > 0) { const child = row.original._backlink; return (
{formatNumber(child?.rank)}
); } return null; }, }, { id: "domainAuthority", accessorKey: "domainAuthority", header: ({ column }) => ( ), size: 70, minSize: 50, cell: ({ row }) => { if (row.depth > 0) return null; return (
{formatNumber(row.original.domainAuthority)}
); }, sortingFn: numericNullsLast, sortDescFirst: true, }, { id: "spamScore", accessorKey: "spamScore", header: ({ column }) => ( ), size: 70, minSize: 50, cell: ({ row }) => { const value = row.depth > 0 ? row.original._backlink?.spamScore : row.original.spamScore; return (
{value != null && value > 0 ? Math.round(value) : null}
); }, sortingFn: numericNullsLast, sortDescFirst: true, }, { id: "firstSeen", accessorKey: "firstSeen", header: ({ column }) => ( ), size: 110, minSize: 80, cell: ({ row }) => { if (row.depth > 0) { const child = row.original._backlink; return (
{formatCompactDate(child?.firstSeen)}
{child?.lastSeen ? (
Last {formatCompactDate(child.lastSeen)}
) : null}
); } return (
{formatCompactDate(row.original.firstSeen)}
); }, sortingFn: dateNullsLast, sortDescFirst: true, }, ];