From a336728d0cfbc21e44e176cd66fea7aeafabcecb Mon Sep 17 00:00:00 2001 From: lukman Date: Tue, 30 Jul 2024 15:07:41 +0800 Subject: [PATCH] feat : add group --- api.http | 4 +- src/module/_global/bin/api_address.ts | 25 ++ src/module/group/api/api_index.ts | 2 +- src/module/group/api/get/listGroup.ts | 6 +- src/module/group/api/post/createGroup.ts | 12 +- src/module/group/api/post/deleteGroup.ts | 23 +- .../group/components/list_group_active.tsx | 218 ++++++++++++------ .../components/list_group_non_active.tsx | 100 -------- .../group/components/tab_list_group.tsx | 44 ++-- .../group/components/ui/drawer_group.tsx | 59 ++++- .../group/components/ui/edit_drawer_group.tsx | 128 ++++++++-- 11 files changed, 378 insertions(+), 243 deletions(-) delete mode 100644 src/module/group/components/list_group_non_active.tsx diff --git a/api.http b/api.http index 6f4e656..14bfa3d 100644 --- a/api.http +++ b/api.http @@ -9,14 +9,14 @@ Content-Type: application/json // GROUP ### -GET http://localhost:3000/api/group/get?path=list-group&villageId=121212 HTTP/1.1 +GET http://localhost:3000/api/group/get?path=get-all-group&villageId=121212&active=true HTTP/1.1 ### POST http://localhost:3000/api/group/post?path=create-group HTTP/1.1 Content-Type: application/json { - "name": "amalia2", + "name": "LPD 3", "idVillage": "121212" } diff --git a/src/module/_global/bin/api_address.ts b/src/module/_global/bin/api_address.ts index 2b45504..b60844e 100644 --- a/src/module/_global/bin/api_address.ts +++ b/src/module/_global/bin/api_address.ts @@ -1,4 +1,29 @@ export const API_ADDRESS = { + // Group "apiGetAllGroup": "/api/group/get?path=get-all-group", + "apiGetOneGroup": "/api/group/get?path=get-one-group", + "apiCreateGroup": "/api/group/post?path=create-group", + "apiUpdateGroup": "/api/group/post?path=update-group", + "apiDeleteGroup": "/api/group/post?path=delete-group", + // User + "apiGetAllUser": "/api/user/get?path=get-all-users", + "apiGetOneUser": "/api/user/get?path=get-one-users", + "apiCreateUser": "/api/user/post?path=create-users", + "apiUpdateUser": "/api/user/post?path=update-users", + "apiDeleteUser": "/api/user/post?path=delete-users", + + // Announcement + "apiGetAllAnnouncement": "/api/announcement/get?path=get-all-announcement", + "apiGetOneAnnouncement": "/api/announcement/get?path=get-one-announcement", + "apiCreateAnnouncement": "/api/announcement/post?path=create-announcement", + "apiUpdateAnnouncement": "/api/announcement/post?path=update-announcement", + "apiDeleteAnnouncement": "/api/announcement/post?path=delete-announcement", + + // Village + "apiGetAllVillage": "/api/village/get?path=get-all-village", + "apiGetOneVillage": "/api/village/get?path=get-one-village", + "apiCreateVillage": "/api/village/post?path=create-village", + "apiUpdateVillage": "/api/village/post?path=update-village", + "apiDeleteVillage": "/api/village/post?path=delete-village", } \ No newline at end of file diff --git a/src/module/group/api/api_index.ts b/src/module/group/api/api_index.ts index f447967..92919ee 100644 --- a/src/module/group/api/api_index.ts +++ b/src/module/group/api/api_index.ts @@ -6,7 +6,7 @@ import { updateGroup } from "./post/updateGroup"; export const API_INDEX_GROUP = [ { - path: "list-group", + path: "get-all-group", method: "GET", bin: listGroups, }, diff --git a/src/module/group/api/get/listGroup.ts b/src/module/group/api/get/listGroup.ts index 424c9cd..3a16422 100644 --- a/src/module/group/api/get/listGroup.ts +++ b/src/module/group/api/get/listGroup.ts @@ -5,15 +5,17 @@ export async function listGroups(req: NextRequest): Promise { try { const searchParams = req.nextUrl.searchParams - const villaId = searchParams.get('villageId'); + const villaId = "121212" + const active = searchParams.get('active'); const groups = await prisma.group.findMany({ where: { - isActive: true, + isActive: (active == "true" ? true : false), idVillage: String(villaId), }, select: { id: true, name: true, + isActive: true }, }); diff --git a/src/module/group/api/post/createGroup.ts b/src/module/group/api/post/createGroup.ts index 9d514e6..6b49d17 100644 --- a/src/module/group/api/post/createGroup.ts +++ b/src/module/group/api/post/createGroup.ts @@ -1,9 +1,10 @@ import { prisma } from "@/module/_global"; +import { revalidatePath } from "next/cache"; export async function createGroup(req: Request) { try { const data = await req.json(); - + const villaId = "121212"; if (!data || !data.name) { return Response.json( @@ -16,17 +17,20 @@ export async function createGroup(req: Request) { data: { name: data.name, isActive: true, - idVillage: data.idVillage, + idVillage: villaId, }, select: { id: true, name: true, }, }); - + revalidatePath("/group"); return Response.json(group, { status: 201 }); } catch (error) { console.error(error); - return Response.json({ success: false, message: "Internal Server Error" }, { status: 500 }); + return Response.json( + { success: false, message: "Internal Server Error" }, + { status: 500 } + ); } } diff --git a/src/module/group/api/post/deleteGroup.ts b/src/module/group/api/post/deleteGroup.ts index 8c4ef2f..68dc4b3 100644 --- a/src/module/group/api/post/deleteGroup.ts +++ b/src/module/group/api/post/deleteGroup.ts @@ -1,19 +1,32 @@ import { prisma } from "@/module/_global"; +import { revalidatePath } from "next/cache"; +import { NextRequest } from "next/server"; -export async function deleteGroup(req: Request) { +export async function deleteGroup(req: NextRequest) { try { const data = await req.json(); - const update = await prisma.group.update({ + const active = data.isActive; + + await prisma.group.update({ where: { id: data.id, }, data: { - isActive: false, + isActive: !active, }, }); - return Response.json({ success: true, message: "Sukses Delete Grup" }, { status: 200 }); + + revalidatePath("/group"); + + return Response.json( + { success: true, message: "Sukses update status grup" }, + { status: 200 } + ); } catch (error) { console.error(error); - return Response.json({ message: "Internal Server Error", success: false }, { status: 500 }); + return Response.json( + { message: "Internal Server Error", success: false }, + { status: 500 } + ); } } diff --git a/src/module/group/components/list_group_active.tsx b/src/module/group/components/list_group_active.tsx index 4f1750c..1d21e37 100644 --- a/src/module/group/components/list_group_active.tsx +++ b/src/module/group/components/list_group_active.tsx @@ -1,49 +1,59 @@ -import { LayoutDrawer, WARNA } from '@/module/_global'; -import { ActionIcon, Box, Group, Text, TextInput } from '@mantine/core'; -import React, { useState } from 'react'; -import { HiOutlineOfficeBuilding } from 'react-icons/hi'; -import { HiMagnifyingGlass } from 'react-icons/hi2'; -import EditDrawerGroup from './ui/edit_drawer_group'; -import toast from 'react-hot-toast'; +import { API_ADDRESS, LayoutDrawer, WARNA } from "@/module/_global"; +import { + ActionIcon, + Box, + Group, + Skeleton, + Text, + TextInput, +} from "@mantine/core"; +import React, { useEffect, useState } from "react"; +import { HiOutlineOfficeBuilding } from "react-icons/hi"; +import { HiMagnifyingGlass } from "react-icons/hi2"; +import EditDrawerGroup from "./ui/edit_drawer_group"; +import toast from "react-hot-toast"; +import { useShallowEffect } from "@mantine/hooks"; -const dataGroup = [ - { - id: 1, - name: 'Dinas' - }, - { - id: 2, - name: 'Adat' - }, - { - id: 3, - name: 'LPD' - }, - { - id: 4, - name: 'Karang Taruna' - }, - { - id: 5, - name: 'BPD' - }, - { - id: 6, - name: 'LPM' - }, - { - id: 7, - name: 'PKK' - }, - { - id: 8, - name: 'Pengelolaan Penduduk' - }, -] +type dataGroup = { + id: string; + name: string; + isActive: boolean; +}; -export default function ListGroupActive() { - const [openDrawer, setOpenDrawer] = useState(false) - const [valChoose, setValChoose] = useState("") +export default function ListGroupActive({ status }: { status: boolean }) { + const [openDrawer, setOpenDrawer] = useState(false); + const [valChoose, setValChoose] = useState(""); + const [isData, setData] = useState([]); + const [selectId, setSelectId] = useState(null); + const [active, setActive] = useState(null); + const [loading, setLoading] = useState(true); + const [isname, setName] = useState(""); + + const getData = async () => { + try { + setData([]); + setLoading(true); + const res = await fetch( + `${API_ADDRESS.apiGetAllGroup}&villageId=121212&active=` + status + ); + const data = await res.json(); + setData(data); + setLoading(false); + } catch (error) { + if (error instanceof Error) { + console.error(error); + toast.error("Terjadi kesalahan"); + } else { + console.error("Error tidak diketahui"); + } + } finally { + setLoading(false); + } + }; + + useEffect(() => { + getData(); + }, [status]); return ( @@ -60,40 +70,96 @@ export default function ListGroupActive() { leftSection={} placeholder="Pencarian" /> - {dataGroup.map((v, i) => { - return ( - - { - setValChoose(v.name) - setOpenDrawer(true) - }} - > - - - - + {loading + ? Array(6) + .fill(null) + .map((_, i) => ( + + + + + + + + + + + - - {v.name} + )) + : isData.map((v, i) => { + return ( + + { + setValChoose(v.name); + setOpenDrawer(true); + setSelectId(v.id); + setActive(v.isActive); + setName(v.name) + }} + > + + + + + + + + {v.name} + + + - - - ) - })} - setOpenDrawer(false)} title={valChoose}> - { - if (val) { - toast.success('Sukses! data tersimpan') - } - setOpenDrawer(false) - }} /> + ); + })} + setOpenDrawer(false)} + title={valChoose} + > + { + if (val) { + toast.success("Sukses! data tersimpan"); + getData(); + } + setOpenDrawer(false); + }} + /> ); diff --git a/src/module/group/components/list_group_non_active.tsx b/src/module/group/components/list_group_non_active.tsx deleted file mode 100644 index 00c5840..0000000 --- a/src/module/group/components/list_group_non_active.tsx +++ /dev/null @@ -1,100 +0,0 @@ -import { LayoutDrawer, WARNA } from '@/module/_global'; -import { ActionIcon, Box, Group, Text, TextInput } from '@mantine/core'; -import React, { useState } from 'react'; -import { HiOutlineOfficeBuilding } from 'react-icons/hi'; -import { HiMagnifyingGlass } from 'react-icons/hi2'; -import EditDrawerGroup from './ui/edit_drawer_group'; -import toast from 'react-hot-toast'; - -const dataGroup = [ - { - id: 1, - name: 'Dinas' - }, - { - id: 2, - name: 'Adat' - }, - { - id: 3, - name: 'LPD' - }, - { - id: 4, - name: 'Karang Taruna' - }, - { - id: 5, - name: 'BPD' - }, - { - id: 6, - name: 'LPM' - }, - { - id: 7, - name: 'PKK' - }, - { - id: 8, - name: 'Pengelolaan Penduduk' - }, -] - -export default function ListGroupNonActive() { - const [openDrawer, setOpenDrawer] = useState(false) - const [valChoose, setValChoose] = useState("") - - return ( - - } - placeholder="Pencarian" - /> - {dataGroup.map((v, i) => { - return ( - - { - setValChoose(v.name) - setOpenDrawer(true) - }} - > - - - - - - - {v.name} - - - - ) - })} - setOpenDrawer(false)} title={valChoose}> - { - if (val) { - toast.success('Sukses! data tersimpan') - } - setOpenDrawer(false) - }} /> - - - ); -} diff --git a/src/module/group/components/tab_list_group.tsx b/src/module/group/components/tab_list_group.tsx index 3338d37..0315881 100644 --- a/src/module/group/components/tab_list_group.tsx +++ b/src/module/group/components/tab_list_group.tsx @@ -1,38 +1,48 @@ -'use client' -import { Box, Tabs, rem } from '@mantine/core'; -import { IoCloseCircleOutline } from "react-icons/io5" -import { IoMdCheckmarkCircleOutline } from "react-icons/io" -import ListGroupActive from './list_group_active'; -import ListGroupNonActive from './list_group_non_active'; +"use client"; +import { Box, Tabs, rem } from "@mantine/core"; +import { IoCloseCircleOutline } from "react-icons/io5"; +import { IoMdCheckmarkCircleOutline } from "react-icons/io"; +import ListGroupActive from "./list_group_active"; export default function TabListGroup() { const iconStyle = { width: rem(20), height: rem(20) }; return ( - - - }> + + + } + > Aktif - }> + } + > Tidak Aktif - + - + {/* */} + ); } - diff --git a/src/module/group/components/ui/drawer_group.tsx b/src/module/group/components/ui/drawer_group.tsx index 10cebfa..2382200 100644 --- a/src/module/group/components/ui/drawer_group.tsx +++ b/src/module/group/components/ui/drawer_group.tsx @@ -1,14 +1,44 @@ -import { LayoutDrawer, WARNA } from '@/module/_global'; -import { Box, Button, Center, Flex, Group, SimpleGrid, Stack, Text, TextInput } from '@mantine/core'; -import React, { useState } from 'react'; +import { API_ADDRESS, LayoutDrawer, WARNA } from "@/module/_global"; +import { + Box, + Button, + Center, + Flex, + Group, + SimpleGrid, + Stack, + Text, + TextInput, +} from "@mantine/core"; +import React, { useState } from "react"; import { IoAddCircle } from "react-icons/io5"; -export default function DrawerGroup({ onSuccess }: { onSuccess: (val: boolean) => void }) { - const [openDrawerGroup, setOpenDrawerGroup] = useState(false) +export default function DrawerGroup({ + onSuccess, +}: { + onSuccess: (val: boolean) => void; +}) { + const [openDrawerGroup, setOpenDrawerGroup] = useState(false); + const [namaGroup, setNamaGroup] = useState(""); - function onCLose() { - setOpenDrawerGroup(false) - onSuccess(true) + + async function onCreate() { + try { + const res = await fetch(API_ADDRESS.apiCreateGroup, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + name: namaGroup, + }), + }); + setOpenDrawerGroup(false); + onSuccess(true); + } catch (error) { + console.log(error); + onSuccess(false); + } } return ( @@ -18,7 +48,7 @@ export default function DrawerGroup({ onSuccess }: { onSuccess: (val: boolean) = cols={{ base: 3, sm: 3, lg: 3 }} onClick={() => setOpenDrawerGroup(true)} > - + @@ -28,7 +58,11 @@ export default function DrawerGroup({ onSuccess }: { onSuccess: (val: boolean) = - setOpenDrawerGroup(false)} title={'Tambah Grup'}> + setOpenDrawerGroup(false)} + title={"Tambah Grup"} + > setNamaGroup(e.target.value)} /> - + diff --git a/src/module/group/components/ui/edit_drawer_group.tsx b/src/module/group/components/ui/edit_drawer_group.tsx index cea9bf4..9fcff0a 100644 --- a/src/module/group/components/ui/edit_drawer_group.tsx +++ b/src/module/group/components/ui/edit_drawer_group.tsx @@ -1,32 +1,96 @@ -'use client' -import { LayoutDrawer, WARNA } from '@/module/_global'; -import LayoutModal from '@/module/_global/layout/layout_modal'; -import { Box, Button, Center, Flex, Group, SimpleGrid, Stack, Text, TextInput } from '@mantine/core'; -import React, { useState } from 'react'; -import { FaPencil, FaToggleOff } from 'react-icons/fa6'; +"use client"; +import { API_ADDRESS, LayoutDrawer, WARNA } from "@/module/_global"; +import LayoutModal from "@/module/_global/layout/layout_modal"; +import { + Box, + Button, + Center, + Flex, + Group, + SimpleGrid, + Stack, + Text, + TextInput, +} from "@mantine/core"; +import React, { useState } from "react"; +import toast from "react-hot-toast"; +import { FaPencil, FaToggleOff } from "react-icons/fa6"; import { IoAddCircle, IoCloseCircleOutline } from "react-icons/io5"; -export default function EditDrawerGroup({ onUpdated }: { onUpdated: (val: boolean) => void }) { - const [openDrawerGroup, setOpenDrawerGroup] = useState(false) - const [isModal, setModal] = useState(false) +export default function EditDrawerGroup({ + onUpdated, + id, + isActive, + isName, +}: { + onUpdated: (val: boolean) => void; + id: string | null; + isActive: boolean | null; + isName: string; +}) { + const [openDrawerGroup, setOpenDrawerGroup] = useState(false); + const [isModal, setModal] = useState(false); + const [name, setName] = useState(isName); - function onCLose() { - setOpenDrawerGroup(false) - onUpdated(true) + async function isUpdate() { + try { + const res = await fetch(API_ADDRESS.apiUpdateGroup, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + id: id, + name : name + }), + }); + setOpenDrawerGroup(false); + onUpdated(true); + } catch (error) { + console.error(error); + } } - function onTrue(val: boolean) { - if (val) { - onUpdated(true) + async function nonActive(val: boolean) { + try { + if (val) { + const res = await fetch(API_ADDRESS.apiDeleteGroup, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + id, + isActive, + }), + }); + + if (res.status == 200) { + onUpdated(true); + } else { + onUpdated(false); + } + } + setModal(false); + } catch (error) { + console.log(error); + setModal(false); + toast.error("Terjadi kesalahan"); + onUpdated(false); } - setModal(false) } return ( - setModal(true)} style={{ cursor: 'pointer' }}> + setModal(true)} + style={{ cursor: "pointer" }} + > @@ -34,7 +98,13 @@ export default function EditDrawerGroup({ onUpdated }: { onUpdated: (val: boolea Non Aktifkan - setOpenDrawerGroup(true)} style={{ cursor: 'pointer' }}> + setOpenDrawerGroup(true)} + style={{ cursor: "pointer" }} + > @@ -44,7 +114,11 @@ export default function EditDrawerGroup({ onUpdated }: { onUpdated: (val: boolea - setOpenDrawerGroup(false)} title={'Edit Grup'}> + setOpenDrawerGroup(false)} + title={"Edit Grup"} + > setName(e.target.value)} radius={10} placeholder="Grup" /> - + @@ -73,10 +149,14 @@ export default function EditDrawerGroup({ onUpdated }: { onUpdated: (val: boolea - setModal(false)} + setModal(false)} description="Apakah Anda yakin ingin mangubah status aktifasi data?" - onYes={(val) => { onTrue(val) }} /> + onYes={(val) => { + nonActive(val); + }} + /> ); } -