fix: investasi

deskripsi:
- fix use server menjadi API pada:
src/app/api/investasi/[id]/invoice/route.ts
src/app/dev/(user)/investasi/transaksi/invoice/[id]/page.tsx
src/app/dev/(user)/investasi/transaksi/metode-pembayaran/[id]/page.tsx
src/app/dev/(user)/investasi/transaksi/proses-transaksi/[id]/page.tsx
src/app_modules/investasi/_lib/api_fetch_new_investasi.ts
src/app_modules/investasi/_ui/transaksi/ui_invoice.tsx
src/app_modules/investasi/_ui/transaksi/ui_metode_pembayaran.tsx
src/app_modules/investasi/_ui/transaksi/ui_proses_transaksi.tsx
src/app_modules/investasi/_view/transaksi/view_invoice.tsx
src/app_modules/investasi/_view/transaksi/view_metode_pembayaran.tsx
src/app_modules/investasi/_view/transaksi/view_proses_transaksi.tsx

No Issue
This commit is contained in:
2025-06-04 17:50:17 +08:00
parent 5c3fe551ae
commit 7a95395fe9
11 changed files with 209 additions and 95 deletions

View File

@@ -0,0 +1,55 @@
import { NextResponse } from "next/server";
import { prisma } from "@/lib";
export async function GET(
request: Request,
context: { params: { id: string } }
) {
try {
const { id } = context.params;
const data = await prisma.investasi_Invoice.findFirst({
where: {
id: id,
},
include: {
MasterBank: true,
StatusInvoice: true,
Investasi: {
include: {
MasterPembagianDeviden: true,
MasterPencarianInvestor: true,
MasterPeriodeDeviden: true,
ProspektusInvestasi: true,
Investasi_Invoice: {
where: {
statusInvoiceId: "1",
},
},
},
},
Author: {
include: {
Profile: true,
},
},
},
});
const { ...allData } = data;
const Investor = data?.Investasi?.Investasi_Invoice;
const result = { ...allData, Investor };
return NextResponse.json({
success: true,
message: "Berhasil mendapatkan data invoice",
data: result,
});
} catch (error) {
console.error("Error get invoice", error);
return NextResponse.json({
success: false,
message: "Gagal mendapatkan data invoice, coba lagi nanti ",
reason: (error as Error).message,
});
}
}

View File

