| 1 | import { MessageSquareDashedIcon, PlusIcon } from "lucide-react"; |
| 2 | import { useCallback } from "react"; |
| 3 | |
| 4 | import { openCommandPalette } from "../commandPaletteBus"; |
| 5 | import { isElectron } from "../env"; |
| 6 | import { useScratchProject } from "../hooks/useScratchProject"; |
| 7 | import { usePrimaryEnvironmentId } from "../state/environments"; |
| 8 | import { Button } from "./ui/button"; |
| 9 | import { Empty, EmptyDescription, EmptyHeader, EmptyTitle } from "./ui/empty"; |
| 10 | import { SidebarInset } from "./ui/sidebar"; |
| 11 | import { WorkspacePageHeader } from "./WorkspacePageHeader"; |
| 12 | |
| 13 | export function NoProjectsHero() { |
| 14 | const openAddProject = useCallback(() => openCommandPalette({ open: "add-project" }), []); |
| 15 | const primaryEnvironmentId = usePrimaryEnvironmentId(); |
| 16 | const { scratchEnvironmentId, startScratchThread } = useScratchProject(); |
| 17 | const scratchTargetEnvironmentId = scratchEnvironmentId(primaryEnvironmentId); |
| 18 | |
| 19 | return ( |
| 20 | <SidebarInset className="h-dvh min-h-0 overflow-hidden overscroll-y-none"> |
| 21 | <div className="flex min-h-0 min-w-0 flex-1 flex-col overflow-x-hidden bg-background"> |
| 22 | {/* The desktop window only moves where CSS opts in, so keep a titlebar strip. */} |
| 23 | {isElectron ? <WorkspacePageHeader electron /> : null} |
| 24 | <Empty size="hero" className="flex-1"> |
| 25 | <div className="w-full max-w-lg px-8 py-12"> |
| 26 | <EmptyHeader className="max-w-none"> |
| 27 | <EmptyTitle>What should we work on?</EmptyTitle> |
| 28 | <EmptyDescription> |
| 29 | {scratchTargetEnvironmentId === null |
| 30 | ? "Add a project to start your first thread." |
| 31 | : "Add a project, or start without one."} |
| 32 | </EmptyDescription> |
| 33 | <div className="mt-6 flex justify-center gap-2"> |
| 34 | <Button size="sm" onClick={openAddProject}> |
| 35 | <PlusIcon className="size-4" /> |
| 36 | Add project |
| 37 | </Button> |
| 38 | {scratchTargetEnvironmentId === null ? null : ( |
| 39 | <Button |
| 40 | size="sm" |
| 41 | variant="outline" |
| 42 | onClick={() => void startScratchThread(scratchTargetEnvironmentId)} |
| 43 | > |
| 44 | <MessageSquareDashedIcon className="size-4" /> |
| 45 | Start without a project |
| 46 | </Button> |
| 47 | )} |
| 48 | </div> |
| 49 | </EmptyHeader> |
| 50 | </div> |
| 51 | </Empty> |
| 52 | </div> |
| 53 | </SidebarInset> |
| 54 | ); |
| 55 | } |