70 lines
2.6 KiB
TypeScript
70 lines
2.6 KiB
TypeScript
import React from "react";
|
|
import { useMatches } from "react-router";
|
|
import { useShallow } from "zustand/react/shallow";
|
|
import { useServerListStore } from "~/stores/server-list-store";
|
|
import { CreateServerButton } from "./custom-ui/create-server-button";
|
|
import { HomeButton } from "./custom-ui/home-button";
|
|
import { ServerButton } from "./custom-ui/server-button";
|
|
import UserStatus from "./custom-ui/user-status";
|
|
import { ScrollArea } from "./ui/scroll-area";
|
|
import { Separator } from "./ui/separator";
|
|
|
|
interface AppLayoutProps {
|
|
children: React.ReactNode;
|
|
}
|
|
|
|
export default function AppLayout({ children }: AppLayoutProps) {
|
|
let servers = Object.values(useServerListStore(useShallow((state) => state.servers)));
|
|
|
|
const matches = useMatches();
|
|
|
|
let list = React.useMemo(() => {
|
|
return matches
|
|
.map(
|
|
(match) =>
|
|
(
|
|
match.handle as {
|
|
listComponent?: React.ReactNode;
|
|
}
|
|
)?.listComponent,
|
|
)
|
|
.reverse()
|
|
.find((component) => !!component);
|
|
}, [matches]);
|
|
|
|
return (
|
|
<div className="flex h-screen w-screen overflow-hidden">
|
|
<div
|
|
className="grid h-full max-h-screen bg-background min-w-80 border-r-2"
|
|
style={{
|
|
gridTemplateColumns: "auto 1fr",
|
|
gridTemplateRows: "1fr auto",
|
|
}}
|
|
>
|
|
<div className="col-start-1 row-start-1 col-span-1 row-span-1 overflow-hidden border-r-2 min-w-fit">
|
|
<ScrollArea className="h-full px-1" scrollbarSize="none">
|
|
<aside className="flex flex-col gap-2 p-2 h-full">
|
|
<HomeButton />
|
|
<Separator />
|
|
{servers.map((server, _) => (
|
|
<React.Fragment key={server.id}>
|
|
<ServerButton server={server} />
|
|
</React.Fragment>
|
|
))}
|
|
{servers.length > 0 && <Separator />}
|
|
<CreateServerButton />
|
|
</aside>
|
|
</ScrollArea>
|
|
</div>
|
|
<div className="col-start-2 row-start-1 col-span-1 row-span-1 overflow-hidden">{list}</div>
|
|
|
|
<div className="col-start-1 row-start-2 col-span-2 row-span-1 mb-2 mx-2 min-w-fit z-1">
|
|
<UserStatus />
|
|
</div>
|
|
</div>
|
|
|
|
<div className="grow">{children}</div>
|
|
</div>
|
|
);
|
|
}
|