diff --git a/src/app/(application)/project/[id]/layout.tsx b/src/app/(application)/project/[id]/layout.tsx
new file mode 100644
index 0000000..c3f8779
--- /dev/null
+++ b/src/app/(application)/project/[id]/layout.tsx
@@ -0,0 +1,11 @@
+import { WrapLayoutProject } from "@/module/project";
+
+export default async function Layout({ children }: { children: React.ReactNode }) {
+ return (
+ <>
+
+ {children}
+
+ >
+ );
+}
\ No newline at end of file
diff --git a/src/module/project/index.ts b/src/module/project/index.ts
index 090f969..1c33e04 100644
--- a/src/module/project/index.ts
+++ b/src/module/project/index.ts
@@ -14,6 +14,7 @@ import CancelProject from "./ui/cancel_project";
import AddMemberDetailProject from "./ui/add_member_detail_project";
import CreateProject from "./ui/create_project";
import AddFileDetailProject from "./ui/add_file_detail_project";
+import WrapLayoutProject from "./ui/wrap_project";
export { ViewDateEndTask }
export { CreateUsersProject }
@@ -29,4 +30,5 @@ export { AddDetailTaskProject }
export { CancelProject }
export { AddMemberDetailProject }
export { CreateProject }
-export { AddFileDetailProject }
\ No newline at end of file
+export { AddFileDetailProject }
+export { WrapLayoutProject }
\ No newline at end of file
diff --git a/src/module/project/lib/val_project.ts b/src/module/project/lib/val_project.ts
index 1566b5b..70c2d24 100644
--- a/src/module/project/lib/val_project.ts
+++ b/src/module/project/lib/val_project.ts
@@ -3,6 +3,7 @@ import { IFormMemberProject } from "./type_project";
export const globalRefreshProject = hookstate(false)
export const globalMemberProject = hookstate([]);
+export const globalIsMemberProject = hookstate(false)
export const valStatusDetailProject = [
{
diff --git a/src/module/project/ui/list_anggota_detail_project.tsx b/src/module/project/ui/list_anggota_detail_project.tsx
index e5b5220..b1a78cb 100644
--- a/src/module/project/ui/list_anggota_detail_project.tsx
+++ b/src/module/project/ui/list_anggota_detail_project.tsx
@@ -111,7 +111,7 @@ export default function ListAnggotaDetailProject() {
return (
- Anggota Terpilih
+ Anggota
Total {isData.length} Anggota
diff --git a/src/module/project/ui/list_file_detail_project.tsx b/src/module/project/ui/list_file_detail_project.tsx
index 2e0c424..9a65f43 100644
--- a/src/module/project/ui/list_file_detail_project.tsx
+++ b/src/module/project/ui/list_file_detail_project.tsx
@@ -1,5 +1,5 @@
'use client'
-import { keyWibu, LayoutDrawer, LayoutModalViewFile, TEMA } from '@/module/_global';
+import { globalRole, keyWibu, LayoutDrawer, LayoutModalViewFile, TEMA } from '@/module/_global';
import LayoutModal from '@/module/_global/layout/layout_modal';
import { useHookstate } from '@hookstate/core';
import { Box, Flex, Grid, Group, SimpleGrid, Skeleton, Stack, Text } from '@mantine/core';
@@ -12,6 +12,7 @@ import { FaTrash } from 'react-icons/fa6';
import { useWibuRealtime } from 'wibu-realtime';
import { funDeleteFileProject, funGetOneProjectById } from '../lib/api_project';
import { IDataFileProject } from '../lib/type_project';
+import { globalIsMemberProject } from '../lib/val_project';
export default function ListFileDetailProject() {
const [isData, setData] = useState([])
@@ -26,6 +27,8 @@ export default function ListFileDetailProject() {
const [isOpenModalView, setOpenModalView] = useState(false)
const [isExtension, setExtension] = useState('')
const tema = useHookstate(TEMA)
+ const roleLogin = useHookstate(globalRole)
+ const memberProject = useHookstate(globalIsMemberProject)
const isMobile = useMediaQuery("(max-width: 350px)");
const [reason, setReason] = useState("")
const [dataRealTime, setDataRealtime] = useWibuRealtime({
@@ -212,18 +215,22 @@ export default function ListFileDetailProject() {
- {
- reason == null ?
- setOpenModal(true)
- : setOpenModal(false)
- }} justify={'center'} align={'center'} direction={'column'} >
-
-
-
-
- Hapus file
-
-
+ {
+ (roleLogin.get() == "user" || roleLogin.get() == "coadmin") && !memberProject.get() ? <>>
+ :
+ {
+ reason == null ?
+ setOpenModal(true)
+ : setOpenModal(false)
+ }} justify={'center'} align={'center'} direction={'column'} >
+
+
+
+
+ Hapus file
+
+
+ }
diff --git a/src/module/project/ui/list_tugas_detail_project.tsx b/src/module/project/ui/list_tugas_detail_project.tsx
index 2e8fd48..c14c45a 100644
--- a/src/module/project/ui/list_tugas_detail_project.tsx
+++ b/src/module/project/ui/list_tugas_detail_project.tsx
@@ -1,8 +1,8 @@
'use client'
-import { keyWibu, LayoutDrawer, SkeletonDetailListTugasTask, TEMA } from '@/module/_global';
+import { globalRole, keyWibu, LayoutDrawer, SkeletonDetailListTugasTask, TEMA } from '@/module/_global';
import LayoutModal from '@/module/_global/layout/layout_modal';
import { useHookstate } from '@hookstate/core';
-import { Box, Center, Checkbox, Divider, Flex, Grid, Group, SimpleGrid, Stack, Text } from '@mantine/core';
+import { Box, Center, Checkbox, Divider, Flex, Grid, Group, SimpleGrid, Stack, Text, Loader } from '@mantine/core';
import { useShallowEffect } from '@mantine/hooks';
import { useParams, useRouter } from 'next/navigation';
import { useState } from 'react';
@@ -12,7 +12,7 @@ import { FaCheck, FaPencil, FaTrash } from 'react-icons/fa6';
import { useWibuRealtime } from 'wibu-realtime';
import { funDeleteDetailProject, funGetOneProjectById, funUpdateStatusProject } from '../lib/api_project';
import { IDataListTaskProject } from '../lib/type_project';
-import { globalRefreshProject, valStatusDetailProject } from '../lib/val_project';
+import { globalIsMemberProject, globalRefreshProject, valStatusDetailProject } from '../lib/val_project';
export default function ListTugasDetailProject() {
const [isData, setData] = useState([])
@@ -27,6 +27,10 @@ export default function ListTugasDetailProject() {
const [loadingDelete, setLoadingDelete] = useState(false)
const router = useRouter()
const tema = useHookstate(TEMA)
+ const roleLogin = useHookstate(globalRole)
+ const memberProject = useHookstate(globalIsMemberProject)
+ const [loadingStatus, setLoadingStatus] = useState(false)
+ const [pilihStatus, setPilihStatus] = useState(0)
const [reason, setReason] = useState("")
const [dataRealTime, setDataRealtime] = useWibuRealtime({
WIBU_REALTIME_TOKEN: keyWibu,
@@ -102,6 +106,8 @@ export default function ListTugasDetailProject() {
async function onUpdateStatus(val: number) {
try {
+ setLoadingStatus(true)
+ setPilihStatus(val)
const res = await funUpdateStatusProject(idData, { status: val, idProject: param.id });
if (res.success) {
setDataRealtime([{
@@ -120,6 +126,8 @@ export default function ListTugasDetailProject() {
} catch (error) {
console.error(error);
toast.error("Gagal update status tugas Kegiatan, coba lagi nanti");
+ } finally {
+ setLoadingStatus(false)
}
}
@@ -158,11 +166,15 @@ export default function ListTugasDetailProject() {
return (
{
- setIdData(item.id)
- setStatusData(item.status)
- reason == null ?
- setOpenDrawer(true)
- : setOpenDrawer(false)
+ if (!memberProject.get() && ((roleLogin.get() == "user" || roleLogin.get() == "coadmin"))) {
+ setOpenDrawer(false)
+ } else {
+ setIdData(item.id)
+ setStatusData(item.status)
+ reason == null ?
+ setOpenDrawer(true)
+ : setOpenDrawer(false)
+ }
}} my={18}>
{
return (
- { onUpdateStatus(item.value) }}>
+ {
+ if (!loadingStatus) {
+ onUpdateStatus(item.value)
+ }
+ }}>
- {statusData === item.value ? : ""}
+ {
+ loadingStatus && pilihStatus == item.value ?
+ :
+ statusData === item.value ? : ""
+ }
diff --git a/src/module/project/ui/navbar_detail_project.tsx b/src/module/project/ui/navbar_detail_project.tsx
index dcbaba7..2444f20 100644
--- a/src/module/project/ui/navbar_detail_project.tsx
+++ b/src/module/project/ui/navbar_detail_project.tsx
@@ -12,6 +12,7 @@ import { IoAddCircle } from 'react-icons/io5';
import { MdCancel } from 'react-icons/md';
import { useWibuRealtime } from 'wibu-realtime';
import { funGetOneProjectById } from '../lib/api_project';
+import { globalIsMemberProject } from '../lib/val_project';
export default function NavbarDetailProject() {
const router = useRouter()
@@ -20,6 +21,7 @@ export default function NavbarDetailProject() {
const [grup, setGrup] = useState("")
const [isOpen, setOpen] = useState(false)
const roleLogin = useHookstate(globalRole)
+ const memberProject = useHookstate(globalIsMemberProject)
const tema = useHookstate(TEMA)
const [reason, setReason] = useState("")
const [dataRealTime, setDataRealtime] = useWibuRealtime({
@@ -57,16 +59,18 @@ export default function NavbarDetailProject() {
return (
<>
{ setOpen(true) }}
- >
-
-
+ (roleLogin.get() == "user" || roleLogin.get() == "coadmin") && !memberProject.get() ? <>>
+ :
+ { setOpen(true) }}
+ >
+
+
} />
setOpen(false)}>
diff --git a/src/module/project/ui/wrap_project.tsx b/src/module/project/ui/wrap_project.tsx
new file mode 100644
index 0000000..f1e6643
--- /dev/null
+++ b/src/module/project/ui/wrap_project.tsx
@@ -0,0 +1,28 @@
+'use client'
+import { useHookstate } from "@hookstate/core";
+import { useShallowEffect } from "@mantine/hooks";
+import { useParams } from "next/navigation";
+import { funGetUserByCookies } from "@/module/auth";
+import { globalIsMemberProject } from "../lib/val_project";
+import { funGetOneProjectById } from "../lib/api_project";
+
+export default function WrapLayoutProject({ children }: { children: React.ReactNode }) {
+ const isMember = useHookstate(globalIsMemberProject)
+ const param = useParams<{ id: string }>()
+
+ const getData = async () => {
+ const res = await funGetOneProjectById(param.id, 'member');
+ const login = await funGetUserByCookies()
+ const cekMember = res.data.some((i: any) => i.idUser == login.id)
+ isMember.set(cekMember)
+ }
+
+ useShallowEffect(() => {
+ getData()
+ }, [])
+ return (
+ <>
+ {children}
+ >
+ );
+}
\ No newline at end of file