diff --git a/backend/index.js b/backend/index.js index 94fbf68..c8ecab6 100644 --- a/backend/index.js +++ b/backend/index.js @@ -26,8 +26,10 @@ app.use("/", indexRoute); // "/projects" const projectsIndexRoute = require('./routes/projects/index')(sequelize); const projectsNewRoute = require('./routes/projects/new')(sequelize); +const projectsDeleteRoute = require('./routes/projects/delete')(sequelize); app.use('/projects', projectsIndexRoute); app.use('/projects', projectsNewRoute); +app.use('/projects', projectsDeleteRoute); // "/folders" const foldersIndexRoute = require('./routes/folders/index')(sequelize); diff --git a/backend/routes/projects/delete.js b/backend/routes/projects/delete.js new file mode 100644 index 0000000..69e62eb --- /dev/null +++ b/backend/routes/projects/delete.js @@ -0,0 +1,29 @@ +const express = require("express"); +const router = express.Router(); +const defineProject = require("../../models/projects"); +const { DataTypes } = require("sequelize"); + +module.exports = function (sequelize) { + const Project = defineProject(sequelize, DataTypes); + + router.delete("/:projectId", async (req, res) => { + const projectId = req.params.projectId; + try { + const project = await Project.findOne({ + where: { + id: projectId, + }, + }); + if (!project) { + return res.status(404).send("Project not found"); + } + await project.destroy(); + res.status(204).send(); + } catch (error) { + console.error(error); + res.status(500).send("Internal Server Error"); + } + }); + + return router; +}; diff --git a/frontend/app/projects/page.tsx b/frontend/app/projects/page.tsx index 8a4417b..8c487dd 100644 --- a/frontend/app/projects/page.tsx +++ b/frontend/app/projects/page.tsx @@ -79,6 +79,27 @@ async function createProject(name, detail) { } } +async function deleteProject(projectId: number) { + const fetchOptions = { + method: "DELETE", + headers: { + "Content-Type": "application/json", + }, + }; + + const url = `${apiServer}/projects/${projectId}`; + + try { + const response = await fetch(url, fetchOptions); + if (!response.ok) { + throw new Error(`HTTP error! Status: ${response.status}`); + } + } catch (error) { + console.error("Error deleting project:", error); + throw error; + } +} + export default function ProjectsPage() { // projects const [projects, setProjects] = useState([]); @@ -144,6 +165,15 @@ export default function ProjectsPage() { } }; + const onDeleteClicked = async (projectId: number) => { + try { + await deleteProject(projectId); + setProjects(projects.filter((project) => project.id !== projectId)); + } catch (error) { + console.error("Error deleting project:", error); + } + }; + return (
@@ -157,15 +187,20 @@ export default function ProjectsPage() { {projects.map((project, index) => ( ))}
- + { + setIsCreateDialogOpen(false); + }} + > - Modal Title + Project - + + + Edit project + onDeleteClicked(project.id)} + > + Delete project + + + + + + +

{project.detail}

+
+ ); } diff --git a/frontend/components/icons.tsx b/frontend/components/icons.tsx index b047c84..bfc2031 100644 --- a/frontend/components/icons.tsx +++ b/frontend/components/icons.tsx @@ -284,3 +284,22 @@ export const FolderIcon: React.FC = ({ ); }; + +export const DotsIcon: React.FC = ({ + size = 24, + width, + height, + ...props +}) => { + return ( + + + + ); +};