Donation – User

- app/(application)/(user)/donation/(tabs)/index.tsx
- app/(application)/(user)/donation/(tabs)/my-donation.tsx
- app/(application)/(user)/donation/[id]/(transaction-flow)/index.tsx

Donation – Admin
- app/(application)/admin/donation/[id]/disbursement-of-funds.tsx

Image Preview
- app/(application)/(image)/preview-image/[id]/index.tsx

### No Issue
This commit is contained in:
2026-01-27 17:42:14 +08:00
parent 07e64c335e
commit 71e45d06cc
5 changed files with 74 additions and 21 deletions

View File

@@ -1,8 +1,10 @@
import { CenterCustom, TextCustom, ViewWrapper } from "@/components"; import { CenterCustom, TextCustom, ViewWrapper } from "@/components";
import API_STRORAGE from "@/constants/base-url-api-strorage"; import API_STRORAGE from "@/constants/base-url-api-strorage";
import { MainColor } from "@/constants/color-palet";
import { Image } from "expo-image"; import { Image } from "expo-image";
import { useLocalSearchParams } from "expo-router"; import { useLocalSearchParams } from "expo-router";
import React, { useState } from "react"; import React, { useState } from "react";
import { View } from "react-native";
export default function PreviewImage() { export default function PreviewImage() {
const { id } = useLocalSearchParams(); const { id } = useLocalSearchParams();
@@ -11,18 +13,48 @@ export default function PreviewImage() {
return ( return (
<ViewWrapper> <ViewWrapper>
{id ? ( {id ? (
<Image <View
onLoad={() => { style={{
setIsLoading(false); width: "100%",
height: "100%",
position: "relative",
}} }}
source={ >
isLoading {/* Main Image */}
? require("@/assets/images/loading.gif") <Image
: API_STRORAGE.GET({ fileId: id as string }) onLoad={() => {
} setIsLoading(false);
contentFit="contain" }}
style={{ width: "100%", height: "100%" }} source={API_STRORAGE.GET({ fileId: id as string })}
/> contentFit="contain"
style={{ width: "100%", height: "100%" }}
// placeholder={require("@/assets/images/loading.gif")}
/>
{/* Custom Loader Overlay */}
{isLoading && (
<View
style={{
position: "absolute",
top: 0,
left: 0,
right: 0,
bottom: 0,
justifyContent: "center",
alignItems: "center",
backgroundColor: MainColor.darkblue,
zIndex: 1,
opacity: 0.5,
}}
>
<Image
source={require("@/assets/images/loading.gif")}
contentFit="contain"
style={{ width: 60, height: 60 }}
/>
</View>
)}
</View>
) : ( ) : (
<CenterCustom> <CenterCustom>
<TextCustom>File not found</TextCustom> <TextCustom>File not found</TextCustom>

View File

@@ -26,7 +26,6 @@ export default function DonationBeranda() {
const response = await apiDonationGetAll({ const response = await apiDonationGetAll({
category: "beranda" category: "beranda"
}); });
console.log("[RES GET ALL]", JSON.stringify(response.data, null, 2));
setList(response.data); setList(response.data);
} catch (error) { } catch (error) {

View File

@@ -16,6 +16,7 @@ import { Href, router, useFocusEffect } from "expo-router";
import _ from "lodash"; import _ from "lodash";
import { useCallback, useState } from "react"; import { useCallback, useState } from "react";
import { View } from "react-native"; import { View } from "react-native";
import Toast from "react-native-toast-message";
export default function DonationMyDonation() { export default function DonationMyDonation() {
const { user } = useAuth(); const { user } = useAuth();
@@ -25,20 +26,25 @@ export default function DonationMyDonation() {
useFocusEffect( useFocusEffect(
useCallback(() => { useCallback(() => {
onLoadData(); onLoadData();
}, [user?.id]) }, [user?.id]),
); );
const onLoadData = async () => { const onLoadData = async () => {
if (!user?.id) {
Toast.show({
type: "error",
text1: "Load data gagal, user tidak ditemukan",
});
return;
}
try { try {
setLoadList(true); setLoadList(true);
const response = await apiDonationGetAll({ const response = await apiDonationGetAll({
category: "my-donation", category: "my-donation",
authorId: user?.id, authorId: user?.id,
}); });
console.log(
"[RES GET MY DONATION]",
JSON.stringify(response.data, null, 2)
);
setList(response.data); setList(response.data);
} catch (error) { } catch (error) {

View File

@@ -10,21 +10,32 @@ import {
import { MainColor } from "@/constants/color-palet"; import { MainColor } from "@/constants/color-palet";
import { ICON_SIZE_SMALL } from "@/constants/constans-value"; import { ICON_SIZE_SMALL } from "@/constants/constans-value";
import { LOCAL_STORAGE_KEY } from "@/constants/local-storage-key"; import { LOCAL_STORAGE_KEY } from "@/constants/local-storage-key";
import { useAuth } from "@/hooks/use-auth";
import { formatCurrencyDisplay } from "@/utils/formatCurrencyDisplay"; import { formatCurrencyDisplay } from "@/utils/formatCurrencyDisplay";
import { Ionicons } from "@expo/vector-icons"; import { Ionicons } from "@expo/vector-icons";
import AsyncStorage from "@react-native-async-storage/async-storage"; import AsyncStorage from "@react-native-async-storage/async-storage";
import { router, useLocalSearchParams } from "expo-router"; import { router, useLocalSearchParams } from "expo-router";
import { useState } from "react"; import { useState } from "react";
import Toast from "react-native-toast-message";
export default function InvestmentInputDonation() { export default function InvestmentInputDonation() {
const { user } = useAuth();
const { id } = useLocalSearchParams(); const { id } = useLocalSearchParams();
const [nominal, setNominal] = useState<number>(0); const [nominal, setNominal] = useState<number>(0);
const handlerSubmit = async () => { const handlerSubmit = async () => {
if (!user?.id) {
Toast.show({
type: "error",
text1: "User tidak ditemukan",
});
return;
}
try { try {
await AsyncStorage.setItem( await AsyncStorage.setItem(
LOCAL_STORAGE_KEY.transactionDonation, LOCAL_STORAGE_KEY.transactionDonation,
JSON.stringify({ nominal: nominal.toString() }) JSON.stringify({ nominal: nominal.toString() }),
); );
router.replace(`/donation/${id}/select-bank`); router.replace(`/donation/${id}/select-bank`);
} catch (error) { } catch (error) {

View File

@@ -14,7 +14,11 @@ import {
} from "@/components"; } from "@/components";
import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle"; import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButtonAntTitle";
import DIRECTORY_ID from "@/constants/directory-id"; import DIRECTORY_ID from "@/constants/directory-id";
import { apiAdminDonationDetailById, apiAdminDonationDisbursementOfFundsCreated } from "@/service/api-admin/api-admin-donation"; import { useAuth } from "@/hooks/use-auth";
import {
apiAdminDonationDetailById,
apiAdminDonationDisbursementOfFundsCreated,
} from "@/service/api-admin/api-admin-donation";
import { uploadFileService } from "@/service/upload-service"; import { uploadFileService } from "@/service/upload-service";
import { formatCurrencyDisplay } from "@/utils/formatCurrencyDisplay"; import { formatCurrencyDisplay } from "@/utils/formatCurrencyDisplay";
import pickFile from "@/utils/pickFile"; import pickFile from "@/utils/pickFile";
@@ -25,7 +29,7 @@ import Toast from "react-native-toast-message";
export default function AdminDonationDisbursementOfFunds() { export default function AdminDonationDisbursementOfFunds() {
const { id } = useLocalSearchParams(); const { id } = useLocalSearchParams();
const { user } = useAuth();
const [data, setData] = React.useState<any | null>(null); const [data, setData] = React.useState<any | null>(null);
const [isLoading, setIsLoading] = React.useState(false); const [isLoading, setIsLoading] = React.useState(false);
@@ -40,7 +44,7 @@ export default function AdminDonationDisbursementOfFunds() {
useFocusEffect( useFocusEffect(
React.useCallback(() => { React.useCallback(() => {
onLoadData(); onLoadData();
}, [id]) }, [id]),
); );
const onLoadData = async () => { const onLoadData = async () => {
@@ -94,6 +98,7 @@ export default function AdminDonationDisbursementOfFunds() {
const newData = { const newData = {
...value, ...value,
authorId: user?.id,
imageId: imageId, imageId: imageId,
}; };