🚧 make labels column paid, and cleanup

This commit is contained in:
Fred KISSIE
2026-05-11 18:13:19 +02:00
parent 8a0c2031d4
commit 21f72639b6

View File

@@ -37,8 +37,7 @@ import {
ChevronDown, ChevronDown,
ChevronsUpDownIcon, ChevronsUpDownIcon,
MoreHorizontal, MoreHorizontal,
PlusIcon, PlusIcon
XIcon
} from "lucide-react"; } from "lucide-react";
import { useTranslations } from "next-intl"; import { useTranslations } from "next-intl";
import Link from "next/link"; import Link from "next/link";
@@ -58,9 +57,11 @@ import {
type ExtendedColumnDef type ExtendedColumnDef
} from "./ui/controlled-data-table"; } from "./ui/controlled-data-table";
import { cn } from "@app/lib/cn";
import { LabelsSelector, type SelectedLabel } from "./labels-selector"; import { LabelsSelector, type SelectedLabel } from "./labels-selector";
import { Popover, PopoverContent, PopoverTrigger } from "./ui/popover"; import { Popover, PopoverContent, PopoverTrigger } from "./ui/popover";
import { cn } from "@app/lib/cn"; import { usePaidStatus } from "@app/hooks/usePaidStatus";
import { tierMatrix } from "@server/lib/billing/tierMatrix";
export type SiteRow = { export type SiteRow = {
id: number; id: number;
@@ -110,10 +111,12 @@ export default function SitesTable({
const [selectedSite, setSelectedSite] = useState<SiteRow | null>(null); const [selectedSite, setSelectedSite] = useState<SiteRow | null>(null);
const [resourcesDialogSite, setResourcesDialogSite] = const [resourcesDialogSite, setResourcesDialogSite] =
useState<SiteRow | null>(null); useState<SiteRow | null>(null);
const [isLabelsDialogOpen, setIsLabelsDialogOpen] = useState(false);
const [isRefreshing, startTransition] = useTransition(); const [isRefreshing, startTransition] = useTransition();
const [isNavigatingToAddPage, startNavigation] = useTransition(); const [isNavigatingToAddPage, startNavigation] = useTransition();
const { isPaidUser } = usePaidStatus();
const isLabelFeatureEnabled = isPaidUser(tierMatrix.labels);
const api = createApiClient(useEnvContext()); const api = createApiClient(useEnvContext());
const t = useTranslations(); const t = useTranslations();
@@ -466,18 +469,26 @@ export default function SitesTable({
); );
} }
}, },
// The label feature should be added to the tiers ...(isLabelFeatureEnabled
{ ? [
accessorKey: "labels", {
header: () => ( accessorKey: "labels",
<span className="p-3 text-end w-full inline-block"> header: () => (
{t("labels")} <span className="p-3 text-end w-full inline-block">
</span> {t("labels")}
), </span>
cell: ({ row }) => { ),
return <SiteLabelCell site={row.original} orgId={orgId} />; cell: ({ row }: { row: { original: SiteRow } }) => {
} return (
}, <SiteLabelCell
site={row.original}
orgId={orgId}
/>
);
}
}
]
: []),
{ {
id: "actions", id: "actions",
enableHiding: false, enableHiding: false,
@@ -518,24 +529,6 @@ export default function SitesTable({
{t("sitesTableViewPrivateResources")} {t("sitesTableViewPrivateResources")}
</DropdownMenuItem> </DropdownMenuItem>
</Link> </Link>
<DropdownMenuItem
onClick={() => {
setSelectedSite(siteRow);
setIsLabelsDialogOpen(true);
}}
>
<span>{t("addLabels")}</span>
</DropdownMenuItem>
<DropdownMenuItem
onClick={() => {
setSelectedSite(siteRow);
setIsDeleteModalOpen(true);
}}
>
<span className="text-red-500">
{t("delete")}
</span>
</DropdownMenuItem>
</DropdownMenuContent> </DropdownMenuContent>
</DropdownMenu> </DropdownMenu>
<Link <Link
@@ -616,27 +609,25 @@ export default function SitesTable({
</Credenza> </Credenza>
{selectedSite && ( {selectedSite && (
<> <ConfirmDeleteDialog
<ConfirmDeleteDialog open={isDeleteModalOpen}
open={isDeleteModalOpen} setOpen={(val) => {
setOpen={(val) => { setIsDeleteModalOpen(val);
setIsDeleteModalOpen(val); setSelectedSite(null);
setSelectedSite(null); }}
}} dialog={
dialog={ <div className="space-y-2">
<div className="space-y-2"> <p>{t("siteQuestionRemove")}</p>
<p>{t("siteQuestionRemove")}</p> <p>{t("siteMessageRemove")}</p>
<p>{t("siteMessageRemove")}</p> </div>
</div> }
} buttonText={t("siteConfirmDelete")}
buttonText={t("siteConfirmDelete")} onConfirm={async () =>
onConfirm={async () => startTransition(() => deleteSite(selectedSite!.id))
startTransition(() => deleteSite(selectedSite!.id)) }
} string={selectedSite.name}
string={selectedSite.name} title={t("siteDelete")}
title={t("siteDelete")} />
/>
</>
)} )}
<ControlledDataTable <ControlledDataTable
@@ -732,11 +723,11 @@ function SiteLabelCell({ site, orgId }: SiteLabelCellProps) {
<Button <Button
key={label.labelId} key={label.labelId}
variant="outline" variant="outline"
onClick={() => toggleSiteLabel(label, "detach")} onClick={() => setIsPopoverOpen(true)}
className={cn( className={cn(
"inline-flex gap-1 items-center", "inline-flex gap-1 items-center",
"rounded-full text-sm cursor-pointer", "rounded-full text-sm cursor-pointer",
"px-1.5 py-0 h-auto" "pl-1.5 pr-2 py-0 h-auto"
)} )}
> >
<div <div
@@ -746,11 +737,9 @@ function SiteLabelCell({ site, orgId }: SiteLabelCellProps) {
"--color": label.color "--color": label.color
}} }}
/> />
<span className="whitespace-nowrap text-ellipsis max-w-16 overflow-hidden relative bottom-0.5"> <span className="whitespace-nowrap text-ellipsis max-w-16 overflow-hidden relative">
{label.name} {label.name}
</span> </span>
<XIcon className="size-3 flex-none" />
</Button> </Button>
))} ))}
{optimisticLabels.length > 3 && ( {optimisticLabels.length > 3 && (