HackingFactory-v2 / client /src /components /NewProjectDialog.tsx
FECUOY's picture
Initial commit: HackingFactory v2 Enhanced with Self-Refining AI features
4c41b3d
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>
);
}