Saya telah melakukan serangkaian perubahan penting dalam pengembangan aplikasi HIPMI Mobile, khususnya dalam modul
Donasi. Berikut adalah ringkasan perubahan yang telah dilakukan:
1. Menerapkan sistem pagination pada berbagai komponen layar donasi:
- ScreenBeranda.tsx
- ScreenMyDonation.tsx
- ScreenRecapOfNews.tsx
- ScreenListOfNews.tsx
- ScreenListOfDonatur.tsx
- ScreenFundDisbursement.tsx
2. Memperbarui fungsi-fungsi API untuk mendukung parameter page:
- apiDonationGetAll
- apiDonationGetNewsById
- apiDonationListOfDonaturById
- apiDonationDisbursementOfFundsListById
3. Mengganti komponen wrapper lama (ViewWrapper) dengan NewWrapper yang mendukung sistem pagination
4. Membuat komponen layar terpisah untuk meningkatkan modularitas kode
5. Memperbaiki berbagai error yang terjadi, termasuk masalah dengan import komponen dan struktur JSX
### No Issue
This commit is contained in:
21
screens/Donation/BoxNews.tsx
Normal file
21
screens/Donation/BoxNews.tsx
Normal file
@@ -0,0 +1,21 @@
|
||||
import { BaseBox, Grid, Spacing, TextCustom } from "@/components";
|
||||
import { formatChatTime } from "@/utils/formatChatTime";
|
||||
|
||||
export default function Donation_BoxNews({item}: {item: any}){
|
||||
return <>
|
||||
<BaseBox href={`/donation/[id]/(news)/${item?.id}`}>
|
||||
<Grid>
|
||||
<Grid.Col span={8}>
|
||||
<TextCustom truncate bold>
|
||||
{item?.title || "-"}
|
||||
</TextCustom>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={4} style={{ alignItems: "flex-end" }}>
|
||||
<TextCustom size="small">
|
||||
{formatChatTime(item?.createdAt)}
|
||||
</TextCustom>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
</BaseBox>
|
||||
</>
|
||||
}
|
||||
62
screens/Donation/ScreenBeranda.tsx
Normal file
62
screens/Donation/ScreenBeranda.tsx
Normal file
@@ -0,0 +1,62 @@
|
||||
import FloatingButton from "@/components/Button/FloatingButton";
|
||||
import NewWrapper from "@/components/_ShareComponent/NewWrapper";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import { PAGINATION_DEFAULT_TAKE } from "@/constants/constans-value";
|
||||
import { createPaginationComponents } from "@/helpers/paginationHelpers";
|
||||
import { usePagination } from "@/hooks/use-pagination";
|
||||
import Donation_BoxPublish from "@/screens/Donation/BoxPublish";
|
||||
import { apiDonationGetAll } from "@/service/api-client/api-donation";
|
||||
import { router } from "expo-router";
|
||||
import { RefreshControl } from "react-native";
|
||||
|
||||
export default function Donation_ScreenBeranda() {
|
||||
const pagination = usePagination({
|
||||
fetchFunction: async (page, search) => {
|
||||
return await apiDonationGetAll({
|
||||
category: "beranda",
|
||||
page: String(page),
|
||||
}).then((res) => {
|
||||
console.log("RES", JSON.stringify(res, null, 2));
|
||||
return res;
|
||||
});
|
||||
},
|
||||
pageSize: PAGINATION_DEFAULT_TAKE, // Sesuaikan dengan jumlah item per halaman yang diinginkan
|
||||
onError: (error) => console.error("[ERROR] Fetch event beranda:", error),
|
||||
dependencies: [],
|
||||
});
|
||||
|
||||
const { ListEmptyComponent, ListFooterComponent } =
|
||||
createPaginationComponents({
|
||||
loading: pagination.loading,
|
||||
refreshing: pagination.refreshing,
|
||||
listData: pagination.listData,
|
||||
isInitialLoad: pagination.isInitialLoad,
|
||||
emptyMessage: "Belum ada donasi",
|
||||
skeletonCount: PAGINATION_DEFAULT_TAKE,
|
||||
skeletonHeight: 150,
|
||||
});
|
||||
|
||||
return (
|
||||
<NewWrapper
|
||||
listData={pagination.listData}
|
||||
renderItem={({ item }) => (
|
||||
<Donation_BoxPublish data={item} id={item.id} />
|
||||
)}
|
||||
onEndReached={pagination.loadMore}
|
||||
ListEmptyComponent={ListEmptyComponent}
|
||||
ListFooterComponent={ListFooterComponent}
|
||||
refreshControl={
|
||||
<RefreshControl
|
||||
refreshing={pagination.refreshing}
|
||||
onRefresh={pagination.onRefresh}
|
||||
tintColor={MainColor.yellow}
|
||||
colors={[MainColor.yellow]}
|
||||
/>
|
||||
}
|
||||
hideFooter
|
||||
floatingButton={
|
||||
<FloatingButton onPress={() => router.push("/donation/create")} />
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
174
screens/Donation/ScreenFundDisbursement.tsx
Normal file
174
screens/Donation/ScreenFundDisbursement.tsx
Normal file
@@ -0,0 +1,174 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
import {
|
||||
ActionIcon,
|
||||
BaseBox,
|
||||
Grid,
|
||||
InformationBox,
|
||||
Spacing,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
} from "@/components";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import { usePagination } from "@/hooks/use-pagination";
|
||||
import {
|
||||
apiDonationDisbursementOfFundsListById,
|
||||
apiDonationGetOne,
|
||||
} from "@/service/api-client/api-donation";
|
||||
import { formatCurrencyDisplay } from "@/utils/formatCurrencyDisplay";
|
||||
import { Feather } from "@expo/vector-icons";
|
||||
import dayjs from "dayjs";
|
||||
import { router, useLocalSearchParams } from "expo-router";
|
||||
import _ from "lodash";
|
||||
import React, { useState } from "react";
|
||||
import { RefreshControl, View } from "react-native";
|
||||
import { createPaginationComponents } from "@/helpers/paginationHelpers";
|
||||
import { PAGINATION_DEFAULT_TAKE } from "@/constants/constans-value";
|
||||
import NewWrapper from "@/components/_ShareComponent/NewWrapper";
|
||||
import { Divider } from "react-native-paper";
|
||||
|
||||
interface Donation_ScreenFundDisbursementProps {
|
||||
donationId: string;
|
||||
}
|
||||
|
||||
export default function Donation_ScreenFundDisbursement({
|
||||
donationId,
|
||||
}: Donation_ScreenFundDisbursementProps) {
|
||||
const [data, setData] = useState({
|
||||
totalPencairan: 0,
|
||||
akumulasiPencairan: 0,
|
||||
});
|
||||
|
||||
// Ambil data utama (total pencairan, dll) terpisah dari pagination
|
||||
React.useEffect(() => {
|
||||
const onLoadData = async () => {
|
||||
try {
|
||||
const responseData = await apiDonationGetOne({
|
||||
id: donationId,
|
||||
category: "permanent",
|
||||
});
|
||||
|
||||
if (responseData.success) {
|
||||
setData({
|
||||
totalPencairan: responseData.data.totalPencairan,
|
||||
akumulasiPencairan: responseData.data.akumulasiPencairan,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("[ERROR]", error);
|
||||
}
|
||||
};
|
||||
|
||||
onLoadData();
|
||||
}, [donationId]);
|
||||
|
||||
const pagination = usePagination({
|
||||
fetchFunction: async (page) => {
|
||||
return await apiDonationDisbursementOfFundsListById({
|
||||
id: donationId,
|
||||
page: String(page),
|
||||
});
|
||||
},
|
||||
pageSize: PAGINATION_DEFAULT_TAKE, // Sesuaikan dengan jumlah item per halaman dari API
|
||||
dependencies: [donationId],
|
||||
});
|
||||
|
||||
const renderItem = ({ item, index }: { item: any; index: number }) => (
|
||||
<BaseBox key={index}>
|
||||
<StackCustom>
|
||||
<Grid>
|
||||
<Grid.Col span={8}>
|
||||
<TextCustom bold>{item?.title}</TextCustom>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={4} style={{ alignItems: "flex-end" }}>
|
||||
<TextCustom size="small">
|
||||
{dayjs(item?.createdAt).format("DD MMM YYYY")}
|
||||
</TextCustom>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
<TextCustom>{item?.deskripsi}</TextCustom>
|
||||
{/* <Spacing /> */}
|
||||
<Divider />
|
||||
<Grid>
|
||||
<Grid.Col span={8} style={{ alignSelf: "center" }}>
|
||||
<TextCustom bold size={"large"}>
|
||||
Rp. {formatCurrencyDisplay(item?.nominalCair)}
|
||||
</TextCustom>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={4} style={{ alignItems: "flex-end" }}>
|
||||
<ActionIcon
|
||||
icon={<Feather name="file-text" color={MainColor.black} />}
|
||||
onPress={() => {
|
||||
router.navigate(
|
||||
`/(application)/(image)/preview-image/${item?.imageId}`,
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
{/*
|
||||
<ButtonCenteredOnly
|
||||
onPress={() => {
|
||||
router.navigate(
|
||||
`/(application)/(image)/preview-image/${item?.imageId}`,
|
||||
);
|
||||
}}
|
||||
icon="file-text"
|
||||
>
|
||||
Bukti Transaksi
|
||||
</ButtonCenteredOnly> */}
|
||||
</StackCustom>
|
||||
</BaseBox>
|
||||
);
|
||||
|
||||
const { ListEmptyComponent, ListFooterComponent } =
|
||||
createPaginationComponents({
|
||||
loading: pagination.loading,
|
||||
refreshing: pagination.refreshing,
|
||||
listData: pagination.listData,
|
||||
isInitialLoad: pagination.isInitialLoad,
|
||||
emptyMessage: "Belum ada data",
|
||||
skeletonCount: PAGINATION_DEFAULT_TAKE,
|
||||
skeletonHeight: 150,
|
||||
});
|
||||
|
||||
// Komponen header yang akan ditampilkan di atas daftar
|
||||
const ListHeaderComponent = (
|
||||
<View>
|
||||
<InformationBox text="Pencairan dana akan dilakukan oleh Admin HIPMI tanpa campur tangan pihak manapun, jika berita pencairan dana dibawah tidak sesuai dengan kabar yang diberikan oleh PENGGALANG DANA. Maka pegguna lain dapat melaporkannya pada Admin HIPMI !" />
|
||||
<BaseBox>
|
||||
<Grid>
|
||||
<Grid.Col span={6}>
|
||||
<TextCustom bold color="yellow">
|
||||
Rp. {formatCurrencyDisplay(data?.totalPencairan)}
|
||||
</TextCustom>
|
||||
<TextCustom size="small">Total Pencairan Dana</TextCustom>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={6}>
|
||||
<TextCustom bold color="yellow">
|
||||
{data?.akumulasiPencairan} kali
|
||||
</TextCustom>
|
||||
<TextCustom size="small">Akumulasi Pencairan</TextCustom>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
</BaseBox>
|
||||
</View>
|
||||
);
|
||||
|
||||
return (
|
||||
<NewWrapper
|
||||
listData={pagination.listData}
|
||||
renderItem={renderItem}
|
||||
onEndReached={pagination.loadMore}
|
||||
ListEmptyComponent={ListEmptyComponent}
|
||||
ListFooterComponent={ListFooterComponent}
|
||||
ListHeaderComponent={ListHeaderComponent}
|
||||
refreshControl={
|
||||
<RefreshControl
|
||||
refreshing={pagination.refreshing}
|
||||
onRefresh={pagination.onRefresh}
|
||||
/>
|
||||
}
|
||||
hideFooter
|
||||
/>
|
||||
);
|
||||
}
|
||||
98
screens/Donation/ScreenListOfDonatur.tsx
Normal file
98
screens/Donation/ScreenListOfDonatur.tsx
Normal file
@@ -0,0 +1,98 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
import {
|
||||
BaseBox,
|
||||
Grid,
|
||||
LoaderCustom,
|
||||
Spacing,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
} from "@/components";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import { usePagination } from "@/hooks/use-pagination";
|
||||
import { apiDonationListOfDonaturById } from "@/service/api-client/api-donation";
|
||||
import { formatCurrencyDisplay } from "@/utils/formatCurrencyDisplay";
|
||||
import { FontAwesome6 } from "@expo/vector-icons";
|
||||
import dayjs from "dayjs";
|
||||
import { RefreshControl } from "react-native";
|
||||
import { createPaginationComponents } from "@/helpers/paginationHelpers";
|
||||
import { PAGINATION_DEFAULT_TAKE } from "@/constants/constans-value";
|
||||
import NewWrapper from "@/components/_ShareComponent/NewWrapper";
|
||||
|
||||
interface Donation_ScreenListOfDonaturProps {
|
||||
donationId: string;
|
||||
}
|
||||
|
||||
export default function Donation_ScreenListOfDonatur({
|
||||
donationId,
|
||||
}: Donation_ScreenListOfDonaturProps) {
|
||||
const pagination = usePagination({
|
||||
fetchFunction: async (page) => {
|
||||
return await apiDonationListOfDonaturById({
|
||||
id: donationId,
|
||||
page: String(page),
|
||||
});
|
||||
},
|
||||
pageSize: PAGINATION_DEFAULT_TAKE, // Sesuaikan dengan jumlah item per halaman dari API
|
||||
dependencies: [donationId],
|
||||
});
|
||||
|
||||
const renderItem = ({ item, index }: { item: any; index: number }) => (
|
||||
<BaseBox key={index}>
|
||||
<Grid>
|
||||
<Grid.Col
|
||||
span={3}
|
||||
style={{ alignItems: "center", justifyContent: "center" }}
|
||||
>
|
||||
<FontAwesome6
|
||||
name="face-smile-wink"
|
||||
size={50}
|
||||
style={{ color: MainColor.yellow }}
|
||||
/>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={9}>
|
||||
<TextCustom bold size="large">
|
||||
{item?.Author?.username || "-"}
|
||||
</TextCustom>
|
||||
<Spacing />
|
||||
<StackCustom gap={"xs"}>
|
||||
<TextCustom size={"small"}>Berdonas sebesar </TextCustom>
|
||||
<TextCustom bold size="large" color="yellow">
|
||||
Rp. {formatCurrencyDisplay(item?.nominal)}
|
||||
</TextCustom>
|
||||
<TextCustom>
|
||||
{dayjs(item?.createdAt).format("DD MMM YYYY, HH:mm")}
|
||||
</TextCustom>
|
||||
</StackCustom>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
</BaseBox>
|
||||
);
|
||||
|
||||
const { ListEmptyComponent, ListFooterComponent } =
|
||||
createPaginationComponents({
|
||||
loading: pagination.loading,
|
||||
refreshing: pagination.refreshing,
|
||||
listData: pagination.listData,
|
||||
isInitialLoad: pagination.isInitialLoad,
|
||||
emptyMessage: "Belum ada donatur",
|
||||
skeletonCount: PAGINATION_DEFAULT_TAKE,
|
||||
skeletonHeight: 120,
|
||||
});
|
||||
|
||||
return (
|
||||
<NewWrapper
|
||||
hideFooter
|
||||
listData={pagination.listData}
|
||||
renderItem={renderItem}
|
||||
onEndReached={pagination.loadMore}
|
||||
ListEmptyComponent={ListEmptyComponent}
|
||||
ListFooterComponent={ListFooterComponent}
|
||||
refreshControl={
|
||||
<RefreshControl
|
||||
refreshing={pagination.refreshing}
|
||||
onRefresh={pagination.onRefresh}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
97
screens/Donation/ScreenListOfNews.tsx
Normal file
97
screens/Donation/ScreenListOfNews.tsx
Normal file
@@ -0,0 +1,97 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
import { BackButton, DrawerCustom, MenuDrawerDynamicGrid } from "@/components";
|
||||
import { IconPlus } from "@/components/_Icon";
|
||||
import NewWrapper from "@/components/_ShareComponent/NewWrapper";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import { PAGINATION_DEFAULT_TAKE } from "@/constants/constans-value";
|
||||
import { createPaginationComponents } from "@/helpers/paginationHelpers";
|
||||
import { usePagination } from "@/hooks/use-pagination";
|
||||
import { apiDonationGetNewsById } from "@/service/api-client/api-donation";
|
||||
import { router, Stack } from "expo-router";
|
||||
import { useState } from "react";
|
||||
import { RefreshControl } from "react-native";
|
||||
import Donation_BoxNews from "./BoxNews";
|
||||
|
||||
interface Donation_ScreenListOfNewsProps {
|
||||
donationId: string;
|
||||
}
|
||||
|
||||
export default function Donation_ScreenListOfNews({
|
||||
donationId,
|
||||
}: Donation_ScreenListOfNewsProps) {
|
||||
const [openDrawer, setOpenDrawer] = useState(false);
|
||||
|
||||
const pagination = usePagination({
|
||||
fetchFunction: async (page) => {
|
||||
return await apiDonationGetNewsById({
|
||||
id: donationId,
|
||||
category: "get-all",
|
||||
page: String(page),
|
||||
});
|
||||
},
|
||||
pageSize: PAGINATION_DEFAULT_TAKE, // Sesuaikan dengan jumlah item per halaman dari API
|
||||
dependencies: [donationId],
|
||||
});
|
||||
|
||||
const renderItem = ({ item, index }: { item: any; index: number }) => (
|
||||
<Donation_BoxNews key={index} item={item} />
|
||||
);
|
||||
|
||||
const { ListEmptyComponent, ListFooterComponent } =
|
||||
createPaginationComponents({
|
||||
loading: pagination.loading,
|
||||
refreshing: pagination.refreshing,
|
||||
listData: pagination.listData,
|
||||
isInitialLoad: pagination.isInitialLoad,
|
||||
emptyMessage: "Tidak ada kabar",
|
||||
skeletonCount: PAGINATION_DEFAULT_TAKE,
|
||||
skeletonHeight: 80,
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<Stack.Screen
|
||||
options={{
|
||||
title: "Daftar Kabar",
|
||||
headerLeft: () => <BackButton />,
|
||||
}}
|
||||
/>
|
||||
<NewWrapper
|
||||
listData={pagination.listData}
|
||||
renderItem={renderItem}
|
||||
onEndReached={pagination.loadMore}
|
||||
ListEmptyComponent={ListEmptyComponent}
|
||||
ListFooterComponent={ListFooterComponent}
|
||||
refreshControl={
|
||||
<RefreshControl
|
||||
refreshing={pagination.refreshing}
|
||||
onRefresh={pagination.onRefresh}
|
||||
tintColor={MainColor.yellow}
|
||||
colors={[MainColor.yellow]}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
|
||||
<DrawerCustom
|
||||
isVisible={openDrawer}
|
||||
closeDrawer={() => setOpenDrawer(false)}
|
||||
height={"auto"}
|
||||
>
|
||||
<MenuDrawerDynamicGrid
|
||||
data={[
|
||||
{
|
||||
icon: <IconPlus />,
|
||||
label: "Tambah Berita",
|
||||
path: `/donation/${donationId}/(news)/add-news`,
|
||||
},
|
||||
]}
|
||||
onPressItem={(item) => {
|
||||
console.log("PATH ", item.path);
|
||||
router.navigate(item.path as any);
|
||||
setOpenDrawer(false);
|
||||
}}
|
||||
/>
|
||||
</DrawerCustom>
|
||||
</>
|
||||
);
|
||||
}
|
||||
152
screens/Donation/ScreenMyDonation.tsx
Normal file
152
screens/Donation/ScreenMyDonation.tsx
Normal file
@@ -0,0 +1,152 @@
|
||||
import {
|
||||
BadgeCustom,
|
||||
BaseBox,
|
||||
DummyLandscapeImage,
|
||||
Grid,
|
||||
StackCustom,
|
||||
TextCustom,
|
||||
} from "@/components";
|
||||
import FloatingButton from "@/components/Button/FloatingButton";
|
||||
import NewWrapper from "@/components/_ShareComponent/NewWrapper";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import { PAGINATION_DEFAULT_TAKE } from "@/constants/constans-value";
|
||||
import { createPaginationComponents } from "@/helpers/paginationHelpers";
|
||||
import { useAuth } from "@/hooks/use-auth";
|
||||
import { usePagination } from "@/hooks/use-pagination";
|
||||
import { apiDonationGetAll } from "@/service/api-client/api-donation";
|
||||
import { formatCurrencyDisplay } from "@/utils/formatCurrencyDisplay";
|
||||
import { Href, router } from "expo-router";
|
||||
import _ from "lodash";
|
||||
import { RefreshControl, View } from "react-native";
|
||||
|
||||
export default function Donation_ScreenMyDonation() {
|
||||
const { user } = useAuth();
|
||||
|
||||
const pagination = usePagination({
|
||||
fetchFunction: async (page, search) => {
|
||||
if (!user?.id) {
|
||||
throw new Error("User tidak ditemukan");
|
||||
}
|
||||
|
||||
return await apiDonationGetAll({
|
||||
category: "my-donation",
|
||||
authorId: user?.id,
|
||||
page: String(page),
|
||||
});
|
||||
},
|
||||
pageSize: PAGINATION_DEFAULT_TAKE, // Sesuaikan dengan jumlah item per halaman yang diinginkan
|
||||
dependencies: [user?.id], // Reload ketika user.id berubah
|
||||
});
|
||||
|
||||
const { ListEmptyComponent, ListFooterComponent } =
|
||||
createPaginationComponents({
|
||||
loading: pagination.loading,
|
||||
refreshing: pagination.refreshing,
|
||||
listData: pagination.listData,
|
||||
isInitialLoad: pagination.isInitialLoad,
|
||||
emptyMessage: "Belum ada transaksi",
|
||||
skeletonCount: PAGINATION_DEFAULT_TAKE,
|
||||
skeletonHeight: 150,
|
||||
});
|
||||
|
||||
const handlerColor = (status: string) => {
|
||||
if (status === "menunggu") {
|
||||
return "orange";
|
||||
} else if (status === "proses") {
|
||||
return "white";
|
||||
} else if (status === "berhasil") {
|
||||
return "green";
|
||||
} else if (status === "gagal") {
|
||||
return "red";
|
||||
}
|
||||
};
|
||||
|
||||
const handlePress = ({
|
||||
invoiceId,
|
||||
donationId,
|
||||
status,
|
||||
}: {
|
||||
invoiceId: string;
|
||||
donationId: string;
|
||||
status: string;
|
||||
}) => {
|
||||
const url: Href = `../${donationId}/(transaction-flow)/${invoiceId}`;
|
||||
if (status === "menunggu") {
|
||||
router.push(`${url}/invoice`);
|
||||
} else if (status === "proses") {
|
||||
router.push(`${url}/process`);
|
||||
} else if (status === "berhasil") {
|
||||
router.push(`${url}/success`);
|
||||
} else if (status === "gagal") {
|
||||
router.push(`${url}/failed`);
|
||||
}
|
||||
};
|
||||
|
||||
const renderItem = ({ item }: { item: any }) => (
|
||||
<BaseBox
|
||||
paddingTop={7}
|
||||
paddingBottom={7}
|
||||
onPress={() => {
|
||||
handlePress({
|
||||
status: _.lowerCase(item.statusInvoice),
|
||||
invoiceId: item.id,
|
||||
donationId: item.donasiId,
|
||||
});
|
||||
}}
|
||||
>
|
||||
<Grid>
|
||||
<Grid.Col span={5}>
|
||||
<DummyLandscapeImage
|
||||
height={100}
|
||||
unClickPath
|
||||
imageId={item.imageId}
|
||||
/>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={1}>
|
||||
<View />
|
||||
</Grid.Col>
|
||||
<Grid.Col span={6}>
|
||||
<StackCustom>
|
||||
<TextCustom truncate={2} bold>
|
||||
{item.title || "-"}
|
||||
</TextCustom>
|
||||
|
||||
<TextCustom bold color="yellow">
|
||||
Rp. {formatCurrencyDisplay(item.nominal)}
|
||||
</TextCustom>
|
||||
|
||||
<BadgeCustom
|
||||
variant="light"
|
||||
color={handlerColor(_.lowerCase(item.statusInvoice))}
|
||||
fullWidth
|
||||
>
|
||||
{item.statusInvoice}
|
||||
</BadgeCustom>
|
||||
</StackCustom>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
</BaseBox>
|
||||
);
|
||||
|
||||
return (
|
||||
<NewWrapper
|
||||
listData={pagination.listData}
|
||||
renderItem={renderItem}
|
||||
onEndReached={pagination.loadMore}
|
||||
ListEmptyComponent={ListEmptyComponent}
|
||||
ListFooterComponent={ListFooterComponent}
|
||||
refreshControl={
|
||||
<RefreshControl
|
||||
refreshing={pagination.refreshing}
|
||||
onRefresh={pagination.onRefresh}
|
||||
tintColor={MainColor.yellow}
|
||||
colors={[MainColor.yellow]}
|
||||
/>
|
||||
}
|
||||
hideFooter
|
||||
floatingButton={
|
||||
<FloatingButton onPress={() => router.push("/donation/create")} />
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
105
screens/Donation/ScreenRecapOfNews.tsx
Normal file
105
screens/Donation/ScreenRecapOfNews.tsx
Normal file
@@ -0,0 +1,105 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
import {
|
||||
BackButton,
|
||||
DotButton,
|
||||
DrawerCustom,
|
||||
MenuDrawerDynamicGrid,
|
||||
} from "@/components";
|
||||
import { IconPlus } from "@/components/_Icon";
|
||||
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 { apiDonationGetNewsById } from "@/service/api-client/api-donation";
|
||||
import { router, Stack, useFocusEffect } from "expo-router";
|
||||
import { useCallback, useState } from "react";
|
||||
import { RefreshControl } from "react-native";
|
||||
import Donation_BoxNews from "./BoxNews";
|
||||
|
||||
interface Donation_ScreenRecapOfNewsProps {
|
||||
donationId: string;
|
||||
}
|
||||
|
||||
export default function Donation_ScreenRecapOfNews({
|
||||
donationId,
|
||||
}: Donation_ScreenRecapOfNewsProps) {
|
||||
const [openDrawer, setOpenDrawer] = useState(false);
|
||||
|
||||
const pagination = usePagination({
|
||||
fetchFunction: async (page) => {
|
||||
return await apiDonationGetNewsById({
|
||||
id: donationId,
|
||||
category: "get-all",
|
||||
page: String(page),
|
||||
});
|
||||
},
|
||||
pageSize: PAGINATION_DEFAULT_TAKE, // Sesuaikan dengan jumlah item per halaman dari API
|
||||
dependencies: [donationId],
|
||||
});
|
||||
|
||||
useFocusEffect(
|
||||
useCallback(() => {
|
||||
pagination.onRefresh();
|
||||
}, [donationId]),
|
||||
);
|
||||
|
||||
const renderItem = ({ item, index }: { item: any; index: number }) => (
|
||||
<Donation_BoxNews key={index} item={item} />
|
||||
);
|
||||
const { ListEmptyComponent, ListFooterComponent } =
|
||||
createPaginationComponents({
|
||||
loading: pagination.loading,
|
||||
refreshing: pagination.refreshing,
|
||||
listData: pagination.listData,
|
||||
isInitialLoad: pagination.isInitialLoad,
|
||||
emptyMessage: "Tidak ada kabar",
|
||||
skeletonCount: PAGINATION_DEFAULT_TAKE,
|
||||
skeletonHeight: 80,
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<Stack.Screen
|
||||
options={{
|
||||
title: "Rekap Kabar",
|
||||
headerLeft: () => <BackButton />,
|
||||
headerRight: () => <DotButton onPress={() => setOpenDrawer(true)} />,
|
||||
}}
|
||||
/>
|
||||
<NewWrapper
|
||||
listData={pagination.listData}
|
||||
renderItem={renderItem}
|
||||
onEndReached={pagination.loadMore}
|
||||
ListEmptyComponent={ListEmptyComponent}
|
||||
ListFooterComponent={ListFooterComponent}
|
||||
refreshControl={
|
||||
<RefreshControl
|
||||
refreshing={pagination.refreshing}
|
||||
onRefresh={pagination.onRefresh}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
|
||||
<DrawerCustom
|
||||
isVisible={openDrawer}
|
||||
closeDrawer={() => setOpenDrawer(false)}
|
||||
height={"auto"}
|
||||
>
|
||||
<MenuDrawerDynamicGrid
|
||||
data={[
|
||||
{
|
||||
icon: <IconPlus />,
|
||||
label: "Tambah Berita",
|
||||
path: `/donation/${donationId}/(news)/add-news`,
|
||||
},
|
||||
]}
|
||||
onPressItem={(item) => {
|
||||
console.log("PATH ", item.path);
|
||||
router.navigate(item.path as any);
|
||||
setOpenDrawer(false);
|
||||
}}
|
||||
/>
|
||||
</DrawerCustom>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -1,28 +1,29 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
import {
|
||||
LoaderCustom,
|
||||
ScrollableCustom,
|
||||
TextCustom,
|
||||
} from "@/components";
|
||||
import { ScrollableCustom } from "@/components";
|
||||
import NewWrapper from "@/components/_ShareComponent/NewWrapper";
|
||||
import { MainColor } from "@/constants/color-palet";
|
||||
import { PAGINATION_DEFAULT_TAKE } from "@/constants/constans-value";
|
||||
import { createPaginationComponents } from "@/helpers/paginationHelpers";
|
||||
import { useAuth } from "@/hooks/use-auth";
|
||||
import { usePagination } from "@/hooks/use-pagination";
|
||||
import { dummyMasterStatus } from "@/lib/dummy-data/_master/status";
|
||||
import Donasi_BoxStatus from "@/screens/Donation/BoxStatus";
|
||||
import { usePagination } from "@/hooks/use-pagination";
|
||||
import { apiDonationGetByStatus } from "@/service/api-client/api-donation";
|
||||
import { useFocusEffect } from "expo-router";
|
||||
import _ from "lodash";
|
||||
import { useCallback, useState } from "react";
|
||||
import { RefreshControl } from "react-native";
|
||||
import { createPaginationComponents } from "@/helpers/paginationHelpers";
|
||||
|
||||
interface DonationStatusProps {
|
||||
initialStatus?: string;
|
||||
}
|
||||
|
||||
export default function Donation_ScreenStatus({ initialStatus = "publish" }: DonationStatusProps) {
|
||||
export default function Donation_ScreenStatus({
|
||||
initialStatus = "publish",
|
||||
}: DonationStatusProps) {
|
||||
const { user } = useAuth();
|
||||
const [activeCategory, setActiveCategory] = useState<string | null>(initialStatus);
|
||||
const [activeCategory, setActiveCategory] = useState<string | null>(
|
||||
initialStatus,
|
||||
);
|
||||
|
||||
const pagination = usePagination({
|
||||
fetchFunction: async (page) => {
|
||||
@@ -32,18 +33,19 @@ export default function Donation_ScreenStatus({ initialStatus = "publish" }: Don
|
||||
page: String(page),
|
||||
});
|
||||
},
|
||||
pageSize: 5, // Sesuaikan dengan jumlah item per halaman dari API
|
||||
pageSize: PAGINATION_DEFAULT_TAKE, // Sesuaikan dengan jumlah item per halaman dari API
|
||||
dependencies: [user?.id, activeCategory],
|
||||
});
|
||||
|
||||
useFocusEffect(
|
||||
useCallback(() => {
|
||||
pagination.onRefresh();
|
||||
}, [user?.id, activeCategory])
|
||||
}, [user?.id, activeCategory]),
|
||||
);
|
||||
|
||||
const handlePress = (item: any) => {
|
||||
setActiveCategory(item.value);
|
||||
pagination.reset();
|
||||
};
|
||||
|
||||
const scrollComponent = (
|
||||
@@ -59,21 +61,19 @@ export default function Donation_ScreenStatus({ initialStatus = "publish" }: Don
|
||||
);
|
||||
|
||||
const renderItem = ({ item, index }: { item: any; index: number }) => (
|
||||
<Donasi_BoxStatus
|
||||
data={item}
|
||||
status={activeCategory as string}
|
||||
/>
|
||||
<Donasi_BoxStatus data={item} status={activeCategory as string} />
|
||||
);
|
||||
|
||||
const { ListEmptyComponent, ListFooterComponent } = createPaginationComponents({
|
||||
loading: pagination.loading,
|
||||
refreshing: pagination.refreshing,
|
||||
listData: pagination.listData,
|
||||
isInitialLoad: pagination.isInitialLoad,
|
||||
emptyMessage: `Tidak ada data ${activeCategory}`,
|
||||
skeletonCount: 5,
|
||||
skeletonHeight: 200,
|
||||
});
|
||||
const { ListEmptyComponent, ListFooterComponent } =
|
||||
createPaginationComponents({
|
||||
loading: pagination.loading,
|
||||
refreshing: pagination.refreshing,
|
||||
listData: pagination.listData,
|
||||
isInitialLoad: pagination.isInitialLoad,
|
||||
emptyMessage: `Tidak ada data ${activeCategory}`,
|
||||
skeletonCount: 5,
|
||||
skeletonHeight: 120,
|
||||
});
|
||||
|
||||
return (
|
||||
<NewWrapper
|
||||
@@ -83,13 +83,15 @@ export default function Donation_ScreenStatus({ initialStatus = "publish" }: Don
|
||||
ListEmptyComponent={ListEmptyComponent}
|
||||
ListFooterComponent={ListFooterComponent}
|
||||
refreshControl={
|
||||
<RefreshControl
|
||||
refreshing={pagination.refreshing}
|
||||
onRefresh={pagination.onRefresh}
|
||||
<RefreshControl
|
||||
refreshing={pagination.refreshing}
|
||||
onRefresh={pagination.onRefresh}
|
||||
tintColor={MainColor.yellow}
|
||||
colors={[MainColor.yellow]}
|
||||
/>
|
||||
}
|
||||
hideFooter
|
||||
headerComponent={scrollComponent}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user