From c2597b25bf8b18aff00e7fbcf7751df6587eee71 Mon Sep 17 00:00:00 2001 From: amaliadwiy Date: Thu, 25 Sep 2025 11:22:39 +0800 Subject: [PATCH 1/3] upd: push notification Deskripsi: - update push notification warning No Issues --- lib/useNotification.ts | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/lib/useNotification.ts b/lib/useNotification.ts index 46d562f..b1dd761 100644 --- a/lib/useNotification.ts +++ b/lib/useNotification.ts @@ -1,10 +1,14 @@ import { getApp, getApps, initializeApp } from '@react-native-firebase/app'; -import { getMessaging, registerDeviceForRemoteMessages, setAutoInitEnabled } from '@react-native-firebase/messaging'; +import { + getMessaging, + getToken as getMessagingToken, + setAutoInitEnabled, +} from '@react-native-firebase/messaging'; import * as Notifications from 'expo-notifications'; import { useEffect } from 'react'; import { PermissionsAndroid, Platform } from 'react-native'; -// Your Firebase project configuration +// Firebase config const RNfirebaseConfig = { apiKey: "AIzaSyB2hbsW91J3oRQx4_jgrCCNY0tNt5-21e8", authDomain: "googleapis.com", @@ -15,14 +19,15 @@ const RNfirebaseConfig = { databaseURL: "https://mobile-darmasaba-default-rtdb.asia-southeast1.firebasedatabase.app/" }; - const initializeFirebase = async () => { try { const app = getApps().length ? getApp() : initializeApp(RNfirebaseConfig); const mess = getMessaging(app); - await registerDeviceForRemoteMessages(mess); - setAutoInitEnabled(mess, true); - return mess + // await registerDeviceForRemoteMessages(mess); + // `registerDeviceForRemoteMessages` tidak perlu lagi + await setAutoInitEnabled(mess, true); + + return mess; } catch (error) { console.error('Failed to initialize Firebase:', error); } @@ -31,17 +36,16 @@ const initializeFirebase = async () => { export const requestPermission = async () => { try { if (Platform.OS === 'android') { - const cek = await PermissionsAndroid.check(PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS) + const cek = await PermissionsAndroid.check( + PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS + ); if (!cek) { const granted = await PermissionsAndroid.request( PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS ); - if (granted === PermissionsAndroid.RESULTS.GRANTED) { - return true - } - return false + return granted === PermissionsAndroid.RESULTS.GRANTED; } - return true + return true; } else if (Platform.OS === 'ios') { const { status } = await Notifications.requestPermissionsAsync(); return status === 'granted'; @@ -54,10 +58,13 @@ export const requestPermission = async () => { export const getToken = async () => { try { const mess = await initializeFirebase(); - const token = await mess?.getToken(); + if (!mess) return null; + + // pakai modular API + const token = await getMessagingToken(mess); return token; } catch (error) { - console.error("Error getting token:", error); + console.error('Error getting token:', error); } }; @@ -73,4 +80,4 @@ export const useNotification = () => { initializeAndSetup(); }, []); -}; \ No newline at end of file +}; From 65d53951c3f48e709326f8ea3c987fb8ce5ff7a1 Mon Sep 17 00:00:00 2001 From: amaliadwiy Date: Thu, 25 Sep 2025 11:27:51 +0800 Subject: [PATCH 2/3] upd: caraousel kegiatan home Deskripsi: - loop false pada home caraousel kegiatan No Issues --- components/home/projectHome.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/home/projectHome.tsx b/components/home/projectHome.tsx index 6f5f70b..47a4431 100644 --- a/components/home/projectHome.tsx +++ b/components/home/projectHome.tsx @@ -62,7 +62,7 @@ export default function ProjectHome({ refreshing }: { refreshing: boolean }) { width={width * 0.8} height={235} data={data} - loop={true} + loop={false} autoPlay={false} autoPlayReverse={false} pagingEnabled={true} From ecc41c905f766c8585dffc77163fa2796da1b7c9 Mon Sep 17 00:00:00 2001 From: amaliadwiy Date: Thu, 25 Sep 2025 17:13:44 +0800 Subject: [PATCH 3/3] upd --- app/(application)/discussion/[id].tsx | 11 ++- app/(application)/discussion/index.tsx | 36 +++++----- app/(application)/discussion/member/[id].tsx | 31 ++++---- .../(fitur-division)/discussion/index.tsx | 70 ++++++++++++++----- app/(application)/division/[id]/info.tsx | 32 ++++++++- app/(application)/position/index.tsx | 5 +- .../headerDiscussionGeneral.tsx | 5 +- components/member/headerMemberList.tsx | 5 +- 8 files changed, 137 insertions(+), 58 deletions(-) diff --git a/app/(application)/discussion/[id].tsx b/app/(application)/discussion/[id].tsx index 2d846d7..101e2e7 100644 --- a/app/(application)/discussion/[id].tsx +++ b/app/(application)/discussion/[id].tsx @@ -153,14 +153,14 @@ export default function DetailDiscussionGeneral() { } - title={data?.title} + title={data?.title + " " + data?.createdAt} subtitle={ !data?.isActive ? : } - rightTopInfo={data?.createdAt} + // rightTopInfo={data?.createdAt} desc={data?.desc} leftBottomInfo={ @@ -168,6 +168,11 @@ export default function DetailDiscussionGeneral() { {dataKomentar.length} Komentar } + rightBottomInfo={ + + {data?.createdAt} + + } /> } @@ -210,7 +215,7 @@ export default function DetailDiscussionGeneral() { disable={(data?.status === 2 || !data?.isActive || (!memberDiscussion && (entityUser.role == "user" || entityUser.role == "coadmin")))} type="default" round - placeholder="Kirim Komentar2" + placeholder="Kirim Komentar" bg="white" onChange={setKomentar} value={komentar} diff --git a/app/(application)/discussion/index.tsx b/app/(application)/discussion/index.tsx index 9fc4f8c..4fb07fa 100644 --- a/app/(application)/discussion/index.tsx +++ b/app/(application)/discussion/index.tsx @@ -98,22 +98,26 @@ export default function Discussion() { return ( - - { setStatus("true") }} - label="Aktif" - icon={} - n={2} /> - { setStatus("false") }} - label="Arsip" - icon={} - n={2} /> - + { + entityUser.role != "user" && entityUser.role != "coadmin" && + + { setStatus("true") }} + label="Aktif" + icon={} + n={2} /> + { setStatus("false") }} + label="Arsip" + icon={} + n={2} /> + + } + { (entityUser.role == "supadmin" || entityUser.role == "developer") && diff --git a/app/(application)/discussion/member/[id].tsx b/app/(application)/discussion/member/[id].tsx index 0f527e2..0f16c49 100644 --- a/app/(application)/discussion/member/[id].tsx +++ b/app/(application)/discussion/member/[id].tsx @@ -135,22 +135,25 @@ export default function MemberDiscussionDetail() { router.push(`/member/${chooseUser.idUser}`) }} /> + { + entityUser.role != "user" && entityUser.role != "coadmin" && + } + title="Keluarkan" + onPress={() => { + setModal(false) + AlertKonfirmasi({ + title: 'Konfirmasi', + desc: 'Apakah Anda yakin ingin mengeluarkan anggota?', + onPress: () => { + handleDeleteUser() + } + }) - } - title="Keluarkan" - onPress={() => { - setModal(false) - AlertKonfirmasi({ - title: 'Konfirmasi', - desc: 'Apakah Anda yakin ingin mengeluarkan anggota?', - onPress: () => { - handleDeleteUser() - } - }) + }} + /> + } - }} - /> diff --git a/app/(application)/division/[id]/(fitur-division)/discussion/index.tsx b/app/(application)/division/[id]/(fitur-division)/discussion/index.tsx index c6d494a..35c32c8 100644 --- a/app/(application)/division/[id]/(fitur-division)/discussion/index.tsx +++ b/app/(application)/division/[id]/(fitur-division)/discussion/index.tsx @@ -7,7 +7,7 @@ import SkeletonContent from "@/components/skeletonContent"; import Text from "@/components/Text"; import { ConstEnv } from "@/constants/ConstEnv"; import Styles from "@/constants/Styles"; -import { apiGetDiscussion } from "@/lib/api"; +import { apiGetDiscussion, apiGetDivisionOneFeature } from "@/lib/api"; import { useAuthSession } from "@/providers/AuthProvider"; import { AntDesign, Feather, Ionicons } from "@expo/vector-icons"; import { router, useLocalSearchParams } from "expo-router"; @@ -41,6 +41,30 @@ export default function DiscussionDivision() { const [waiting, setWaiting] = useState(false) const [status, setStatus] = useState<'true' | 'false'>('true') 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) { try { @@ -80,6 +104,10 @@ export default function DiscussionDivision() { }, 1000); } + useEffect(() => { + handleCheckMember() + }, []) + const handleRefresh = async () => { setRefreshing(true) handleLoad(false, 1) @@ -101,25 +129,29 @@ export default function DiscussionDivision() { return ( - - - { setStatus("true") }} - label="Aktif" - icon={} - n={2} /> - { setStatus("false") }} - label="Arsip" - icon={} - n={2} /> + { + ((entityUser.role != "user" && entityUser.role != "coadmin") || isAdminDivision) && + + + { setStatus("true") }} + label="Aktif" + icon={} + n={2} /> + { setStatus("false") }} + label="Arsip" + icon={} + n={2} /> + + - - + } + { diff --git a/app/(application)/division/[id]/info.tsx b/app/(application)/division/[id]/info.tsx index 055ced6..c87979c 100644 --- a/app/(application)/division/[id]/info.tsx +++ b/app/(application)/division/[id]/info.tsx @@ -11,7 +11,7 @@ import Text from "@/components/Text" import { ColorsStatus } from "@/constants/ColorsStatus" import { ConstEnv } from "@/constants/ConstEnv" 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 { Feather, MaterialCommunityIcons, MaterialIcons } from "@expo/vector-icons" import { router, Stack, useLocalSearchParams } from "expo-router" @@ -39,6 +39,7 @@ type PropsMember = { } export default function InformationDivision() { + const entityUser = useSelector((state: any) => state.user) const { id } = useLocalSearchParams<{ id: string }>() const [isModal, setModal] = useState(false) const { token, decryptToken } = useAuthSession() @@ -48,6 +49,8 @@ export default function InformationDivision() { const update = useSelector((state: any) => state.divisionUpdate) const arrSkeleton = Array.from({ length: 5 }, (_, index) => index) const [loading, setLoading] = useState(true) + const [isMemberDivision, setIsMemberDivision] = useState(false) + const [isAdminDivision, setIsAdminDivision] = useState(false) const [dataMemberChoose, setDataMemberChoose] = useState({ id: '', 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(() => { handleLoad(false) }, [refresh, update]) useEffect(() => { handleLoad(true) + handleCheckMember() }, []) function handleChooseMember(item: PropsMember) { @@ -133,7 +158,7 @@ export default function InformationDivision() { headerLeft: () => { router.back() }} />, headerTitle: 'Informasi Divisi', headerTitleAlign: 'center', - headerRight: () => , + headerRight: () => ((entityUser.role != "user" && entityUser.role != "coadmin") || isAdminDivision) && , }} /> @@ -161,6 +186,7 @@ export default function InformationDivision() { {dataMember.length} Anggota { + ((entityUser.role != "user" && entityUser.role != "coadmin") || isAdminDivision) && dataDetail?.isActive && ( { router.push(`/division/${id}/add-member`) }} @@ -188,7 +214,7 @@ export default function InformationDivision() { { dataDetail?.isActive && handleChooseMember(item) }} + onPress={() => { dataDetail?.isActive && (isAdminDivision || (entityUser.role != "user" && entityUser.role != "coadmin")) && handleChooseMember(item) }} icon={ } diff --git a/app/(application)/position/index.tsx b/app/(application)/position/index.tsx index d3d38c1..3bde226 100644 --- a/app/(application)/position/index.tsx +++ b/app/(application)/position/index.tsx @@ -189,7 +189,10 @@ export default function Index() { return ( { handleChooseData(item.id, item.name, item.isActive, item.idGroup) }} + onPress={() => { + entityUser.role != "user" && + handleChooseData(item.id, item.name, item.isActive, item.idGroup) + }} borderType="all" icon={ diff --git a/components/discussion_general/headerDiscussionGeneral.tsx b/components/discussion_general/headerDiscussionGeneral.tsx index 8b7e6b9..8b8a88d 100644 --- a/components/discussion_general/headerDiscussionGeneral.tsx +++ b/components/discussion_general/headerDiscussionGeneral.tsx @@ -16,7 +16,10 @@ export default function HeaderDiscussionGeneral() { return ( <> - { setVisible(true) }} /> + { + entityUser.role != "user" && entityUser.role != "coadmin" && + { setVisible(true) }} /> + } - { setVisible(true) }} /> + { + entityUser.role != "user" && + { setVisible(true) }} /> + } setVisible(false)} title="Menu">