Skip to content

Dashboard: Update team layout #7464

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions apps/dashboard/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"@radix-ui/react-alert-dialog": "^1.1.14",
"@radix-ui/react-avatar": "^1.1.10",
"@radix-ui/react-checkbox": "^1.3.2",
"@radix-ui/react-collapsible": "^1.1.11",
"@radix-ui/react-dialog": "1.1.14",
"@radix-ui/react-dropdown-menu": "^2.1.15",
"@radix-ui/react-hover-card": "^1.1.14",
Expand Down
21 changes: 20 additions & 1 deletion apps/dashboard/redirects.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,27 @@ const projectPageRedirects = [
source: `${projectRoute}/nebula/:path*`,
},
{
source: `${projectRoute}/connect/analytics`,
destination: `${projectRoute}`,
permanent: false,
source: `${projectRoute}/connect/analytics`,
},
];

const teamPageRedirects = [
{
destination: "/team/:team_slug/~/billing/:path*",
permanent: false,
source: "/team/:team_slug/~/settings/billing/:path*",
},
{
destination: "/team/:team_slug/~/billing/invoices/:path*",
permanent: false,
source: "/team/:team_slug/~/settings/invoices/:path*",
},
{
destination: "/team/:team_slug/~/billing",
permanent: false,
source: "/team/:team_slug/~/settings/credits",
},
];

Expand Down Expand Up @@ -426,6 +444,7 @@ async function redirects() {
},
...legacyDashboardToTeamRedirects,
...projectPageRedirects,
...teamPageRedirects,
];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ import {
SelectValue,
} from "@/components/ui/select";
import { normalizeTime } from "@/lib/time";
import { cn } from "@/lib/utils";

