Spaces:
Sleeping
Sleeping
File size: 5,807 Bytes
4c41b3d | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | 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>
);
}
|