diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 0748a9d..ef686fc 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -166,7 +166,7 @@ model Project { idVillage String Group Group @relation(fields: [idGroup], references: [id]) idGroup String - name String + title String status Int @default(0) // 0 = pending, 1 = ongoing, 2 = done, 3 = cancelled desc String? @db.Text reason String? @db.Text @@ -208,9 +208,9 @@ model ProjectTask { id String @id @default(cuid()) Project Project @relation(fields: [idProject], references: [id]) idProject String - name String + title String desc String? - status Int @default(0) // 0 = pending, 1 = ongoing + status Int @default(0) // 0 = todo, 1 = done dateStart DateTime @db.Date dateEnd DateTime @db.Date isActive Boolean @default(true) diff --git a/src/app/(application)/project/create/page.tsx b/src/app/(application)/project/create/page.tsx index 41b26fa..3aac089 100644 --- a/src/app/(application)/project/create/page.tsx +++ b/src/app/(application)/project/create/page.tsx @@ -1,15 +1,12 @@ -import { CreateUsersProject, ViewCreateProject, ViewDateEndTask, ViewFileSave } from "@/module/project"; +import { CreateProject, ViewFileSave } from "@/module/project"; import React from "react"; function Page({ searchParams }: { searchParams: any }) { - if (searchParams.page == "task") - return ; - if (searchParams.page == "create-users") - return + if (searchParams.page == "file-save") return - return ; + return ; } export default Page; diff --git a/src/app/api/project/[id]/route.ts b/src/app/api/project/[id]/route.ts index 589c3e0..f08b29f 100644 --- a/src/app/api/project/[id]/route.ts +++ b/src/app/api/project/[id]/route.ts @@ -59,7 +59,7 @@ export async function GET(request: Request, context: { params: { id: string } }) }, select: { id: true, - name: true, + title: true, desc: true, status: true, dateStart: true, @@ -159,7 +159,7 @@ export async function POST(request: Request, context: { params: { id: string } } const dataCreate = await prisma.projectTask.create({ data: { - name, + title: name, idProject: id, dateStart: new Date(moment(dateStart).format('YYYY-MM-DD')), dateEnd: new Date(moment(dateEnd).format('YYYY-MM-DD')), @@ -249,7 +249,7 @@ export async function PUT(request: Request, context: { params: { id: string } }) id }, data: { - name + title: name } }) diff --git a/src/app/api/project/detail/[id]/route.ts b/src/app/api/project/detail/[id]/route.ts index 8ca266e..fb9a956 100644 --- a/src/app/api/project/detail/[id]/route.ts +++ b/src/app/api/project/detail/[id]/route.ts @@ -174,7 +174,7 @@ export async function POST(request: Request, context: { params: { id: string } } id }, data: { - name: name, + title: name, dateStart: new Date(moment(dateStart).format('YYYY-MM-DD')), dateEnd: new Date(moment(dateEnd).format('YYYY-MM-DD')), } diff --git a/src/app/api/project/route.ts b/src/app/api/project/route.ts index 7464663..994d373 100644 --- a/src/app/api/project/route.ts +++ b/src/app/api/project/route.ts @@ -29,7 +29,7 @@ export async function GET(request: Request) { idVillage: String(villageId), idGroup: String(groupId), createdBy: String(userId), - name: { + title: { contains: (name == undefined || name == "null") ? "" : name, mode: "insensitive" }, @@ -37,7 +37,7 @@ export async function GET(request: Request) { }, select: { id: true, - name: true, + title: true, desc: true, status: true, ProjectMember: { @@ -73,16 +73,15 @@ export async function POST(request: Request) { return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }); } - const { idVillage, idGroup, name, task, member, file } = (await request.json()) + const { idGroup, title, task, member, file } = (await request.json()) const userId = user.id - + const data = await prisma.project.create({ data: { - idVillage: String(idVillage), + idVillage: String(user.idVillage), idGroup: String(idGroup), - name: name, - desc: "", + title, createdBy: String(userId) }, select: { @@ -94,7 +93,7 @@ export async function POST(request: Request) { const dataProject = task.map((v: any) => ({ ..._.omit(v, ["dateStart", "dateEnd", "name"]), idProject: data.id, - name: v.name, + title: v.title, dateStart: new Date(moment(v.dateStart).format('YYYY-MM-DD')), dateEnd: new Date(moment(v.dateEnd).format('YYYY-MM-DD')), })) @@ -109,7 +108,6 @@ export async function POST(request: Request) { ..._.omit(v, ["idUser", "name"]), idProject: data.id, idUser: v.idUser, - name: v.name })) const insertMember = await prisma.projectMember.createMany({ @@ -121,31 +119,31 @@ export async function POST(request: Request) { if (file.length > 0) { file.map((v: any, index: any) => { - const f: any = file[index].get('file') - const fName = f.name - const fExt = fName.split(".").pop() - // funUploadFile(fName, f) - - const dataFile = { - name: fName, - extension: fExt, - idProject: data.id, - } - - fileFix.push(dataFile) + const f: any = file[index].get('file') + const fName = f.name + const fExt = fName.split(".").pop() + // funUploadFile(fName, f) + + const dataFile = { + name: fName, + extension: fExt, + idProject: data.id, + } + + fileFix.push(dataFile) }) - + const insertFile = await prisma.divisionProjectFile.createMany({ - data: fileFix + data: fileFix }) - - } + + } - return NextResponse.json({ success: true, message: "Berhasil mendapatkan divisi", data: data, }, { status: 200 }); + return NextResponse.json({ success: true, message: "Berhasil membuat proyek", data: data, }, { status: 200 }); } catch (error) { console.error(error); - return NextResponse.json({ success: false, message: "Gagal mendapatkan divisi, coba lagi nanti", reason: (error as Error).message, }, { status: 500 }); + return NextResponse.json({ success: false, message: "Gagal membuat proyek, coba lagi nanti", reason: (error as Error).message, }, { status: 500 }); } } \ No newline at end of file diff --git a/src/module/project/components/create_date_end_task.tsx b/src/module/project/components/create_date_end_task.tsx deleted file mode 100644 index 60392be..0000000 --- a/src/module/project/components/create_date_end_task.tsx +++ /dev/null @@ -1,187 +0,0 @@ -"use client"; -import { LayoutNavbarNew, WARNA } from "@/module/_global"; -import { - Avatar, - Box, - Button, - Flex, - Group, - Input, - SimpleGrid, - Stack, - Text, -} from "@mantine/core"; -import React, { useState } from "react"; -import { DatePicker } from "@mantine/dates"; -import moment from "moment"; -import { IoIosArrowDropright } from "react-icons/io"; -import { useRouter } from "next/navigation"; - -const dataTugas = [ - { - id: 1, - name: "Iqbal Ramadan", - image: "https://i.pravatar.cc/1000?img=5", - email: "iqbal.ramadan@gmail.com", - }, - { - id: 2, - name: "Doni Setiawan", - image: "https://i.pravatar.cc/1000?img=10", - email: "doni.setiawan@gmail.com", - }, - { - id: 3, - name: "Rangga Agung", - image: "https://i.pravatar.cc/1000?img=51", - email: "rangga.agung@gmail.com", - }, - { - id: 4, - name: "Ramadan Sananta", - image: "https://i.pravatar.cc/1000?img=15", - email: "ramadan@gmail.com", - }, - { - id: 5, - name: "Imam Baroni", - image: "https://i.pravatar.cc/1000?img=22", - email: "imam.baroni@gmail.com", - }, -]; - -export default function ViewDateEndTask({ kategori }: { kategori: string }) { - const [value, setValue] = useState<[Date | null, Date | null]>([null, null]); - const router = useRouter() - - return ( - - - - - - - - - Tanggal Mulai - - {value[0] ? `${value[0].toLocaleDateString()}` : ""} - - - - Tanggal Berakhir - - {value[1] ? `${value[1].toLocaleDateString()}` : ""} - - - - - - router.push(`/${kategori}/create?page=create-users`)}> - - Tambah Anggota - - - - - - - Anggota Terpilih - Total 10 Anggota - - - - - - Divisi Kerohanian - - {dataTugas.map((v, i) => { - return ( - - - - - - {v.name} - - - {v.email} - - - - - Anggota - - - ); - })} - - - - - - - - - - ); -} diff --git a/src/module/project/components/create_project.tsx b/src/module/project/components/create_project.tsx deleted file mode 100644 index 18d6ba0..0000000 --- a/src/module/project/components/create_project.tsx +++ /dev/null @@ -1,156 +0,0 @@ -"use client"; -import { LayoutDrawer, LayoutNavbarNew, WARNA } from "@/module/_global"; -import { Box, Button, Center, Flex, Group, Select, Stack, Text, TextInput } from "@mantine/core"; -import { useRouter } from "next/navigation"; -import React, { useState } from "react"; -import { IoIosArrowDropright } from "react-icons/io"; -import { BsFiletypeCsv } from "react-icons/bs"; -import ResultsDateAndTask from "./results_date-and_task"; -import ResultsFile from "./results_file"; -import LayoutModal from "@/module/_global/layout/layout_modal"; -import toast from "react-hot-toast"; - -export default function CreateProject({ searchParams }: { searchParams: any }) { - const router = useRouter(); - const [openDrawer, setOpenDrawer] = useState(false); - const [isModal, setModal] = useState(false) - - function onTrue(val: boolean) { - if (val) { - toast.success("Sukses! Data tersimpan"); - router.push('/project') - } - setModal(false) - } - - return ( - - - - - setTitle(e.target.value)} + /> + + + + + + + ); +} diff --git a/src/module/project/ui/create_project.tsx b/src/module/project/ui/create_project.tsx new file mode 100644 index 0000000..7094d3d --- /dev/null +++ b/src/module/project/ui/create_project.tsx @@ -0,0 +1,416 @@ +"use client"; +import { LayoutDrawer, LayoutNavbarNew, WARNA } from "@/module/_global"; +import { Avatar, Box, Button, Center, Flex, Group, Select, SimpleGrid, Stack, Text, TextInput } from "@mantine/core"; +import { useRouter, useSearchParams } from "next/navigation"; +import React, { useRef, useState } from "react"; +import { IoIosArrowDropright } from "react-icons/io"; +import { BsFiletypeCsv } from "react-icons/bs"; +import ResultsDateAndTask from "./results_date-and_task"; +import ResultsFile from "./results_file"; +import LayoutModal from "@/module/_global/layout/layout_modal"; +import toast from "react-hot-toast"; +import { funGetAllGroup, IDataGroup } from "@/module/group"; +import { funGetUserByCookies } from "@/module/auth"; +import { useShallowEffect } from "@mantine/hooks"; +import { useHookstate } from "@hookstate/core"; +import { globalMemberProject } from "../lib/val_project"; +import ViewDateEndTask from "./create_date_end_task"; +import { IFormDateProject, IFormMemberProject, IListFileTaskProject } from "../lib/type_project"; +import CreateUsersProject from "./create_users_project"; +import { FaTrash } from "react-icons/fa6"; +import { Dropzone } from "@mantine/dropzone"; +import _ from "lodash"; +import { funCreateProject } from "../lib/api_project"; + +export default function CreateProject() { + const router = useRouter(); + const [openDrawer, setOpenDrawer] = useState(false) + const [openDrawerFile, setOpenDrawerFile] = useState(false) + const [openDrawerTask, setOpenDrawerTask] = useState(false) + const [isModal, setModal] = useState(false) + const [dataGroup, setDataGroup] = useState([]); + const [roleUser, setRoleUser] = useState("") + const [isChooseAnggota, setChooseAnggota] = useState(false) + const member = useHookstate(globalMemberProject) + const memberValue = member.get() as IFormMemberProject[] + const [openTugas, setOpenTugas] = useState(false) + const [dataTask, setDataTask] = useState([]) + const openRef = useRef<() => void>(null) + const [fileForm, setFileForm] = useState([]) + const [listFile, setListFile] = useState([]) + const [indexDelFile, setIndexDelFile] = useState(0) + const [indexDelTask, setIndexDelTask] = useState(0) + const [body, setBody] = useState({ + idGroup: "", + title: "", + desc: "", + }); + + function deleteFile(index: number) { + setListFile([...listFile.filter((val, i) => i !== index)]) + setFileForm([...fileForm.filter((val, i) => i !== index)]) + setOpenDrawerFile(false) + } + + function deleteTask(index: number) { + setDataTask([...dataTask.filter((val, i) => i !== index)]) + setOpenDrawerTask(false) + } + + async function loadData() { + const loadGroup = await funGetAllGroup('?active=true') + if (loadGroup.success) { + setDataGroup(loadGroup.data); + } else { + toast.error(loadGroup.message); + } + + const loadUser = await funGetUserByCookies(); + setRoleUser(loadUser.idUserRole) + } + + function onToChooseAnggota() { + if (roleUser == "supadmin" && body.idGroup == "") + return toast.error("Error! grup harus diisi") + setChooseAnggota(true) + } + + function onChooseGroup(val: any) { + member.set([]) + setBody({ ...body, idGroup: val }) + } + + useShallowEffect(() => { + loadData(); + }, []); + + + async function onSubmit() { + try { + const response = await funCreateProject({ title: body.title, idGroup: body.idGroup, task: dataTask, file: fileForm, member: memberValue }) + + if (response.success) { + toast.success(response.message) + setBody({ + idGroup: "", + title: "", + desc: "", + }) + member.set([]) + setFileForm([]) + setListFile([]) + setDataTask([]) + } else { + toast.error(response.message) + } + } catch (error) { + console.log(error) + toast.error("Gagal menambahkan tugas divisi, coba lagi nanti"); + } + } + + + + if (openTugas) return { + setDataTask([...dataTask, val]) + setOpenTugas(false) + }} />; + + if (isChooseAnggota) return { setChooseAnggota(false) }} /> + + + return ( + + + + + { + (roleUser == "supadmin") && ( +