73 lines
2.8 KiB
TypeScript
73 lines
2.8 KiB
TypeScript
import { type Component, type JSX, createSignal, Show } from "solid-js";
|
|
import { Sidebar, BottomNav } from "./Navigation";
|
|
import { QuickEntry } from "./QuickEntry";
|
|
import { TaskDetail } from "./TaskDetail";
|
|
import { store, activeTaskId, setActiveTaskId } from "@/store";
|
|
import { PanelLeftOpen } from "lucide-solid";
|
|
import { Button } from "./ui/button";
|
|
import { cn } from "@/lib/utils";
|
|
|
|
interface LayoutProps {
|
|
children: JSX.Element;
|
|
currentView: string;
|
|
setView: (v: string) => void;
|
|
}
|
|
|
|
export const Layout: Component<LayoutProps> = (props) => {
|
|
const [isSidebarLocked, setIsSidebarLocked] = createSignal(true);
|
|
const [isSidebarPeeking, setIsSidebarPeeking] = createSignal(false);
|
|
|
|
// Derived active task for the detail view
|
|
const activeTask = () => store.tasks.find(t => t.id === activeTaskId());
|
|
|
|
return (
|
|
<div class="flex h-screen w-full bg-background overflow-hidden relative font-sans antialiased text-foreground">
|
|
<Sidebar
|
|
currentView={props.currentView}
|
|
setView={props.setView}
|
|
isLocked={isSidebarLocked()}
|
|
setIsLocked={setIsSidebarLocked}
|
|
isPeeking={isSidebarPeeking()}
|
|
setIsPeeking={setIsSidebarPeeking}
|
|
/>
|
|
|
|
<div class={cn(
|
|
"flex-1 flex flex-col h-full transition-all duration-300 ease-in-out relative",
|
|
isSidebarLocked() ? "md:ml-48" : "ml-0"
|
|
)}>
|
|
{/* Expand Trigger Button (visible when not locked) */}
|
|
{!isSidebarLocked() && (
|
|
<div class="fixed top-4 left-4 z-[60] md:flex hidden">
|
|
<Button
|
|
variant="ghost"
|
|
size="icon"
|
|
onMouseEnter={() => setIsSidebarPeeking(true)}
|
|
onClick={() => setIsSidebarLocked(true)}
|
|
class="bg-background/80 backdrop-blur-sm border border-border hover:bg-muted shadow-sm"
|
|
>
|
|
<PanelLeftOpen size={18} />
|
|
</Button>
|
|
</div>
|
|
)}
|
|
|
|
<main class="flex-1 overflow-auto p-4 md:p-8 pt-4 pb-20 md:pb-8 scroll-smooth relative z-0">
|
|
{props.children}
|
|
</main>
|
|
|
|
{/* Mobile Bottom Nav */}
|
|
<BottomNav currentView={props.currentView} setView={props.setView} />
|
|
</div>
|
|
|
|
<QuickEntry />
|
|
|
|
<Show when={activeTask()}>
|
|
<TaskDetail
|
|
task={activeTask()!}
|
|
isOpen={!!activeTaskId()}
|
|
onClose={() => setActiveTaskId(null)}
|
|
/>
|
|
</Show>
|
|
</div>
|
|
);
|
|
};
|