diff --git a/client/App.tsx b/client/App.tsx index cfd5ff9d..43a9bf4c 100644 --- a/client/App.tsx +++ b/client/App.tsx @@ -34,6 +34,7 @@ import Privacy from "./pages/Privacy"; import Terms from "./pages/Terms"; import Admin from "./pages/Admin"; import Network from "./pages/Network"; +import ProjectsNew from "./pages/ProjectsNew"; import { Navigate } from "react-router-dom"; import NotFound from "./pages/NotFound"; @@ -52,6 +53,7 @@ const App = () => ( } /> } /> } /> + } /> } diff --git a/client/pages/ProjectsNew.tsx b/client/pages/ProjectsNew.tsx new file mode 100644 index 00000000..a93c716b --- /dev/null +++ b/client/pages/ProjectsNew.tsx @@ -0,0 +1,130 @@ +import { useState } from "react"; +import { useNavigate } from "react-router-dom"; +import Layout from "@/components/Layout"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { Label } from "@/components/ui/label"; +import { Textarea } from "@/components/ui/textarea"; +import LoadingScreen from "@/components/LoadingScreen"; +import { useAuth } from "@/contexts/AuthContext"; +import { aethexToast } from "@/lib/aethex-toast"; +import { aethexProjectService } from "@/lib/aethex-database-adapter"; + +export default function ProjectsNew() { + const navigate = useNavigate(); + const { user } = useAuth(); + const [title, setTitle] = useState(""); + const [description, setDescription] = useState(""); + const [technologies, setTechnologies] = useState(""); + const [githubUrl, setGithubUrl] = useState(""); + const [liveUrl, setLiveUrl] = useState(""); + const [status, setStatus] = useState<"planning" | "in_progress" | "completed" | "on_hold">("planning"); + const [isSubmitting, setIsSubmitting] = useState(false); + + if (!user) { + return ( + + ); + } + + const handleSubmit = async (e: any) => { + e.preventDefault(); + if (!title.trim()) { + aethexToast.error({ title: "Title required", description: "Please provide a project title." }); + return; + } + + setIsSubmitting(true); + + try { + const techArray = technologies + .split(",") + .map((t) => t.trim()) + .filter(Boolean); + + const project = await aethexProjectService.createProject({ + user_id: user.id, + title: title.trim(), + description: description.trim(), + status, + technologies: techArray, + github_url: githubUrl.trim() || undefined, + live_url: liveUrl.trim() || undefined, + } as any); + + if (project) { + aethexToast.success({ title: "Project created", description: "Your project has been created." }); + navigate("/dashboard"); + } else { + throw new Error("Project creation failed"); + } + } catch (err: any) { + console.error("Error creating project:", err); + aethexToast.error({ title: "Failed to create project", description: err?.message || "Please try again." }); + } finally { + setIsSubmitting(false); + } + }; + + return ( + + + + Start a New Project + + + + Project Title + setTitle(e.target.value)} placeholder="e.g. Decentralized Chat App" /> + + + + Description + setDescription(e.target.value)} placeholder="Short description of the project" /> + + + + Technologies (comma separated) + setTechnologies(e.target.value)} placeholder="React, Node.js, Supabase, Typescript" /> + + + + + GitHub URL + setGithubUrl(e.target.value)} placeholder="https://github.com/your/repo" /> + + + + Live URL + setLiveUrl(e.target.value)} placeholder="https://example.com" /> + + + + + Status + setStatus(e.target.value as any)} className="w-full p-2 rounded border border-border/30 bg-background"> + Planning + In Progress + Completed + On Hold + + + + + + {isSubmitting ? "Creating..." : "Create Project"} + + navigate(-1)}> + Cancel + + + + + + + ); +}