@@ -1,13 +1,9 @@
import { investasi_funGetOneInvoiceById } from "@/app_modules/investasi/_fun/get/fun_get_one_invoice_by_id";
import { Investasi_UiInvoice } from "@/app_modules/investasi/_ui";
export default async function Page({ params }: { params: { id: string } }) {
const invoiceId = params.id;
const dataInvoice = await investasi_funGetOneInvoiceById({ invoiceId: invoiceId });
export default async function Page() {
return (
<>
<Investasi_UiInvoice dataInvoice={dataInvoice as any} />
<Investasi_UiInvoice />
</>
);
}

View File

@@ -1,13 +1,9 @@
import { funGlobal_getAllBank } from "@/app_modules/_global/fun/get/fun_get_all_bank";
import { Investasi_UiMetodePembayaran } from "@/app_modules/investasi/_ui";
export default async function Page({ params }: { params: { id: string } }) {
const investasiId = params.id;
const listBank = await funGlobal_getAllBank();
export default async function Page() {
return (
<>
<Investasi_UiMetodePembayaran listBank={listBank} investasiId={investasiId} />
<Investasi_UiMetodePembayaran />
</>
);
}

View File

@@ -1,13 +1,9 @@
import { funGlobal_getNomorAdmin } from "@/app_modules/_global/fun/get";
import { Investasi_UiProsesTransaksi } from "@/app_modules/investasi/_ui";
export default async function Page({ params }: { params: { id: string } }) {
const invoiceId = params.id;
const nomorAdmin = await funGlobal_getNomorAdmin();
export default async function Page() {
return (
<>
<Investasi_UiProsesTransaksi nomorAdmin={nomorAdmin} />
<Investasi_UiProsesTransaksi />
</>
);
}

View File

@@ -3,6 +3,7 @@ export {
apiNewGetOneInvestasiById,
apiGetInvestorById,
apiGetOneSahamInvestasiById,
apiGetInvoiceById,
};
const apiFetchGetAllInvestasi = async ({ page }: { page: string }) => {
@@ -156,3 +157,45 @@ const apiGetOneSahamInvestasiById = async ({
throw error; // Re-throw the error to handle it in the calling function
}
};
const apiGetInvoiceById = async ({
id,
}: {
id: string;
}) => {
try {
// Fetch token from cookie
const { token } = await fetch("/api/get-cookie").then((res) => res.json());
if (!token) {
console.error("No token found");
return null;
}
const response = await fetch(`/api/investasi/${id}/invoice`, {
method: "GET",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
Authorization: `Bearer ${token}`,
},
});
// Check if the response is OK
if (!response.ok) {
const errorData = await response.json().catch(() => null);
console.error(
"Failed to get list investor",
response.statusText,
errorData
);
throw new Error(errorData?.message || "Failed to get list investor");
}
// Return the JSON response
return await response.json();
} catch (error) {
console.error("Error get list investor", error);
throw error; // Re-throw the error to handle it in the calling function
}
};

View File

@@ -2,7 +2,6 @@
import { useAtom } from "jotai";
import { Investasi_ViewInvoice } from "../../_view";
import { Component_Header } from "@/app_modules/_global/component/new/component_header";
import UI_NewLayoutTamplate, {
UI_NewChildren,
@@ -15,34 +14,12 @@ import { useRouter } from "next/navigation";
import { useState } from "react";
import { gs_investas_menu } from "../../g_state";
export function Investasi_UiInvoice({ dataInvoice }: { dataInvoice: any }) {
export function Investasi_UiInvoice() {
const router = useRouter();
const [hotMenu, setHotMenu] = useAtom(gs_investas_menu);
const [isLoading, setLoading] = useState(false);
return (
// <UIGlobal_LayoutTamplate
// header={
// <UIGlobal_LayoutHeaderTamplate
// title="Invoice"
// customButtonLeft={
// <ActionIcon
// variant="transparent"
// onClick={() => {
// setHotMenu(3);
// setLoading(true);
// router.push(RouterInvestasi_OLD.main_transaksi);
// }}
// >
// {isLoading ? <Loader color="yellow" /> : <IconX />}
// </ActionIcon>
// }
// />
// }
// >
// <Investasi_ViewInvoice dataInvoice={dataInvoice} />
// </UIGlobal_LayoutTamplate>
<UI_NewLayoutTamplate>
<UI_NewHeader>
<Component_Header
@@ -62,7 +39,7 @@ export function Investasi_UiInvoice({ dataInvoice }: { dataInvoice: any }) {
/>
</UI_NewHeader>
<UI_NewChildren>
<Investasi_ViewInvoice dataInvoice={dataInvoice} />
<Investasi_ViewInvoice />
</UI_NewChildren>
</UI_NewLayoutTamplate>
);

View File

@@ -7,33 +7,15 @@ import UI_NewLayoutTamplate, {
} from "@/app_modules/_global/ui/V2_layout_tamplate";
import { Investasi_ViewMetodePembayaran } from "../../_view";
export function Investasi_UiMetodePembayaran({
listBank,
investasiId,
}: {
listBank: any[];
investasiId: string;
}) {
export function Investasi_UiMetodePembayaran() {
return (
<>
{/* <UIGlobal_LayoutTamplate
header={<UIGlobal_LayoutHeaderTamplate title="Metode Pembayaran" />}
>
<Investasi_ViewMetodePembayaran
listBank={listBank}
investasiId={investasiId}
/>
</UIGlobal_LayoutTamplate> */}
<UI_NewLayoutTamplate>
<UI_NewHeader>
<Component_Header title="Metode Pembayaran" />
</UI_NewHeader>
<UI_NewChildren>
<Investasi_ViewMetodePembayaran
listBank={listBank}
investasiId={investasiId}
/>
<Investasi_ViewMetodePembayaran />
</UI_NewChildren>
</UI_NewLayoutTamplate>
</>

View File

@@ -12,7 +12,7 @@ import { useRouter } from "next/navigation";
import { RouterInvestasi_OLD } from "@/lib/router_hipmi/router_investasi";
import { useState } from "react";
export function Investasi_UiProsesTransaksi({ nomorAdmin }: { nomorAdmin : any}) {
export function Investasi_UiProsesTransaksi() {
const router = useRouter();
const [hotMenu, setHotMenu] = useAtom(gs_investas_menu);
const [isLoading, setLoading] = useState(false);
@@ -38,7 +38,7 @@ export function Investasi_UiProsesTransaksi({ nomorAdmin }: { nomorAdmin : any})
/>
}
>
<Investasi_ViewProsesTransaksi nomorAdmin={nomorAdmin} />
<Investasi_ViewProsesTransaksi />
</UIGlobal_LayoutTamplate>
</>
);

View File

@@ -19,7 +19,7 @@ import {
Text,
} from "@mantine/core";
import { IconCamera, IconCircleCheck } from "@tabler/icons-react";
import { useRouter } from "next/navigation";
import { useParams, useRouter } from "next/navigation";
import { useState } from "react";
import { MODEL_INVOICE_INVESTASI } from "../../_lib/interface";
import { investasi_funUploadBuktiTransferById } from "../../_fun";
@@ -33,18 +33,34 @@ import { notifikasiToAdmin_funCreate } from "@/app_modules/notifikasi/fun";
import { WibuRealtime } from "wibu-pkg";
import { clientLogger } from "@/util/clientLogger";
import { ComponentGlobal_ButtonUploadFileImage } from "@/app_modules/_global/component";
import { useShallowEffect } from "@mantine/hooks";
import { apiGetInvoiceById } from "../../_lib/api_fetch_new_investasi";
import CustomSkeleton from "@/app_modules/components/CustomSkeleton";
export function Investasi_ViewInvoice({
dataInvoice,
}: {
dataInvoice: MODEL_INVOICE_INVESTASI;
}) {
export function Investasi_ViewInvoice() {
const param = useParams<{ id: string }>();
const invoiceId = param.id;
const router = useRouter();
const [isLoading, setLoading] = useState(false);
const [data, setData] = useState(dataInvoice);
const [data, setData] = useState<MODEL_INVOICE_INVESTASI | null>(null);
const [file, setFile] = useState<File | null>(null);
const [img, setImg] = useState<any | null>(null);
useShallowEffect(() => {
onLoadData();
}, [invoiceId]);
async function onLoadData() {
try {
const response = await apiGetInvoiceById({ id: invoiceId });
if (response.success) {
setData(response.data);
}
} catch (error) {
console.error("Error get invoice", error);
}
}
async function onUpload() {
try {
setLoading(true);
@@ -60,7 +76,7 @@ export function Investasi_ViewInvoice({
}
const res = await investasi_funUploadBuktiTransferById({
invoiceId: data.id,
invoiceId: invoiceId as string,
fileId: uploadFileToStorage.data.id,
});
@@ -71,9 +87,9 @@ export function Investasi_ViewInvoice({
}
const dataNotifikasi: IRealtimeData = {
appId: dataInvoice.Investasi.id,
appId: data?.Investasi.id,
status: "Proses",
userId: dataInvoice.authorId as string,
userId: data?.authorId as string,
pesan: "Bukti transfer telah diupload",
kategoriApp: "INVESTASI",
title: "Invoice baru",
@@ -92,7 +108,7 @@ export function Investasi_ViewInvoice({
ComponentGlobal_NotifikasiBerhasil(res.message);
router.push(NEW_RouterInvestasi.proses_transaksi + data.id, {
router.push(NEW_RouterInvestasi.proses_transaksi + invoiceId, {
scroll: false,
});
}
@@ -102,6 +118,10 @@ export function Investasi_ViewInvoice({
}
}
if (!data) {
return <CustomSkeleton height={300}/>
}
return (
<>
<Stack spacing={"lg"} py={"md"}>

View File

@@ -9,22 +9,20 @@ import { IRealtimeData } from "@/lib/global_state";
import { NEW_RouterInvestasi } from "@/lib/router_hipmi/router_investasi";
import { clientLogger } from "@/util/clientLogger";
import { Button, Paper, Radio, Stack, Title } from "@mantine/core";
import { useLocalStorage } from "@mantine/hooks";
import { useRouter } from "next/navigation";
import { useLocalStorage, useShallowEffect } from "@mantine/hooks";
import { useParams, useRouter } from "next/navigation";
import { useState } from "react";
import { WibuRealtime } from "wibu-pkg";
import { investasi_funCreateInvoice } from "../../_fun/create/fun_create_invoice";
import { MODEL_MASTER_BANK } from "../../_lib/interface";
import { apiGetMasterBank } from "@/app_modules/_global/lib/api_fetch_master";
import CustomSkeleton from "@/app_modules/components/CustomSkeleton";
export function Investasi_ViewMetodePembayaran({
listBank,
investasiId,
}: {
listBank: MODEL_MASTER_BANK[];
investasiId: string;
}) {
export function Investasi_ViewMetodePembayaran() {
// id = investasiId
const param = useParams<{ id: string }>();
const router = useRouter();
const [bank, setBank] = useState(listBank);
const [bank, setBank] = useState<MODEL_MASTER_BANK[]>([]);
const [pilihBank, setPilihBank] = useState("");
const [isLoading, setLoading] = useState(false);
const [total, setTotal] = useLocalStorage({
@@ -36,6 +34,25 @@ export function Investasi_ViewMetodePembayaran({
defaultValue: 0,
});
useShallowEffect(() => {
onLoadData();
}, []);
async function onLoadData() {
try {
const response = await apiGetMasterBank();
if (response.success) {
setBank(response.data);
} else {
setBank([]);
}
} catch (error) {
console.error("Error get investasi", error);
setBank([]);
}
}
async function onProses() {
try {
setLoading(true);
@@ -43,7 +60,7 @@ export function Investasi_ViewMetodePembayaran({
data: {
total: total,
pilihBank: pilihBank,
investasiId: investasiId,
investasiId: param.id,
jumlah: jumlah,
},
});
@@ -55,7 +72,7 @@ export function Investasi_ViewMetodePembayaran({
}
const dataNotifikasi: IRealtimeData = {
appId: investasiId,
appId: param.id,
status: "Menunggu",
userId: res.data?.authorId as string,
pesan: "Menunggu transfer",
@@ -85,6 +102,10 @@ export function Investasi_ViewMetodePembayaran({
}
}
if (bank.length === 0) {
return <CustomSkeleton height={300} />;
}
return (
<>
<Stack>

View File

@@ -14,12 +14,34 @@ import {
} from "@mantine/core";
import { IconBrandWhatsapp } from "@tabler/icons-react";
import Link from "next/link";
import { useState } from "react";
import { useShallowEffect } from "@mantine/hooks";
import { apiGetAdminContact } from "@/app_modules/_global/lib/api_fetch_master";
import CustomSkeleton from "@/app_modules/components/CustomSkeleton";
export function Investasi_ViewProsesTransaksi({
nomorAdmin,
}: {
nomorAdmin: any;
}) {
export function Investasi_ViewProsesTransaksi() {
const [nomorAdmin, setNomorAdmin] = useState<string | undefined>(undefined);
useShallowEffect(() => {
onLoadData();
}, []);
async function onLoadData() {
try {
const data = await apiGetAdminContact();
if (data.success) {
setNomorAdmin(data.data.nomor);
} else {
console.error("Error get admin contact", data.message);
setNomorAdmin(undefined);
}
} catch (error) {
console.error("Error get admin contact", error);
setNomorAdmin(undefined);
}
}
if (!nomorAdmin) return <CustomSkeleton height={300} />;
return (
<>
<Stack>
@@ -47,7 +69,13 @@ export function Investasi_ViewProsesTransaksi({
<Stack align="center" justify="center">
<Title order={6}>Admin sedang memproses transaksimu</Title>
<Paper radius={1000} w={100} h={100}>
<Center style={{ backgroundColor: MainColor.white, borderRadius: "100%"}} h={"100%"}>
<Center
style={{
backgroundColor: MainColor.white,
borderRadius: "100%",
}}
h={"100%"}
>
<Loader size={"lg"} color="yellow" variant="dots" />
</Center>
</Paper>
@@ -92,7 +120,7 @@ export function Investasi_ViewProsesTransaksi({
textDecoration: "none",
}}
target="_blank"
href={`https://wa.me/+${nomorAdmin.nomor}?text=Hallo Admin , Saya ada kendala dalam proses transfer investasi !`}
href={`https://wa.me/+${nomorAdmin}?text=Hallo Admin , Saya ada kendala dalam proses transfer investasi !`}
>
<IconBrandWhatsapp size={40} color={MainColor.green} />
</Link>