clear runtime consent and settings

This commit is contained in:
Will Chen
2025-04-11 14:23:14 -07:00
parent 34f069960c
commit d3c1f8e34c
11 changed files with 740 additions and 14 deletions

View File

@@ -0,0 +1,125 @@
import { useState } from "react";
import { Button } from "@/components/ui/button";
import { IpcClient } from "@/ipc/ipc_client";
import { useSettings } from "@/hooks/useSettings"; // Assuming useSettings provides a refresh function
import { RuntimeMode } from "@/lib/schemas";
interface SetupRuntimeFlowProps {
onRuntimeSelected: (mode: RuntimeMode) => Promise<void>;
}
export function SetupRuntimeFlow({ onRuntimeSelected }: SetupRuntimeFlowProps) {
const [isLoading, setIsLoading] = useState<RuntimeMode | null>(null);
const handleSelect = async (mode: RuntimeMode) => {
setIsLoading(mode);
try {
await onRuntimeSelected(mode);
// No need to setIsLoading(null) as the component will unmount on success
} catch (error) {
console.error("Failed to set runtime mode:", error);
alert(
`Error setting runtime mode: ${
error instanceof Error ? error.message : String(error)
}`
);
setIsLoading(null); // Reset loading state on error
}
};
return (
<div className="flex flex-col items-center justify-center max-w-2xl m-auto p-8">
<h1 className="text-4xl font-bold mb-4 text-center">Welcome to Dyad</h1>
<p className="text-lg text-gray-600 dark:text-gray-400 mb-10 text-center">
You can start building apps with AI in a moment, but first pick how you
want to run these apps. You can always change your mind later.
</p>
<div className="w-full space-y-4">
<Button
variant="outline"
className="relative bg-(--background-lightest) w-full justify-start p-6 h-auto text-left relative"
onClick={() => handleSelect("web-sandbox")}
disabled={!!isLoading}
>
{isLoading === "web-sandbox" && (
<svg
className="animate-spin h-5 w-5 mr-3 absolute right-4 top-1/2 -translate-y-1/2"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
>
<circle
className="opacity-25"
cx="12"
cy="12"
r="10"
stroke="currentColor"
strokeWidth="4"
></circle>
<path
className="opacity-75"
fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
></path>
</svg>
)}
<div>
<p className="font-medium text-base">Sandboxed Runtime</p>
<p className="text-sm text-gray-500 dark:text-gray-400 mt-1">
<div>
<span className="absolute top-4 right-2 bg-blue-100 text-blue-800 text-xs font-medium px-2 py-0.5 rounded-full">
Recommended for beginners
</span>
Code will run inside a browser sandbox.
</div>
</p>
</div>
</Button>
<Button
variant="outline"
className="bg-(--background-lightest) w-full justify-start p-6 h-auto text-left relative"
onClick={() => handleSelect("local-node")}
disabled={!!isLoading}
>
{isLoading === "local-node" && (
<svg
className="animate-spin h-5 w-5 mr-3 absolute right-4 top-1/2 -translate-y-1/2"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
>
<circle
className="opacity-25"
cx="12"
cy="12"
r="10"
stroke="currentColor"
strokeWidth="4"
></circle>
<path
className="opacity-75"
fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
></path>
</svg>
)}
<div>
<p className="font-medium text-base">Local Node.js Runtime</p>
<div className="text-sm text-gray-500 dark:text-gray-400 mt-1">
<p>
Code will run using Node.js on your computer and have full
system access.
</p>
<p className=" mt-2 text-wrap wrap-break-word text-red-600 dark:text-red-400 bg-red-100 dark:bg-red-900 px-2 py-1 rounded-md">
Warning: this will run AI-generated code directly on your
computer, which could put your system at risk.
</p>
</div>
</div>
</Button>
</div>
</div>
);
}

View File

@@ -0,0 +1,71 @@
import * as React from "react"
import * as ToggleGroupPrimitive from "@radix-ui/react-toggle-group"
import { type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
import { toggleVariants } from "@/components/ui/toggle"
const ToggleGroupContext = React.createContext<
VariantProps<typeof toggleVariants>
>({
size: "default",
variant: "default",
})
function ToggleGroup({
className,
variant,
size,
children,
...props
}: React.ComponentProps<typeof ToggleGroupPrimitive.Root> &
VariantProps<typeof toggleVariants>) {
return (
<ToggleGroupPrimitive.Root
data-slot="toggle-group"
data-variant={variant}
data-size={size}
className={cn(
"group/toggle-group flex w-fit items-center rounded-md data-[variant=outline]:shadow-xs",
className
)}
{...props}
>
<ToggleGroupContext.Provider value={{ variant, size }}>
{children}
</ToggleGroupContext.Provider>
</ToggleGroupPrimitive.Root>
)
}
function ToggleGroupItem({
className,
children,
variant,
size,
...props
}: React.ComponentProps<typeof ToggleGroupPrimitive.Item> &
VariantProps<typeof toggleVariants>) {
const context = React.useContext(ToggleGroupContext)
return (
<ToggleGroupPrimitive.Item
data-slot="toggle-group-item"
data-variant={context.variant || variant}
data-size={context.size || size}
className={cn(
toggleVariants({
variant: context.variant || variant,
size: context.size || size,
}),
"min-w-0 flex-1 shrink-0 rounded-none shadow-none first:rounded-l-md last:rounded-r-md focus:z-10 focus-visible:z-10 data-[variant=outline]:border-l-0 data-[variant=outline]:first:border-l",
className
)}
{...props}
>
{children}
</ToggleGroupPrimitive.Item>
)
}
export { ToggleGroup, ToggleGroupItem }

View File

@@ -0,0 +1,47 @@
"use client"
import * as React from "react"
import * as TogglePrimitive from "@radix-ui/react-toggle"
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
const toggleVariants = cva(
"inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium hover:bg-muted hover:text-muted-foreground disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] outline-none transition-[color,box-shadow] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive whitespace-nowrap",
{
variants: {
variant: {
default: "bg-transparent",
outline:
"border border-input bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground",
},
size: {
default: "h-9 px-2 min-w-9",
sm: "h-8 px-1.5 min-w-8",
lg: "h-10 px-2.5 min-w-10",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
}
)
function Toggle({
className,
variant,
size,
...props
}: React.ComponentProps<typeof TogglePrimitive.Root> &
VariantProps<typeof toggleVariants>) {
return (
<TogglePrimitive.Root
data-slot="toggle"
className={cn(toggleVariants({ variant, size, className }))}
{...props}
/>
)
}
export { Toggle, toggleVariants }