From 42314a9b69a8104300290ac44487e86075b5c6ed Mon Sep 17 00:00:00 2001 From: charles-gauthereau Date: Sun, 1 Dec 2024 09:33:35 +0100 Subject: [PATCH] Working on project creation and patch with multiselect. --- .../wrappers/Project/ProjectForm.action.ts | 62 -------- .../wrappers/Project/ProjectForm.schema.ts | 2 +- .../wrappers/Project/ProjectForm.tsx | 39 +++-- .../wrappers/Project/project-form.action.ts | 150 ++++++++++++++++++ 4 files changed, 170 insertions(+), 83 deletions(-) delete mode 100644 src/components/wrappers/Project/ProjectForm.action.ts create mode 100644 src/components/wrappers/Project/project-form.action.ts diff --git a/src/components/wrappers/Project/ProjectForm.action.ts b/src/components/wrappers/Project/ProjectForm.action.ts deleted file mode 100644 index d4ea80e9..00000000 --- a/src/components/wrappers/Project/ProjectForm.action.ts +++ /dev/null @@ -1,62 +0,0 @@ -"use server" - -import {userAction} from "@/safe-actions"; -import {prisma} from "@/prisma"; -import {ProjectSchema} from "@/components/wrappers/Project/ProjectForm.schema"; -import {z} from "zod"; -import {ServerActionResult} from "@/types/action-type"; -import {Projects} from "@prisma/client"; - - -export const createProjectAction = userAction - .schema( - z.object({ - data: ProjectSchema, - organizationId: z.string(), - }) - ) - .action(async ({parsedInput, ctx}): Promise> => { - try { - - const project = await prisma.project.create({ - data: { - name: parsedInput.data.name, - slug: parsedInput.data.slug, - organizationId: parsedInput.organizationId, - } - }) - - for (const db of parsedInput.data.databases) { - - await prisma.database.update({ - where: { - id: db, - }, - data:{ - projectId: project.id, - } - }) - } - - return { - success: true, - value: project, - actionSuccess: { - message: "Project has been successfully created.", - messageParams: {projectName: parsedInput.data.name}, - }, - }; - } catch (error) { - return { - success: false, - actionError: { - message: "Failed to create Project.", - status: 500, // Optional: Use a meaningful status code - cause: error instanceof Error ? error.message : "Unknown error", - messageParams: {projectName: parsedInput.data.name}, - }, - }; - } - - - }); \ No newline at end of file diff --git a/src/components/wrappers/Project/ProjectForm.schema.ts b/src/components/wrappers/Project/ProjectForm.schema.ts index a66f21c7..751b2cb8 100644 --- a/src/components/wrappers/Project/ProjectForm.schema.ts +++ b/src/components/wrappers/Project/ProjectForm.schema.ts @@ -7,4 +7,4 @@ export const ProjectSchema = z.object({ databases: z.array(z.string()), }); -export type ProjectSchema = z.infer; +export type ProjectType = z.infer; diff --git a/src/components/wrappers/Project/ProjectForm.tsx b/src/components/wrappers/Project/ProjectForm.tsx index 38556250..118cf9c9 100644 --- a/src/components/wrappers/Project/ProjectForm.tsx +++ b/src/components/wrappers/Project/ProjectForm.tsx @@ -14,16 +14,18 @@ import {Input} from "@/components/ui/input"; import {Form} from "@/components/ui/form" import {Button} from "@/components/ui/button"; import {useMutation} from "@tanstack/react-query"; -import {ProjectSchema} from "@/components/wrappers/Project/ProjectForm.schema"; -import {createProjectAction} from "@/components/wrappers/Project/ProjectForm.action"; +import {ProjectSchema, ProjectType} from "@/components/wrappers/Project/ProjectForm.schema"; +import {createProjectAction, updateProjectAction} from "@/components/wrappers/Project/project-form.action"; import {useRouter} from "next/navigation"; -import {Database, Organization} from "@prisma/client" +import {Database, Organization, Project, Projects} from "@prisma/client" import {MultiSelect} from "@/components/wrappers/MultiSelect/MultiSelect"; import {ZodString} from "zod"; +import {toast} from "sonner"; +import {ServerActionResult} from "@/types/action-type"; export type projectFormProps = { - defaultValues?: ProjectSchema; + defaultValues?: ProjectType; databases: Database[], organization: Organization, projectId?: string; @@ -43,7 +45,7 @@ export const ProjectForm = (props: projectFormProps) => { })); }; - const formatDefaultDatabases = (databases: ProjectSchema["databases"]): string[] => { + const formatDefaultDatabases = (databases: ProjectType['databases']): string[] => { return databases.map(database => database.id); }; @@ -60,21 +62,18 @@ export const ProjectForm = (props: projectFormProps) => { }); const mutation = useMutation({ - mutationFn: async (values: ProjectSchema) => { + mutationFn: async (values: ProjectType) => { console.log(values) - const projectCreated = await createProjectAction({data: values, organizationId: props.organization.id}); - console.log(projectCreated) - // - // if (data) { - // toast.success(`Success`); - // router.push(`/dashboard/projects/${data.id}`); - // router.refresh() - // } - // - // if (validationErrors) { - // toast.success(`Error`); - // - // } + const project: Projects = isCreate ? await createProjectAction({data: values, organizationId: props.organization.id}) : await updateProjectAction({data: values, organizationId: props.organization.id, projectId: props.projectId}); + console.log(project) + + if (project.data.success) { + toast.success(project.data.actionSuccess.message); + router.push(`/dashboard/projects/${project.data.value.id}`); + router.refresh() + }else{ + toast.success(project.data.actionError.message); + } } @@ -147,7 +146,7 @@ export const ProjectForm = (props: projectFormProps) => { } /> diff --git a/src/components/wrappers/Project/project-form.action.ts b/src/components/wrappers/Project/project-form.action.ts new file mode 100644 index 00000000..ea7fee38 --- /dev/null +++ b/src/components/wrappers/Project/project-form.action.ts @@ -0,0 +1,150 @@ +"use server" + +import {userAction} from "@/safe-actions"; +import {prisma} from "@/prisma"; +import {ProjectSchema} from "@/components/wrappers/Project/ProjectForm.schema"; +import {z} from "zod"; +import {ServerActionResult} from "@/types/action-type"; +import {Projects} from "@prisma/client"; + + +export const createProjectAction = userAction + .schema( + z.object({ + data: ProjectSchema, + organizationId: z.string(), + }) + ) + .action(async ({parsedInput, ctx}): Promise> => { + try { + + const project = await prisma.project.create({ + data: { + name: parsedInput.data.name, + slug: parsedInput.data.slug, + organizationId: parsedInput.organizationId, + } + }) + + for (const db of parsedInput.data.databases) { + + await prisma.database.update({ + where: { + id: db, + }, + data:{ + projectId: project.id, + } + }) + } + + return { + success: true, + value: project, + actionSuccess: { + message: "Project has been successfully created.", + messageParams: {projectName: parsedInput.data.name}, + }, + }; + } catch (error) { + return { + success: false, + actionError: { + message: "Failed to create Project.", + status: 500, // Optional: Use a meaningful status code + cause: error instanceof Error ? error.message : "Unknown error", + messageParams: {projectName: parsedInput.data.name}, + }, + }; + } + + + }); + + +export const updateProjectAction = userAction + .schema( + z.object({ + data: ProjectSchema, + organizationId: z.string(), + projectId: z.string(), + }) + ) + .action(async ({parsedInput, ctx}): Promise> => { + try { + const newDatabaseList = parsedInput.data.databases + const project = await prisma.project.findFirst({ + where:{ + id: parsedInput.projectId, + }, + include: { + databases : {} + } + }) + const existingItemIds = project.databases.map((db) => db.id); + + const databasesToAdd = newDatabaseList.filter( + (id) => !existingItemIds.includes(id) + ); + const databasesToRemove = existingItemIds.filter( + (id) => !newDatabaseList.includes(id) + ); + + console.log(databasesToAdd); + console.log(databasesToRemove); + + if (databasesToAdd.length > 0) { + await prisma.database.updateMany({ + where: { + id: { in: databasesToAdd }, + }, + data: { + projectId: parsedInput.projectId, + }, + }); + } + + if (databasesToRemove.length > 0) { + await prisma.database.updateMany({ + where: { + id: { in: databasesToRemove }, + }, + data: { + projectId: null, + }, + }); + } + + const updatedProject = await prisma.project.update({ + where:{ + id: parsedInput.projectId + }, + data:{ + name: parsedInput.data.name, + slug: parsedInput.data.slug, + } + }) + + + return { + success: true, + value: updatedProject, + actionSuccess: { + message: "Project has been successfully updated.", + messageParams: {projectName: parsedInput.data.name}, + }, + }; + } catch (error) { + return { + success: false, + actionError: { + message: "Failed to update Project.", + status: 500, // Optional: Use a meaningful status code + cause: error instanceof Error ? error.message : "Unknown error", + messageParams: {projectName: parsedInput.data.name}, + }, + }; + } + + + }); \ No newline at end of file