export function DateRangeSelector(props: {
range: Range;
setRange: (range: Range) => void;
popoverAlign?: "start" | "end" | "center";
className?: string;
}) {
const { range, setRange } = props;
const daysDiff = differenceInCalendarDays(range.to, range.from);
Expand All @@ -26,7 +28,7 @@ export function DateRangeSelector(props: {

return (
<DatePickerWithRange
className="w-auto bg-card"
className={cn("w-auto bg-card", props.className)}
from={range.from}
header={
<div className="mb-2 border-border border-b p-4">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,9 @@ export function RangeSelector({
});

return (
<div className="flex justify-end gap-4">
<div className="flex justify-end gap-3 flex-col lg:flex-row">
<DateRangeSelector
className="rounded-full"
range={localRange}
setRange={(newRange) => {
setRange(newRange);
Expand All @@ -89,7 +90,7 @@ export function RangeSelector({
}}
/>
<IntervalSelector
className="bg-card"
className="bg-card rounded-full"
intervalType={localInterval}
setIntervalType={(newInterval) => {
setInterval(newInterval);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ function UnpaidInvoicesWarning({ teamSlug }: { teamSlug: string }) {

<Button asChild className="w-full gap-2 bg-card" variant="outline">
<Link
href={`/team/${teamSlug}/~/settings/invoices?status=open`}
href={`/team/${teamSlug}/~/billing/invoices?status=open`}
rel="noopener noreferrer"
target="_blank"
>
Expand Down
2 changes: 1 addition & 1 deletion apps/dashboard/src/@/components/billing/billing.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ function BillingWarning({ teamSlug }: { teamSlug: string }) {
You have outstanding invoices. Please{" "}
<Link
className="font-medium text-amber-700 underline transition-colors hover:text-amber-900 dark:text-amber-400 dark:hover:text-amber-300"
href={`/team/${teamSlug}/~/settings/invoices?status=open`}
href={`/team/${teamSlug}/~/billing/invoices?status=open`}
>
pay them
</Link>{" "}
Expand Down
2 changes: 1 addition & 1 deletion apps/dashboard/src/@/components/blocks/GatedSwitch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export const GatedSwitch: React.FC<GatedSwitchProps> = (
<div className="flex w-full flex-col gap-2">
<Button asChild className="justify-start gap-2" size="sm">
<Link
href={`/team/${props.teamSlug}/~/settings/billing?showPlans=true&highlight=${props.requiredPlan}`}
href={`/team/${props.teamSlug}/~/billing?showPlans=true&highlight=${props.requiredPlan}`}
rel="noopener noreferrer"
target="_blank"
>
Expand Down
2 changes: 1 addition & 1 deletion apps/dashboard/src/@/components/blocks/MobileSidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export function MobileSidebar(props: {
);
}

export function useActiveSidebarLink(links: SidebarLink[]) {
function useActiveSidebarLink(links: SidebarLink[]) {
const pathname = usePathname();

const activeLink = useMemo(() => {
Expand Down
149 changes: 3 additions & 146 deletions apps/dashboard/src/@/components/blocks/SidebarLayout.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,7 @@
import {
Sidebar,
SidebarContent,
SidebarFooter,
SidebarGroup,
SidebarGroupContent,
SidebarGroupLabel,
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
SidebarMenuSubItem,
SidebarRail,
SidebarSeparator,
SidebarTrigger,
useSidebar,
} from "@/components/ui/sidebar";
"use client";

import { cn } from "../../lib/utils";
import { AppFooter } from "../footers/app-footer";
import { NavLink } from "../ui/NavLink";
import { Separator } from "../ui/separator";
import { MobileSidebar, useActiveSidebarLink } from "./MobileSidebar";
import { MobileSidebar } from "./MobileSidebar";
import { CustomSidebar, type SidebarLink } from "./Sidebar";

export function SidebarLayout(props: {
Expand Down Expand Up @@ -51,129 +34,3 @@ export function SidebarLayout(props: {
</div>
);
}

export function FullWidthSidebarLayout(props: {
contentSidebarLinks: SidebarLink[];
footerSidebarLinks?: SidebarLink[];
children: React.ReactNode;
className?: string;
}) {
const { contentSidebarLinks, children, footerSidebarLinks } = props;
return (
<div
className={cn(
"relative flex w-full flex-1 overflow-y-hidden",
props.className,
)}
>
{/* left - sidebar */}
<Sidebar className="pt-2" collapsible="icon" side="left">
<SidebarContent className="p-2">
<RenderSidebarMenu links={contentSidebarLinks} />
</SidebarContent>

{footerSidebarLinks && (
<SidebarFooter className="pb-3">
<RenderSidebarMenu links={footerSidebarLinks} />
</SidebarFooter>
)}

<SidebarRail />
</Sidebar>

{/* right - content */}
<div className="flex h-full flex-grow flex-col overflow-y-auto">
<MobileSidebarTrigger
links={[...contentSidebarLinks, ...(footerSidebarLinks || [])]}
/>

<main className="flex min-w-0 grow flex-col max-sm:w-full">
{children}
</main>
<AppFooter containerClassName="max-w-7xl" />
</div>
</div>
);
}

function RenderSidebarGroup(props: {
sidebarLinks: SidebarLink[];
groupName: string;
}) {
return (
<SidebarGroup className="p-0">
<SidebarMenuItem>
<SidebarGroupLabel> {props.groupName}</SidebarGroupLabel>
<SidebarGroupContent>
<RenderSidebarMenu links={props.sidebarLinks} />
</SidebarGroupContent>
</SidebarMenuItem>
</SidebarGroup>
);
}

function RenderSidebarMenu(props: { links: SidebarLink[] }) {
const sidebar = useSidebar();
return (
<SidebarMenu className="gap-1.5">
{props.links.map((link, idx) => {
// link
if ("href" in link) {
return (
<SidebarMenuSubItem key={link.href}>
<SidebarMenuButton asChild>
<NavLink
activeClassName="text-foreground bg-accent"
className="flex items-center gap-2 text-muted-foreground text-sm hover:bg-accent"
exactMatch={link.exactMatch}
href={link.href}
isActive={link.isActive}
onClick={() => {
sidebar.setOpenMobile(false);
}}
>
{link.icon && <link.icon className="size-4" />}
<span>{link.label}</span>
</NavLink>
</SidebarMenuButton>
</SidebarMenuSubItem>
);
}

// separator
if ("separator" in link) {
return (
<SidebarSeparator
className="my-1"
key={`separator-${
// biome-ignore lint/suspicious/noArrayIndexKey: index is fine here
idx
}`}
/>
);
}

// group
return (
<RenderSidebarGroup
groupName={link.group}
key={link.group}
sidebarLinks={link.links}
/>
);
})}
</SidebarMenu>
);
}

function MobileSidebarTrigger(props: { links: SidebarLink[] }) {
const activeLink = useActiveSidebarLink(props.links);

return (
<div className="flex items-center gap-3 border-b px-4 py-4 lg:hidden">
<SidebarTrigger className="size-4" />
<Separator className="h-4" orientation="vertical" />
{activeLink && <span className="text-sm">{activeLink.label}</span>}
</div>
);
}
2 changes: 1 addition & 1 deletion apps/dashboard/src/@/components/blocks/TeamPlanBadge.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export function TeamPlanBadge(props: {
}
e.stopPropagation();
e.preventDefault();
router.push(`/team/${props.teamSlug}/~/settings/billing?showPlans=true`);
router.push(`/team/${props.teamSlug}/~/billing?showPlans=true`);
}

return (
Expand Down
Loading
Loading