feat(web): add projects page with CRUD operations (#477)
Some checks failed
ci/woodpecker/push/web Pipeline failed

Co-authored-by: Jason Woltje <jason@diversecanvas.com>
Co-committed-by: Jason Woltje <jason@diversecanvas.com>
This commit was merged in pull request #477.
This commit is contained in:
2026-02-23 04:13:26 +00:00
committed by jason.woltje
parent 5a6d00a064
commit ee2ddfc8b8
3 changed files with 914 additions and 0 deletions

View File

@@ -14,3 +14,4 @@ export * from "./teams";
export * from "./personalities";
export * from "./telemetry";
export * from "./dashboard";
export * from "./projects";

View File

@@ -0,0 +1,104 @@
/**
* Projects API Client
* Handles project-related API requests
*/
import { apiGet, apiPost, apiPatch, apiDelete } from "./client";
/**
* Project status enum (matches backend ProjectStatus)
*/
export enum ProjectStatus {
PLANNING = "PLANNING",
ACTIVE = "ACTIVE",
PAUSED = "PAUSED",
COMPLETED = "COMPLETED",
ARCHIVED = "ARCHIVED",
}
/**
* Project response interface (matches Prisma Project model)
*/
export interface Project {
id: string;
workspaceId: string;
name: string;
description: string | null;
status: ProjectStatus;
startDate: string | null;
endDate: string | null;
creatorId: string;
domainId: string | null;
color: string | null;
metadata: Record<string, unknown>;
createdAt: string;
updatedAt: string;
}
/**
* DTO for creating a new project
*/
export interface CreateProjectDto {
name: string;
description?: string;
status?: ProjectStatus;
startDate?: string;
endDate?: string;
color?: string;
metadata?: Record<string, unknown>;
}
/**
* DTO for updating an existing project
*/
export interface UpdateProjectDto {
name?: string;
description?: string | null;
status?: ProjectStatus;
startDate?: string | null;
endDate?: string | null;
color?: string | null;
metadata?: Record<string, unknown>;
}
/**
* Fetch all projects for a workspace
*/
export async function fetchProjects(workspaceId?: string): Promise<Project[]> {
return apiGet<Project[]>("/api/projects", workspaceId);
}
/**
* Fetch a single project by ID
*/
export async function fetchProject(id: string, workspaceId?: string): Promise<Project> {
return apiGet<Project>(`/api/projects/${id}`, workspaceId);
}
/**
* Create a new project
*/
export async function createProject(
data: CreateProjectDto,
workspaceId?: string
): Promise<Project> {
return apiPost<Project>("/api/projects", data, workspaceId);
}
/**
* Update an existing project
*/
export async function updateProject(
id: string,
data: UpdateProjectDto,
workspaceId?: string
): Promise<Project> {
return apiPatch<Project>(`/api/projects/${id}`, data, workspaceId);
}
/**
* Delete a project
*/
export async function deleteProject(id: string, workspaceId?: string): Promise<void> {
await apiDelete<Record<string, never>>(`/api/projects/${id}`, workspaceId);
}