diff --git a/package-lock.json b/package-lock.json index 037d88c..41571df 100644 --- a/package-lock.json +++ b/package-lock.json @@ -37,6 +37,7 @@ "@radix-ui/react-toggle-group": "^1.1.10", "@radix-ui/react-tooltip": "^1.2.7", "@tanstack/react-query": "^5.96.1", + "@tanstack/react-query-devtools": "^5.100.9", "axios": "^1.14.0", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", @@ -2795,9 +2796,19 @@ } }, "node_modules/@tanstack/query-core": { - "version": "5.96.1", - "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.96.1.tgz", - "integrity": "sha512-u1yBgtavSy+N8wgtW3PiER6UpxcplMje65yXnnVgiHTqiMwLlxiw4WvQDrXyn+UD6lnn8kHaxmerJUzQcV/MMg==", + "version": "5.100.9", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.100.9.tgz", + "integrity": "sha512-SJSFw1S8+kQ0+knv/XGfrbocWoAlT7vDKsSImtLx3ZPQmEcR46hkDjLSvynSy25N8Ms4tIEini1FuBd5k7IscQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/query-devtools": { + "version": "5.100.9", + "resolved": "https://registry.npmjs.org/@tanstack/query-devtools/-/query-devtools-5.100.9.tgz", + "integrity": "sha512-gqiptrTIhbK2PuCaPRHmWXfJG1NGYVFpAr0HqogEqiSBNB5xDz6fmesQt7w4WgMOqOQPnPHJ3ZDMuhDaXvNO8g==", "license": "MIT", "funding": { "type": "github", @@ -2805,12 +2816,12 @@ } }, "node_modules/@tanstack/react-query": { - "version": "5.96.1", - "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.96.1.tgz", - "integrity": "sha512-2X7KYK5KKWUKGeWCVcqxXAkYefJtrKB7tSKWgeG++b0H6BRHxQaLSSi8AxcgjmUnnosHuh9WsFZqvE16P1WCzA==", + "version": "5.100.9", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.100.9.tgz", + "integrity": "sha512-Oa44XkaI3kCNN6ME0KByU3xT3SEUNOMfZpHxL6+wFoTm+OeUFYHKdeYVe0aOXlRDm/f15sgLwEt2HDorIdW8+A==", "license": "MIT", "dependencies": { - "@tanstack/query-core": "5.96.1" + "@tanstack/query-core": "5.100.9" }, "funding": { "type": "github", @@ -2820,6 +2831,23 @@ "react": "^18 || ^19" } }, + "node_modules/@tanstack/react-query-devtools": { + "version": "5.100.9", + "resolved": "https://registry.npmjs.org/@tanstack/react-query-devtools/-/react-query-devtools-5.100.9.tgz", + "integrity": "sha512-mM3slaVGXJmz+pOLgXdANj75ikgQCyudyl3kmFvm6brI1JyVeY/+IeD17uDHIvZrD8hfoO2sdZ54RFsHdYAuhA==", + "license": "MIT", + "dependencies": { + "@tanstack/query-devtools": "5.100.9" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "@tanstack/react-query": "^5.100.9", + "react": "^18 || ^19" + } + }, "node_modules/@testing-library/dom": { "version": "10.4.1", "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz", diff --git a/package.json b/package.json index 5a6e204..e014e74 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "@radix-ui/react-toggle-group": "^1.1.10", "@radix-ui/react-tooltip": "^1.2.7", "@tanstack/react-query": "^5.96.1", + "@tanstack/react-query-devtools": "^5.100.9", "axios": "^1.14.0", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", diff --git a/src/App.tsx b/src/App.tsx index 3719e4a..4e07f65 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -13,6 +13,9 @@ import ProjectDetails from "./pages/ProjectDetails"; import Projects from "./pages/Projects"; import { QueryProvider } from "./provider/QueryProvider"; import OverviewPage from "./pages/admins/components/dashboards/OverviewPage"; +import ManageProject from "./pages/admins/components/projects/ManageProject"; +import { ReactQueryDevtools } from "@tanstack/react-query-devtools"; + function AnimatedRoutes() { const location = useLocation(); @@ -33,6 +36,7 @@ function AnimatedRoutes() { {/* dashboard layouts */} }> } /> + }/> {/* } /> } /> */} @@ -44,6 +48,7 @@ function AnimatedRoutes() { const App = () => ( + diff --git a/src/hooks/queires/useProjects.ts b/src/hooks/queires/useProjects.ts index 72783bb..be6b8ab 100644 --- a/src/hooks/queires/useProjects.ts +++ b/src/hooks/queires/useProjects.ts @@ -1,6 +1,7 @@ import { IProjectsQueryParams, projectsService } from "@/api/services/project.service"; +import { T_projects } from "@/types/projects.type"; import { queryKeys } from "@/utils/queryKeys"; -import { useQuery } from "@tanstack/react-query"; +import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; export const useProjects = (params?: IProjectsQueryParams) => { @@ -10,6 +11,27 @@ export const useProjects = (params?: IProjectsQueryParams) => { }); }; +export const useUpdateProject = () => { + const queryClient = useQueryClient(); + return useMutation({ + mutationFn: ({ id, data }: { id: string; data: Partial }) => + projectsService.updateProject(id, data), + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: queryKeys.projects }); + }, + }); +}; + +export const useDeleteProject = () => { + const queryClient = useQueryClient(); + return useMutation({ + mutationFn: (id: string) => projectsService.deleteProject(id), + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: queryKeys.projects }); + }, + }); +}; + export const useProjectById = (id: string) => { return useQuery({ queryKey: queryKeys.project(id), diff --git a/src/pages/admins/components/dashboards/Sidebar.tsx b/src/pages/admins/components/dashboards/Sidebar.tsx index 15639c2..dcfb9f4 100644 --- a/src/pages/admins/components/dashboards/Sidebar.tsx +++ b/src/pages/admins/components/dashboards/Sidebar.tsx @@ -13,7 +13,7 @@ import { import { Link } from "react-router-dom"; const navItems = [ - { title: "Overview", icon: LayoutDashboard, href: "/" }, + { title: "Overview", icon: LayoutDashboard, href: "/dashboard" }, { title: "Manage Projects", icon: FolderKanban, href: "/dashboard/projects" }, { title: "Manage Team", icon: Users, href: "/dashboard/team" }, { diff --git a/src/pages/admins/components/projects/EditProjectModal.tsx b/src/pages/admins/components/projects/EditProjectModal.tsx new file mode 100644 index 0000000..09f5854 --- /dev/null +++ b/src/pages/admins/components/projects/EditProjectModal.tsx @@ -0,0 +1,70 @@ +import { useState } from "react"; +import { T_projects } from "@/types/projects.type"; +import { X } from "lucide-react"; + +export const EditProjectModal = ({ + project, + onClose, + onSave +}: { + project: T_projects; + onClose: () => void; + onSave: (data: Partial) => void +}) => { + const [formData, setFormData] = useState({ + name: project.name, + shortDescription: project.description, + previewUrl: project.liveLink, + }); + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + onSave(formData); + }; + + return ( +
+
+ + +

Edit Project

+ +
+
+ + setFormData({ ...formData, name: e.target.value })} + /> +
+
+ +