diff --git a/app/(application)/(user)/_layout.tsx b/app/(application)/(user)/_layout.tsx index 8019694..1270427 100644 --- a/app/(application)/(user)/_layout.tsx +++ b/app/(application)/(user)/_layout.tsx @@ -449,7 +449,7 @@ export default function UserLayout() { }} /> ( diff --git a/app/(application)/(user)/donation/(tabs)/index.tsx b/app/(application)/(user)/donation/(tabs)/index.tsx index 0e7f85e..5d843a1 100644 --- a/app/(application)/(user)/donation/(tabs)/index.tsx +++ b/app/(application)/(user)/donation/(tabs)/index.tsx @@ -23,7 +23,9 @@ export default function DonationBeranda() { const onLoadData = async () => { try { setLoadList(true); - const response = await apiDonationGetAll(); + const response = await apiDonationGetAll({ + category: "beranda" + }); console.log("[RES GET ALL]", JSON.stringify(response.data, null, 2)); setList(response.data); @@ -44,7 +46,7 @@ export default function DonationBeranda() { {loadList ? ( ) : _.isEmpty(list) ? ( - Belum ada data + Belum ada donasi ) : ( list?.map((item: any, index: number) => ( diff --git a/app/(application)/(user)/donation/(tabs)/my-donation.tsx b/app/(application)/(user)/donation/(tabs)/my-donation.tsx index b1cc12a..34697aa 100644 --- a/app/(application)/(user)/donation/(tabs)/my-donation.tsx +++ b/app/(application)/(user)/donation/(tabs)/my-donation.tsx @@ -3,74 +3,124 @@ import { BaseBox, DummyLandscapeImage, Grid, + LoaderCustom, StackCustom, TextCustom, ViewWrapper, } from "@/components"; +import { useAuth } from "@/hooks/use-auth"; import { dummyMasterStatusTransaction } from "@/lib/dummy-data/_master/status-transaction"; -import { router } from "expo-router"; +import { apiDonationGetAll } from "@/service/api-client/api-donation"; +import { formatCurrencyDisplay } from "@/utils/formatCurrencyDisplay"; +import { Href, router, useFocusEffect } from "expo-router"; +import _ from "lodash"; +import { useCallback, useState } from "react"; import { View } from "react-native"; export default function DonationMyDonation() { - const randomStatusData = Array.from({ length: 10 }, () => { - const randomIndex = Math.floor( - Math.random() * dummyMasterStatusTransaction.length - ); - return dummyMasterStatusTransaction[randomIndex]; - }); + const { user } = useAuth(); + const [list, setList] = useState(null); + const [loadList, setLoadList] = useState(false); - const handlePress = (value: string) => { - if (value === "menunggu") { - router.push(`/donation/${value}/(transaction-flow)/123/invoice`); - } else if (value === "proses") { - router.push(`/donation/${value}/(transaction-flow)/123/process`); - } else if (value === "berhasil") { - router.push(`/donation/${value}/(transaction-flow)/123/success`); - } else if (value === "gagal") { - router.push(`/donation/${value}/(transaction-flow)/123/failed`); + useFocusEffect( + useCallback(() => { + onLoadData(); + }, []) + ); + + const onLoadData = async () => { + try { + setLoadList(true); + const response = await apiDonationGetAll({ + category: "my-donation", + authorId: user?.id, + }); + console.log( + "[RES GET MY DONATION]", + JSON.stringify(response.data, null, 2) + ); + + setList(response.data); + } catch (error) { + console.log("[ERROR]", error); + } finally { + setLoadList(false); + } + }; + + const handlePress = ({ + invoiceId, + donationId, + status, + }: { + invoiceId: string; + donationId: string; + status: string; + }) => { + const url: Href = `../${donationId}/(transaction-flow)/${invoiceId}/invoice`; + if (status === "menunggu") { + router.push(url); + } else if (status === "proses") { + router.push(url); + } else if (status === "berhasil") { + router.push(url); + } else if (status === "gagal") { + router.push(url); } }; return ( - {randomStatusData.map((item, index) => ( - { - handlePress(item.value); - }} - > - - - - - - - - - - - - Judul Donasi: Lorem ipsum dolor sit amet consectetur - adipisicing elit. + {loadList ? ( + + ) : _.isEmpty(list) ? ( + + Belum ada transaksi + + ) : ( + list?.map((item, index) => ( + { + handlePress({ + status: _.lowerCase(item.statusInvoice), + invoiceId: item.id, + donationId: item.donasiId, + }); + }} + > + + + + + + + + + + + {item.title || "-"} - - - Donasi Saya + - Rp. 7.500.000 + Rp. {formatCurrencyDisplay(item.nominal)} - - - {item.label} - - - - - - ))} + + + {item.statusInvoice} + + + + + + )) + )} ); } diff --git a/app/(application)/(user)/donation/[id]/(transaction-flow)/[transaction]/failed.tsx b/app/(application)/(user)/donation/[id]/(transaction-flow)/[invoiceId]/failed.tsx similarity index 100% rename from app/(application)/(user)/donation/[id]/(transaction-flow)/[transaction]/failed.tsx rename to app/(application)/(user)/donation/[id]/(transaction-flow)/[invoiceId]/failed.tsx diff --git a/app/(application)/(user)/donation/[id]/(transaction-flow)/[transaction]/invoice.tsx b/app/(application)/(user)/donation/[id]/(transaction-flow)/[invoiceId]/invoice.tsx similarity index 91% rename from app/(application)/(user)/donation/[id]/(transaction-flow)/[transaction]/invoice.tsx rename to app/(application)/(user)/donation/[id]/(transaction-flow)/[invoiceId]/invoice.tsx index 51d723e..9a973af 100644 --- a/app/(application)/(user)/donation/[id]/(transaction-flow)/[transaction]/invoice.tsx +++ b/app/(application)/(user)/donation/[id]/(transaction-flow)/[invoiceId]/invoice.tsx @@ -13,12 +13,15 @@ import { MainColor } from "@/constants/color-palet"; import { router, useLocalSearchParams } from "expo-router"; export default function DonationInvoice() { - const { id, transaction } = useLocalSearchParams(); + const { invoiceId } = useLocalSearchParams(); + console.log("invoiceId", invoiceId); return ( <> - + Nama BANK @@ -97,7 +100,7 @@ export default function DonationInvoice() { { - router.push(`/donation/${id}/(transaction-flow)/process`); + router.push(`/donation/${invoiceId}/(transaction-flow)/process`); }} > Saya Sudah Transfer diff --git a/app/(application)/(user)/donation/[id]/(transaction-flow)/[transaction]/process.tsx b/app/(application)/(user)/donation/[id]/(transaction-flow)/[invoiceId]/process.tsx similarity index 100% rename from app/(application)/(user)/donation/[id]/(transaction-flow)/[transaction]/process.tsx rename to app/(application)/(user)/donation/[id]/(transaction-flow)/[invoiceId]/process.tsx diff --git a/app/(application)/(user)/donation/[id]/(transaction-flow)/[transaction]/success.tsx b/app/(application)/(user)/donation/[id]/(transaction-flow)/[invoiceId]/success.tsx similarity index 100% rename from app/(application)/(user)/donation/[id]/(transaction-flow)/[transaction]/success.tsx rename to app/(application)/(user)/donation/[id]/(transaction-flow)/[invoiceId]/success.tsx diff --git a/app/(application)/(user)/donation/[id]/(transaction-flow)/index.tsx b/app/(application)/(user)/donation/[id]/(transaction-flow)/index.tsx index 1af686a..4a40b3d 100644 --- a/app/(application)/(user)/donation/[id]/(transaction-flow)/index.tsx +++ b/app/(application)/(user)/donation/[id]/(transaction-flow)/index.tsx @@ -9,15 +9,44 @@ import { } from "@/components"; import { MainColor } from "@/constants/color-palet"; import { ICON_SIZE_SMALL } from "@/constants/constans-value"; +import { LOCAL_STORAGE_KEY } from "@/constants/local-storage-key"; +import { formatCurrencyDisplay } from "@/utils/formatCurrencyDisplay"; import { Ionicons } from "@expo/vector-icons"; +import AsyncStorage from "@react-native-async-storage/async-storage"; import { router, useLocalSearchParams } from "expo-router"; +import { useState } from "react"; export default function InvestmentInputDonation() { const { id } = useLocalSearchParams(); + const [nominal, setNominal] = useState(0); + + const handlerSubmit = async () => { + try { + console.log("jumlah", nominal); + await AsyncStorage.setItem( + LOCAL_STORAGE_KEY.transactionDonation, + JSON.stringify({ nominal: nominal.toString() }) + ); + router.replace(`/donation/${id}/select-bank`); + } catch (error) { + console.log("[ERROR]", error); + } + }; + + const displayJumlah = formatCurrencyDisplay(nominal); + + const handleChangeCurrency = (text: string) => { + const numeric = text.replace(/\D/g, ""); + setNominal(Number(numeric)); + }; + const bottomComponent = ( router.replace(`/donation/${id}/select-bank`)} + disabled={nominal < 10000 || nominal === 0} + onPress={() => { + handlerSubmit(); + }} > Lanjutan @@ -27,7 +56,7 @@ export default function InvestmentInputDonation() { <> {listData.map((item, i) => ( - + setNominal(item.value)}> @@ -51,6 +80,8 @@ export default function InvestmentInputDonation() { label="Nominal lainnya" placeholder="0" iconLeft="Rp." + value={displayJumlah} + onChangeText={(value) => handleChangeCurrency(value)} /> Minimal donasi Rp. 10.000 diff --git a/app/(application)/(user)/donation/[id]/(transaction-flow)/select-bank.tsx b/app/(application)/(user)/donation/[id]/(transaction-flow)/select-bank.tsx index 4564373..aee0b52 100644 --- a/app/(application)/(user)/donation/[id]/(transaction-flow)/select-bank.tsx +++ b/app/(application)/(user)/donation/[id]/(transaction-flow)/select-bank.tsx @@ -5,24 +5,93 @@ import { ViewWrapper, } from "@/components"; import { RadioCustom, RadioGroup } from "@/components/Radio/RadioCustom"; +import { LOCAL_STORAGE_KEY } from "@/constants/local-storage-key"; +import { useAuth } from "@/hooks/use-auth"; import { dummyMasterBank } from "@/lib/dummy-data/_master/bank"; -import { router, useLocalSearchParams } from "expo-router"; -import { useState } from "react"; +import { apiDonationCreateInvoice } from "@/service/api-client/api-donation"; +import { apiMasterBank } from "@/service/api-client/api-master"; +import AsyncStorage from "@react-native-async-storage/async-storage"; +import { router, useFocusEffect, useLocalSearchParams } from "expo-router"; +import _ from "lodash"; +import { useCallback, useEffect, useState } from "react"; export default function DonationSelectBank() { - const { id, transaction } = useLocalSearchParams(); - const [value, setValue] = useState(""); + const { user } = useAuth(); + const { id } = useLocalSearchParams(); + + console.log("id", id); + const [select, setSelect] = useState(""); + const [listBank, setListBank] = useState([]); + const [isLoading, setIsLoading] = useState(false); + + useEffect(() => { + loadListBank(); + }, []); + + const loadListBank = async () => { + try { + const response = await apiMasterBank(); + + setListBank(response.data); + } catch (error) { + console.log("[ERROR]", error); + setListBank([]); + } + }; + + const handlerSubmit = async () => { + try { + setIsLoading(true); + const dataStorage = await AsyncStorage.getItem( + LOCAL_STORAGE_KEY.transactionDonation + ); + + if (dataStorage) { + const storage = JSON.parse(dataStorage); + const newData = { + ...storage, + bankId: select, + authorId: user?.id, + }; + + console.log("[NEW DATA]", newData); + + const response = await apiDonationCreateInvoice({ + id: id as string, + data: newData, + }); + console.log("[RESPONSE CREATE>>]", response); + + if (response.success) { + const invoiceId = response.data.id; + + const delStorage = await AsyncStorage.removeItem( + LOCAL_STORAGE_KEY.transactionDonation + ); + + console.log("[DEL STORAGE]", delStorage); + router.replace( + `/(application)/(user)/donation/[id]/(transaction-flow)/${invoiceId}/invoice` + ); + } else { + console.log("[FAILED]", response); + } + } + } catch (error) { + console.log("[ERROR]", error); + } finally { + setIsLoading(false); + } + }; const buttonSubmit = () => { return ( <> - router.replace( - `/(application)/(user)/donation/${id}/(transaction-flow)/${transaction}/invoice` - ) - } + isLoading={isLoading} + disabled={!select} + onPress={() => handlerSubmit()} > Pilih @@ -32,12 +101,14 @@ export default function DonationSelectBank() { }; return ( - - {dummyMasterBank.map((item) => ( - - - - ))} + + {_.isEmpty(listBank) + ? [] + : listBank?.map((item: any, index: number) => ( + + + + ))} ); diff --git a/app/(application)/(user)/donation/[id]/infromation-fundrising.tsx b/app/(application)/(user)/donation/[id]/infromation-fundrising.tsx index 0fa3da8..43fc02b 100644 --- a/app/(application)/(user)/donation/[id]/infromation-fundrising.tsx +++ b/app/(application)/(user)/donation/[id]/infromation-fundrising.tsx @@ -1,15 +1,13 @@ /* eslint-disable react-hooks/exhaustive-deps */ import { AvatarComp, - AvatarCustom, BaseBox, ButtonCustom, - CenterCustom, Grid, LoaderCustom, Spacing, TextCustom, - ViewWrapper, + ViewWrapper } from "@/components"; import Donation_BoxPublish from "@/screens/Donation/BoxPublish"; import { apiDonationFundrising } from "@/service/api-client/api-donation"; diff --git a/service/api-client/api-donation.ts b/service/api-client/api-donation.ts index c9e98cc..7023b50 100644 --- a/service/api-client/api-donation.ts +++ b/service/api-client/api-donation.ts @@ -103,20 +103,63 @@ export async function apiDonationUpdateData({ } } -export async function apiDonationGetAll() { +export async function apiDonationGetAll({ + category, + authorId, +}: { + category: "beranda" | "my-donation"; + authorId?: string; +}) { + const authorQuery = authorId ? `&authorId=${authorId}` : ""; try { - const response = await apiConfig.get(`/mobile/donation`); + const response = await apiConfig.get( + `/mobile/donation?category=${category}${authorQuery}` + ); return response.data; } catch (error) { throw error; } } -export async function apiDonationFundrising({id}: {id: string}) { - try { - const response = await apiConfig.get(`/mobile/donation/${id}/fundrising`); - return response.data; - } catch (error) { - throw error; - } +export async function apiDonationFundrising({ id }: { id: string }) { + try { + const response = await apiConfig.get(`/mobile/donation/${id}/fundrising`); + return response.data; + } catch (error) { + throw error; + } +} + +export async function apiDonationCreateDonatur({ + id, + data, +}: { + id: string; + data: any; +}) { + try { + const response = await apiConfig.post(`/mobile/donation/${id}/donatur`, { + data: data, + }); + return response.data; + } catch (error) { + throw error; + } +} + +export async function apiDonationCreateInvoice({ + id, + data, +}: { + id: string; + data: any; +}) { + try { + const response = await apiConfig.post(`/mobile/donation/${id}/invoice`, { + data: data, + }); + return response.data; + } catch (error) { + throw error; + } }