Spaces:
Sleeping
Sleeping
| import React, { useState } from "react"; | |
| import { trpc } from "@/lib/trpc"; | |
| import { Button } from "@/components/ui/button"; | |
| import { Input } from "@/components/ui/input"; | |
| import { Textarea } from "@/components/ui/textarea"; | |
| import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; | |
| import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"; | |
| import { toast } from "sonner"; | |
| interface NewProjectDialogProps { | |
| onProjectCreated?: () => void; | |
| } | |
| export function NewProjectDialog({ onProjectCreated }: NewProjectDialogProps) { | |
| const [open, setOpen] = useState(false); | |
| const [name, setName] = useState(""); | |
| const [description, setDescription] = useState(""); | |
| const [mode, setMode] = useState("auto"); | |
| const [contentType, setContentType] = useState("code"); | |
| const [prompt, setPrompt] = useState(""); | |
| const createProjectMutation = trpc.projects.create.useMutation({ | |
| onSuccess: () => { | |
| toast.success("Project created successfully!"); | |
| setOpen(false); | |
| setName(""); | |
| setDescription(""); | |
| setMode("auto"); | |
| setContentType("code"); | |
| setPrompt(""); | |
| onProjectCreated?.(); | |
| }, | |
| onError: (error) => { | |
| toast.error("Failed to create project: " + error.message); | |
| }, | |
| }); | |
| const handleCreate = async () => { | |
| if (!name.trim() || !prompt.trim()) { | |
| toast.error("Please fill in project name and prompt"); | |
| return; | |
| } | |
| await createProjectMutation.mutateAsync({ | |
| name, | |
| description: description || undefined, | |
| mode: mode as any, | |
| contentType: contentType as any, | |
| originalPrompt: prompt, | |
| }); | |
| }; | |
| return ( | |
| <Dialog open={open} onOpenChange={setOpen}> | |
| <DialogTrigger asChild> | |
| <Button className="bg-gradient-to-r from-green-500 to-cyan-500 text-black hover:from-green-600 hover:to-cyan-600"> | |
| + New Project | |
| </Button> | |
| </DialogTrigger> | |
| <DialogContent className="bg-gray-900 border-green-500/20 text-white max-w-md"> | |
| <DialogHeader> | |
| <DialogTitle className="text-green-400">Create New Project</DialogTitle> | |
| <DialogDescription className="text-gray-400"> | |
| Set up a new AI code generation project | |
| </DialogDescription> | |
| </DialogHeader> | |
| <div className="space-y-4"> | |
| <div> | |
| <label className="text-sm text-gray-400 mb-1 block">Project Name</label> | |
| <Input | |
| placeholder="My Awesome Project" | |
| value={name} | |
| onChange={(e) => setName(e.target.value)} | |
| className="bg-black/50 border-green-500/20 text-white" | |
| /> | |
| </div> | |
| <div> | |
| <label className="text-sm text-gray-400 mb-1 block">Description</label> | |
| <Textarea | |
| placeholder="What is this project about?" | |
| value={description} | |
| onChange={(e) => setDescription(e.target.value)} | |
| className="bg-black/50 border-green-500/20 text-white h-20" | |
| /> | |
| </div> | |
| <div className="grid grid-cols-2 gap-4"> | |
| <div> | |
| <label className="text-sm text-gray-400 mb-1 block">Mode</label> | |
| <Select value={mode} onValueChange={setMode}> | |
| <SelectTrigger className="bg-black/50 border-green-500/20 text-white"> | |
| <SelectValue /> | |
| </SelectTrigger> | |
| <SelectContent className="bg-gray-900 border-green-500/20"> | |
| <SelectItem value="auto">Auto</SelectItem> | |
| <SelectItem value="qwen">Qwen</SelectItem> | |
| <SelectItem value="deepseek">DeepSeek</SelectItem> | |
| <SelectItem value="loop">Loop</SelectItem> | |
| </SelectContent> | |
| </Select> | |
| </div> | |
| <div> | |
| <label className="text-sm text-gray-400 mb-1 block">Content Type</label> | |
| <Select value={contentType} onValueChange={setContentType}> | |
| <SelectTrigger className="bg-black/50 border-green-500/20 text-white"> | |
| <SelectValue /> | |
| </SelectTrigger> | |
| <SelectContent className="bg-gray-900 border-green-500/20"> | |
| <SelectItem value="code">Code</SelectItem> | |
| <SelectItem value="exploit">Exploit</SelectItem> | |
| <SelectItem value="payload">Payload</SelectItem> | |
| <SelectItem value="information">Information</SelectItem> | |
| <SelectItem value="strategy">Strategy</SelectItem> | |
| </SelectContent> | |
| </Select> | |
| </div> | |
| </div> | |
| <div> | |
| <label className="text-sm text-gray-400 mb-1 block">Initial Prompt</label> | |
| <Textarea | |
| placeholder="Describe what you want to generate..." | |
| value={prompt} | |
| onChange={(e) => setPrompt(e.target.value)} | |
| className="bg-black/50 border-green-500/20 text-white h-24" | |
| /> | |
| </div> | |
| <div className="flex gap-2 pt-4"> | |
| <Button | |
| variant="outline" | |
| onClick={() => setOpen(false)} | |
| className="flex-1 border-gray-500/20 text-gray-400" | |
| > | |
| Cancel | |
| </Button> | |
| <Button | |
| onClick={handleCreate} | |
| disabled={createProjectMutation.isPending} | |
| className="flex-1 bg-gradient-to-r from-green-500 to-cyan-500 text-black hover:from-green-600 hover:to-cyan-600" | |
| > | |
| {createProjectMutation.isPending ? "Creating..." : "Create"} | |
| </Button> | |
| </div> | |
| </div> | |
| </DialogContent> | |
| </Dialog> | |
| ); | |
| } | |