This commit is contained in:
2025-09-25 17:13:44 +08:00
parent 65d53951c3
commit ecc41c905f
8 changed files with 137 additions and 58 deletions

View File

@@ -153,14 +153,14 @@ export default function DetailDiscussionGeneral() {
<MaterialIcons name="chat" size={25} color={'#384288'} /> <MaterialIcons name="chat" size={25} color={'#384288'} />
</View> </View>
} }
title={data?.title} title={data?.title + " " + data?.createdAt}
subtitle={ subtitle={
!data?.isActive ? !data?.isActive ?
<LabelStatus category='warning' text='ARSIP' size="small" /> <LabelStatus category='warning' text='ARSIP' size="small" />
: :
<LabelStatus category={data.status == 1 ? 'success' : 'error'} text={data.status == 1 ? 'BUKA' : 'TUTUP'} size="small" /> <LabelStatus category={data.status == 1 ? 'success' : 'error'} text={data.status == 1 ? 'BUKA' : 'TUTUP'} size="small" />
} }
rightTopInfo={data?.createdAt} // rightTopInfo={data?.createdAt}
desc={data?.desc} desc={data?.desc}
leftBottomInfo={ leftBottomInfo={
<View style={[Styles.rowItemsCenter]}> <View style={[Styles.rowItemsCenter]}>
@@ -168,6 +168,11 @@ export default function DetailDiscussionGeneral() {
<Text style={[Styles.textInformation, Styles.cGray, Styles.mb05]}>{dataKomentar.length} Komentar</Text> <Text style={[Styles.textInformation, Styles.cGray, Styles.mb05]}>{dataKomentar.length} Komentar</Text>
</View> </View>
} }
rightBottomInfo={
<View style={[Styles.rowItemsCenter]}>
<Text style={[Styles.textInformation, Styles.cGray, Styles.mb05]}>{data?.createdAt}</Text>
</View>
}
/> />
} }
<View style={[Styles.p15]}> <View style={[Styles.p15]}>
@@ -210,7 +215,7 @@ export default function DetailDiscussionGeneral() {
disable={(data?.status === 2 || !data?.isActive || (!memberDiscussion && (entityUser.role == "user" || entityUser.role == "coadmin")))} disable={(data?.status === 2 || !data?.isActive || (!memberDiscussion && (entityUser.role == "user" || entityUser.role == "coadmin")))}
type="default" type="default"
round round
placeholder="Kirim Komentar2" placeholder="Kirim Komentar"
bg="white" bg="white"
onChange={setKomentar} onChange={setKomentar}
value={komentar} value={komentar}

View File

@@ -98,22 +98,26 @@ export default function Discussion() {
return ( return (
<View style={[Styles.p15, { flex: 1 }]}> <View style={[Styles.p15, { flex: 1 }]}>
<View> <View>
<View style={[Styles.wrapBtnTab]}> {
<ButtonTab entityUser.role != "user" && entityUser.role != "coadmin" &&
active={status == "false" ? "false" : "true"} <View style={[Styles.wrapBtnTab]}>
value="true" <ButtonTab
onPress={() => { setStatus("true") }} active={status == "false" ? "false" : "true"}
label="Aktif" value="true"
icon={<Feather name="check-circle" color={status == "false" ? 'black' : 'white'} size={20} />} onPress={() => { setStatus("true") }}
n={2} /> label="Aktif"
<ButtonTab icon={<Feather name="check-circle" color={status == "false" ? 'black' : 'white'} size={20} />}
active={status == "false" ? "false" : "true"} n={2} />
value="false" <ButtonTab
onPress={() => { setStatus("false") }} active={status == "false" ? "false" : "true"}
label="Arsip" value="false"
icon={<AntDesign name="closecircleo" color={status == "true" ? 'black' : 'white'} size={20} />} onPress={() => { setStatus("false") }}
n={2} /> label="Arsip"
</View> icon={<AntDesign name="closecircleo" color={status == "true" ? 'black' : 'white'} size={20} />}
n={2} />
</View>
}
<InputSearch onChange={setSearch} /> <InputSearch onChange={setSearch} />
{ {
(entityUser.role == "supadmin" || entityUser.role == "developer") && (entityUser.role == "supadmin" || entityUser.role == "developer") &&

View File

@@ -135,22 +135,25 @@ export default function MemberDiscussionDetail() {
router.push(`/member/${chooseUser.idUser}`) router.push(`/member/${chooseUser.idUser}`)
}} }}
/> />
{
entityUser.role != "user" && entityUser.role != "coadmin" &&
<MenuItemRow
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: () => {
handleDeleteUser()
}
})
<MenuItemRow }}
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: () => {
handleDeleteUser()
}
})
}}
/>
</View> </View>
</DrawerBottom> </DrawerBottom>
</SafeAreaView> </SafeAreaView>

