1+ import { OrganizationSwitcher , useClerk } from "@clerk/clerk-react" ;
12import {
23 faArrowUpRight ,
34 faLink ,
@@ -6,7 +7,12 @@ import {
67 Icon ,
78} from "@rivet-gg/icons" ;
89import { useQuery } from "@tanstack/react-query" ;
9- import { Link , useMatchRoute , useNavigate } from "@tanstack/react-router" ;
10+ import {
11+ Link ,
12+ useMatch ,
13+ useMatchRoute ,
14+ useNavigate ,
15+ } from "@tanstack/react-router" ;
1016import {
1117 type ComponentProps ,
1218 createContext ,
@@ -20,8 +26,10 @@ import {
2026 useState ,
2127} from "react" ;
2228import type { ImperativePanelGroupHandle } from "react-resizable-panels" ;
29+ import { match } from "ts-pattern" ;
2330import {
2431 Button ,
32+ type ButtonProps ,
2533 cn ,
2634 DocsSheet ,
2735 type ImperativePanelHandle ,
@@ -146,13 +154,25 @@ const Sidebar = ({
146154 />
147155 </ Link >
148156 < div className = "flex flex-1 flex-col gap-4 px-2 min-h-0" >
149- { __APP_TYPE__ === "inspector" ? (
150- < ConnectionStatus />
151- ) : null }
152- { __APP_TYPE__ === "engine" ? < Breadcrumbs /> : null }
153- < ScrollArea >
154- < Subnav />
155- </ ScrollArea >
157+ { match ( __APP_TYPE__ )
158+ . with ( "engine" , ( ) => (
159+ < >
160+ < ConnectionStatus />
161+ < ScrollArea >
162+ < Subnav />
163+ </ ScrollArea >
164+ </ >
165+ ) )
166+ . with ( "inspector" , ( ) => (
167+ < >
168+ < Breadcrumbs />
169+ < ScrollArea >
170+ < Subnav />
171+ </ ScrollArea >
172+ </ >
173+ ) )
174+ . with ( "cloud" , ( ) => < CloudSidebar /> )
175+ . exhaustive ( ) }
156176 </ div >
157177 < div >
158178 < div className = "border-t p-2 flex flex-col gap-[1px] text-sm" >
@@ -241,7 +261,7 @@ const Footer = () => {
241261
242262export { Root , Main , Header , Footer , VisibleInFull , Sidebar } ;
243263
244- const Breadcrumbs = ( ) => {
264+ const Breadcrumbs = ( ) : ReactNode => {
245265 const matchRoute = useMatchRoute ( ) ;
246266 const nsMatch = matchRoute ( {
247267 to : "/ns/$namespace" ,
@@ -341,26 +361,37 @@ const Subnav = () => {
341361
342362function HeaderLink ( { icon, children, className, ...props } : HeaderLinkProps ) {
343363 return (
344- < Button
364+ < HeaderButton
345365 asChild
346366 variant = "ghost"
347367 { ...props }
348- className = { cn (
349- "text-muted-foreground px-2 aria-current-page:text-foreground relative h-auto py-1 justify-start" ,
350- className ,
351- ) }
352368 startIcon = {
353369 icon ? (
354370 < Icon className = { cn ( "size-5 opacity-80" ) } icon = { icon } />
355371 ) : undefined
356372 }
357373 >
358374 < Link to = { props . to } > { children } </ Link >
375+ </ HeaderButton >
376+ ) ;
377+ }
378+
379+ function HeaderButton ( { children, className, ...props } : ButtonProps ) {
380+ return (
381+ < Button
382+ variant = "ghost"
383+ { ...props }
384+ className = { cn (
385+ "text-muted-foreground px-2 aria-current-page:text-foreground relative h-auto py-1 justify-start" ,
386+ className ,
387+ ) }
388+ >
389+ { children }
359390 </ Button >
360391 ) ;
361392}
362393
363- function ConnectionStatus ( ) {
394+ function ConnectionStatus ( ) : ReactNode {
364395 const { endpoint, ...queries } = useManager ( ) ;
365396 const { setCredentials } = useInspectorCredentials ( ) ;
366397 const { isLoading, isError, isSuccess } = useQuery (
@@ -414,4 +445,48 @@ function ConnectionStatus() {
414445 </ div >
415446 ) ;
416447 }
448+
449+ return null ;
450+ }
451+
452+ function CloudSidebar ( ) : ReactNode {
453+ const match = useMatch ( {
454+ from : "/_layout/orgs/$organization/" ,
455+ shouldThrow : false ,
456+ } ) ;
457+
458+ const clerk = useClerk ( ) ;
459+ return (
460+ < >
461+ < OrganizationSwitcher />
462+
463+ < ScrollArea >
464+ < div className = "flex gap-1.5 flex-col" >
465+ < HeaderLink
466+ to = "/orgs/$organization"
467+ className = "font-normal"
468+ params = { match ?. params }
469+ >
470+ Projects
471+ </ HeaderLink >
472+ < HeaderButton
473+ onClick = { ( ) => {
474+ clerk . openUserProfile ( {
475+ __experimental_startPath : "/billing" ,
476+ } ) ;
477+ } }
478+ >
479+ Billing
480+ </ HeaderButton >
481+ < HeaderButton
482+ onClick = { ( ) => {
483+ clerk . openUserProfile ( ) ;
484+ } }
485+ >
486+ Settings
487+ </ HeaderButton >
488+ </ div >
489+ </ ScrollArea >
490+ </ >
491+ ) ;
417492}
0 commit comments