Add projects new route import and path
cgen-42d9850d06c148e9b9a1f857d948dfea
This commit is contained in:
parent
f193768eb2
commit
85340a094f
2 changed files with 132 additions and 0 deletions
|
|
@ -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 = () => (
|
|||
<Route path="/dashboard" element={<Dashboard />} />
|
||||
<Route path="/admin" element={<Admin />} />
|
||||
<Route path="/network" element={<Network />} />
|
||||
<Route path="/projects/new" element={<ProjectsNew />} />
|
||||
<Route
|
||||
path="/profile"
|
||||
element={<Navigate to="/network" replace />}
|
||||
|
|
|
|||
130
client/pages/ProjectsNew.tsx
Normal file
130
client/pages/ProjectsNew.tsx
Normal file
|
|
@ -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 (
|
||||
<LoadingScreen
|
||||
message="Please sign in to create a project..."
|
||||
showProgress={true}
|
||||
duration={800}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
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 (
|
||||
<Layout>
|
||||
<div className="min-h-screen py-8">
|
||||
<div className="container mx-auto px-4 max-w-3xl">
|
||||
<h1 className="text-2xl font-bold mb-4">Start a New Project</h1>
|
||||
|
||||
<form onSubmit={handleSubmit} className="space-y-4 bg-card/50 border-border/50 p-6 rounded-lg">
|
||||
<div>
|
||||
<Label htmlFor="title">Project Title</Label>
|
||||
<Input id="title" value={title} onChange={(e) => setTitle(e.target.value)} placeholder="e.g. Decentralized Chat App" />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Label htmlFor="description">Description</Label>
|
||||
<Textarea id="description" value={description} onChange={(e) => setDescription(e.target.value)} placeholder="Short description of the project" />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Label htmlFor="technologies">Technologies (comma separated)</Label>
|
||||
<Input id="technologies" value={technologies} onChange={(e) => setTechnologies(e.target.value)} placeholder="React, Node.js, Supabase, Typescript" />
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div>
|
||||
<Label htmlFor="github">GitHub URL</Label>
|
||||
<Input id="github" value={githubUrl} onChange={(e) => setGithubUrl(e.target.value)} placeholder="https://github.com/your/repo" />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Label htmlFor="live">Live URL</Label>
|
||||
<Input id="live" value={liveUrl} onChange={(e) => setLiveUrl(e.target.value)} placeholder="https://example.com" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Label htmlFor="status">Status</Label>
|
||||
<select id="status" value={status} onChange={(e) => setStatus(e.target.value as any)} className="w-full p-2 rounded border border-border/30 bg-background">
|
||||
<option value="planning">Planning</option>
|
||||
<option value="in_progress">In Progress</option>
|
||||
<option value="completed">Completed</option>
|
||||
<option value="on_hold">On Hold</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center space-x-3">
|
||||
<Button type="submit" disabled={isSubmitting} className="hover-lift">
|
||||
{isSubmitting ? "Creating..." : "Create Project"}
|
||||
</Button>
|
||||
<Button type="button" variant="outline" onClick={() => navigate(-1)}>
|
||||
Cancel
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
Loading…
Reference in a new issue