import {
ArrowLeftIcon,
ChartNoAxesColumnIcon,
GitPullRequestIcon,
SettingsIcon,
} from "lucide-react";
import type { ReactNode } from "react";
import { memo, useCallback } from "react";
import { Link, useCanGoBack, useLocation, useNavigate } from "@tanstack/react-router";
import { useEnvironmentIdentificationMode } from "../../hooks/useSettings";
import { cn } from "../../lib/utils";
import { useEnvironments } from "../../state/environments";
import { T3Wordmark } from "../T3Wordmark";
import {
resolveEnvironmentIdentificationPillLabel,
resolveSidebarStageBackdropVariant,
resolveSidebarStageFocusRingOffsetClass,
SidebarStageBackdrop,
useEnvironmentStageLabel,
} from "../SidebarStageBackdrop";
import { Badge } from "../ui/badge";
import {
SidebarFooter,
SidebarHeader,
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
SidebarTrigger,
useSidebar,
} from "../ui/sidebar";
import { Tooltip, TooltipPopup, TooltipTrigger } from "../ui/tooltip";
import { readPullRequestListPreferences } from "../pullRequest/pullRequestListPreferences";
import { SidebarProviderUpdatePill } from "./SidebarProviderUpdatePill";
import { SidebarUpdateArchitectureWarning, SidebarUpdatePill } from "./SidebarUpdatePill";
export const SidebarChromeHeader = memo(function SidebarChromeHeader({
isElectron,
}: {
isElectron: boolean;
}) {
const stageLabel = useEnvironmentStageLabel();
const environmentIdentificationMode = useEnvironmentIdentificationMode();
const backdropVariant = resolveSidebarStageBackdropVariant(
stageLabel,
environmentIdentificationMode === "artwork",
);
const pillLabel =
environmentIdentificationMode === "pill"
? resolveEnvironmentIdentificationPillLabel(stageLabel)
: null;
return (
{backdropVariant ? : null}
{pillLabel ? (
{pillLabel}
) : null}
);
});
function SidebarBrand({ onBackdrop }: { onBackdrop: boolean }) {
return (
Code
);
}
function SidebarUtilityItem({
icon,
label,
onClick,
}: {
icon: ReactNode;
label: string;
onClick: () => void;
}) {
return (
{icon}
}
/>
{label}
);
}
export const SidebarUtilityMenu = memo(function SidebarUtilityMenu() {
const navigate = useNavigate();
const canGoBack = useCanGoBack();
const { isMobile, setOpenMobile } = useSidebar();
const currentFooterPage = useLocation({
select: (location) =>
/^\/settings(?:\/|$)/.test(location.pathname)
? "settings"
: /^\/projects\/[^/]+\/?$/.test(location.pathname)
? "project-settings"
: location.pathname === "/usage"
? "usage"
: location.pathname === "/pull-requests"
? "pull-requests"
: null,
});
const { environments } = useEnvironments();
// The page reads every connected server, so one of them offering pull requests is enough for
// the link to lead somewhere.
const pullRequestsSupported = environments.some(
(environment) => environment.serverConfig?.environment.capabilities.pullRequests === true,
);
const closeMobileSidebar = useCallback(() => {
if (isMobile) {
setOpenMobile(false);
}
}, [isMobile, setOpenMobile]);
const handlePullRequestsClick = useCallback(() => {
closeMobileSidebar();
void navigate({
to: "/pull-requests",
search: readPullRequestListPreferences(),
});
}, [closeMobileSidebar, navigate]);
const handleSettingsClick = useCallback(() => {
closeMobileSidebar();
void navigate({ to: "/settings" });
}, [closeMobileSidebar, navigate]);
const handleUsageClick = useCallback(() => {
if (isMobile) {
setOpenMobile(false);
}
void navigate({ to: "/usage" });
}, [isMobile, navigate, setOpenMobile]);
const handleBackClick = useCallback(() => {
closeMobileSidebar();
if (canGoBack) {
window.history.back();
return;
}
void navigate({ to: "/" });
}, [canGoBack, closeMobileSidebar, navigate]);
return (
{currentFooterPage ? (
Back
) : (
<>
}
label="Settings"
onClick={handleSettingsClick}
/>
{pullRequestsSupported ? (
}
label="Pull Requests"
onClick={handlePullRequestsClick}
/>
) : null}
}
label="Usage"
onClick={handleUsageClick}
/>
>
)}
);
});
export const SidebarChromeFooter = memo(function SidebarChromeFooter() {
return (
);
});