From d31df8c39090693502ef4e9a4955a062a80124a5 Mon Sep 17 00:00:00 2001 From: Bagasbanuna02 Date: Fri, 17 Oct 2025 17:41:25 +0800 Subject: [PATCH] Integrasi API: Admin forum Add: app/(application)/admin/forum/[id]/list-comment.tsx components/_Icon/IconOpenTo.tsx service/api-admin/api-admin-forum.ts Fix: app/(application)/admin/collaboration/index.tsx app/(application)/admin/forum/[id]/index.tsx app/(application)/admin/forum/[id]/list-report-comment.tsx app/(application)/admin/forum/index.tsx app/(application)/admin/forum/posting.tsx ### Issue: Report komentar masih belum berfungsi --- .../admin/collaboration/index.tsx | 3 - app/(application)/admin/forum/[id]/index.tsx | 235 +++++++++--------- .../admin/forum/[id]/list-comment.tsx | 153 ++++++++++++ .../admin/forum/[id]/list-report-comment.tsx | 54 ++-- app/(application)/admin/forum/index.tsx | 67 +++-- app/(application)/admin/forum/posting.tsx | 96 +++++-- components/_Icon/IconOpenTo.tsx | 27 ++ service/api-admin/api-admin-forum.ts | 43 ++++ 8 files changed, 490 insertions(+), 188 deletions(-) create mode 100644 app/(application)/admin/forum/[id]/list-comment.tsx create mode 100644 components/_Icon/IconOpenTo.tsx create mode 100644 service/api-admin/api-admin-forum.ts diff --git a/app/(application)/admin/collaboration/index.tsx b/app/(application)/admin/collaboration/index.tsx index fb6f797..25d3cf1 100644 --- a/app/(application)/admin/collaboration/index.tsx +++ b/app/(application)/admin/collaboration/index.tsx @@ -22,8 +22,6 @@ export default function AdminCollaboration() { category: "dashboard", }); - console.log("[RESPONSE]", JSON.stringify(response, null, 2)); - if (response.success) { setList(response.data); } @@ -46,7 +44,6 @@ export default function AdminCollaboration() { } const listData = (list: any) => { - console.log("[LIST masuk]", JSON.stringify(list, null, 2)); return [ { label: "Publish", diff --git a/app/(application)/admin/forum/[id]/index.tsx b/app/(application)/admin/forum/[id]/index.tsx index b2de796..21e7f98 100644 --- a/app/(application)/admin/forum/[id]/index.tsx +++ b/app/(application)/admin/forum/[id]/index.tsx @@ -1,58 +1,84 @@ +/* eslint-disable react-hooks/exhaustive-deps */ import { ActionIcon, - AlertDefaultSystem, BadgeCustom, BaseBox, DrawerCustom, MenuDrawerDynamicGrid, - Spacing, StackCustom, TextCustom, ViewWrapper, } from "@/components"; -import { IconDot, IconView } from "@/components/_Icon/IconComponent"; -import { IconTrash } from "@/components/_Icon/IconTrash"; +import { IconDot } from "@/components/_Icon/IconComponent"; import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle"; -import AdminTitleTable from "@/components/_ShareComponent/Admin/TableTitle"; -import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue"; import { GridDetail_4_8 } from "@/components/_ShareComponent/GridDetail_4_8"; import { MainColor } from "@/constants/color-palet"; -import { - ICON_SIZE_BUTTON, - ICON_SIZE_MEDIUM, - ICON_SIZE_XLARGE, -} from "@/constants/constans-value"; +import { ICON_SIZE_XLARGE } from "@/constants/constans-value"; +import { apiAdminForumPostingById } from "@/service/api-admin/api-admin-forum"; import { Ionicons } from "@expo/vector-icons"; -import { router } from "expo-router"; -import { useState } from "react"; -import { Divider } from "react-native-paper"; -import Toast from "react-native-toast-message"; +import { router, useFocusEffect, useLocalSearchParams } from "expo-router"; +import { useCallback, useState } from "react"; export default function AdminForumDetailPosting() { + const { id } = useLocalSearchParams(); const [openDrawerPage, setOpenDrawerPage] = useState(false); - const [openDrawerAction, setOpenDrawerAction] = useState(false); - const [id, setId] = useState(); + const [selectedId, setSelectedId] = useState(); - const handlerAction = (item: { value: string; path: string }) => { - if (item.value === "delete") { - AlertDefaultSystem({ - title: "Hapus Posting", - message: "Apakah Anda yakin ingin menghapus posting ini?", - textLeft: "Batal", - textRight: "Hapus", - onPressRight: () => { - Toast.show({ - type: "success", - text1: "Posting berhasil dihapus", - }); - }, + const [data, setData] = useState(null); + const [listComment, setListComment] = useState(null); + + useFocusEffect( + useCallback(() => { + onLoadData(); + }, [id]) + ); + + const onLoadData = async () => { + try { + const response = await apiAdminForumPostingById({ + id: id as string, }); - } else { - router.navigate(item.path as any); + console.log("[RES DATA]", JSON.stringify(response, null, 2)); + + if (response.success) { + setData(response.data); + } + } catch (error) { + console.log("[ERROR]", error); } - setOpenDrawerAction(false); }; + const listDataAction = [ + { + label: "Username", + value: data?.Author?.username || "-", + }, + { + label: "Status", + value: + (data && ( + + {data?.ForumMaster_StatusPosting?.status || "-"} + + )) || + "-", + }, + { + label: "Komentar", + value: data?.JumlahKomentar || 0, + }, + { + label: "Total Report", + value: data?.JumlahReportPosting || 0, + }, + ]; + return ( <> {item.value}} /> ))} - Posting - - Lorem ipsum dolor sit amet consectetur adipisicing elit. - Asperiores cupiditate nobis dignissimos explicabo quo unde dolorum - numquam eos ab laborum fugiat illo nam velit quibusdam, maxime - assumenda aut vero provident! - + + + + + + Postingan + {(data && data?.diskusi) || "-"} {/* */} - + {/* - - {Array.from({ length: 10 }).map((_, index) => ( - - } - onPress={() => { - setOpenDrawerAction(true); - setId(index + 1); - }} - /> - } - value2={Username username} - value3={ - - Lorem ipsum dolor sit amet consectetur adipisicing elit. - Blanditiis asperiores quidem deleniti architecto eaque et - nostrum, ad consequuntur eveniet quisquam quae voluptatum - ducimus! Dolorem nobis modi officia debitis, beatae mollitia. - - } - /> - ))} - + {!listComment ? ( + + ) : _.isEmpty(listComment) ? ( + + Tidak ada komentar + + ) : ( + listComment?.map((item: any, index: number) => ( + + } + onPress={() => { + setSelectedId(index + 1); + }} + /> + } + value2={ + + {item?.Author?.username || "-"} + + } + value3={ + {item?.komentar || "-"} + } + /> + )) + )} + */} + ), + label: "Daftar Komentar", + value: "detail", + path: `/admin/forum/${id}/list-comment`, + }, ]} onPressItem={(item) => { router.navigate(item.path as any); @@ -150,54 +193,6 @@ export default function AdminForumDetailPosting() { }} /> - - setOpenDrawerAction(false)} - height={"auto"} - > - , - label: "Detail Komentar", - value: "detail", - path: `admin/forum/${id}/list-report-comment`, - }, - { - icon: ( - - ), - label: "Hapus Komentar", - value: "delete", - path: "", - color: MainColor.red, - }, - ]} - onPressItem={(item) => { - handlerAction(item as any); - }} - /> - ); } - -const listDataAction = [ - { - label: "Username", - value: "Username", - }, - { - label: "Status", - value: Open, - }, - { - label: "Komentar", - value: "10", - }, - { - label: "Total Report", - value: "1", - }, -]; diff --git a/app/(application)/admin/forum/[id]/list-comment.tsx b/app/(application)/admin/forum/[id]/list-comment.tsx new file mode 100644 index 0000000..085e0ab --- /dev/null +++ b/app/(application)/admin/forum/[id]/list-comment.tsx @@ -0,0 +1,153 @@ +/* eslint-disable react-hooks/exhaustive-deps */ +import { + ActionIcon, + AlertDefaultSystem, + DrawerCustom, + LoaderCustom, + MenuDrawerDynamicGrid, + StackCustom, + TextCustom, + ViewWrapper, +} from "@/components"; +import { IconView } from "@/components/_Icon/IconComponent"; +import { IconOpenTo } from "@/components/_Icon/IconOpenTo"; +import { IconTrash } from "@/components/_Icon/IconTrash"; +import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle"; +import AdminTitleTable from "@/components/_ShareComponent/Admin/TableTitle"; +import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue"; +import { MainColor } from "@/constants/color-palet"; +import { + ICON_SIZE_BUTTON, + ICON_SIZE_MEDIUM, + ICON_SIZE_XLARGE, +} from "@/constants/constans-value"; +import { apiAdminForumCommentById } from "@/service/api-admin/api-admin-forum"; +import { Ionicons } from "@expo/vector-icons"; +import { router, useFocusEffect, useLocalSearchParams } from "expo-router"; +import _ from "lodash"; +import { useCallback, useState } from "react"; +import { Divider } from "react-native-paper"; +import Toast from "react-native-toast-message"; + +export default function AdminForumListComment() { + const { id } = useLocalSearchParams(); + const [openDrawerAction, setOpenDrawerAction] = useState(false); + + console.log("[ID]", id); + + const [listComment, setListComment] = useState(null); + + useFocusEffect( + useCallback(() => { + onLoadComment(); + }, [id]) + ); + + const onLoadComment = async () => { + try { + const response = await apiAdminForumCommentById({ + id: id as string, + category: "get-all", + }); + + console.log("[RES COMMENT]", JSON.stringify(response, null, 2)); + if (response.success) { + setListComment(response.data); + } + } catch (error) { + console.log("[ERROR]", error); + setListComment([]); + } + }; + + const handlerAction = (item: { value: string; path: string }) => { + if (item.value === "delete") { + AlertDefaultSystem({ + title: "Hapus Posting", + message: "Apakah Anda yakin ingin menghapus posting ini?", + textLeft: "Batal", + textRight: "Hapus", + onPressRight: () => { + Toast.show({ + type: "success", + text1: "Posting berhasil dihapus", + }); + }, + }); + } else { + router.navigate(item.path as any); + } + setOpenDrawerAction(false); + }; + return ( + <> + } + > + + + + {!listComment ? ( + + ) : _.isEmpty(listComment) ? ( + + Tidak ada komentar + + ) : ( + listComment?.map((item: any, index: number) => ( + { + router.push( + `/admin/forum/${item.id}/list-report-comment` + ); + }} + /> + } + value2={ + + {item?.Author?.username || "-"} + + } + value3={ + {item?.komentar || "-"} + } + /> + )) + )} + + + + setOpenDrawerAction(false)} + height={"auto"} + > + , + label: "Detail Komentar", + value: "detail", + path: `admin/forum/${id}/list-report-comment`, + }, + { + icon: ( + + ), + label: "Hapus Komentar", + value: "delete", + path: "", + color: MainColor.red, + }, + ]} + onPressItem={(item) => { + handlerAction(item as any); + }} + /> + + + ); +} diff --git a/app/(application)/admin/forum/[id]/list-report-comment.tsx b/app/(application)/admin/forum/[id]/list-report-comment.tsx index 2a6a99d..8a3e6c3 100644 --- a/app/(application)/admin/forum/[id]/list-report-comment.tsx +++ b/app/(application)/admin/forum/[id]/list-report-comment.tsx @@ -1,3 +1,4 @@ +/* eslint-disable react-hooks/exhaustive-deps */ import { ActionIcon, AlertDefaultSystem, @@ -18,15 +19,42 @@ import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue"; import { GridDetail_4_8 } from "@/components/_ShareComponent/GridDetail_4_8"; import { MainColor } from "@/constants/color-palet"; import { ICON_SIZE_BUTTON } from "@/constants/constans-value"; -import { router } from "expo-router"; -import { useState } from "react"; +import { apiAdminForumCommentById } from "@/service/api-admin/api-admin-forum"; +import { router, useFocusEffect, useLocalSearchParams } from "expo-router"; +import { useCallback, useState } from "react"; import { Divider } from "react-native-paper"; import Toast from "react-native-toast-message"; export default function AdminForumReportComment() { + const { id } = useLocalSearchParams(); + console.log("[ID]", id); + const [data, setData] = useState(null); const [openDrawer, setOpenDrawer] = useState(false); const [openDrawerAction, setOpenDrawerAction] = useState(false); + useFocusEffect( + useCallback(() => { + onLoadData(); + }, [id]) + ); + + const onLoadData = async () => { + try { + const response = await apiAdminForumCommentById({ + id: id as string, + category: "get-one", + }); + + console.log("[RES GET ONE COMMENT]", JSON.stringify(response, null, 2)); + if (response.success) { + setData(response.data); + } + } catch (error) { + console.log("[ERROR]", error); + setData(null); + } + }; + return ( <> - {listData.map((item, i) => ( - {item.label}} - value={{item.value}} - /> - ))} - Posting - - Lorem ipsum dolor sit amet consectetur adipisicing elit. - Asperiores cupiditate nobis dignissimos explicabo quo unde dolorum - numquam eos ab laborum fugiat illo nam velit quibusdam, maxime - assumenda aut vero provident! - + Username} + value={{data?.Author?.username || "-"}} + /> + Komentar} + value={{data?.komentar || "-"}} + /> diff --git a/app/(application)/admin/forum/index.tsx b/app/(application)/admin/forum/index.tsx index c80e0c6..0e6e6fe 100644 --- a/app/(application)/admin/forum/index.tsx +++ b/app/(application)/admin/forum/index.tsx @@ -1,13 +1,54 @@ import { Spacing, StackCustom, ViewWrapper } from "@/components"; -import { - IconPublish, - IconReport, -} from "@/components/_Icon/IconComponent"; +import { IconPublish, IconReport } from "@/components/_Icon/IconComponent"; import AdminComp_BoxDashboard from "@/components/_ShareComponent/Admin/BoxDashboard"; import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage"; import { MainColor } from "@/constants/color-palet"; +import { apiAdminForum } from "@/service/api-admin/api-admin-forum"; +import { useFocusEffect } from "expo-router"; +import { useCallback, useState } from "react"; export default function AdminForum() { + const [data, setData] = useState(null); + + useFocusEffect( + useCallback(() => { + handlerLoadList(); + }, []) + ); + + const handlerLoadList = async () => { + try { + const response = await apiAdminForum({ + category: "dashboard", + }); + + console.log("[RES DASHBOARD]", JSON.stringify(response, null, 2)); + if (response.success) { + setData(response.data); + } + } catch (error) { + console.log("[ERROR]", error); + } + }; + + const listData = [ + { + label: "Posting", + value: data?.posting || 0, + icon: , + }, + { + label: "Report Posting", + value: data?.report_posting || 0, + icon: , + }, + { + label: "Report Comment", + value: data?.report_comment || 0, + icon: , + }, + ]; + return ( <> @@ -22,21 +63,3 @@ export default function AdminForum() { ); } - -const listData = [ - { - label: "Posting", - value: 4, - icon: , - }, - { - label: "Report Posting", - value: 7, - icon: , - }, - { - label: "Report Comment", - value: 5, - icon: , - }, -]; diff --git a/app/(application)/admin/forum/posting.tsx b/app/(application)/admin/forum/posting.tsx index b928f1e..fafff4e 100644 --- a/app/(application)/admin/forum/posting.tsx +++ b/app/(application)/admin/forum/posting.tsx @@ -1,8 +1,11 @@ +/* eslint-disable react-hooks/exhaustive-deps */ import { ActionIcon, BaseBox, + LoaderCustom, SearchInput, Spacing, + StackCustom, TextCustom, ViewWrapper, } from "@/components"; @@ -12,15 +15,48 @@ import AdminTitleTable from "@/components/_ShareComponent/Admin/TableTitle"; import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue"; import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage"; import { ICON_SIZE_BUTTON } from "@/constants/constans-value"; -import { router } from "expo-router"; -import React from "react"; +import { apiAdminForum } from "@/service/api-admin/api-admin-forum"; +import { router, useFocusEffect } from "expo-router"; +import _ from "lodash"; +import React, { useCallback, useState } from "react"; import { Divider } from "react-native-paper"; export default function AdminForumPosting() { + const [list, setList] = useState(null); + const [loadList, setLoadList] = useState(false); + const [search, setSearch] = useState(""); + + useFocusEffect( + useCallback(() => { + handlerLoadList(); + }, [search]) + ); + + const handlerLoadList = async () => { + try { + setLoadList(true); + const response = await apiAdminForum({ + category: "posting", + search: search, + }); + + // console.log("[RES LIST POSTING]", JSON.stringify(response, null, 2)); + if (response.success) { + setList(response.data); + } + } catch (error) { + console.log("[ERROR]", error); + } finally { + setLoadList(false); + } + }; + const rightComponent = ( ); @@ -28,33 +64,39 @@ export default function AdminForumPosting() { <> }> - + - - {Array.from({ length: 10 }).map((_, index) => ( - } - onPress={() => { - router.push(`/admin/forum/${index + 1}`); - }} - /> - } - value2={Username username} - value3={ - - Lorem ipsum dolor sit amet consectetur adipisicing elit. - Blanditiis asperiores quidem deleniti architecto eaque et - nostrum, ad consequuntur eveniet quisquam quae voluptatum - ducimus! Dolorem nobis modi officia debitis, beatae mollitia. - - } - /> - ))} - + {loadList ? ( + + ) : _.isEmpty(list) ? ( + + Belum ada data + + ) : ( + list?.map((item: any, index: number) => ( + } + onPress={() => { + router.push(`/admin/forum/${item?.id}`); + }} + /> + } + value2={ + + {item?.Author?.username || "-"} + + } + value3={ + {item?.diskusi || "-"} + } + /> + )) + )} + ); diff --git a/components/_Icon/IconOpenTo.tsx b/components/_Icon/IconOpenTo.tsx new file mode 100644 index 0000000..b726e45 --- /dev/null +++ b/components/_Icon/IconOpenTo.tsx @@ -0,0 +1,27 @@ +import { MainColor } from "@/constants/color-palet"; +import { ICON_SIZE_XLARGE } from "@/constants/constans-value"; +import { Ionicons } from "@expo/vector-icons"; +import React from "react"; + +export { IconOpenTo }; + +function IconOpenTo({ + color, + size, + onPress, +}: { + color?: string; + size?: number; + onPress?: () => void; +}) { + return ( + <> + + + ); +} diff --git a/service/api-admin/api-admin-forum.ts b/service/api-admin/api-admin-forum.ts new file mode 100644 index 0000000..0a5a00e --- /dev/null +++ b/service/api-admin/api-admin-forum.ts @@ -0,0 +1,43 @@ +import { apiConfig } from "../api-config"; + +export async function apiAdminForum({ + category, + search, +}: { + category: "dashboard" | "posting" | "report_posting" | "report_comment"; + search?: string; +}) { + try { + const response = await apiConfig.get( + `/mobile/admin/forum?category=${category}&search=${search}` + ); + return response.data; + } catch (error) { + throw error; + } +} + +export async function apiAdminForumPostingById({ id }: { id: string }) { + try { + const response = await apiConfig.get(`/mobile/admin/forum/${id}`); + return response.data; + } catch (error) { + throw error; + } +} +export async function apiAdminForumCommentById({ + id, + category, +}: { + id: string; + category: "get-all" | "get-one"; +}) { + try { + const response = await apiConfig.get( + `/mobile/admin/forum/${id}/comment?category=${category}` + ); + return response.data; + } catch (error) { + throw error; + } +}