upd: task divisi

Deskripsi:
- update role akses task divisi

No Issues'
This commit is contained in:
2025-08-22 16:29:52 +08:00
parent d88c332b03
commit 298113488c
6 changed files with 164 additions and 125 deletions

View File

@@ -8,7 +8,7 @@ import SectionMemberTask from "@/components/task/sectionMemberTask";
import SectionReportTask from "@/components/task/sectionReportTask"; import SectionReportTask from "@/components/task/sectionReportTask";
import SectionTanggalTugasTask from "@/components/task/sectionTanggalTugasTask"; import SectionTanggalTugasTask from "@/components/task/sectionTanggalTugasTask";
import Styles from "@/constants/Styles"; import Styles from "@/constants/Styles";
import { apiGetTaskOne } from "@/lib/api"; import { apiGetDivisionOneFeature, apiGetTaskOne } from "@/lib/api";
import { useAuthSession } from "@/providers/AuthProvider"; import { useAuthSession } from "@/providers/AuthProvider";
import { router, Stack, useLocalSearchParams } from "expo-router"; import { router, Stack, useLocalSearchParams } from "expo-router";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
@@ -32,6 +32,35 @@ export default function DetailTaskDivision() {
const [progress, setProgress] = useState(0) const [progress, setProgress] = useState(0)
const update = useSelector((state: any) => state.taskUpdate) const update = useSelector((state: any) => state.taskUpdate)
const [refreshing, setRefreshing] = useState(false) const [refreshing, setRefreshing] = useState(false)
const [isMemberDivision, setIsMemberDivision] = useState(false);
const [isAdminDivision, setIsAdminDivision] = useState(false);
const entityUser = useSelector((state: any) => state.user);
async function handleCheckMember() {
try {
const hasil = await decryptToken(String(token?.current));
const response = await apiGetDivisionOneFeature({
id,
user: hasil,
cat: "check-member",
});
setIsMemberDivision(response.data);
const response2 = await apiGetDivisionOneFeature({
id,
user: hasil,
cat: "check-admin",
});
setIsAdminDivision(response2.data);
} catch (error) {
console.error(error);
}
}
useEffect(() => {
handleCheckMember()
}, [])
async function handleLoad(cat: 'data' | 'progress') { async function handleLoad(cat: 'data' | 'progress') {
@@ -74,7 +103,9 @@ export default function DetailTaskDivision() {
headerLeft: () => <ButtonBackHeader onPress={() => { router.back() }} />, headerLeft: () => <ButtonBackHeader onPress={() => { router.back() }} />,
headerTitle: loading ? 'Loading... ' : data?.title, headerTitle: loading ? 'Loading... ' : data?.title,
headerTitleAlign: 'center', headerTitleAlign: 'center',
headerRight: () => <HeaderRightTaskDetail id={detail} division={id} status={data?.status} />, headerRight: () => (entityUser.role == "user" || entityUser.role == "coadmin") && !isMemberDivision
? <></>
: <HeaderRightTaskDetail id={detail} division={id} status={data?.status} isAdminDivision={isAdminDivision} />,
}} }}
/> />
<ScrollView <ScrollView
@@ -91,10 +122,10 @@ export default function DetailTaskDivision() {
} }
<SectionProgress text={`Kemajuan Kegiatan ${progress}%`} progress={progress} /> <SectionProgress text={`Kemajuan Kegiatan ${progress}%`} progress={progress} />
<SectionReportTask refreshing={refreshing} /> <SectionReportTask refreshing={refreshing} />
<SectionTanggalTugasTask refreshing={refreshing} /> <SectionTanggalTugasTask refreshing={refreshing} isMemberDivision={isMemberDivision} />
<SectionFileTask refreshing={refreshing} /> <SectionFileTask refreshing={refreshing} isMemberDivision={isMemberDivision} />
<SectionLinkTask refreshing={refreshing} /> <SectionLinkTask refreshing={refreshing} isMemberDivision={isMemberDivision} />
<SectionMemberTask refreshing={refreshing} /> <SectionMemberTask refreshing={refreshing} isMemberDivision={isMemberDivision} />
</View> </View>
</ScrollView> </ScrollView>
</SafeAreaView> </SafeAreaView>

View File

