Initial commit: img-infinite-canvas AI design workbench MVP
Moteva-style AI design workbench replica. Home prompt creates a project; the project page provides an infinite canvas with node drag, zoom/pan, a design chat panel, history replay, image asset upload, and project save/regenerate. - Backend: go-zero, DDD layering, sqlc/pgx, optional PostgreSQL; memory or Redis cache; asynq job queue; MinIO/S3/R2/OSS object storage; sky-valley/pi agent runtime adapter. - Frontend: Next.js App Router + Vite artifact build, TypeScript, i18n, shadcn/ui components, auth (OTP/Turnstile/Google/WeChat). - Deploy: Docker Compose and k3s manifests. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
"use client";
|
||||
|
||||
import type { ButtonHTMLAttributes } from "react";
|
||||
|
||||
type ButtonProps = ButtonHTMLAttributes<HTMLButtonElement>;
|
||||
|
||||
export function Button({ className = "", type = "button", ...props }: ButtonProps) {
|
||||
return <button type={type} className={["ui-button", className].filter(Boolean).join(" ")} {...props} />;
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
"use client";
|
||||
|
||||
import * as ContextMenuPrimitive from "@radix-ui/react-context-menu";
|
||||
import type { ComponentProps } from "react";
|
||||
|
||||
export const ContextMenu = ContextMenuPrimitive.Root;
|
||||
export const ContextMenuTrigger = ContextMenuPrimitive.Trigger;
|
||||
export const ContextMenuSub = ContextMenuPrimitive.Sub;
|
||||
export const ContextMenuSubTrigger = ContextMenuPrimitive.SubTrigger;
|
||||
export const ContextMenuPortal = ContextMenuPrimitive.Portal;
|
||||
export const ContextMenuSeparator = ContextMenuPrimitive.Separator;
|
||||
|
||||
export function ContextMenuContent({ className = "", ...props }: ComponentProps<typeof ContextMenuPrimitive.Content>) {
|
||||
return (
|
||||
<ContextMenuPrimitive.Portal>
|
||||
<ContextMenuPrimitive.Content className={["ui-context-menu-content", className].filter(Boolean).join(" ")} {...props} />
|
||||
</ContextMenuPrimitive.Portal>
|
||||
);
|
||||
}
|
||||
|
||||
export function ContextMenuItem({ className = "", ...props }: ComponentProps<typeof ContextMenuPrimitive.Item>) {
|
||||
return <ContextMenuPrimitive.Item className={["ui-context-menu-item", className].filter(Boolean).join(" ")} {...props} />;
|
||||
}
|
||||
|
||||
export function ContextMenuSubContent({ className = "", ...props }: ComponentProps<typeof ContextMenuPrimitive.SubContent>) {
|
||||
return (
|
||||
<ContextMenuPrimitive.Portal>
|
||||
<ContextMenuPrimitive.SubContent className={["ui-context-menu-content", className].filter(Boolean).join(" ")} {...props} />
|
||||
</ContextMenuPrimitive.Portal>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
"use client";
|
||||
|
||||
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
|
||||
import type { ComponentProps } from "react";
|
||||
|
||||
export const DropdownMenu = DropdownMenuPrimitive.Root;
|
||||
export const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
|
||||
export const DropdownMenuGroup = DropdownMenuPrimitive.Group;
|
||||
export const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
|
||||
export const DropdownMenuRadioItem = DropdownMenuPrimitive.RadioItem;
|
||||
export const DropdownMenuCheckboxItem = DropdownMenuPrimitive.CheckboxItem;
|
||||
export const DropdownMenuSub = DropdownMenuPrimitive.Sub;
|
||||
export const DropdownMenuSubTrigger = DropdownMenuPrimitive.SubTrigger;
|
||||
export const DropdownMenuSubContent = DropdownMenuPrimitive.SubContent;
|
||||
|
||||
export function DropdownMenuContent({ className = "", align = "center", sideOffset = 8, ...props }: ComponentProps<typeof DropdownMenuPrimitive.Content>) {
|
||||
return (
|
||||
<DropdownMenuPrimitive.Portal>
|
||||
<DropdownMenuPrimitive.Content
|
||||
align={align}
|
||||
sideOffset={sideOffset}
|
||||
className={["ui-dropdown-menu-content", className].filter(Boolean).join(" ")}
|
||||
{...props}
|
||||
/>
|
||||
</DropdownMenuPrimitive.Portal>
|
||||
);
|
||||
}
|
||||
|
||||
export function DropdownMenuItem({ className = "", ...props }: ComponentProps<typeof DropdownMenuPrimitive.Item>) {
|
||||
return <DropdownMenuPrimitive.Item className={["ui-dropdown-menu-item", className].filter(Boolean).join(" ")} {...props} />;
|
||||
}
|
||||
|
||||
export function DropdownMenuSeparator({ className = "", ...props }: ComponentProps<typeof DropdownMenuPrimitive.Separator>) {
|
||||
return <DropdownMenuPrimitive.Separator className={["ui-dropdown-menu-separator", className].filter(Boolean).join(" ")} {...props} />;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
"use client";
|
||||
|
||||
import * as PopoverPrimitive from "@radix-ui/react-popover";
|
||||
import type { ComponentProps } from "react";
|
||||
|
||||
export const Popover = PopoverPrimitive.Root;
|
||||
export const PopoverTrigger = PopoverPrimitive.Trigger;
|
||||
export const PopoverAnchor = PopoverPrimitive.Anchor;
|
||||
export const PopoverClose = PopoverPrimitive.Close;
|
||||
|
||||
export function PopoverContent({ className = "", align = "center", sideOffset = 8, ...props }: ComponentProps<typeof PopoverPrimitive.Content>) {
|
||||
return (
|
||||
<PopoverPrimitive.Portal>
|
||||
<PopoverPrimitive.Content
|
||||
align={align}
|
||||
sideOffset={sideOffset}
|
||||
className={["ui-popover-content", className].filter(Boolean).join(" ")}
|
||||
{...props}
|
||||
/>
|
||||
</PopoverPrimitive.Portal>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
"use client";
|
||||
|
||||
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area";
|
||||
import type { ComponentProps } from "react";
|
||||
|
||||
export function ScrollArea({ className = "", children, ...props }: ComponentProps<typeof ScrollAreaPrimitive.Root>) {
|
||||
return (
|
||||
<ScrollAreaPrimitive.Root className={["ui-scroll-area", className].filter(Boolean).join(" ")} {...props}>
|
||||
<ScrollAreaPrimitive.Viewport className="ui-scroll-area-viewport">{children}</ScrollAreaPrimitive.Viewport>
|
||||
<ScrollAreaPrimitive.Scrollbar className="ui-scroll-area-scrollbar" orientation="vertical">
|
||||
<ScrollAreaPrimitive.Thumb className="ui-scroll-area-thumb" />
|
||||
</ScrollAreaPrimitive.Scrollbar>
|
||||
<ScrollAreaPrimitive.Corner />
|
||||
</ScrollAreaPrimitive.Root>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
"use client";
|
||||
|
||||
import * as SwitchPrimitive from "@radix-ui/react-switch";
|
||||
import type { ComponentProps } from "react";
|
||||
|
||||
export function Switch({ className = "", ...props }: ComponentProps<typeof SwitchPrimitive.Root>) {
|
||||
return (
|
||||
<SwitchPrimitive.Root className={["ui-switch", className].filter(Boolean).join(" ")} {...props}>
|
||||
<SwitchPrimitive.Thumb className="ui-switch-thumb" />
|
||||
</SwitchPrimitive.Root>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
"use client";
|
||||
|
||||
import * as TabsPrimitive from "@radix-ui/react-tabs";
|
||||
import type { ComponentProps } from "react";
|
||||
|
||||
export const Tabs = TabsPrimitive.Root;
|
||||
|
||||
export function TabsList({ className = "", ...props }: ComponentProps<typeof TabsPrimitive.List>) {
|
||||
return <TabsPrimitive.List className={["ui-tabs-list", className].filter(Boolean).join(" ")} {...props} />;
|
||||
}
|
||||
|
||||
export function TabsTrigger({ className = "", ...props }: ComponentProps<typeof TabsPrimitive.Trigger>) {
|
||||
return <TabsPrimitive.Trigger className={["ui-tabs-trigger", className].filter(Boolean).join(" ")} {...props} />;
|
||||
}
|
||||
|
||||
export function TabsContent({ className = "", ...props }: ComponentProps<typeof TabsPrimitive.Content>) {
|
||||
return <TabsPrimitive.Content className={["ui-tabs-content", className].filter(Boolean).join(" ")} {...props} />;
|
||||
}
|
||||
Reference in New Issue
Block a user