diff --git a/app/(application)/discussion/[id].tsx b/app/(application)/discussion/[id].tsx
index e47e18a..bc364bf 100644
--- a/app/(application)/discussion/[id].tsx
+++ b/app/(application)/discussion/[id].tsx
@@ -1,11 +1,9 @@
import AppHeader from "@/components/AppHeader";
-import BorderBottomItem from "@/components/borderBottomItem";
import BorderBottomItem2 from "@/components/borderBottomItem2";
import HeaderRightDiscussionGeneralDetail from "@/components/discussion_general/headerDiscussionDetail";
import DrawerBottom from "@/components/drawerBottom";
import ImageUser from "@/components/imageNew";
import { InputForm } from "@/components/inputForm";
-import LabelStatus from "@/components/labelStatus";
import MenuItemRow from "@/components/menuItemRow";
import ModalConfirmation from "@/components/ModalConfirmation";
import Skeleton from "@/components/skeleton";
@@ -271,29 +269,36 @@ export default function DetailDiscussionGeneral() {
borderType="all"
bgColor="white"
icon={
-
-
+
+
}
title={data?.title}
titleShowAll={true}
subtitle={
- !data?.isActive ?
-
- :
-
+
+
+ {!data?.isActive ? 'Arsip' : data?.status == 1 ? 'Buka' : 'Tutup'}
+
+
}
desc={data?.desc}
leftBottomInfo={
-
- {dataKomentar.length} Komentar
+
+ {dataKomentar.length} Komentar
}
rightBottomInfo={
-
- {data?.createdAt}
-
+ {data?.createdAt}
}
/>
}
@@ -306,36 +311,56 @@ export default function DetailDiscussionGeneral() {
)
})
:
- dataKomentar.map((item, i) => {
- return (
-
+ dataKomentar.map((item, i) => (
+ {
+ setDetailMore((prev: any) =>
+ prev.includes(item.id)
+ ? prev.filter((id: string) => id !== item.id)
+ : [...prev, item.id]
+ )
+ }}
+ onLongPress={() => {
+ item.idUser == entities.id && data?.status != 2 && data?.isActive && handleMenuKomentar(item.id, item.comment)
+ }}
+ style={({ pressed }) => [
+ Styles.discussionCommentCard,
+ {
+ backgroundColor: pressed ? colors.icon + '10' : colors.card,
+ borderColor: colors.icon + '20',
}
- title={item.username}
- rightTopInfo={item.createdAt}
- desc={item.comment}
- rightBottomInfo={item.isEdited ? "Edited" : ""}
- descEllipsize={detailMore.includes(item.id) ? false : true}
- bgColor="white"
- onPress={() => {
- setDetailMore((prev: any) => {
- if (prev.includes(item.id)) {
- return prev.filter((id: string) => id !== item.id)
- } else {
- return [...prev, item.id]
- }
- })
- }}
- onLongPress={() => {
- item.idUser == entities.id && data?.status != 2 && data?.isActive && handleMenuKomentar(item.id, item.comment)
- }}
- />
- )
- })
+ ]}
+ >
+
+ {/* Name + time */}
+
+
+
+
+ {item.username}
+
+ {item.isEdited && (
+
+ diedit
+
+ )}
+
+
+ {item.createdAt}
+
+
+
+ {/* Comment text */}
+
+ {item.comment}
+
+
+
+ ))
}
@@ -372,15 +397,14 @@ export default function DetailDiscussionGeneral() {
multiline
focus={viewEdit}
itemRight={
- {
- (!loadingSendKomentar && selectKomentar.comment != '' && !regexOnlySpacesOrEnter.test(selectKomentar.comment) && data?.status === 1 && data?.isActive && (memberDiscussion || (entityUser.role != "user" && entityUser.role != "coadmin")))
- && handleEditKomentar()
- }}
- style={[
- Platform.OS == 'android' && Styles.mb12,
- ]}
+ {
+ (!loadingSendKomentar && selectKomentar.comment != '' && !regexOnlySpacesOrEnter.test(selectKomentar.comment) && data?.status === 1 && data?.isActive && (memberDiscussion || (entityUser.role != "user" && entityUser.role != "coadmin")))
+ && handleEditKomentar()
+ }}
+ style={[Platform.OS == 'android' && Styles.mb12]}
>
-
+
}
/>
@@ -398,15 +422,14 @@ export default function DetailDiscussionGeneral() {
multiline
focus={viewEdit}
itemRight={
- {
- (!loadingSendKomentar && komentar != '' && !regexOnlySpacesOrEnter.test(komentar) && data?.status === 1 && data?.isActive && (memberDiscussion || (entityUser.role != "user" && entityUser.role != "coadmin")))
- && handleKomentar()
- }}
- style={[
- Platform.OS == 'android' && Styles.mb12,
- ]}
+ {
+ (!loadingSendKomentar && komentar != '' && !regexOnlySpacesOrEnter.test(komentar) && data?.status === 1 && data?.isActive && (memberDiscussion || (entityUser.role != "user" && entityUser.role != "coadmin")))
+ && handleKomentar()
+ }}
+ style={[Platform.OS == 'android' && Styles.mb12]}
>
-
+
}
/>
diff --git a/app/(application)/discussion/index.tsx b/app/(application)/discussion/index.tsx
index 14b521d..c7f4bb1 100644
--- a/app/(application)/discussion/index.tsx
+++ b/app/(application)/discussion/index.tsx
@@ -1,23 +1,20 @@
-import BorderBottomItem from "@/components/borderBottomItem";
import ButtonTab from "@/components/buttonTab";
import InputSearch from "@/components/inputSearch";
import LabelStatus from "@/components/labelStatus";
import SkeletonContent from "@/components/skeletonContent";
import Text from "@/components/Text";
import WrapTab from "@/components/wrapTab";
-import { ColorsStatus } from "@/constants/ColorsStatus";
import Styles from "@/constants/Styles";
import { apiGetDiscussionGeneral } from "@/lib/api";
import { useAuthSession } from "@/providers/AuthProvider";
import { useTheme } from "@/providers/ThemeProvider";
-import { AntDesign, Feather, Ionicons, MaterialIcons } from "@expo/vector-icons";
+import { AntDesign, Feather } from "@expo/vector-icons";
import { useInfiniteQuery, useQueryClient } from "@tanstack/react-query";
import { router, useLocalSearchParams } from "expo-router";
import { useEffect, useMemo, useState } from "react";
-import { RefreshControl, View, VirtualizedList } from "react-native";
+import { FlatList, Pressable, RefreshControl, View } from "react-native";
import { useSelector } from "react-redux";
-
type Props = {
id: string
title: string
@@ -38,7 +35,6 @@ export default function Discussion() {
const [status, setStatus] = useState<'true' | 'false'>(active == 'false' ? 'false' : 'true')
const [refreshing, setRefreshing] = useState(false)
- // TanStack Query for Discussions with Infinite Scroll
const {
data,
fetchNextPage,
@@ -50,12 +46,12 @@ export default function Discussion() {
queryKey: ['discussions', { status, search, group }],
queryFn: async ({ pageParam = 1 }) => {
const hasil = await decryptToken(String(token?.current))
- const response = await apiGetDiscussionGeneral({
- user: hasil,
- active: status,
- search: search,
- group: String(group),
- page: pageParam
+ const response = await apiGetDiscussionGeneral({
+ user: hasil,
+ active: status,
+ search: search,
+ group: String(group),
+ page: pageParam
})
return response;
},
@@ -67,17 +63,14 @@ export default function Discussion() {
staleTime: 0,
})
- // Flatten pages into a single data array
const flatData = useMemo(() => {
return data?.pages.flatMap(page => page.data) || [];
}, [data])
- // Get nameGroup from the first available page
const nameGroup = useMemo(() => {
return data?.pages[0]?.filter?.name || "";
}, [data])
- // Refetch when manual update state changes
useEffect(() => {
refetch()
}, [update, refetch])
@@ -88,113 +81,129 @@ export default function Discussion() {
setRefreshing(false)
};
- const loadMoreData = () => {
- if (hasNextPage && !isFetchingNextPage) {
- fetchNextPage()
- }
- };
-
- const arrSkeleton = [0, 1, 2, 3, 4]
-
- const getItem = (_data: unknown, index: number): Props => ({
- id: flatData[index]?.id,
- title: flatData[index]?.title,
- desc: flatData[index]?.desc,
- status: flatData[index]?.status,
- total_komentar: flatData[index]?.total_komentar,
- createdAt: flatData[index]?.createdAt,
- })
+ const isOpen = (item: Props) => item.status === 1
return (
-
-
- {
- entityUser.role != "user" && entityUser.role != "coadmin" &&
+
+ {/* Header controls */}
+
+ {entityUser.role != "user" && entityUser.role != "coadmin" && (
{ setStatus("true") }}
+ onPress={() => setStatus("true")}
label="Aktif"
icon={}
- n={2} />
+ n={2}
+ />
{ setStatus("false") }}
+ onPress={() => setStatus("false")}
label="Arsip"
icon={}
- n={2} />
+ n={2}
+ />
- }
-
+ )}
- {
- (entityUser.role == "supadmin" || entityUser.role == "developer") &&
-
- Filter :
+ {(entityUser.role == "supadmin" || entityUser.role == "developer") && (
+
+ Filter:
- }
+ )}
-
- {
- isLoading ?
- arrSkeleton.map((item: any, i: number) => {
- return (
-
- )
- })
- :
- flatData.length > 0
- ?
- flatData.length}
- getItem={getItem}
- renderItem={({ item, index }: { item: Props, index: number }) => {
- return (
- { router.push(`/discussion/${item.id}`) }}
- borderType="bottom"
- icon={
-
- }
- title={item.title}
- subtitle={
- status != "false" &&
- }
- rightTopInfo={item.createdAt}
- desc={item.desc?.replace(/<[^>]*>?/gm, ' ').replace(/\r?\n|\r/g, ' ')}
- leftBottomInfo={
-
-
- Diskusikan
-
- }
- rightBottomInfo={`${item.total_komentar} Komentar`}
- />
- )
- }}
- keyExtractor={(item, index) => String(index)}
- onEndReached={loadMoreData}
- onEndReachedThreshold={0.5}
- showsVerticalScrollIndicator={false}
- refreshControl={
-
- }
+ {/* List */}
+
+ {isLoading ? (
+ [0, 1, 2, 3, 4].map((_, i) => )
+ ) : flatData.length === 0 ? (
+
+
+
+ Tidak ada diskusi
+
+
+ ) : (
+ String(i)}
+ showsVerticalScrollIndicator={false}
+ onEndReached={() => {
+ if (hasNextPage && !isFetchingNextPage) fetchNextPage()
+ }}
+ onEndReachedThreshold={0.5}
+ refreshControl={
+
- :
- Tidak ada data
- }
+ }
+ ItemSeparatorComponent={() => }
+ renderItem={({ item }: { item: Props }) => (
+ router.push(`/discussion/${item.id}`)}
+ style={({ pressed }) => [
+ Styles.discussionCard,
+ {
+ backgroundColor: pressed ? colors.icon + '10' : colors.card,
+ borderColor: colors.icon + '20',
+ }
+ ]}
+ >
+ {/* Top row: icon + title + status badge */}
+
+ {/* Discussion icon */}
+
+
+
+
+ {/* Title + status badge */}
+
+
+ {item.title}
+
+ {status !== "false" && (
+
+
+ {isOpen(item) ? 'Buka' : 'Tutup'}
+
+
+ )}
+
+
+
+ {/* Description */}
+ {item.desc ? (
+
+ {item.desc.replace(/<[^>]*>?/gm, ' ').replace(/\r?\n|\r/g, ' ')}
+
+ ) : null}
+
+ {/* Bottom row: comment count + date */}
+
+
+
+
+ {item.total_komentar} Komentar
+
+
+
+ {item.createdAt}
+
+
+
+ )}
+ />
+ )}
);
-}
\ No newline at end of file
+}
diff --git a/app/(application)/division/[id]/(fitur-division)/discussion/[detail]/index.tsx b/app/(application)/division/[id]/(fitur-division)/discussion/[detail]/index.tsx
index e85030f..bf1301b 100644
--- a/app/(application)/division/[id]/(fitur-division)/discussion/[detail]/index.tsx
+++ b/app/(application)/division/[id]/(fitur-division)/discussion/[detail]/index.tsx
@@ -1,11 +1,9 @@
import AppHeader from "@/components/AppHeader";
-import BorderBottomItem from "@/components/borderBottomItem";
import BorderBottomItem2 from "@/components/borderBottomItem2";
import HeaderRightDiscussionDetail from "@/components/discussion/headerDiscussionDetail";
import DrawerBottom from "@/components/drawerBottom";
import ImageUser from "@/components/imageNew";
import { InputForm } from "@/components/inputForm";
-import LabelStatus from "@/components/labelStatus";
import MenuItemRow from "@/components/menuItemRow";
import ModalConfirmation from "@/components/ModalConfirmation";
import Skeleton from "@/components/skeleton";
@@ -24,7 +22,7 @@ import {
import { getDB } from "@/lib/firebaseDatabase";
import { useAuthSession } from "@/providers/AuthProvider";
import { useTheme } from "@/providers/ThemeProvider";
-import { Feather, Ionicons, MaterialCommunityIcons, MaterialIcons } from "@expo/vector-icons";
+import { Feather, MaterialCommunityIcons, 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";
@@ -87,24 +85,15 @@ export default function DiscussionDetail() {
const [detailMore, setDetailMore] = useState([])
const entities = useSelector((state: any) => state.entities)
const [isVisible, setVisible] = useState(false)
- const [selectKomentar, setSelectKomentar] = useState({
- id: '',
- comment: ''
- })
+ const [selectKomentar, setSelectKomentar] = useState({ id: '', comment: '' })
const [viewEdit, setViewEdit] = useState(false)
const [showDeleteModal, setShowDeleteModal] = useState(false)
-
-
useEffect(() => {
const onValueChange = reference.on('value', snapshot => {
- if (snapshot.val() == null) {
- reference.set({ trigger: true })
- }
+ if (snapshot.val() == null) { reference.set({ trigger: true }) }
handleLoadComment(false)
});
-
- // Stop listening for updates when no longer required
return () => reference.off('value', onValueChange);
}, []);
@@ -115,23 +104,12 @@ export default function DiscussionDetail() {
});
}
-
async function handleLoad(loading: boolean) {
try {
setLoading(loading)
const hasil = await decryptToken(String(token?.current));
- const response = await apiGetDiscussionOne({
- id: detail,
- user: hasil,
- cat: "data",
- });
-
- const responseFile = await apiGetDiscussionOne({
- id: detail,
- user: hasil,
- cat: "file",
- });
-
+ const response = await apiGetDiscussionOne({ id: detail, user: hasil, cat: "data" });
+ const responseFile = await apiGetDiscussionOne({ id: detail, user: hasil, cat: "file" });
setData(response.data);
setFileDiscussion(responseFile.data)
setIsCreator(response.data.createdBy == hasil);
@@ -146,11 +124,7 @@ export default function DiscussionDetail() {
try {
setLoadingKomentar(loading)
const hasil = await decryptToken(String(token?.current));
- const response = await apiGetDiscussionOne({
- id: detail,
- user: hasil,
- cat: "comment",
- });
+ const response = await apiGetDiscussionOne({ id: detail, user: hasil, cat: "comment" });
setDataComment(response.data);
} catch (error) {
console.error(error);
@@ -162,17 +136,8 @@ export default function DiscussionDetail() {
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",
- });
+ 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) {
@@ -180,33 +145,18 @@ export default function DiscussionDetail() {
}
}
- useEffect(() => {
- handleLoad(false);
- }, [update.data]);
-
- useEffect(() => {
- handleLoad(true)
- handleLoadComment(true);
- handleCheckMember();
- }, []);
+ useEffect(() => { handleLoad(false); }, [update.data]);
+ useEffect(() => { handleLoad(true); handleLoadComment(true); handleCheckMember(); }, []);
async function handleKomentar() {
try {
setLoadingSend(true);
const hasil = await decryptToken(String(token?.current));
- const response = await apiSendDiscussionCommentar({
- id: detail,
- data: { comment: komentar, user: hasil },
- });
- if (response.success) {
- setKomentar("")
- updateTrigger()
- }
+ const response = await apiSendDiscussionCommentar({ id: detail, data: { comment: komentar, user: hasil } });
+ if (response.success) { setKomentar(""); updateTrigger() }
} catch (error: any) {
console.error(error);
- const message = error?.response?.data?.message || "Gagal menambahkan komentar"
-
- Toast.show({ type: 'small', text1: message })
+ Toast.show({ type: 'small', text1: error?.response?.data?.message || "Gagal menambahkan komentar" })
} finally {
setLoadingSend(false);
}
@@ -216,20 +166,11 @@ export default function DiscussionDetail() {
try {
setLoadingSend(true);
const hasil = await decryptToken(String(token?.current));
- const response = await apiEditDiscussionCommentar({
- id: selectKomentar.id,
- data: { comment: selectKomentar.comment, user: hasil },
- });
- if (response.success) {
- updateTrigger()
- } else {
- Toast.show({ type: 'small', text1: response.message })
- }
- } catch (error : any ) {
+ const response = await apiEditDiscussionCommentar({ id: selectKomentar.id, data: { comment: selectKomentar.comment, user: hasil } });
+ if (response.success) { updateTrigger() } else { Toast.show({ type: 'small', text1: response.message }) }
+ } catch (error: any) {
console.error(error);
- const message = error?.response?.data?.message || "Gagal mengedit komentar"
-
- Toast.show({ type: 'small', text1: message })
+ Toast.show({ type: 'small', text1: error?.response?.data?.message || "Gagal mengedit komentar" })
} finally {
setLoadingSend(false);
handleViewEditKomentar()
@@ -240,20 +181,11 @@ export default function DiscussionDetail() {
try {
setLoadingSend(true);
const hasil = await decryptToken(String(token?.current));
- const response = await apiDeleteDiscussionCommentar({
- id: selectKomentar.id,
- data: { user: hasil },
- });
- if (response.success) {
- updateTrigger()
- } else {
- Toast.show({ type: 'small', text1: response.message })
- }
- } catch (error : any ) {
+ const response = await apiDeleteDiscussionCommentar({ id: selectKomentar.id, data: { user: hasil } });
+ if (response.success) { updateTrigger() } else { Toast.show({ type: 'small', text1: response.message }) }
+ } catch (error: any) {
console.error(error);
- const message = error?.response?.data?.message || "Gagal menghapus komentar"
-
- Toast.show({ type: 'small', text1: message })
+ Toast.show({ type: 'small', text1: error?.response?.data?.message || "Gagal menghapus komentar" })
} finally {
setLoadingSend(false)
setVisible(false)
@@ -265,13 +197,11 @@ export default function DiscussionDetail() {
setVisible(true)
}
-
function handleViewEditKomentar() {
setVisible(false)
setViewEdit(!viewEdit)
}
-
const handleRefresh = async () => {
setRefreshing(true)
handleLoad(false)
@@ -280,27 +210,15 @@ export default function DiscussionDetail() {
setRefreshing(false)
};
+ const canWrite = data?.status != 2 && data?.isActive && ((entityUser.role != "user" && entityUser.role != "coadmin") || isMemberDivision)
+ const isOpen = data?.status === 1
+
return (
<>
(
- // {
- // router.back();
- // }}
- // />
- // ),
headerTitle: "Diskusi",
headerTitleAlign: "center",
- // headerRight: () =>
- // (entityUser.role != "user" && entityUser.role != "coadmin") || isAdminDivision || isCreator ?
- // : (<>>)
- // ,
header: () => (
router.back()}
right={
((entityUser.role != "user" && entityUser.role != "coadmin") || isAdminDivision || isCreator) ?
- : (<>>)
+ : undefined
}
/>
)
}}
/>
-
+
- }
+ showsVerticalScrollIndicator={false}
+ refreshControl={}
>
-
- {
- loading ?
-
- :
-
- }
- title={data?.username}
- subtitle={
- data?.isActive ? (
- data?.status == 1 ? (
-
- ) : (
-
+
+ {loading ? (
+
+ ) : (
+
+ }
+ title={data?.username}
+ titleShowAll={true}
+ subtitle={
+
+
+ {!data?.isActive ? 'Arsip' : isOpen ? 'Buka' : 'Tutup'}
+
+
+ }
+ desc={data?.desc}
+ leftBottomInfo={
+
+
+ {dataComment.length} Komentar
+
+ }
+ rightBottomInfo={{data?.createdAt}}
+ />
+ )}
+
+
+ {loadingKomentar ? (
+ arrSkeleton.map((_, i) => (
+
+ ))
+ ) : (
+ dataComment.map((item, i) => (
+ {
+ setDetailMore((prev: any) =>
+ prev.includes(item.id) ? prev.filter((id: string) => id !== item.id) : [...prev, item.id]
)
- ) : (
-
- )
- }
- rightTopInfo={data?.createdAt}
- desc={data?.desc}
- leftBottomInfo={
-
-
-
- {dataComment.length} Komentar
+ }}
+ onLongPress={() => {
+ item.idUser == entities.id && data?.status != 2 && data?.isActive && handleMenuKomentar(item.id, item.comment)
+ }}
+ style={({ pressed }) => [
+ Styles.discussionCommentCard,
+ { backgroundColor: pressed ? colors.icon + '10' : colors.card, borderColor: colors.icon + '20' }
+ ]}
+ >
+
+
+
+
+
+ {item.username}
+
+ {item.isEdited && (
+ diedit
+ )}
+
+
+ {item.createdAt}
+
+
+
+ {item.comment}
- }
- />
- }
-
-
- {
- loadingKomentar ?
- arrSkeleton.map((item, index) => (
-
- ))
- :
- dataComment.map((item, index) => (
-
- }
- title={item.username}
- rightTopInfo={item.createdAt}
- desc={item.comment}
- rightBottomInfo={item.isEdited ? "Edited" : ""}
- descEllipsize={detailMore.includes(item.id) ? false : true}
- bgColor="white"
- onPress={() => {
- setDetailMore((prev: any) => {
- if (prev.includes(item.id)) {
- return prev.filter((id: string) => id !== item.id)
- } else {
- return [...prev, item.id]
- }
- })
- }}
- onLongPress={() => {
- item.idUser == entities.id && data?.status != 2 && data?.isActive && handleMenuKomentar(item.id, item.comment)
- }}
- />
- ))
- }
-
+
+ ))
+ )}
-
-
- {
- viewEdit ?
- <>
-
-
-
- Edit Komentar
-
- handleViewEditKomentar()}>
-
-
-
- setSelectKomentar({ ...selectKomentar, comment: val })}
- value={selectKomentar.comment}
- itemRight={
- {
- selectKomentar.comment != "" &&
- !regexOnlySpacesOrEnter.test(selectKomentar.comment) &&
- !loadingSend &&
- data?.status != 2 &&
- data?.isActive &&
- (((entityUser.role == "user" ||
- entityUser.role == "coadmin") &&
- isMemberDivision) ||
- entityUser.role == "admin" ||
- entityUser.role == "supadmin" ||
- entityUser.role == "developer" ||
- entityUser.role == "cosupadmin") &&
- handleEditKomentar();
- }}
- style={[
- Platform.OS == 'android' && Styles.mb12,
- ]}
- >
-
-
- }
- />
- >
- :
- data?.status != 2 && data?.isActive && ((entityUser.role != "user" && entityUser.role != "coadmin") ||
- isMemberDivision)
- ?
- {
- komentar != "" &&
- !regexOnlySpacesOrEnter.test(komentar) &&
- !loadingSend &&
- data?.status != 2 &&
- data?.isActive &&
- (((entityUser.role == "user" ||
- entityUser.role == "coadmin") &&
- isMemberDivision) ||
- entityUser.role == "admin" ||
- entityUser.role == "supadmin" ||
- entityUser.role == "developer" ||
- entityUser.role == "cosupadmin") &&
- handleKomentar();
- }}
- style={[
- Platform.OS == 'android' && Styles.mb12,
- ]}
- >
-
-
- }
- />
- :
-
-
- {
- data?.status == 2 ? "Diskusi telah ditutup" : data?.isActive == false ? "Diskusi telah diarsipkan" : "Hanya anggota divisi yang dapat memberikan komentar"
- }
-
-
- }
+
+
+ {viewEdit ? (
+ <>
+
+
+
+ Edit Komentar
+
+ handleViewEditKomentar()}>
+
+
+
+ setSelectKomentar({ ...selectKomentar, comment: val })}
+ value={selectKomentar.comment}
+ itemRight={
+ {
+ selectKomentar.comment != "" && !regexOnlySpacesOrEnter.test(selectKomentar.comment) && !loadingSend && data?.status != 2 && data?.isActive
+ && (((entityUser.role == "user" || entityUser.role == "coadmin") && isMemberDivision) || entityUser.role == "admin" || entityUser.role == "supadmin" || entityUser.role == "developer" || entityUser.role == "cosupadmin")
+ && handleEditKomentar();
+ }}
+ style={[Platform.OS == 'android' && Styles.mb12]}
+ >
+
+
+ }
+ />
+ >
+ ) : canWrite ? (
+ {
+ komentar != "" && !regexOnlySpacesOrEnter.test(komentar) && !loadingSend && data?.status != 2 && data?.isActive
+ && (((entityUser.role == "user" || entityUser.role == "coadmin") && isMemberDivision) || entityUser.role == "admin" || entityUser.role == "supadmin" || entityUser.role == "developer" || entityUser.role == "cosupadmin")
+ && handleKomentar();
+ }}
+ style={[Platform.OS == 'android' && Styles.mb12]}
+ >
+
+
+ }
+ />
+ ) : (
+
+
+ {data?.status == 2 ? "Diskusi telah ditutup" : data?.isActive == false ? "Diskusi telah diarsipkan" : "Hanya anggota divisi yang dapat memberikan komentar"}
+
+
+ )}
+
- }
- title="Edit"
- onPress={() => { handleViewEditKomentar() }}
- />
- }
- title="Hapus"
- onPress={() => {
- setVisible(false)
- setTimeout(() => {
- setShowDeleteModal(true)
- }, 600)
- }}
- />
+ } title="Edit" onPress={() => handleViewEditKomentar()} />
+ } title="Hapus" onPress={() => { setVisible(false); setTimeout(() => setShowDeleteModal(true), 600) }} />
@@ -566,10 +404,7 @@ export default function DiscussionDetail() {
visible={showDeleteModal}
title="Konfirmasi"
message="Apakah anda yakin ingin menghapus komentar?"
- onConfirm={() => {
- setShowDeleteModal(false)
- handleDeleteKomentar()
- }}
+ onConfirm={() => { setShowDeleteModal(false); handleDeleteKomentar() }}
onCancel={() => setShowDeleteModal(false)}
confirmText="Hapus"
cancelText="Batal"
diff --git a/app/(application)/division/[id]/(fitur-division)/discussion/index.tsx b/app/(application)/division/[id]/(fitur-division)/discussion/index.tsx
index 43feec0..75dee0b 100644
--- a/app/(application)/division/[id]/(fitur-division)/discussion/index.tsx
+++ b/app/(application)/division/[id]/(fitur-division)/discussion/index.tsx
@@ -1,8 +1,6 @@
-import BorderBottomItem from "@/components/borderBottomItem";
import ButtonTab from "@/components/buttonTab";
import ImageUser from "@/components/imageNew";
import InputSearch from "@/components/inputSearch";
-import LabelStatus from "@/components/labelStatus";
import SkeletonContent from "@/components/skeletonContent";
import Text from "@/components/Text";
import WrapTab from "@/components/wrapTab";
@@ -11,13 +9,12 @@ import Styles from "@/constants/Styles";
import { apiGetDiscussion, apiGetDivisionOneFeature } from "@/lib/api";
import { useAuthSession } from "@/providers/AuthProvider";
import { useTheme } from "@/providers/ThemeProvider";
-import { AntDesign, Feather, Ionicons } from "@expo/vector-icons";
+import { AntDesign, Feather } from "@expo/vector-icons";
import { router, useLocalSearchParams } from "expo-router";
import { useEffect, useState } from "react";
-import { RefreshControl, View, VirtualizedList } from "react-native";
+import { FlatList, Pressable, RefreshControl, View } from "react-native";
import { useSelector } from "react-redux";
-
type Props = {
id: string,
title: string,
@@ -30,7 +27,6 @@ type Props = {
isActive: boolean
}
-
export default function DiscussionDivision() {
const { colors } = useTheme();
const { id, active } = useLocalSearchParams<{ id: string, active?: string }>()
@@ -51,17 +47,8 @@ export default function DiscussionDivision() {
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",
- });
+ 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) {
@@ -80,8 +67,6 @@ export default function DiscussionDivision() {
setData(response.data)
} else if (thisPage > 1 && response.data.length > 0) {
setData([...data, ...response.data])
- } else {
- return;
}
} catch (error) {
console.error(error)
@@ -91,26 +76,15 @@ export default function DiscussionDivision() {
}
}
- useEffect(() => {
- handleLoad(false, 1)
- }, [update.data])
-
-
- useEffect(() => {
- handleLoad(true, 1)
- }, [status, search])
+ useEffect(() => { handleLoad(false, 1) }, [update.data])
+ useEffect(() => { handleLoad(true, 1) }, [status, search])
+ useEffect(() => { handleCheckMember() }, [])
const loadMoreData = () => {
if (waiting) return
- setTimeout(() => {
- handleLoad(false, page + 1)
- }, 1000);
+ setTimeout(() => { handleLoad(false, page + 1) }, 1000);
}
- useEffect(() => {
- handleCheckMember()
- }, [])
-
const handleRefresh = async () => {
setRefreshing(true)
handleLoad(false, 1)
@@ -118,100 +92,101 @@ export default function DiscussionDivision() {
setRefreshing(false)
};
- const getItem = (_data: unknown, index: number): Props => ({
- id: data[index].id,
- title: data[index].title,
- desc: data[index].desc,
- status: data[index].status,
- user_name: data[index].user_name,
- img: data[index].img,
- total_komentar: data[index].total_komentar,
- createdAt: data[index].createdAt,
- isActive: data[index].isActive,
- })
+ const isOpen = (item: Props) => item.status === 1
return (
-
- {
- ((entityUser.role != "user" && entityUser.role != "coadmin") || isAdminDivision) &&
-
+
+ {((entityUser.role != "user" && entityUser.role != "coadmin") || isAdminDivision) && (
+
{ setStatus("true") }}
+ onPress={() => setStatus("true")}
label="Aktif"
icon={}
- n={2} />
+ n={2}
+ />
{ setStatus("false") }}
+ onPress={() => setStatus("false")}
label="Arsip"
icon={}
- n={2} />
+ n={2}
+ />
- }
+ )}
+
+ {loading ? (
+ arrSkeleton.map((_, i) => )
+ ) : data.length === 0 ? (
+
+
+
+ Tidak ada diskusi
+
+
+ ) : (
+ String(i)}
+ showsVerticalScrollIndicator={false}
+ onEndReached={loadMoreData}
+ onEndReachedThreshold={0.5}
+ refreshControl={
+
+ }
+ ItemSeparatorComponent={() => }
+ renderItem={({ item }: { item: Props }) => (
+ router.push(`./discussion/${item.id}`)}
+ style={({ pressed }) => [
+ Styles.discussionCard,
+ { backgroundColor: pressed ? colors.icon + '10' : colors.card, borderColor: colors.icon + '20' }
+ ]}
+ >
+
+
+
+
+ {item.user_name}
+
+ {status === "true" && (
+
+
+ {isOpen(item) ? 'Buka' : 'Tutup'}
+
+
+ )}
+
+
-
- {
- loading ?
- arrSkeleton.map((item: any, i: number) => {
- return (
-
- )
- })
- :
- data.length > 0 ?
- data.length}
- getItem={getItem}
- renderItem={({ item, index }: { item: Props, index: number }) => {
- return (
- { router.push(`./discussion/${item.id}`) }}
- borderType="bottom"
- icon={
-
- }
- title={item.user_name}
- subtitle={
- status == "true" ? item.status == 1 ? : : <>>
- }
- rightTopInfo={item.createdAt}
- desc={item.desc}
- leftBottomInfo={
-
-
- Diskusikan
-
- }
- rightBottomInfo={item.total_komentar + ' Komentar'}
- bgColor="transparent"
- />
- )
- }}
- keyExtractor={(item, index) => String(index)}
- onEndReached={loadMoreData}
- onEndReachedThreshold={0.5}
- showsVerticalScrollIndicator={false}
- refreshControl={
-
- }
- />
- :
- (Tidak ada diskusi)
- }
+ {item.desc ? (
+
+ {item.desc}
+
+ ) : null}
+
+
+
+
+
+ {item.total_komentar} Komentar
+
+
+
+ {item.createdAt}
+
+
+
+ )}
+ />
+ )}
);
-}
\ No newline at end of file
+}
diff --git a/constants/Styles.ts b/constants/Styles.ts
index b9fab98..e3b2462 100644
--- a/constants/Styles.ts
+++ b/constants/Styles.ts
@@ -1113,6 +1113,62 @@ const Styles = StyleSheet.create({
flex: 1,
marginLeft: 10,
},
+ discussionCard: {
+ borderRadius: 10,
+ borderWidth: 1,
+ padding: 14,
+ },
+ discussionIconCircle: {
+ width: 40,
+ height: 40,
+ borderRadius: 20,
+ alignItems: 'center',
+ justifyContent: 'center',
+ flexShrink: 0,
+ },
+ discussionIconCircleLg: {
+ width: 44,
+ height: 44,
+ borderRadius: 22,
+ alignItems: 'center',
+ justifyContent: 'center',
+ },
+ discussionStatusPill: {
+ alignSelf: 'flex-start',
+ marginTop: 3,
+ paddingHorizontal: 8,
+ paddingVertical: 2,
+ borderRadius: 20,
+ borderWidth: 1,
+ },
+ discussionStatusText: {
+ fontSize: 11,
+ fontWeight: '600',
+ },
+ discussionCardIndent: {
+ marginLeft: 50,
+ },
+ discussionSeparator: {
+ height: 8,
+ },
+ discussionCommentText: {
+ fontSize: 12,
+ marginLeft: 5,
+ },
+ discussionDateText: {
+ fontSize: 11,
+ },
+ discussionCommentCard: {
+ borderRadius: 10,
+ borderWidth: 1,
+ padding: 12,
+ marginBottom: 8,
+ flexDirection: 'row',
+ },
+ discussionEditedText: {
+ fontSize: 10,
+ fontStyle: 'italic',
+ },
})
export default Styles;
\ No newline at end of file