@@ -1,10 +1,10 @@
import Styles from "@/constants/Styles" import Styles from "@/constants/Styles"
import { apiAddLinkTask, apiDeleteTask, apiGetDivisionOneFeature } from "@/lib/api" import { apiAddLinkTask, apiDeleteTask } from "@/lib/api"
import { setUpdateTask } from "@/lib/taskUpdate" import { setUpdateTask } from "@/lib/taskUpdate"
import { useAuthSession } from "@/providers/AuthProvider" import { useAuthSession } from "@/providers/AuthProvider"
import { AntDesign, Feather, Ionicons, MaterialCommunityIcons, MaterialIcons } from "@expo/vector-icons" import { AntDesign, Feather, Ionicons, MaterialCommunityIcons, MaterialIcons } from "@expo/vector-icons"
import { router } from "expo-router" import { router } from "expo-router"
import { useEffect, useState } from "react" import { useState } from "react"
import { View } from "react-native" import { View } from "react-native"
import Toast from "react-native-toast-message" import Toast from "react-native-toast-message"
import { useDispatch, useSelector } from "react-redux" import { useDispatch, useSelector } from "react-redux"
@@ -18,46 +18,19 @@ import ModalFloat from "../modalFloat"
type Props = { type Props = {
id: string | string[] id: string | string[]
division: string division: string
status: number | undefined status: number | undefined,
isAdminDivision: boolean
} }
export default function HeaderRightTaskDetail({ id, division, status }: Props) { export default function HeaderRightTaskDetail({ id, division, status, isAdminDivision }: Props) {
const { token, decryptToken } = useAuthSession() const { token, decryptToken } = useAuthSession()
const [isVisible, setVisible] = useState(false) const [isVisible, setVisible] = useState(false)
const entityUser = useSelector((state: any) => state.user); const entityUser = useSelector((state: any) => state.user);
const [isMemberDivision, setIsMemberDivision] = useState(false);
const [isAdminDivision, setIsAdminDivision] = useState(false);
const dispatch = useDispatch() const dispatch = useDispatch()
const update = useSelector((state: any) => state.taskUpdate) const update = useSelector((state: any) => state.taskUpdate)
const [isAddLink, setAddLink] = useState(false) const [isAddLink, setAddLink] = useState(false)
const [link, setLink] = useState("") const [link, setLink] = useState("")
async function handleCheckMember() {
try {
const hasil = await decryptToken(String(token?.current));
const response = await apiGetDivisionOneFeature({
id: division,
user: hasil,
cat: "check-member",
});
setIsMemberDivision(response.data);
const response2 = await apiGetDivisionOneFeature({
id: division,
user: hasil,
cat: "check-admin",
});
setIsAdminDivision(response2.data);
} catch (error) {
console.error(error);
}
}
useEffect(() => {
handleCheckMember()
}, [])
async function handleDelete() { async function handleDelete() {
try { try {
const hasil = await decryptToken(String(token?.current)) const hasil = await decryptToken(String(token?.current))
@@ -95,12 +68,7 @@ export default function HeaderRightTaskDetail({ id, division, status }: Props) {
return ( return (
<> <>
{ <ButtonMenuHeader onPress={() => { setVisible(true) }} />
(entityUser.role == "user" || entityUser.role == "coadmin") && !isMemberDivision
? <></>
:
<ButtonMenuHeader onPress={() => { setVisible(true) }} />
}
<DrawerBottom animation="slide" isVisible={isVisible} setVisible={setVisible} title="Menu" height={30}> <DrawerBottom animation="slide" isVisible={isVisible} setVisible={setVisible} title="Menu" height={30}>
<View style={Styles.rowItemsCenter}> <View style={Styles.rowItemsCenter}>
<MenuItemRow <MenuItemRow

View File

@@ -28,7 +28,7 @@ type Props = {
idStorage: string idStorage: string
} }
export default function SectionFileTask({ refreshing }: { refreshing: boolean }) { export default function SectionFileTask({ refreshing, isMemberDivision }: { refreshing: boolean, isMemberDivision: boolean }) {
const [isModal, setModal] = useState(false) const [isModal, setModal] = useState(false)
const { token, decryptToken } = useAuthSession() const { token, decryptToken } = useAuthSession()
const { detail } = useLocalSearchParams<{ detail: string }>() const { detail } = useLocalSearchParams<{ detail: string }>()
@@ -39,6 +39,7 @@ export default function SectionFileTask({ refreshing }: { refreshing: boolean })
const arrSkeleton = Array.from({ length: 5 }) const arrSkeleton = Array.from({ length: 5 })
const [selectFile, setSelectFile] = useState<Props | null>(null) const [selectFile, setSelectFile] = useState<Props | null>(null)
const [loadingOpen, setLoadingOpen] = useState(false) const [loadingOpen, setLoadingOpen] = useState(false)
const entityUser = useSelector((state: any) => state.user);
async function handleLoad(loading: boolean) { async function handleLoad(loading: boolean) {
try { try {
@@ -163,21 +164,28 @@ export default function SectionFileTask({ refreshing }: { refreshing: boolean })
openFile() openFile()
}} }}
/> />
<MenuItemRow {
icon={<Ionicons name="trash" color="black" size={25} />} (entityUser.role != "user" && entityUser.role != "coadmin") || isMemberDivision
title="Hapus" ?
onPress={() => { <MenuItemRow
setModal(false) icon={<Ionicons name="trash" color="black" size={25} />}
AlertKonfirmasi({ title="Hapus"
title: 'Konfirmasi', onPress={() => {
desc: 'Apakah Anda yakin ingin menghapus file ini? File yang dihapus tidak dapat dikembalikan', setModal(false)
onPress: () => { AlertKonfirmasi({
handleDelete() title: 'Konfirmasi',
} desc: 'Apakah Anda yakin ingin menghapus file ini? File yang dihapus tidak dapat dikembalikan',
}) onPress: () => {
handleDelete()
}
})
}}
/>
:
<></>
}
}}
/>
</View> </View>
</DrawerBottom> </DrawerBottom>
</> </>

View File

@@ -20,7 +20,7 @@ type Props = {
link: string link: string
} }
export default function SectionLinkTask({ refreshing }: { refreshing: boolean }) { export default function SectionLinkTask({ refreshing, isMemberDivision }: { refreshing: boolean, isMemberDivision: boolean }) {
const [isModal, setModal] = useState(false) const [isModal, setModal] = useState(false)
const { token, decryptToken } = useAuthSession() const { token, decryptToken } = useAuthSession()
const { detail } = useLocalSearchParams<{ detail: string }>() const { detail } = useLocalSearchParams<{ detail: string }>()
@@ -28,6 +28,7 @@ export default function SectionLinkTask({ refreshing }: { refreshing: boolean })
const update = useSelector((state: any) => state.taskUpdate) const update = useSelector((state: any) => state.taskUpdate)
const dispatch = useDispatch() const dispatch = useDispatch()
const [selectLink, setSelectLink] = useState<Props | null>(null) const [selectLink, setSelectLink] = useState<Props | null>(null)
const entityUser = useSelector((state: any) => state.user);
async function handleLoad() { async function handleLoad() {
try { try {
@@ -101,18 +102,25 @@ export default function SectionLinkTask({ refreshing }: { refreshing: boolean })
Linking.openURL(urlCompleted(String(selectLink?.link))) Linking.openURL(urlCompleted(String(selectLink?.link)))
}} }}
/> />
<MenuItemRow {
icon={<Ionicons name="trash" color="black" size={25} />} (entityUser.role != "user" && entityUser.role != "coadmin") || isMemberDivision
title="Hapus" ?
onPress={() => { <MenuItemRow
setModal(false) icon={<Ionicons name="trash" color="black" size={25} />}
AlertKonfirmasi({ title="Hapus"
title: 'Konfirmasi', onPress={() => {
desc: 'Apakah Anda yakin ingin menghapus link ini? Link yang dihapus tidak dapat dikembalikan', setModal(false)
onPress: () => { handleDelete() } AlertKonfirmasi({
}) title: 'Konfirmasi',
}} desc: 'Apakah Anda yakin ingin menghapus link ini? Link yang dihapus tidak dapat dikembalikan',
/> onPress: () => { handleDelete() }
})
}}
/>
:
<></>
}
</View> </View>
</DrawerBottom> </DrawerBottom>
</> </>

View File

@@ -26,8 +26,9 @@ type Props = {
position: string; position: string;
}; };
export default function SectionMemberTask({ refreshing }: { refreshing: boolean }) { export default function SectionMemberTask({ refreshing, isMemberDivision }: { refreshing: boolean, isMemberDivision: boolean }) {
const [isModal, setModal] = useState(false); const [isModal, setModal] = useState(false);
const entityUser = useSelector((state: any) => state.user);
const { token, decryptToken } = useAuthSession(); const { token, decryptToken } = useAuthSession();
const { id, detail } = useLocalSearchParams<{ id: string; detail: string }>(); const { id, detail } = useLocalSearchParams<{ id: string; detail: string }>();
const [data, setData] = useState<Props[]>([]); const [data, setData] = useState<Props[]>([]);
@@ -165,24 +166,31 @@ export default function SectionMemberTask({ refreshing }: { refreshing: boolean
}} }}
/> />
<MenuItemRow
icon={ {
<MaterialCommunityIcons (entityUser.role != "user" && entityUser.role != "coadmin") || isMemberDivision
name="account-remove" ?
color="black" <MenuItemRow
size={25} icon={
<MaterialCommunityIcons
name="account-remove"
color="black"
size={25}
/>
}
title="Keluarkan"
onPress={() => {
setModal(false)
AlertKonfirmasi({
title: "Konfirmasi",
desc: "Apakah Anda yakin ingin mengeluarkan anggota?",
onPress: () => { handleDeleteMember() },
});
}}
/> />
} :
title="Keluarkan" <></>
onPress={() => { }
setModal(false)
AlertKonfirmasi({
title: "Konfirmasi",
desc: "Apakah Anda yakin ingin mengeluarkan anggota?",
onPress: () => { handleDeleteMember() },
});
}}
/>
</View> </View>
</DrawerBottom> </DrawerBottom>
</> </>

View File

@@ -26,8 +26,9 @@ type Props = {
dateEnd: string; dateEnd: string;
} }
export default function SectionTanggalTugasTask({ refreshing }: { refreshing: boolean }) { export default function SectionTanggalTugasTask({ refreshing, isMemberDivision }: { refreshing: boolean, isMemberDivision: boolean }) {
const dispatch = useDispatch() const dispatch = useDispatch()
const entityUser = useSelector((state: any) => state.user);
const update = useSelector((state: any) => state.taskUpdate) const update = useSelector((state: any) => state.taskUpdate)
const [isModal, setModal] = useState(false) const [isModal, setModal] = useState(false)
const [isSelect, setSelect] = useState(false) const [isSelect, setSelect] = useState(false)
@@ -155,24 +156,6 @@ export default function SectionTanggalTugasTask({ refreshing }: { refreshing: bo
<DrawerBottom animation="slide" isVisible={isModal} setVisible={setModal} title="Menu"> <DrawerBottom animation="slide" isVisible={isModal} setVisible={setModal} title="Menu">
<View style={Styles.rowItemsCenter}> <View style={Styles.rowItemsCenter}>
<MenuItemRow
icon={<MaterialCommunityIcons name="list-status" color="black" size={25} />}
title="Update Status"
onPress={() => {
setModal(false)
setTimeout(() => {
setSelect(true)
}, 600);
}}
/>
<MenuItemRow
icon={<MaterialCommunityIcons name="pencil-outline" color="black" size={25} />}
title="Edit Tugas"
onPress={() => {
setModal(false)
router.push(`./update/${tugas.id}`)
}}
/>
<MenuItemRow <MenuItemRow
icon={ icon={
<MaterialCommunityIcons <MaterialCommunityIcons
@@ -189,24 +172,57 @@ export default function SectionTanggalTugasTask({ refreshing }: { refreshing: bo
}, 600) }, 600)
}} }}
/> />
</View> {
<View style={[Styles.rowItemsCenter, Styles.mt15]}> (entityUser.role != "user" && entityUser.role != "coadmin") || isMemberDivision
<MenuItemRow ?
icon={<Ionicons name="trash" color="black" size={25} />} <>
title="Hapus Tugas" <MenuItemRow
onPress={() => { icon={<MaterialCommunityIcons name="list-status" color="black" size={25} />}
setModal(false) title="Update Status"
AlertKonfirmasi({ onPress={() => {
title: 'Konfirmasi', setModal(false)
desc: 'Apakah anda yakin ingin menghapus data ini?', setTimeout(() => {
onPress: () => { setSelect(true)
handleDelete() }, 600);
} }}
}) />
<MenuItemRow
icon={<MaterialCommunityIcons name="pencil-outline" color="black" size={25} />}
title="Edit Tugas"
onPress={() => {
setModal(false)
router.push(`./update/${tugas.id}`)
}}
/>
</>
:
<></>
}
}}
/>
</View> </View>
{
(entityUser.role != "user" && entityUser.role != "coadmin") || isMemberDivision
?
<View style={[Styles.rowItemsCenter, Styles.mt15]}>
<MenuItemRow
icon={<Ionicons name="trash" color="black" size={25} />}
title="Hapus Tugas"
onPress={() => {
setModal(false)
AlertKonfirmasi({
title: 'Konfirmasi',
desc: 'Apakah anda yakin ingin menghapus data ini?',
onPress: () => {
handleDelete()
}
})
}}
/>
</View>
:
<></>
}
</DrawerBottom> </DrawerBottom>
<ModalSelect <ModalSelect