diff --git a/app/(application)/admin/donation/[id]/detail-disbursement-of-funds.tsx b/app/(application)/admin/donation/[id]/detail-disbursement-of-funds.tsx index 10bdd96..586e5eb 100644 --- a/app/(application)/admin/donation/[id]/detail-disbursement-of-funds.tsx +++ b/app/(application)/admin/donation/[id]/detail-disbursement-of-funds.tsx @@ -42,19 +42,19 @@ export default function AdminDonationDetailDisbursementOfFunds() { const listData = [ { label: "Nominal", - value: `Rp ${(data && formatCurrencyDisplay(data?.nominalCair)) || 0}`, + value: `Rp ${data ? formatCurrencyDisplay(data?.nominalCair) : 0}`, }, { label: "Tanggal", - value: dateTimeView({ date: data?.createdAt }), + value: data ? dateTimeView({ date: data?.createdAt }) : "-", }, { label: "Judul", - value: (data && data?.title) || "-", + value: data ? data?.title : "-", }, { label: "Deskripsi", - value: (data && data?.deskripsi) || "-", + value: data ? data?.deskripsi : "-", }, ]; return ( diff --git a/app/(application)/admin/donation/[id]/list-disbursement-of-funds.tsx b/app/(application)/admin/donation/[id]/list-disbursement-of-funds.tsx index 173cc68..10c67fe 100644 --- a/app/(application)/admin/donation/[id]/list-disbursement-of-funds.tsx +++ b/app/(application)/admin/donation/[id]/list-disbursement-of-funds.tsx @@ -1,126 +1,5 @@ -/* eslint-disable react-hooks/exhaustive-deps */ -import { - ActionIcon, - CenterCustom, - Divider, - LoaderCustom, - StackCustom, - TextCustom, - ViewWrapper, -} from "@/components"; -import { IconView } from "@/components/_Icon/IconComponent"; -import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle"; -import { GridViewCustomSpan } from "@/components/_ShareComponent/GridViewCustomSpan"; -import { ICON_SIZE_BUTTON } from "@/constants/constans-value"; -import { apiAdminDonationDisbursementOfFundsListById } from "@/service/api-admin/api-admin-donation"; -import { formatCurrencyDisplay } from "@/utils/formatCurrencyDisplay"; -import dayjs from "dayjs"; -import { router, useFocusEffect, useLocalSearchParams } from "expo-router"; -import _ from "lodash"; -import React, { useCallback } from "react"; -import { View } from "react-native"; +import { Admin_ScreenDonationListDisbursementOfFunds } from "@/screens/Admin/Donation/ScreenDonationListDisbursementOfFunds"; export default function AdminDonasiListOfDisbursementOfFunds() { - const { id } = useLocalSearchParams(); - const [listData, setListData] = React.useState(null); - const [loadData, setLoadData] = React.useState(false); - - useFocusEffect( - useCallback(() => { - onLoadData(); - }, [id]) - ); - - const onLoadData = async () => { - try { - setLoadData(true); - const response = await apiAdminDonationDisbursementOfFundsListById({ - id: id as string, - category: "get-all", - }); - - if (response.success) { - setListData(response.data); - } - } catch (error) { - console.log("[ERROR]", error); - } finally { - setLoadData(false); - } - }; - - return ( - <> - - } - > - - Aksi - - } - component2={ - - Tanggal - - } - component3={ - - Nominal - - } - /> - - - {loadData ? ( - - ) : _.isEmpty(listData) ? ( - - Belum ada data - - ) : ( - listData?.map((item, index) => ( - - - - } - onPress={() => { - router.push( - `/admin/donation/${item?.id}/detail-disbursement-of-funds` - ); - }} - /> - - } - component2={ - - {dayjs(item?.createdAt).format("DD-MM-YYYY")} - - } - component3={ - - Rp. {formatCurrencyDisplay(item?.nominalCair)} - - } - /> - - )) - )} - - - - ); + return ; } diff --git a/app/(application)/admin/donation/[id]/list-of-donatur.tsx b/app/(application)/admin/donation/[id]/list-of-donatur.tsx index aa0a885..061ef0b 100644 --- a/app/(application)/admin/donation/[id]/list-of-donatur.tsx +++ b/app/(application)/admin/donation/[id]/list-of-donatur.tsx @@ -1,186 +1,5 @@ -/* eslint-disable react-hooks/exhaustive-deps */ -import { - ActionIcon, - BadgeCustom, - CenterCustom, - LoaderCustom, - SelectCustom, - StackCustom, - TextCustom, - ViewWrapper, -} from "@/components"; -import { IconView } from "@/components/_Icon/IconComponent"; -import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle"; -import { GridViewCustomSpan } from "@/components/_ShareComponent/GridViewCustomSpan"; -import { ICON_SIZE_BUTTON } from "@/constants/constans-value"; -import { apiAdminDonationListOfDonatur } from "@/service/api-admin/api-admin-donation"; -import { apiMasterTransaction } from "@/service/api-client/api-master"; -import { colorBadgeTransaction } from "@/utils/colorBadge"; -import { router, useFocusEffect, useLocalSearchParams } from "expo-router"; -import _ from "lodash"; -import React, { useEffect } from "react"; -import { View } from "react-native"; -import { Divider } from "react-native-paper"; +import { Admin_ScreenDonationListOfDonatur } from "@/screens/Admin/Donation/ScreenDonationListOfDonatur"; export default function AdminDonasiListOfDonatur() { - const { id } = useLocalSearchParams(); - const [listData, setListData] = React.useState(null); - const [loadData, setLoadData] = React.useState(false); - const [master, setMaster] = React.useState([]); - - const [selectValue, setSelectValue] = React.useState(null); - const [selectedStatus, setSelectedStatus] = React.useState( - null - ); - - useFocusEffect( - React.useCallback(() => { - onLoadData(); - }, [id, selectValue]) - ); - - const onLoadData = async () => { - try { - setLoadData(true); - const response = await apiAdminDonationListOfDonatur({ - id: id as string, - status: selectedStatus as any, - }); - // console.log("[LIST OF DONATUR]", JSON.stringify(response, null, 2)); - - if (response.success) { - setListData(response.data); - } - } catch (error) { - console.log("[ERROR]", error); - setListData([]); - } finally { - setLoadData(false); - } - }; - - useEffect(() => { - onLoadMaster(); - }, []); - - const onLoadMaster = async () => { - try { - const response = await apiMasterTransaction(); - - if (response.success) { - setMaster(response.data); - } - } catch (error) { - console.log("[ERROR]", error); - setMaster([]); - } - }; - - const searchComponent = ( - - ({ - label: item.name, - value: item.id, - })) - } - value={selectValue} - onChange={(value: any) => { - setSelectValue(value); - const nameSelected = master.find((item: any) => item.id === value); - const statusChooses = _.lowerCase(nameSelected?.name); - setSelectedStatus(statusChooses); - }} - styleContainer={{ width: "100%", marginBottom: 0 }} - allowClear - /> - - ); - return ( - <> - - } - > - - - Aksi - - } - component2={ - - Donatur - - } - component3={ - - Status - - } - /> - - - {loadData ? ( - - ) : _.isEmpty(listData) ? ( - - Belum ada data - - ) : ( - listData?.map((item: any, index: number) => ( - - - - } - onPress={() => { - router.push( - `/admin/donation/${item?.id}/${_.lowerCase( - item?.DonasiMaster_StatusInvoice?.name - )}/transaction-detail` - ); - }} - /> - - } - component2={ - - {item?.Author?.username || "-"} - - } - component3={ - - {item?.DonasiMaster_StatusInvoice?.name} - - } - /> - - )) - )} - - - - - ); + return ; } diff --git a/app/(application)/admin/donation/[status]/status.tsx b/app/(application)/admin/donation/[status]/status.tsx index eb7dfb4..b88f1d0 100644 --- a/app/(application)/admin/donation/[status]/status.tsx +++ b/app/(application)/admin/donation/[status]/status.tsx @@ -1,117 +1,5 @@ -/* eslint-disable react-hooks/exhaustive-deps */ -import { - ActionIcon, - LoaderCustom, - SearchInput, - StackCustom, - TextCustom, - ViewWrapper -} from "@/components"; -import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage"; -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 { apiAdminDonation } from "@/service/api-admin/api-admin-donation"; -import { Octicons } 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 { Admin_ScreenDonationStatus } from "@/screens/Admin/Donation/ScreenDonationStatus"; export default function AdminDonationStatus() { - const { status } = useLocalSearchParams(); - console.log("[STATUS]", status); - - const [data, setData] = useState(null); - const [search, setSearch] = useState(""); - const [loadData, setLoadData] = useState(false); - - useFocusEffect( - useCallback(() => { - onLoadData(); - }, [status, search]) - ); - - const onLoadData = async () => { - try { - setLoadData(true); - const response = await apiAdminDonation({ - category: status as "publish" | "review" | "reject", - search, - }); - - console.log("[RES]", JSON.stringify(response, null, 2)); - - if (response.success) { - setData(response.data); - } - } catch (error) { - console.log("[ERROR]", error); - setData([]); - } finally { - setLoadData(false); - } - }; - - const rightComponent = ( - setSearch(value)} - /> - ); - return ( - <> - }> - - - - - - {loadData ? ( - - ) : _.isEmpty(data) ? ( - - Belum ada data - - ) : ( - data?.map((item: any, index: number) => ( - - } - onPress={() => { - router.push(`/admin/donation/${item.id}/${status}`); - }} - /> - } - value2={{item?.Author?.username || "-"}} - value3={ - - {item?.title || "-"} - - } - /> - )) - )} - - - - ); + return ; } diff --git a/app/(application)/admin/donation/category-update.tsx b/app/(application)/admin/donation/category-update.tsx index 640dd5a..1e3e743 100644 --- a/app/(application)/admin/donation/category-update.tsx +++ b/app/(application)/admin/donation/category-update.tsx @@ -30,7 +30,6 @@ export default function AdminDonationCategoryUpdate() { const response = await apiAdminMasterDonationCategoryById({ id: id as any, }); - console.log(JSON.stringify(response.data, null, 2)); setData(response.data); }; @@ -44,10 +43,9 @@ export default function AdminDonationCategoryUpdate() { id: id as any, data: data, }); - console.log(JSON.stringify(response.data, null, 2)); router.back(); } catch (error) { - console.log(error); + console.log("Error update category:", error); } finally { setIsLoading(false); } diff --git a/app/(application)/admin/donation/category.tsx b/app/(application)/admin/donation/category.tsx index ec2e69f..bb767f0 100644 --- a/app/(application)/admin/donation/category.tsx +++ b/app/(application)/admin/donation/category.tsx @@ -1,135 +1,5 @@ -import { - BadgeCustom, - CenterCustom, - ClickableCustom, - Spacing, - StackCustom, - TextCustom, - ViewWrapper -} from "@/components"; -import AdminActionIconPlus from "@/components/_ShareComponent/Admin/ActionIconPlus"; -import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage"; -import AdminTitlePage from "@/components/_ShareComponent/Admin/TitlePage"; -import { GridSpan_4_8 } from "@/components/_ShareComponent/GridSpan_4_8"; -import { apiAdminMasterDonationCategory } from "@/service/api-admin/api-master-admin"; -import { colorActivationForBadge } from "@/utils/colorActivationForBadge"; -import { router, useFocusEffect } from "expo-router"; -import { useCallback, useState } from "react"; -import { RefreshControl, View } from "react-native"; -import { Divider } from "react-native-paper"; +import { Admin_ScreenDonationCategory } from "@/screens/Admin/Donation/ScreenDonationCategory"; export default function AdminDonationCategory() { - const [listData, setListData] = useState([]); - const [refreshing, setRefreshing] = useState(false); - const [loading, setLoading] = useState(false); - - useFocusEffect( - useCallback(() => { - fetchMaster(); - }, []) - ); - - const fetchMaster = async () => { - try { - setLoading(true); - const response = await apiAdminMasterDonationCategory(); - if (response.success) { - console.log(JSON.stringify(response.data, null, 2)); - setListData(response.data); - } else { - setListData([]); - } - } catch (error) { - console.log("[Error]", error); - } finally { - setLoading(false); - } - }; - - const onRefresh = async () => { - setRefreshing(true); - await fetchMaster(); - setRefreshing(false); - }; - - return ( - <> - - } - headerComponent={} - > - { - router.push(`/admin/donation/category-create`); - }} - /> - } - /> - - - Status} - value={Kategori} - /> - {/* - - Status - - - Kategori - - */} - - - - - - {listData.map((item, index) => ( - { - router.push(`/admin/donation/category-update?id=${item.id}`); - }} - key={index} - > - - - {item.active ? "Aktif" : "Tidak Aktif"} - - - } - value={{item.name}} - /> - {/* - - - - {item.active ? "Aktif" : "Tidak Aktif"} - - - - - {item.name} - - */} - - - ))} - - - - - ); + return ; } diff --git a/docs/prompt-for-qwen-code.md b/docs/prompt-for-qwen-code.md index bc68619..c0a1ed7 100644 --- a/docs/prompt-for-qwen-code.md +++ b/docs/prompt-for-qwen-code.md @@ -55,10 +55,10 @@ Component yang digunakan: components/_ShareComponent/NewWrapper.tsx -File source: app/(application)/admin/event/type-of-event.tsx -Folder tujuan: screens/Admin/Voting -Nama file utama: ScreenEventTypeOfEvent.tsx -Nama function utama: Admin_ScreenEventTypeOfEvent +File source: app/(application)/admin/donation/[id]/list-disbursement-of-funds.tsx +Folder tujuan: screens/Admin/Donation +Nama file utama: ScreenDonationListDisbursementOfFunds.tsx +Nama function utama: Admin_ScreenDonationListDisbursementOfFunds File komponen wrapper: components/_ShareComponent/NewWrapper.tsx Buat file baru pada "Folder tujuan" dengan nama "Nama file utama" dan ubah nama function menjadi "Nama function utama" kemudian clean code, import dan panggil function tersebut pada file "File source" @@ -66,8 +66,8 @@ Analisa juga file "Nama file utama" , jika belum menggunakan NewWrapper pada fil -Function fecth: apiAdminMasterTypeOfEvent -File function fetch: service/api-admin/api-master-admin.ts +Function fecth: apiAdminDonationDisbursementOfFundsListById +File function fetch: service/api-admin/api-admin-donation.ts Terapkan pagination pada file "Nama file utama" Komponen pagination yang digunaka berada pada file hooks/use-pagination.tsx dan helpers/paginationHelpers.tsx @@ -75,13 +75,16 @@ Perbaiki fetch "Function fecth" , pada file "File function fetch" Jika tidak ada props page maka tambahkan props page dan default page: "1" ( string ) Kemudian rapikan code nya pisah komponen seperti render item dan lainnya agar lebih rapi dan di dalam return panggil komponen tersebut + Gunakan bahasa indonesia pada cli agar saya mudah membacanya. -File refrensi: screens/Admin/Event/ScreenVotingStatus.tsx +File refrensi: screens/Admin/Voting/ScreenEventTypeOfEvent.tsx Anda bisa menggunakan refrensi dari "File refrensi" jika butuh pemahaman dengan tipe fitur yang hampir sama +Untuk refrensi tampilan Box bisa anda gunakan dari file: screens/Admin/Donation/BoxDonationCategory.tsx dan buatkan komponen yang mirip untuk list of donatur dengan nama file: BoxDonationListOfDonatur.tsx + Terapkan NewWrapper pada file: screens/Admin/App-Information/InformationBankSection.tsx Component yang digunakan: components/_ShareComponent/NewWrapper.tsx @@ -95,7 +98,7 @@ Perbaiki fetch "Function fecth" , pada file "File function fetch" Jika tidak ada props page maka tambahkan props page dan default page: "1" ( string ) - + File Utama: screens/Admin/App-Information/InformationBankSection.tsx Terapkan FlatList dan pagination pada file "File Utama" Komponen pagination yang digunaka berada pada file hooks/use-pagination.tsx dan helpers/paginationHelpers.tsx @@ -103,4 +106,12 @@ Function fecth: apiAdminMasterBank File function fetch: service/api-admin/api-master-admin.ts Jika tidak ada props page maka tambahkan props page dan default page: "1" ( string ) Jika butuh refrensi FlatList bisa lihat pada file components/_ShareComponent/NewWrapper.tsx + + +File Utama: screens/Admin/Donation/Admin_ScreenDonationStatus.tsx +Folder tujuan: screens/Admin/Donation +Buat box component baru pada file "File Utama" di bagian renderItem, + + + diff --git a/screens/Admin/Donation/BoxDonationCategory.tsx b/screens/Admin/Donation/BoxDonationCategory.tsx new file mode 100644 index 0000000..f11c097 --- /dev/null +++ b/screens/Admin/Donation/BoxDonationCategory.tsx @@ -0,0 +1,36 @@ +import { TextCustom, BadgeCustom } from "@/components"; +import AdminBasicBox from "@/components/_ShareComponent/Admin/AdminBasicBox"; +import GridTwoView from "@/components/_ShareComponent/GridTwoView"; +import { router } from "expo-router"; +import { View } from "react-native"; + +export default function Admin_BoxDonationCategory({item}: {item: any}) { + return ( + <> + { + router.push(`/admin/donation/category-update?id=${item.id}`); + }} + style={{ marginHorizontal: 10, marginVertical: 5 }} + > + {item?.name || "-"}} + rightItem={ + + {item?.active ? ( + Aktif + ) : ( + Tidak Aktif + )} + + } + spanLeft={8} + spanRight={4} + styleRight={{ + alignItems: "flex-end", + }} + /> + + + ) +} \ No newline at end of file diff --git a/screens/Admin/Donation/BoxDonationListDisbursementOfFunds.tsx b/screens/Admin/Donation/BoxDonationListDisbursementOfFunds.tsx new file mode 100644 index 0000000..8c9a12e --- /dev/null +++ b/screens/Admin/Donation/BoxDonationListDisbursementOfFunds.tsx @@ -0,0 +1,53 @@ +import { Divider, StackCustom, TextCustom } from "@/components"; +import AdminBasicBox from "@/components/_ShareComponent/Admin/AdminBasicBox"; +import { GridSpan_4_8 } from "@/components/_ShareComponent/GridSpan_4_8"; +import { formatCurrencyDisplay } from "@/utils/formatCurrencyDisplay"; +import dayjs from "dayjs"; +import { router } from "expo-router"; +import { View } from "react-native"; + +interface BoxDonationListDisbursementOfFundsProps { + item: any; +} + +export default function Admin_BoxDonationListDisbursementOfFunds({ + item, +}: BoxDonationListDisbursementOfFundsProps) { + return ( + <> + { + router.push( + `/admin/donation/${item?.id}/detail-disbursement-of-funds`, + ); + }} + > + + + + {item?.title || "-"} + + + + Tanggal} + value={ + + {dayjs(item?.createdAt).format("DD-MM-YYYY") || "-"} + + } + /> + Nominal} + value={ + + Rp {formatCurrencyDisplay(item?.nominalCair)} + + } + /> + + + + ); +} diff --git a/screens/Admin/Donation/BoxDonationListOfDonatur.tsx b/screens/Admin/Donation/BoxDonationListOfDonatur.tsx new file mode 100644 index 0000000..1289950 --- /dev/null +++ b/screens/Admin/Donation/BoxDonationListOfDonatur.tsx @@ -0,0 +1,68 @@ +import { + BadgeCustom, + Divider, + StackCustom, + TextCustom +} from "@/components"; +import AdminBasicBox from "@/components/_ShareComponent/Admin/AdminBasicBox"; +import { GridSpan_4_8 } from "@/components/_ShareComponent/GridSpan_4_8"; +import { colorBadgeTransaction } from "@/utils/colorBadge"; +import { formatCurrencyDisplay } from "@/utils/formatCurrencyDisplay"; +import { router } from "expo-router"; +import _ from "lodash"; +import { View } from "react-native"; + +interface BoxDonationListOfDonaturProps { + item: any; +} + +export default function Admin_BoxDonationListOfDonatur({ + item, +}: BoxDonationListOfDonaturProps) { + const statusName = item?.DonasiMaster_StatusInvoice?.name || "-"; + return ( + <> + { + router.push( + `/admin/donation/${item?.id}/${_.lowerCase( + item?.DonasiMaster_StatusInvoice?.name, + )}/transaction-detail`, + ); + }} + > + + + + {item?.Author?.username || "-"} + + + + Status} + value={ + + {statusName} + + } + /> + Nominal} + value={ + + {item?.nominal + ? `Rp ${formatCurrencyDisplay(item?.nominal)}` + : "-"} + + } + /> + + + + ); +} diff --git a/screens/Admin/Donation/BoxDonationStatus.tsx b/screens/Admin/Donation/BoxDonationStatus.tsx new file mode 100644 index 0000000..55721e3 --- /dev/null +++ b/screens/Admin/Donation/BoxDonationStatus.tsx @@ -0,0 +1,54 @@ +import { Divider, StackCustom, TextCustom } from "@/components"; +import AdminBasicBox from "@/components/_ShareComponent/Admin/AdminBasicBox"; +import { GridSpan_4_8 } from "@/components/_ShareComponent/GridSpan_4_8"; +import { formatCurrencyDisplay } from "@/utils/formatCurrencyDisplay"; +import { router } from "expo-router"; +import { View } from "react-native"; + +interface BoxDonationStatusProps { + item: any; + status?: string; +} + +export default function Admin_BoxDonationStatus({ + item, + status, +}: BoxDonationStatusProps) { + return ( + <> + { + router.push(`/admin/donation/${item.id}/${status}`); + }} + > + + + + {item?.title || "-"} + + + + Durasi} + value={ + + {item?.DonasiMaster_Durasi?.name || "-"} hari + + } + /> + Target} + value={ + + {item?.target + ? `Rp ${formatCurrencyDisplay(item?.target)}` + : "-"} + + } + /> + + + + ); +} diff --git a/screens/Admin/Donation/ScreenDonationCategory.tsx b/screens/Admin/Donation/ScreenDonationCategory.tsx new file mode 100644 index 0000000..6a3c7d1 --- /dev/null +++ b/screens/Admin/Donation/ScreenDonationCategory.tsx @@ -0,0 +1,107 @@ +import { BadgeCustom, TextCustom } from "@/components"; +import AdminActionIconPlus from "@/components/_ShareComponent/Admin/ActionIconPlus"; +import AdminBasicBox from "@/components/_ShareComponent/Admin/AdminBasicBox"; +import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage"; +import GridTwoView from "@/components/_ShareComponent/GridTwoView"; +import NewWrapper from "@/components/_ShareComponent/NewWrapper"; +import { PAGINATION_DEFAULT_TAKE } from "@/constants/constans-value"; +import { createPaginationComponents } from "@/helpers/paginationHelpers"; +import { usePagination } from "@/hooks/use-pagination"; +import { apiAdminMasterDonationCategory } from "@/service/api-admin/api-master-admin"; +import { router, useFocusEffect } from "expo-router"; +import { useCallback, useMemo, useState } from "react"; +import { RefreshControl, View } from "react-native"; +import Admin_BoxDonationCategory from "./BoxDonationCategory"; + +export function Admin_ScreenDonationCategory() { + const [search, setSearch] = useState(""); + + // Gunakan hook pagination + const pagination = usePagination({ + fetchFunction: async (page, searchQuery) => { + const response = await apiAdminMasterDonationCategory({ + page: String(page), + }); + + if (response.success) { + return { data: response.data }; + } else { + return { data: [] }; + } + }, + pageSize: PAGINATION_DEFAULT_TAKE, + searchQuery: search, + dependencies: [], + }); + + // Komponen action plus untuk header + const rightComponent = useMemo( + () => ( + { + router.push(`/admin/donation/category-create`); + }} + /> + ), + [], + ); + + // Header component untuk title + const headerComponent = useMemo( + () => ( + + ), + [rightComponent], + ); + + useFocusEffect( + useCallback(() => { + pagination.onRefresh(); + }, []), + ); + + // Render item untuk daftar kategori donasi + const renderItem = useCallback( + ({ item, index }: { item: any; index: number }) => ( + + ), + [], + ); + + // Buat komponen-komponen pagination + const { ListEmptyComponent, ListFooterComponent } = + createPaginationComponents({ + loading: pagination.loading, + refreshing: pagination.refreshing, + listData: pagination.listData, + searchQuery: search, + emptyMessage: "Belum ada data", + emptySearchMessage: "Tidak ada hasil pencarian", + isInitialLoad: pagination.isInitialLoad, + skeletonCount: PAGINATION_DEFAULT_TAKE, + skeletonHeight: 80, + }); + + return ( + item.id?.toString() || `fallback-${item.id}`} + headerComponent={headerComponent} + ListEmptyComponent={ListEmptyComponent} + ListFooterComponent={ListFooterComponent} + onEndReached={pagination.loadMore} + refreshControl={ + + } + /> + ); +} diff --git a/screens/Admin/Donation/ScreenDonationListDisbursementOfFunds.tsx b/screens/Admin/Donation/ScreenDonationListDisbursementOfFunds.tsx new file mode 100644 index 0000000..9e8ed7e --- /dev/null +++ b/screens/Admin/Donation/ScreenDonationListDisbursementOfFunds.tsx @@ -0,0 +1,82 @@ +import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle"; +import NewWrapper from "@/components/_ShareComponent/NewWrapper"; +import { PAGINATION_DEFAULT_TAKE } from "@/constants/constans-value"; +import { createPaginationComponents } from "@/helpers/paginationHelpers"; +import { usePagination } from "@/hooks/use-pagination"; +import { apiAdminDonationDisbursementOfFundsListById } from "@/service/api-admin/api-admin-donation"; +import { useLocalSearchParams } from "expo-router"; +import { useCallback, useMemo } from "react"; +import { RefreshControl } from "react-native"; +import Admin_BoxDonationListDisbursementOfFunds from "./BoxDonationListDisbursementOfFunds"; + +export function Admin_ScreenDonationListDisbursementOfFunds() { + const { id } = useLocalSearchParams(); + + // Gunakan hook pagination + const pagination = usePagination({ + fetchFunction: async (page, searchQuery) => { + const response = await apiAdminDonationDisbursementOfFundsListById({ + id: id as string, + category: "get-all", + page: String(page), + }); + + if (response.success) { + return { data: response.data }; + } else { + return { data: [] }; + } + }, + pageSize: PAGINATION_DEFAULT_TAKE, + searchQuery: "", + dependencies: [id], + }); + + // Header component dengan back button dan title + const headerComponent = useMemo( + () => , + [], + ); + + // Render item untuk daftar pencairan dana + const renderItem = useCallback( + ({ item, index }: { item: any; index: number }) => ( + + ), + [], + ); + + // Buat komponen-komponen pagination + const { ListEmptyComponent, ListFooterComponent } = + createPaginationComponents({ + loading: pagination.loading, + refreshing: pagination.refreshing, + listData: pagination.listData, + searchQuery: "", + emptyMessage: "Belum ada data", + emptySearchMessage: "Tidak ada hasil pencarian", + isInitialLoad: pagination.isInitialLoad, + skeletonCount: PAGINATION_DEFAULT_TAKE, + skeletonHeight: 100, + }); + + return ( + item.id?.toString() || `fallback-${item.id}`} + headerComponent={headerComponent} + ListEmptyComponent={ListEmptyComponent} + ListFooterComponent={ListFooterComponent} + onEndReached={pagination.loadMore} + refreshControl={ + + } + /> + ); +} diff --git a/screens/Admin/Donation/ScreenDonationListOfDonatur.tsx b/screens/Admin/Donation/ScreenDonationListOfDonatur.tsx new file mode 100644 index 0000000..a35b427 --- /dev/null +++ b/screens/Admin/Donation/ScreenDonationListOfDonatur.tsx @@ -0,0 +1,134 @@ +import { SelectCustom } from "@/components"; +import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle"; +import NewWrapper from "@/components/_ShareComponent/NewWrapper"; +import { PAGINATION_DEFAULT_TAKE } from "@/constants/constans-value"; +import { createPaginationComponents } from "@/helpers/paginationHelpers"; +import { usePagination } from "@/hooks/use-pagination"; +import { apiAdminDonationListOfDonatur } from "@/service/api-admin/api-admin-donation"; +import { apiMasterTransaction } from "@/service/api-client/api-master"; +import { useLocalSearchParams } from "expo-router"; +import _ from "lodash"; +import { useCallback, useEffect, useMemo, useState } from "react"; +import { RefreshControl, View } from "react-native"; +import Admin_BoxDonationListOfDonatur from "./BoxDonationListOfDonatur"; + +export function Admin_ScreenDonationListOfDonatur() { + const { id } = useLocalSearchParams(); + const [selectValue, setSelectValue] = useState(null); + const [selectedStatus, setSelectedStatus] = useState(null); + const [master, setMaster] = useState([]); + + // Gunakan hook pagination + const pagination = usePagination({ + fetchFunction: async (page, searchQuery) => { + const response = await apiAdminDonationListOfDonatur({ + id: id as string, + status: selectedStatus as any, + page: String(page), + }); + + if (response.success) { + return { data: response.data }; + } else { + return { data: [] }; + } + }, + pageSize: PAGINATION_DEFAULT_TAKE, + searchQuery: "", + dependencies: [id, selectedStatus], + }); + + // Load master data untuk select option + useEffect(() => { + onLoadMaster(); + }, []); + + const onLoadMaster = async () => { + try { + const response = await apiMasterTransaction(); + if (response.success) { + setMaster(response.data); + } + } catch (error) { + console.log("[ERROR]", error); + setMaster([]); + } + }; + + // Komponen select untuk filter status + const searchComponent = useMemo( + () => ( + + ({ + label: item.name, + value: item.id, + })) + } + value={selectValue} + onChange={(value: any) => { + setSelectValue(value); + const nameSelected = master.find((item: any) => item.id === value); + const statusChooses = _.lowerCase(nameSelected?.name); + setSelectedStatus(statusChooses); + }} + styleContainer={{ width: "100%", marginBottom: 0 }} + allowClear + /> + + ), + [master, selectValue], + ); + + // Header component dengan back button dan select filter + const headerComponent = useMemo( + () => , + [searchComponent], + ); + + // Render item untuk daftar donatur + const renderItem = useCallback( + ({ item, index }: { item: any; index: number }) => ( + + ), + [], + ); + + // Buat komponen-komponen pagination + const { ListEmptyComponent, ListFooterComponent } = + createPaginationComponents({ + loading: pagination.loading, + refreshing: pagination.refreshing, + listData: pagination.listData, + searchQuery: "", + emptyMessage: "Belum ada data", + emptySearchMessage: "Tidak ada hasil pencarian", + isInitialLoad: pagination.isInitialLoad, + skeletonCount: PAGINATION_DEFAULT_TAKE, + skeletonHeight: 100, + }); + + return ( + item.id?.toString() || `fallback-${item.id}`} + headerComponent={headerComponent} + ListEmptyComponent={ListEmptyComponent} + ListFooterComponent={ListFooterComponent} + onEndReached={pagination.loadMore} + refreshControl={ + + } + /> + ); +} diff --git a/screens/Admin/Donation/ScreenDonationStatus.tsx b/screens/Admin/Donation/ScreenDonationStatus.tsx new file mode 100644 index 0000000..bfa5a07 --- /dev/null +++ b/screens/Admin/Donation/ScreenDonationStatus.tsx @@ -0,0 +1,112 @@ +import { ActionIcon, SearchInput, TextCustom } from "@/components"; +import AdminComp_BoxTitle from "@/components/_ShareComponent/Admin/BoxTitlePage"; +import AdminTableValue from "@/components/_ShareComponent/Admin/TableValue"; +import NewWrapper from "@/components/_ShareComponent/NewWrapper"; +import { + ICON_SIZE_BUTTON, + PAGINATION_DEFAULT_TAKE, +} from "@/constants/constans-value"; +import { createPaginationComponents } from "@/helpers/paginationHelpers"; +import { usePagination } from "@/hooks/use-pagination"; +import { apiAdminDonation } from "@/service/api-admin/api-admin-donation"; +import { Octicons } from "@expo/vector-icons"; +import { router, useLocalSearchParams } from "expo-router"; +import _ from "lodash"; +import { useCallback, useMemo, useState } from "react"; +import { RefreshControl } from "react-native"; +import Admin_BoxDonationStatus from "./BoxDonationStatus"; + +export function Admin_ScreenDonationStatus() { + const { status } = useLocalSearchParams(); + const [search, setSearch] = useState(""); + + // Gunakan hook pagination + const pagination = usePagination({ + fetchFunction: async (page, searchQuery) => { + const response = await apiAdminDonation({ + category: status as "publish" | "review" | "reject", + search: searchQuery, + page: String(page), + }); + + if (response.success) { + return { data: response.data }; + } else { + return { data: [] }; + } + }, + pageSize: PAGINATION_DEFAULT_TAKE, + searchQuery: search, + dependencies: [status], + }); + + // Komponen search input untuk header + const rightComponent = useMemo( + () => ( + setSearch(value)} + /> + ), + [search], + ); + + // Render item untuk daftar donasi + const renderItem = useCallback( + ({ item, index }: { item: any; index: number }) => ( + + ), + [status], + ); + + // Header component dengan judul status donasi + const headerComponent = useMemo( + () => ( + + ), + [status, rightComponent], + ); + + // Buat komponen-komponen pagination + const { ListEmptyComponent, ListFooterComponent } = + createPaginationComponents({ + loading: pagination.loading, + refreshing: pagination.refreshing, + listData: pagination.listData, + searchQuery: search, + emptyMessage: "Belum ada data", + emptySearchMessage: "Tidak ada hasil pencarian", + isInitialLoad: pagination.isInitialLoad, + skeletonCount: PAGINATION_DEFAULT_TAKE, + skeletonHeight: 120, + }); + + return ( + item.id?.toString() || `fallback-${item.id}`} + headerComponent={headerComponent} + ListEmptyComponent={ListEmptyComponent} + ListFooterComponent={ListFooterComponent} + onEndReached={pagination.loadMore} + refreshControl={ + + } + /> + ); +} diff --git a/screens/Admin/Voting/ScreenEventTypeOfEvent.tsx b/screens/Admin/Voting/ScreenEventTypeOfEvent.tsx index c2945be..d922603 100644 --- a/screens/Admin/Voting/ScreenEventTypeOfEvent.tsx +++ b/screens/Admin/Voting/ScreenEventTypeOfEvent.tsx @@ -49,7 +49,7 @@ export function Admin_ScreenEventTypeOfEvent() { // Header component untuk title const headerComponent = useMemo( () => ( - + ), [rightComponent], ); diff --git a/service/api-admin/api-admin-donation.ts b/service/api-admin/api-admin-donation.ts index a0aa925..c187c46 100644 --- a/service/api-admin/api-admin-donation.ts +++ b/service/api-admin/api-admin-donation.ts @@ -4,13 +4,15 @@ import { apiConfig } from "../api-config"; export async function apiAdminDonation({ category, search, + page = "1", }: { category: "dashboard" | "publish" | "review" | "reject"; search?: string; + page?: string; }) { try { const response = await apiConfig.get( - `/mobile/admin/donation?category=${category}&search=${search}` + `/mobile/admin/donation?category=${category}&search=${search}&page=${page}` ); return response.data; } catch (error) { @@ -131,12 +133,16 @@ export async function apiAdminDonationDisbursementOfFundsCreated({ export async function apiAdminDonationDisbursementOfFundsListById({ id, category, + page = "1", }: { id: string; - category: "get-all" | "get-one" + category: "get-all" | "get-one"; + page?: string; }) { try { - const response = await apiConfig.get(`/mobile/admin/donation/${id}/disbursement?category=${category}`); + const response = await apiConfig.get( + `/mobile/admin/donation/${id}/disbursement?category=${category}&page=${page}` + ); return response.data; } catch (error) { throw error; diff --git a/service/api-admin/api-master-admin.ts b/service/api-admin/api-master-admin.ts index 8c3b1b6..ff5d588 100644 --- a/service/api-admin/api-master-admin.ts +++ b/service/api-admin/api-master-admin.ts @@ -193,9 +193,9 @@ export async function apiAdminMasterTypeOfEventUpdate({ // ================== START DONATION ================== // -export async function apiAdminMasterDonationCategory() { +export async function apiAdminMasterDonationCategory({ page = "1" }: { page?: string }) { try { - const response = await apiConfig.get(`/mobile/admin/master/donation`); + const response = await apiConfig.get(`/mobile/admin/master/donation?page=${page}`); return response.data; } catch (error) { throw error;