From da82a02a459a94370db0bc840ecf42c68d39047e Mon Sep 17 00:00:00 2001 From: bagasbanuna Date: Wed, 21 Jan 2026 15:39:08 +0800 Subject: [PATCH] Investment UI (Admin & User) - app/(application)/(user)/investment/[id]/(transaction-flow)/invoice.tsx - app/(application)/admin/investment/[id]/[status]/index.tsx - app/(application)/admin/investment/[id]/[status]/transaction-detail.tsx - app/(application)/admin/investment/[status]/status.tsx API Service (Admin) - service/api-admin/api-admin-investment.ts ### No issue --- .../[id]/(transaction-flow)/invoice.tsx | 11 +- .../admin/investment/[id]/[status]/index.tsx | 196 ++++++++++-------- .../[id]/[status]/transaction-detail.tsx | 23 +- .../admin/investment/[status]/status.tsx | 4 +- service/api-admin/api-admin-investment.ts | 1 + 5 files changed, 131 insertions(+), 104 deletions(-) diff --git a/app/(application)/(user)/investment/[id]/(transaction-flow)/invoice.tsx b/app/(application)/(user)/investment/[id]/(transaction-flow)/invoice.tsx index e76a5a1..fc9c00d 100644 --- a/app/(application)/(user)/investment/[id]/(transaction-flow)/invoice.tsx +++ b/app/(application)/(user)/investment/[id]/(transaction-flow)/invoice.tsx @@ -27,7 +27,6 @@ import Toast from "react-native-toast-message"; export default function InvestmentInvoice() { const { id } = useLocalSearchParams(); - console.log("[ID]", id); const [data, setData] = useState({}); const [image, setImage] = useState({ name: "", @@ -49,7 +48,6 @@ export default function InvestmentInvoice() { category: "invoice", }); - console.log("[RES INVOICE]", JSON.stringify(response.data, null, 2)); setData(response.data); } catch (error) { console.log("[ERROR]", error); @@ -64,8 +62,6 @@ export default function InvestmentInvoice() { imageUri: image?.uri, }); - console.log("[RESPONSE UPLOAD IMAGE]", responseUploadImage); - if (!responseUploadImage?.data?.id) { Toast.show({ type: "error", @@ -83,10 +79,6 @@ export default function InvestmentInvoice() { }); if (response.success) { - console.log( - "[RESPONSE UPDATE]", - JSON.stringify(response.data, null, 2) - ); Toast.show({ type: "success", text1: "Berhasil mengunggah bukti transfer", @@ -210,7 +202,6 @@ export default function InvestmentInvoice() { pickFile({ allowedType: "image", setImageUri(file: any) { - console.log("[IMAGE]", file); setImage(file); }, }); @@ -224,7 +215,7 @@ export default function InvestmentInvoice() { { handlerSubmitUpdate(); }} diff --git a/app/(application)/admin/investment/[id]/[status]/index.tsx b/app/(application)/admin/investment/[id]/[status]/index.tsx index a3dff44..f0ce822 100644 --- a/app/(application)/admin/investment/[id]/[status]/index.tsx +++ b/app/(application)/admin/investment/[id]/[status]/index.tsx @@ -20,6 +20,7 @@ import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButt import AdminButtonReject from "@/components/_ShareComponent/Admin/ButtonReject"; import AdminButtonReview from "@/components/_ShareComponent/Admin/ButtonReview"; import { GridSpan_4_8 } from "@/components/_ShareComponent/GridSpan_4_8"; +import CustomSkeleton from "@/components/_ShareComponent/SkeletonCustom"; import ReportBox from "@/components/Box/ReportBox"; import { MainColor } from "@/constants/color-palet"; import { ICON_SIZE_BUTTON } from "@/constants/constans-value"; @@ -28,6 +29,7 @@ import { apiAdminInvestmentDetailById, } from "@/service/api-admin/api-admin-investment"; import { colorBadgeStatus } from "@/utils/colorBadge"; +import { countDownAndCondition } from "@/utils/countDownAndCondition"; import { formatCurrencyDisplay } from "@/utils/formatCurrencyDisplay"; import { router, useFocusEffect, useLocalSearchParams } from "expo-router"; import _ from "lodash"; @@ -40,91 +42,41 @@ export default function AdminInvestmentDetail() { const [data, setData] = React.useState(null); const [isLoading, setLoading] = React.useState(false); + const [remind, setRemind] = React.useState({ + sisa: 0, + reminder: false, + }); useFocusEffect( React.useCallback(() => { onLoadData(); - }, [id]) + }, [id]), ); const onLoadData = async () => { try { const response = await apiAdminInvestmentDetailById({ id: id as string }); - // console.log("[GETONE INVEST]", JSON.stringify(response, null, 2)); if (response.success) { setData(response.data); + + const duration = response?.data?.MasterPencarianInvestor?.name; + const publishTime = response?.data?.countDown; + + const countDown = countDownAndCondition({ + duration: duration, + publishTime: publishTime + }); + + setRemind({ + sisa: countDown.durationDay, + reminder: countDown.reminder, + }); } } catch (error) { - console.log(error); + console.log("Error", error); } }; - const listData = [ - { - label: "Username", - value: (data && data?.author?.username) || "-", - }, - { - label: "Judul", - value: (data && data?.title) || "-", - }, - { - label: "Status", - value: - data && data?.MasterStatusInvestasi?.name ? ( - - {_.startCase(data?.MasterStatusInvestasi?.name as string)} - - ) : ( - "-" - ), - }, - { - label: "Dana Dibutuhkan", - value: `Rp. ${ - (data && data?.targetDana && formatCurrencyDisplay(data?.targetDana)) || - "-" - }`, - }, - { - label: "Harga Perlembar", - value: `Rp. ${ - (data && - data?.hargaLembar && - formatCurrencyDisplay(data?.hargaLembar)) || - "-" - }`, - }, - { - label: "Total Lembar", - value: - (data && - data?.totalLembar && - formatCurrencyDisplay(data?.totalLembar)) || - "-", - }, - { - label: "ROI", - value: `${(data && data?.roi && data?.roi) || 0} %`, - }, - { - label: "Pembagian Deviden", - value: (data && data?.MasterPembagianDeviden?.name) + " bulan" || "-", - }, - { - label: "Jadwal Pembagian", - value: (data && data?.MasterPeriodeDeviden?.name) || "-", - }, - { - label: "Pencarian Investor", - value: (data && data?.MasterPencarianInvestor?.name) + " hari" || "-", - }, - ]; - const handlerSubmitPublish = async () => { try { setLoading(true); @@ -134,7 +86,6 @@ export default function AdminInvestmentDetail() { data: data, }); - // console.log("[GET ON INVEST]", JSON.stringify(response, null, 2)); if (!response.success) { Toast.show({ type: "error", @@ -164,6 +115,16 @@ export default function AdminInvestmentDetail() { /> ); + if (!data) { + return ( + <> + + + + + ); + } + return ( <> @@ -187,7 +148,8 @@ export default function AdminInvestmentDetail() { label={Sisa Saham} value={ - {data && formatCurrencyDisplay(data && data?.sisaLembar)} lembar + {data && formatCurrencyDisplay(data && data?.sisaLembar)}{" "} + lembar } /> @@ -206,13 +168,15 @@ export default function AdminInvestmentDetail() { - {listData.map((item, i) => ( - {item.label}} - value={{item.value}} - /> - ))} + {listData({ data: data, reminder: remind.reminder })?.map( + (item, i) => ( + {item.label}} + value={{item.value}} + /> + ), + )} @@ -230,7 +194,7 @@ export default function AdminInvestmentDetail() { } onPress={() => { router.push( - `/(application)/(file)/${data?.prospektusFileId}` + `/(application)/(file)/${data?.prospektusFileId}`, ); }} > @@ -259,7 +223,7 @@ export default function AdminInvestmentDetail() { } onPress={() => { router.push( - `/(application)/(file)/${item?.fileId}` + `/(application)/(file)/${item?.fileId}`, ); }} > @@ -299,8 +263,8 @@ export default function AdminInvestmentDetail() { onReject={() => { router.push( `/admin/investment/${id}/reject-input?status=${_.lowerCase( - data?.MasterStatusInvestasi?.name - )}` + data?.MasterStatusInvestasi?.name, + )}`, ); }} /> @@ -343,3 +307,67 @@ export default function AdminInvestmentDetail() { ); } + +const listData = ({ data, reminder }: { data: any; reminder: boolean }) => [ + { + label: "Username", + value: (data && data?.author?.username) || "-", + }, + { + label: "Judul", + value: (data && data?.title) || "-", + }, + { + label: "Status", + value: + data && data?.MasterStatusInvestasi?.name ? ( + + {reminder + ? "Periode Berakhir" + : _.startCase(data?.MasterStatusInvestasi?.name as string)} + + ) : ( + "-" + ), + }, + { + label: "Dana Dibutuhkan", + value: `Rp. ${ + (data && data?.targetDana && formatCurrencyDisplay(data?.targetDana)) || + "-" + }`, + }, + { + label: "Harga Perlembar", + value: `Rp. ${ + (data && data?.hargaLembar && formatCurrencyDisplay(data?.hargaLembar)) || + "-" + }`, + }, + { + label: "Total Lembar", + value: + (data && data?.totalLembar && formatCurrencyDisplay(data?.totalLembar)) || + "-", + }, + { + label: "ROI", + value: `${(data && data?.roi && data?.roi) || 0} %`, + }, + { + label: "Pembagian Deviden", + value: (data && data?.MasterPembagianDeviden?.name) + " bulan" || "-", + }, + { + label: "Jadwal Pembagian", + value: (data && data?.MasterPeriodeDeviden?.name) || "-", + }, + { + label: "Pencarian Investor", + value: (data && data?.MasterPencarianInvestor?.name) + " hari" || "-", + }, +]; diff --git a/app/(application)/admin/investment/[id]/[status]/transaction-detail.tsx b/app/(application)/admin/investment/[id]/[status]/transaction-detail.tsx index 6bab71c..583c248 100644 --- a/app/(application)/admin/investment/[id]/[status]/transaction-detail.tsx +++ b/app/(application)/admin/investment/[id]/[status]/transaction-detail.tsx @@ -13,6 +13,7 @@ import AdminBackButtonAntTitle from "@/components/_ShareComponent/Admin/BackButt import { GridSpan_4_8 } from "@/components/_ShareComponent/GridSpan_4_8"; import GridTwoView from "@/components/_ShareComponent/GridTwoView"; import { MainColor } from "@/constants/color-palet"; +import { useAuth } from "@/hooks/use-auth"; import { apiAdminInvestmentGetOneInvoiceById, apiAdminInvestmentUpdateInvoice, @@ -25,6 +26,7 @@ import { useCallback, useState } from "react"; import Toast from "react-native-toast-message"; export default function AdminInvestmentTransactionDetail() { + const { user } = useAuth(); const { id } = useLocalSearchParams(); const [data, setData] = useState(null); const [isLoading, setLoading] = useState(false); @@ -32,7 +34,7 @@ export default function AdminInvestmentTransactionDetail() { useFocusEffect( useCallback(() => { onLoadData(); - }, [id]) + }, [id]), ); const onLoadData = async () => { @@ -40,7 +42,6 @@ export default function AdminInvestmentTransactionDetail() { const response = await apiAdminInvestmentGetOneInvoiceById({ id: id as string, }); - // console.log("[RESPONSE]", JSON.stringify(response, null, 2)); if (response.success) { setData(response.data); } @@ -92,7 +93,7 @@ export default function AdminInvestmentTransactionDetail() { router.push( - `/(application)/(image)/preview-image/${data?.imageId}` + `/(application)/(image)/preview-image/${data?.imageId}`, ) } > @@ -109,6 +110,13 @@ export default function AdminInvestmentTransactionDetail() { }: { category: "accept" | "deny"; }) => { + if (!user?.id) { + Toast.show({ + type: "error", + text1: "Gagal update status transaksi", + }); + return; + } try { setLoading(true); const response = await apiAdminInvestmentUpdateInvoice({ @@ -117,11 +125,10 @@ export default function AdminInvestmentTransactionDetail() { data: { investasiId: data?.investasiId, lembarTerbeli: data?.lembarTerbeli, + senderId: user?.id as any, }, }); - // console.log("[RESPONSE SUBMIT]", JSON.stringify(response, null, 2)); - if (!response.success) { Toast.show({ type: "error", @@ -153,6 +160,7 @@ export default function AdminInvestmentTransactionDetail() { styleRight={{ paddingLeft: 10 }} leftIcon={ { AlertDefaultSystem({ @@ -198,8 +207,8 @@ export default function AdminInvestmentTransactionDetail() { } else if (data?.StatusInvoice?.name === "Gagal") { return ( <> - router.back()}> - Gagal + router.back()}> + Transaksi telah gagal ); diff --git a/app/(application)/admin/investment/[status]/status.tsx b/app/(application)/admin/investment/[status]/status.tsx index d3c644c..c84c8ad 100644 --- a/app/(application)/admin/investment/[status]/status.tsx +++ b/app/(application)/admin/investment/[status]/status.tsx @@ -22,8 +22,6 @@ import { Divider } from "react-native-paper"; export default function AdminInvestmentStatus() { const { status } = useLocalSearchParams(); - console.log("[STATUS]", status); - const [listData, setListData] = React.useState(null); const [loadData, setLoadingData] = React.useState(false); const [search, setSearch] = React.useState(""); @@ -41,7 +39,7 @@ export default function AdminInvestmentStatus() { category: status as "publish" | "review" | "reject", search, }); - console.log("[LIST DATA]", JSON.stringify(response, null, 2)); + if (response.success) { setListData(response.data); } diff --git a/service/api-admin/api-admin-investment.ts b/service/api-admin/api-admin-investment.ts index 3709237..510bd9c 100644 --- a/service/api-admin/api-admin-investment.ts +++ b/service/api-admin/api-admin-investment.ts @@ -98,6 +98,7 @@ export async function apiAdminInvestmentUpdateInvoice({ data: { investasiId: string; lembarTerbeli: number; + senderId: string }; }) { try {