import BorderBottomItem from "@/components/borderBottomItem"; import ButtonBackHeader from "@/components/buttonBackHeader"; import HeaderRightDiscussionGeneralDetail from "@/components/discussion_general/headerDiscussionDetail"; import ImageUser from "@/components/imageNew"; import { InputForm } from "@/components/inputForm"; import LabelStatus from "@/components/labelStatus"; import Skeleton from "@/components/skeleton"; import SkeletonContent from "@/components/skeletonContent"; import Text from '@/components/Text'; import { ColorsStatus } from "@/constants/ColorsStatus"; import { ConstEnv } from "@/constants/ConstEnv"; import { regexOnlySpacesOrEnter } from "@/constants/OnlySpaceOrEnter"; import Styles from "@/constants/Styles"; import { apiGetDiscussionGeneralOne, apiSendDiscussionGeneralCommentar } from "@/lib/api"; import { getDB } from "@/lib/firebaseDatabase"; import { useAuthSession } from "@/providers/AuthProvider"; import { Ionicons, MaterialIcons } from "@expo/vector-icons"; import { ref } from '@react-native-firebase/database'; import { useHeaderHeight } from '@react-navigation/elements'; import { router, Stack, useLocalSearchParams } from "expo-router"; import { useEffect, useState } from "react"; import { KeyboardAvoidingView, Platform, Pressable, ScrollView, View } from "react-native"; import Toast from "react-native-toast-message"; import { useSelector } from "react-redux"; type Props = { id: string isActive: boolean title: string desc: string status: number createdAt: string } type PropsKomentar = { id: string comment: string createdAt: string idUser: string img: string username: string } export default function DetailDiscussionGeneral() { const { token, decryptToken } = useAuthSession() const entityUser = useSelector((state: any) => state.user) const { id } = useLocalSearchParams<{ id: string }>(); const [data, setData] = useState() const [dataKomentar, setDataKomentar] = useState([]) const [memberDiscussion, setMemberDiscussion] = useState(false) const [komentar, setKomentar] = useState('') const update = useSelector((state: any) => state.discussionGeneralDetailUpdate) const [loading, setLoading] = useState(true) const [loadingKomentar, setLoadingKomentar] = useState(true) const arrSkeleton = Array.from({ length: 3 }, (_, index) => index) const reference = ref(getDB(), `/discussion-general/${id}`); const headerHeight = useHeaderHeight(); const [detailMore, setDetailMore] = useState([]) const [loadingSendKomentar, setLoadingSendKomentar] = useState(false) useEffect(() => { const onValueChange = reference.on('value', snapshot => { if (snapshot.val() == null) { reference.set({ trigger: true }) } handleLoad('komentar', false) }); // Stop listening for updates when no longer required return () => reference.off('value', onValueChange); }, []); function updateTrigger() { reference.once('value', snapshot => { const data = snapshot.val(); reference.update({ trigger: !data.trigger }); }); } async function handleLoad(cat: 'detail' | 'komentar' | 'cek-anggota', loading: boolean) { try { if (cat == "detail") { setLoading(loading) } else if (cat == "komentar") { setLoadingKomentar(loading) } const hasil = await decryptToken(String(token?.current)) const response = await apiGetDiscussionGeneralOne({ id: id, user: hasil, cat }) if (cat == 'detail') { setData(response.data) } else if (cat == 'komentar') { setDataKomentar(response.data) } else if (cat == 'cek-anggota') { setMemberDiscussion(response.data) } } catch (error) { console.error(error) } finally { setLoading(false) setLoadingKomentar(false) } } useEffect(() => { handleLoad('detail', false) handleLoad('komentar', false) handleLoad('cek-anggota', false) }, [update]); useEffect(() => { handleLoad('detail', true) handleLoad('komentar', true) handleLoad('cek-anggota', true) }, []); async function handleKomentar() { try { setLoadingSendKomentar(true) if (komentar != '') { const hasil = await decryptToken(String(token?.current)) const response = await apiSendDiscussionGeneralCommentar({ id: id, data: { desc: komentar, user: hasil } }) if (response.success) { setKomentar('') updateTrigger() } else { Toast.show({ type: 'small', text1: 'Gagal menambahkan komentar' }) } } } catch (error) { console.error(error) } finally { setLoadingSendKomentar(false) } } return ( <> { router.back() }} />, headerTitle: 'Diskusi', headerTitleAlign: 'center', headerRight: () => , }} /> { loading ? : } title={data?.title + " " + data?.createdAt} subtitle={ !data?.isActive ? : } desc={data?.desc} leftBottomInfo={ {dataKomentar.length} Komentar } rightBottomInfo={ {data?.createdAt} } /> } { loadingKomentar ? arrSkeleton.map((item: any, i: number) => { return ( ) }) : dataKomentar.map((item, i) => { return ( } title={item.username} rightTopInfo={item.createdAt} desc={item.comment} descEllipsize={detailMore.includes(item.id) ? false : true} onPress={() => { setDetailMore((prev: any) => { if (prev.includes(item.id)) { return prev.filter((id: string) => id !== item.id) } else { return [...prev, item.id] } }) }} /> ) }) } { data?.status != 2 && data?.isActive && ((entityUser.role != "user" && entityUser.role != "coadmin") || memberDiscussion) ? { (!loadingSendKomentar && komentar != '' && !regexOnlySpacesOrEnter.test(komentar) && data?.status === 1 && data?.isActive && (memberDiscussion || (entityUser.role != "user" && entityUser.role != "coadmin"))) && handleKomentar() }} style={[ Platform.OS == 'android' && Styles.mb12, ]} > } /> : { data?.status == 2 ? "Diskusi telah ditutup" : data?.isActive == false ? "Diskusi telah diarsipkan" : "Hanya anggota diskusi yang dapat memberikan komentar" } } ) }