Files
hipmi-mobile/screens/Donation/ScreenFundDisbursement.tsx
bagasbanuna 243313b8eb feat: Complete User Phase 8 Donation screens + add PADDING_INLINE to all list/recap screens
- Migrate 25 donation screens to OS_Wrapper (tabs, list, detail, forms, transaction flow)
- Add contentPadding={PADDING_INLINE} to 7 list/recap screens for consistent spacing
- Migrate crowdfunding screen to OS_Wrapper
- Fix voting tabs layout height to use OS_IOS_HEIGHT/OS_ANDROID_HEIGHT constants
- Migrate news detail screen to OS_Wrapper
- Update TASK-005 progress to 73% complete (104 files migrated)

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-04-13 16:24:14 +08:00

177 lines
5.4 KiB
TypeScript

/* eslint-disable react-hooks/exhaustive-deps */
import {
ActionIcon,
BaseBox,
Grid,
InformationBox,
OS_Wrapper,
Spacing,
StackCustom,
TextCustom,
} from "@/components";
import { MainColor } from "@/constants/color-palet";
import { PADDING_INLINE } from "@/constants/constans-value";
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 { 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 (
<OS_Wrapper
contentPadding={PADDING_INLINE}
listData={pagination.listData}
renderItem={renderItem}
onEndReached={pagination.loadMore}
ListEmptyComponent={ListEmptyComponent}
ListFooterComponent={ListFooterComponent}
ListHeaderComponent={ListHeaderComponent}
refreshControl={
<RefreshControl
refreshing={pagination.refreshing}
onRefresh={pagination.onRefresh}
/>
}
hideFooter
/>
);
}