View File

@@ -7,7 +7,7 @@ import SkeletonContent from "@/components/skeletonContent";
import Text from "@/components/Text"; import Text from "@/components/Text";
import { ConstEnv } from "@/constants/ConstEnv"; import { ConstEnv } from "@/constants/ConstEnv";
import Styles from "@/constants/Styles"; import Styles from "@/constants/Styles";
import { apiGetDiscussion } from "@/lib/api"; import { apiGetDiscussion, apiGetDivisionOneFeature } from "@/lib/api";
import { useAuthSession } from "@/providers/AuthProvider"; import { useAuthSession } from "@/providers/AuthProvider";
import { AntDesign, Feather, Ionicons } from "@expo/vector-icons"; import { AntDesign, Feather, Ionicons } from "@expo/vector-icons";
import { router, useLocalSearchParams } from "expo-router"; import { router, useLocalSearchParams } from "expo-router";
@@ -41,6 +41,30 @@ export default function DiscussionDivision() {
const [waiting, setWaiting] = useState(false) const [waiting, setWaiting] = useState(false)
const [status, setStatus] = useState<'true' | 'false'>('true') const [status, setStatus] = useState<'true' | 'false'>('true')
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",
});
const response2 = await apiGetDivisionOneFeature({
id,
user: hasil,
cat: "check-admin",
});
setIsMemberDivision(response.data);
setIsAdminDivision(response2.data);
} catch (error) {
console.error(error);
}
}
async function handleLoad(loading: boolean, thisPage: number) { async function handleLoad(loading: boolean, thisPage: number) {
try { try {
@@ -80,6 +104,10 @@ export default function DiscussionDivision() {
}, 1000); }, 1000);
} }
useEffect(() => {
handleCheckMember()
}, [])
const handleRefresh = async () => { const handleRefresh = async () => {
setRefreshing(true) setRefreshing(true)
handleLoad(false, 1) handleLoad(false, 1)
@@ -101,25 +129,29 @@ export default function DiscussionDivision() {
return ( return (
<View style={[Styles.p15, { flex: 1 }]}> <View style={[Styles.p15, { flex: 1 }]}>
<View> {
<View style={[Styles.wrapBtnTab]}> ((entityUser.role != "user" && entityUser.role != "coadmin") || isAdminDivision) &&
<ButtonTab <View>
active={status == "false" ? "false" : "true"} <View style={[Styles.wrapBtnTab]}>
value="true" <ButtonTab
onPress={() => { setStatus("true") }} active={status == "false" ? "false" : "true"}
label="Aktif" value="true"
icon={<Feather name="check-circle" color={status == "false" ? 'black' : 'white'} size={20} />} onPress={() => { setStatus("true") }}
n={2} /> label="Aktif"
<ButtonTab icon={<Feather name="check-circle" color={status == "false" ? 'black' : 'white'} size={20} />}
active={status == "false" ? "false" : "true"} n={2} />
value="false" <ButtonTab
onPress={() => { setStatus("false") }} active={status == "false" ? "false" : "true"}
label="Arsip" value="false"
icon={<AntDesign name="closecircleo" color={status == "true" ? 'black' : 'white'} size={20} />} onPress={() => { setStatus("false") }}
n={2} /> label="Arsip"
icon={<AntDesign name="closecircleo" color={status == "true" ? 'black' : 'white'} size={20} />}
n={2} />
</View>
<InputSearch onChange={setSearch} />
</View> </View>
<InputSearch onChange={setSearch} /> }
</View>
<View style={[{ flex: 2 }, Styles.mt05]}> <View style={[{ flex: 2 }, Styles.mt05]}>
{ {

View File

@@ -11,7 +11,7 @@ import Text from "@/components/Text"
import { ColorsStatus } from "@/constants/ColorsStatus" import { ColorsStatus } from "@/constants/ColorsStatus"
import { ConstEnv } from "@/constants/ConstEnv" import { ConstEnv } from "@/constants/ConstEnv"
import Styles from "@/constants/Styles" import Styles from "@/constants/Styles"
import { apiDeleteMemberDivision, apiGetDivisionOneDetail, apiUpdateStatusAdminDivision } from "@/lib/api" import { apiDeleteMemberDivision, apiGetDivisionOneDetail, apiGetDivisionOneFeature, apiUpdateStatusAdminDivision } from "@/lib/api"
import { useAuthSession } from "@/providers/AuthProvider" import { useAuthSession } from "@/providers/AuthProvider"
import { Feather, MaterialCommunityIcons, MaterialIcons } from "@expo/vector-icons" import { Feather, MaterialCommunityIcons, MaterialIcons } from "@expo/vector-icons"
import { router, Stack, useLocalSearchParams } from "expo-router" import { router, Stack, useLocalSearchParams } from "expo-router"
@@ -39,6 +39,7 @@ type PropsMember = {
} }
export default function InformationDivision() { export default function InformationDivision() {
const entityUser = useSelector((state: any) => state.user)
const { id } = useLocalSearchParams<{ id: string }>() const { id } = useLocalSearchParams<{ id: string }>()
const [isModal, setModal] = useState(false) const [isModal, setModal] = useState(false)
const { token, decryptToken } = useAuthSession() const { token, decryptToken } = useAuthSession()
@@ -48,6 +49,8 @@ export default function InformationDivision() {
const update = useSelector((state: any) => state.divisionUpdate) const update = useSelector((state: any) => state.divisionUpdate)
const arrSkeleton = Array.from({ length: 5 }, (_, index) => index) const arrSkeleton = Array.from({ length: 5 }, (_, index) => index)
const [loading, setLoading] = useState(true) const [loading, setLoading] = useState(true)
const [isMemberDivision, setIsMemberDivision] = useState(false)
const [isAdminDivision, setIsAdminDivision] = useState(false)
const [dataMemberChoose, setDataMemberChoose] = useState({ const [dataMemberChoose, setDataMemberChoose] = useState({
id: '', id: '',
name: '', name: '',
@@ -113,12 +116,34 @@ export default function InformationDivision() {
} }
} }
async function handleCheckMember() {
try {
const hasil = await decryptToken(String(token?.current));
const response = await apiGetDivisionOneFeature({
id,
user: hasil,
cat: "check-member",
});
const response2 = await apiGetDivisionOneFeature({
id,
user: hasil,
cat: "check-admin",
});
setIsMemberDivision(response.data);
setIsAdminDivision(response2.data);
} catch (error) {
console.error(error);
}
}
useEffect(() => { useEffect(() => {
handleLoad(false) handleLoad(false)
}, [refresh, update]) }, [refresh, update])
useEffect(() => { useEffect(() => {
handleLoad(true) handleLoad(true)
handleCheckMember()
}, []) }, [])
function handleChooseMember(item: PropsMember) { function handleChooseMember(item: PropsMember) {
@@ -133,7 +158,7 @@ export default function InformationDivision() {
headerLeft: () => <ButtonBackHeader onPress={() => { router.back() }} />, headerLeft: () => <ButtonBackHeader onPress={() => { router.back() }} />,
headerTitle: 'Informasi Divisi', headerTitle: 'Informasi Divisi',
headerTitleAlign: 'center', headerTitleAlign: 'center',
headerRight: () => <HeaderRightDivisionInfo id={id} active={dataDetail?.isActive} />, headerRight: () => ((entityUser.role != "user" && entityUser.role != "coadmin") || isAdminDivision) && <HeaderRightDivisionInfo id={id} active={dataDetail?.isActive} />,
}} }}
/> />
<ScrollView style={[Styles.h100]}> <ScrollView style={[Styles.h100]}>
@@ -161,6 +186,7 @@ export default function InformationDivision() {
<Text style={[Styles.textDefault, Styles.mv05]}>{dataMember.length} Anggota</Text> <Text style={[Styles.textDefault, Styles.mv05]}>{dataMember.length} Anggota</Text>
<View style={[Styles.wrapPaper]}> <View style={[Styles.wrapPaper]}>
{ {
((entityUser.role != "user" && entityUser.role != "coadmin") || isAdminDivision) &&
dataDetail?.isActive && ( dataDetail?.isActive && (
<BorderBottomItem <BorderBottomItem
onPress={() => { router.push(`/division/${id}/add-member`) }} onPress={() => { router.push(`/division/${id}/add-member`) }}
@@ -188,7 +214,7 @@ export default function InformationDivision() {
<BorderBottomItem <BorderBottomItem
key={index} key={index}
borderType="bottom" borderType="bottom"
onPress={() => { dataDetail?.isActive && handleChooseMember(item) }} onPress={() => { dataDetail?.isActive && (isAdminDivision || (entityUser.role != "user" && entityUser.role != "coadmin")) && handleChooseMember(item) }}
icon={ icon={
<ImageUser src={`${ConstEnv.url_storage}/files/${item.img}`} size="sm" /> <ImageUser src={`${ConstEnv.url_storage}/files/${item.img}`} size="sm" />
} }

View File

@@ -189,7 +189,10 @@ export default function Index() {
return ( return (
<BorderBottomItem <BorderBottomItem
key={index} key={index}
onPress={() => { handleChooseData(item.id, item.name, item.isActive, item.idGroup) }} onPress={() => {
entityUser.role != "user" &&
handleChooseData(item.id, item.name, item.isActive, item.idGroup)
}}
borderType="all" borderType="all"
icon={ icon={
<View style={[Styles.iconContent, ColorsStatus.lightGreen]}> <View style={[Styles.iconContent, ColorsStatus.lightGreen]}>

View File

@@ -16,7 +16,10 @@ export default function HeaderDiscussionGeneral() {
return ( return (
<> <>
<ButtonMenuHeader onPress={() => { setVisible(true) }} /> {
entityUser.role != "user" && entityUser.role != "coadmin" &&
<ButtonMenuHeader onPress={() => { setVisible(true) }} />
}
<DrawerBottom animation="slide" isVisible={isVisible} setVisible={setVisible} title="Menu"> <DrawerBottom animation="slide" isVisible={isVisible} setVisible={setVisible} title="Menu">
<View style={Styles.rowItemsCenter}> <View style={Styles.rowItemsCenter}>
<MenuItemRow <MenuItemRow

View File

@@ -16,7 +16,10 @@ export default function HeaderMemberList() {
return ( return (
<> <>
<ButtonMenuHeader onPress={() => { setVisible(true) }} /> {
entityUser.role != "user" &&
<ButtonMenuHeader onPress={() => { setVisible(true) }} />
}
<DrawerBottom animation="slide" isVisible={isVisible} setVisible={() => setVisible(false)} title="Menu"> <DrawerBottom animation="slide" isVisible={isVisible} setVisible={() => setVisible(false)} title="Menu">
<View style={Styles.rowItemsCenter}> <View style={Styles.rowItemsCenter}>
<MenuItemRow <MenuItemRow