Alur Payment

# feat
- Pembelian saham
- Function progres
### No Issue
This commit is contained in:
2023-12-12 13:56:39 +08:00
parent 26a7b988df
commit 693bb65710
126 changed files with 1204 additions and 316 deletions

View File

@@ -6,6 +6,7 @@ export async function GET(
req: NextRequest,
{ params }: { params: { id: string } }
) {
console.log(params.id)
const data = await prisma.prospektusInvestasi.findUnique({
where: { id: params.id },
select: {

View File

@@ -1,11 +1,12 @@
import { DetailPropektus } from "@/app_modules/investasi";
import getOneInvestasiById from "@/app_modules/investasi/fun/get_one_investasi_by_id";
export default async function Page({params}:{params: {id: string}}) {
const dataInvestasi = await getOneInvestasiById(params.id)
export default async function Page({ params }: { params: { id: string } }) {
const dataInvestasi = await getOneInvestasiById(params.id);
return<>
<DetailPropektus dataInvestasi={dataInvestasi as any}/>
return (
<>
<DetailPropektus dataInvestasi={dataInvestasi as any} />
</>
}
);
}

View File

@@ -1,5 +1,13 @@
import { DetailSahamTerbeli } from "@/app_modules/investasi";
import funTotalInvestorByIdInvestasi from "@/app_modules/investasi/fun/fun_total_investor_by_id";
import getOneTransaksiBerhasilByIdInvestasi from "@/app_modules/investasi/fun/get_one_transaksi_berhasil_by_id";
export default async function Page({ params }: { params: { id: string } }) {
return <DetailSahamTerbeli id={params.id} />;
const dataTransaksi = await getOneTransaksiBerhasilByIdInvestasi(params.id);
const investor = await funTotalInvestorByIdInvestasi(
dataTransaksi?.Investasi.id as any
);
// console.log(investor);
return <DetailSahamTerbeli dataTransaksi={dataTransaksi as any} investor={investor} />;
}

View File

@@ -1,9 +1,23 @@
import { InvestasiSahamTerbeli } from "@/app_modules/investasi";
import getListTransaksiBerhasilInvestasi from "@/app_modules/investasi/fun/get_list_transaksi_berhasil_by_id";
import yaml from "yaml";
import fs from "fs";
import { cookies } from "next/headers";
import { unsealData } from "iron-session";
const config = yaml.parse(fs.readFileSync("config.yaml").toString());
export default async function Page() {
const c = cookies().get("ssn");
const user = JSON.parse(
await unsealData(c?.value as string, {
password: config.server.password,
})
);
const listTransaksi = await getListTransaksiBerhasilInvestasi(user.id)
// console.log(listTransaksi)
return (
<>
<InvestasiSahamTerbeli />
<InvestasiSahamTerbeli listTransaksi={listTransaksi as any} />
</>
);
}

View File

@@ -20,6 +20,7 @@ export default async function Page() {
const userId = tkn.id;
const statusTransaksi = await getMaster_StatusTransaksiInvestasi();
const listTransaksi = await getListAllTransaksiById_Investasi(userId);
// console.log(listTransaksi)
return (
<>

View File

@@ -0,0 +1,12 @@
import { LayoutProsesTransaksiInvestasi } from "@/app_modules/investasi";
import React from "react";
export default async function Layout({
children,
}: {
children: React.ReactNode;
}) {
return (
<LayoutProsesTransaksiInvestasi>{children}</LayoutProsesTransaksiInvestasi>
);
}

View File

@@ -0,0 +1,29 @@
import { ProsesTransaksiInvestasi } from "@/app_modules/investasi";
import getOneInvestasiById from "@/app_modules/investasi/fun/get_one_investasi_by_id";
import { unsealData } from "iron-session";
import { cookies } from "next/headers";
import { funGetUserProfile } from "@/app_modules/fun/get_user_profile";
import yaml from "yaml";
import fs from "fs";
const config = yaml.parse(fs.readFileSync("config.yaml").toString());
export default async function Page({ params }: { params: { id: string } }) {
const c = cookies().get("ssn");
const user = JSON.parse(
await unsealData(c?.value as string, {
password: config.server.password,
})
);
const userLogin = await funGetUserProfile(user.id);
const dataInvestasi = await getOneInvestasiById(params.id);
// console.log(userLogin);
return (
<>
<ProsesTransaksiInvestasi
dataInvestasi={dataInvestasi as any}
userLogin={userLogin as any}
/>
</>
);
}

View File

@@ -18,6 +18,7 @@ export const RouterInvestasi = {
// proses beli saham
proses_investasi: "/dev/investasi/proses_investasi/",
proses_transaksi: "/dev/investasi/proses_transaksi/",
status_transaksi: "/dev/investasi/status_transaksi/berhasil",
status_transaksi_gagal: "/dev/investasi/status_transaksi/gagal/",
metode_transfer: "/dev/investasi/metode_transfer/",
@@ -30,6 +31,7 @@ export const RouterInvestasi = {
edit_berita: "/dev/investasi/edit_berita/",
// detail //
detail: "/dev/investasi/detail/",
detail_portofolio: "",
detail_saham_terbeli: "/dev/investasi/detail_saham_terbeli/",
detail_prospektus: "/dev/investasi/detail_prospektus/",

View File

@@ -1,9 +1,15 @@
"use client"
import { Title } from "@mantine/core"
import { Divider, Stack, Title } from "@mantine/core"
export default function Admin_Award(){
return<>
<Title>halaman award</Title>
<Stack spacing={"sm"}>
<Title>Award</Title>
<Divider mb={"md"} />
<Stack align="center" justify="center" h={"80vh"}>
<Title>Cooming Soon !!</Title>
</Stack>
</Stack>
</>
}

View File

@@ -55,6 +55,7 @@ import toast, { toastConfig } from "react-simple-toasts";
import Admin_funRejectInvestasi from "../fun/fun_reject_investasi";
import { RouterAdminInvestasi } from "@/app/lib/router_hipmi/router_admin";
import "react-simple-toasts/dist/theme/dark.css";
import { BeritaInvestasi } from "@/app_modules/investasi";
toastConfig({ theme: "dark" });
@@ -112,7 +113,7 @@ export default function Admin_KonfirmasiInvestasi({
await Admin_funRejectInvestasi(body).then((res) => {
if (res.status === 200) {
toast(res.message);
router.back()
router.back();
toggle();
} else {
toast(res.message);
@@ -292,6 +293,13 @@ export default function Admin_KonfirmasiInvestasi({
</Text>
</Stack>
)}
{publish &&
investasi.MasterStatusInvestasi.id === "3" &&
_.isEmpty(investasi.BeritaInvestasi) ? (
<BeritaInvestasi dataInvestasi={investasi} />
) : (
""
)}
</Grid.Col>
{/* Note dan dokumen */}
<Grid.Col span={6}>
@@ -370,10 +378,10 @@ export default function Admin_KonfirmasiInvestasi({
minRows={2}
maxRows={4}
value={investasi.catatan === null ? [] : investasi.catatan}
onChange={(val) =>
onChange={(val) =>
setInvestasi({
...investasi,
catatan: val.target.value
catatan: val.target.value,
})
}
/>

View File

@@ -23,6 +23,7 @@ export default function TablePublikasiProgresInvestasi({
radius={"md"}
bg={"gray.4"}
p={"sm"}
h={400}
// sx={{ borderStyle: "solid", borderColor: "teal" }}
>
<Stack spacing={"xl"}>

View File

@@ -72,10 +72,8 @@ export default function Admin_TablePublishInvestasi({
return (
<>
<Stack>
<ActionIcon
variant="outline"
onClick={() => router.push(RouterAdminInvestasi.main_investasi)}
>
<ActionIcon variant="outline" onClick={() => router.push(RouterAdminInvestasi.main_investasi)}>
<IconChevronLeft />
</ActionIcon>
<Box>

View File

@@ -61,7 +61,8 @@ export default function Admin_TableRejectInvestasi({
return (
<>
<Stack>
<ActionIcon variant="outline" onClick={() => router.back()}>
<ActionIcon variant="outline" onClick={() => router.push(RouterAdminInvestasi.main_investasi)}>
<IconChevronLeft />
</ActionIcon>
<Box>

View File

@@ -71,7 +71,7 @@ export default function Admin_TableReviewInvestasi({
return (
<>
<Stack>
<ActionIcon variant="outline" onClick={() => router.back()}>
<ActionIcon variant="outline" onClick={() => router.push(RouterAdminInvestasi.main_investasi)}>
<IconChevronLeft />
</ActionIcon>
<Box>

View File

@@ -20,15 +20,15 @@ export default function TableTotalInvestasi({
<Paper
radius={"md"}
bg={"gray.4"}
p={"sm"}
h={400}
// sx={{ borderStyle: "solid", borderColor: "teal" }}
>
<Stack spacing={"xl"}>
<Center>
<Title order={4}>Total Investasi Pengguna</Title>
</Center>
<Table bg={"gray.2"} sx={{borderRadius: "10px"}}>
<Table bg={"gray.2"} sx={{ borderRadius: "10px" }}>
<thead>
<tr>
<th>

View File

@@ -98,8 +98,10 @@ export default function Admin_Investasi({
<Grid mb={"md"}>
{listBox.map((e) => (
<Grid.Col sm={12} md={6} lg={3} key={e.id}>
<Paper bg={`${e.color}.1`} p={"xs"}
// sx={{borderStyle: "solid", borderColor: e.color}}
<Paper
bg={`${e.color}.1`}
p={"xs"}
// sx={{borderStyle: "solid", borderColor: e.color}}
>
<Stack align="center" justify="center" spacing={0} mb={-35}>
<Text tt={"uppercase"}>{e.name}</Text>
@@ -110,10 +112,13 @@ export default function Admin_Investasi({
<Group position="right">
{e.link === "" ? (
<ActionIcon variant="transparent">
{/* <IconChevronsRight color="black" /> */}
</ActionIcon>
{/* <IconChevronsRight color="black" /> */}
</ActionIcon>
) : (
<ActionIcon variant="transparent" onClick={() => router.push(e.link)}>
<ActionIcon
variant="transparent"
onClick={() => router.push(e.link)}
>
<IconChevronsRight color="black" />
</ActionIcon>
)}
@@ -124,20 +129,15 @@ export default function Admin_Investasi({
</Grid>
{/* Table Total & Progres */}
<Grid>
{/* <Grid>
<Grid.Col sm={12} md={4} lg={4}>
<TableTotalInvestasi totalInvestasiByUser={totalInvestasiByUser} />
</Grid.Col>
<Grid.Col sm={12} md={8} lg={8}>
<TablePublikasiProgresInvestasi publishProgres={publishProgres} />
</Grid.Col>
</Grid>
</Grid> */}
</Stack>
{/* <TablePublish dataInvestsi={investasi as any} />
<TableReview dataInvestsi={investasi as any} />
<TableReject dataInvestsi={investasi as any} /> */}
{/* <pre>{JSON.stringify(targetTerbesar, null, 2)}</pre> */}
</>
);
}

View File

@@ -1,13 +1,18 @@
"use client";
import { Title } from "@mantine/core";
import { Center, Divider, Stack, Title } from "@mantine/core";
import Admin_Investasi from "../investasi/main/view";
export default function AdminMain() {
return (
<>
<Title>Main Dashboard</Title>
<Stack spacing={"sm"}>
<Title>Main Dashboard</Title>
<Divider mb={"md"} />
<Stack align="center" justify="center" h={"80vh"}>
<Title>Cooming Soon !!</Title>
</Stack>
</Stack>
</>
);
}

View File

@@ -57,7 +57,7 @@ export default function MainCrowd() {
</Grid>
</Paper>
<Paper
bg={Warna.biru}
bg={"blue.4"}
radius={"md"}
p={"xs"}
onClick={() => toast("Cooming Soon Feature...")}

View File

@@ -131,7 +131,7 @@ export default function HomeView({ user }: { user: MODEL_User_profile }) {
</Flex>
<Paper bg={"dark"} radius={5} my={"xs"}>
<Image alt="logo" src={"/aset/logo.png"} />
<Image alt="logo" src={"/aset/investasi/home-hipmi.png"} />
</Paper>
{/* <pre>{JSON.stringify(stateUser, null, 2)}</pre> */}

View File

@@ -152,7 +152,7 @@ export default function InvestasiCreate({
</Paper>
) : (
<Paper w={"100%"} bg={"gray.6"} p={"sm"}>
<Text>{pdf.name}</Text>
<Text truncate>{pdf.name}</Text>
</Paper>
)}
{/* {JSON.stringify(filePdf)} */}

View File

@@ -73,7 +73,7 @@ export default function DetailInvestasi({
];
async function onSubmit() {
router.push(RouterInvestasi.proses_investasi + `${investasi.id}`);
router.push(RouterInvestasi.proses_transaksi + `${investasi.id}`);
setTransaksiValue({
...transaksiValue,
lembarTerbeli: "",
@@ -224,7 +224,7 @@ export default function DetailInvestasi({
onSubmit()
}}
>
Investasi
Beli Saham
</Button>
</Center>
)}

View File

@@ -8,6 +8,7 @@ import {
Model_Prospektus_Investasi,
} from "../model/model_investasi";
import { useState } from "react";
import { RouterInvestasi } from "@/app/lib/router_hipmi/router_investasi";
export default function DetailPropektus({
dataInvestasi,
@@ -16,23 +17,16 @@ export default function DetailPropektus({
}) {
const [prospek, setProspek] = useState(dataInvestasi);
return (
<>
{prospek.ProspektusInvestasi !== null ? (
<Link
href={`/file/${prospek.ProspektusInvestasi.url}`}
href={RouterInvestasi.api_file_prospektus + `${prospek.ProspektusInvestasi.id}`}
target="_blank"
style={{ textDecorationLine: "none" }}
>
<Paper w={"100%"} bg={"gray"} mb={"md"}>
<Grid
align="center"
justify="center"
px={"sm"}
onClick={() => ""}
>
<Paper w={"100%"} bg={"gray"} mb={"md"}>
<Grid align="center" justify="center" px={"sm"}>
<Grid.Col span={10}>
<Text>Prospektus_{prospek.title}</Text>
</Grid.Col>

View File

@@ -15,6 +15,7 @@ import {
Group,
Image,
Paper,
Progress,
Slider,
Stack,
Text,
@@ -22,13 +23,24 @@ import {
} from "@mantine/core";
import {
IconBookDownload,
IconCircleCheck,
IconFileDescription,
IconSpeakerphone,
} from "@tabler/icons-react";
import { useRouter } from "next/navigation";
import { MODEL_Transaksi_Investasi } from "../model/model_investasi";
import { useState } from "react";
import moment from "moment";
export default function DetailSahamTerbeli({id}: {id: string}) {
export default function DetailSahamTerbeli({
dataTransaksi,
investor
}: {
dataTransaksi: MODEL_Transaksi_Investasi;
investor: number
}) {
const router = useRouter();
const [investasi, setINvestasi] = useState(dataTransaksi);
const listBox = [
{
id: 1,
@@ -54,50 +66,104 @@ export default function DetailSahamTerbeli({id}: {id: string}) {
<Group position="apart" mb={"md"}>
<Flex align={"center"} gap={"xs"}>
<Avatar src={"/aset/avatar.png"} />
<Text>Username</Text>
<Text>{investasi.Investasi.author.username}</Text>
</Flex>
<Text>Sisa waktu : 20 Hari</Text>
{(() => {
if (
Number(investasi.Investasi.MasterPencarianInvestor.name) -
moment(new Date()).diff(new Date(investasi.createdAt), "days") <=
0
) {
return (
<>
<Group position="right">
<IconCircleCheck color="green" />
<Text c={"green"}>Selesai</Text>
</Group>
</>
);
} else {
return (
<>
<Group position="right" spacing={"xs"}>
<Text>Sisa waktu:</Text>
<Text>
{Number(investasi.Investasi.MasterPencarianInvestor.name) -
moment(new Date()).diff(
new Date(investasi.Investasi.countDown),
"days"
)}{" "}
Hari
</Text>
</Group>
</>
);
}
})()}
</Group>
{/* Gambar Investasi */}
<Paper withBorder mb={"md"}>
<AspectRatio ratio={16 / 9}>
<Image alt="" src={"/aset/no-img.png"} />
<Image alt="" src={RouterInvestasi.api_gambar + `${investasi.Investasi.imagesId}`} />
</AspectRatio>
</Paper>
{/* Title dan Persentase */}
<Box mb={"md"}>
<Title order={4} mb={"xs"}>
Judul Proyek
{investasi.Investasi.title}
</Title>
<Slider
disabled
size={10}
value={60}
marks={[{ value: 60, label: "60%" }]}
/>
<Progress
label={
"" +
(
((+investasi.Investasi.totalLembar - +investasi.Investasi.sisaLembar) /
+investasi.Investasi.totalLembar) *
100
).toFixed(1) +
"%"
}
value={
+(
((+investasi.Investasi.totalLembar - +investasi.Investasi.sisaLembar) /
+investasi.Investasi.totalLembar) *
100
).toFixed(2)
}
color="teal"
size="xl"
radius="xl"
/>
</Box>
{/* Rincian Data */}
<Grid p={"md"}>
<Grid.Col span={6}>
<Stack>
<Box>
{/* <Box>
<Text>Terkumpul</Text>
<Text>Rp. </Text>
</Box>
</Box> */}
<Box>
<Text>Dana Dibutuhkan</Text>
<Text>Rp. </Text>
<Text>Rp. {new Intl.NumberFormat("id-ID", {
maximumSignificantDigits: 10,
}).format(+investasi.Investasi.targetDana)}</Text>
</Box>
<Box>
<Text>Harga Per Lembar</Text>
<Text>Rp. </Text>
<Text>Rp. {new Intl.NumberFormat("id-ID", {
maximumSignificantDigits: 10,
}).format(+investasi.Investasi.hargaLembar)}</Text>
</Box>
<Box>
<Text>Jadwal Pembagian</Text>
<Text>3 Bulan </Text>
<Text>{investasi.Investasi.MasterPembagianDeviden.name} bulan </Text>
</Box>
<Box>
<Text>Pembagian Deviden</Text>
<Text>{investasi.Investasi.MasterPeriodeDeviden.name}</Text>
</Box>
</Stack>
</Grid.Col>
@@ -105,19 +171,23 @@ export default function DetailSahamTerbeli({id}: {id: string}) {
<Stack>
<Box>
<Text>Investor</Text>
<Text>4657</Text>
<Text>{investor} pengguna</Text>
</Box>
<Box>
<Text>ROI</Text>
<Text>%</Text>
<Text>{investasi.Investasi.roi}%</Text>
</Box>
<Box>
<Text>Total Lembar</Text>
<Text>0</Text>
<Text>{new Intl.NumberFormat("id-ID", {
maximumSignificantDigits: 10,
}).format(+investasi.Investasi.totalLembar)} lembar</Text>
</Box>
<Box>
<Text>Pembagian Deviden</Text>
<Text>Selamanya</Text>
<Text>Sisa Lembar</Text>
<Text>{new Intl.NumberFormat("id-ID", {
maximumSignificantDigits: 10,
}).format(+investasi.Investasi.sisaLembar)} lembar</Text>
</Box>
</Stack>
</Grid.Col>
@@ -135,7 +205,9 @@ export default function DetailSahamTerbeli({id}: {id: string}) {
<Stack>
<Box>
<Text>Total Pembelian</Text>
<Text>Rp. 0</Text>
<Text>Rp. {new Intl.NumberFormat("id-ID", {
maximumSignificantDigits: 10,
}).format(+investasi.gross_amount)}</Text>
</Box>
</Stack>
</Grid.Col>
@@ -143,7 +215,9 @@ export default function DetailSahamTerbeli({id}: {id: string}) {
<Stack>
<Box>
<Text>Lembar Dibeli</Text>
<Text>100</Text>
<Text>{new Intl.NumberFormat("id-ID", {
maximumSignificantDigits: 10,
}).format(+investasi.quantity)} lembar</Text>
</Box>
</Stack>
</Grid.Col>
@@ -153,7 +227,11 @@ export default function DetailSahamTerbeli({id}: {id: string}) {
{/* List Box */}
<Grid mb={"sm"} justify="center">
{listBox.map((e) => (
<Grid.Col span={"auto"} key={e.id} onClick={() => router.push(e.route + `${id}`)}>
<Grid.Col
span={"auto"}
key={e.id}
onClick={() => router.push(e.route + `${investasi.Investasi.id}`)}
>
<Center>
<Paper h={100} w={100} bg={"gray.4"} withBorder py={"xs"}>
<Flex direction={"column"} align={"center"} justify={"center"}>

View File

@@ -11,7 +11,7 @@ import { MODEL_Investasi } from "../model/model_investasi";
export async function funCreateInvestasi(
gamabar: FormData,
filePdf: FormData,
data: MODEL_Investasi | any
data: MODEL_Investasi
) {
// Function upload gambar
const file: any = gamabar.get("file");
@@ -32,7 +32,7 @@ export async function funCreateInvestasi(
if (!uploadImage)
return {
status: 400,
message: "File Kosong",
message: "Gambar Kosong",
};
const upFolder = Buffer.from(await file.arrayBuffer());
@@ -67,23 +67,21 @@ export async function funCreateInvestasi(
const pdfExt = _.lowerCase(dataPdf.name.split(".").pop());
const pdfRandomName = v4(pdfName) + "." + pdfExt;
const uploadFile = await prisma.prospektusInvestasi.upsert({
where: {
investasiId: createInvest.id,
},
update: {
url: pdfRandomName,
},
create: {
const uploadFile = await prisma.prospektusInvestasi.create({
data: {
investasiId: createInvest.id,
url: pdfRandomName,
},
select: {
id: true,
url: true,
},
});
if(!uploadFile) return {status: 400, message: "Gagal Upload"}
const upPdfFolder = Buffer.from(await file.arrayBuffer())
fs.writeFileSync(`./public/file/${uploadFile.url}`, upPdfFolder)
if (!uploadFile) return { status: 400, message: "File Kosong" };
const upPdfFolder = Buffer.from(await file.arrayBuffer());
fs.writeFileSync(`./public/file/${uploadFile.url}`, upPdfFolder);
revalidatePath(RouterInvestasi.main_porto);

View File

@@ -12,10 +12,12 @@ export default async function funCreateTransaksiInvestasi(
data: {
namaBank: data.namaBank,
nomorRekening: data.nomorRekening,
lembarTerbeli: "" + data.lembarTerbeli,
totalTransfer: "" + data.totalTransfer,
investasiId: invesId,
authorId: authorId,
gross_amount: "",
merchant_name:"",
price: "",
quantity: ""
},
});
if (!res) return { status: 400, message: "Gagal disimpan" };

View File

@@ -3,24 +3,31 @@
import prisma from "@/app/lib/prisma";
import { RouterAdminInvestasi } from "@/app/lib/router_hipmi/router_admin";
import { RouterInvestasi } from "@/app/lib/router_hipmi/router_investasi";
import moment from "moment";
import { revalidatePath } from "next/cache";
export default async function funGantiStatusInvestasi(id: string, val: string) {
const publishCD = new Date
const data = await prisma.investasi.update({
where: {
id: id,
},
data: {
masterStatusInvestasiId: val,
MasterStatusInvestasi: {
connect: {
id: val,
},
},
countDown: publishCD,
},
});
if(!data) return {status: 400}
if (!data) return { status: 400 };
revalidatePath(RouterInvestasi.portofolio)
revalidatePath(RouterAdminInvestasi.main_investasi)
revalidatePath(RouterInvestasi.portofolio);
revalidatePath(RouterAdminInvestasi.main_investasi);
return {
status: 200
}
status: 200,
};
}

View File

@@ -19,7 +19,6 @@ export default async function funGantiStatusTransaksi_Investasi(
select: {
id: true,
namaBank: true,
totalTransfer: true,
Investasi: true,
MasterStatusTransaksiInvestasi: true
}

View File

@@ -0,0 +1,16 @@
"use server";
import prisma from "@/app/lib/prisma";
export default async function funTotalInvestorByIdInvestasi(id: string) {
// console.log(id)
const data = await prisma.transaksiInvestasi.count({
where: {
investasiId: id,
status_code: "200"
},
});
return data;
}
// belum ke hitungg

View File

@@ -0,0 +1,23 @@
"use server";
import prisma from "@/app/lib/prisma";
import { MODEL_Investasi } from "../model/model_investasi";
export default async function funUpdateInvestasi(data: MODEL_Investasi) {
// console.log(data)
const res = await prisma.investasi.update({
where: {
id: data.id,
},
data: {
sisaLembar: "" + data.sisaLembar,
},
});
if (!res) return { status: 400, message: "Gagal update" };
return {
status: 200,
message: "Update berhasil",
};
}

View File

@@ -0,0 +1,96 @@
"use server";
import prisma from "@/app/lib/prisma";
import { MODEL_Investasi } from "../model/model_investasi";
import { revalidatePath } from "next/cache";
import { RouterInvestasi } from "@/app/lib/router_hipmi/router_investasi";
export interface Model_Midtrans_Success {
status_code: string;
status_message: string;
transaction_id: string;
order_id: string;
gross_amount: string;
payment_type: string;
transaction_time: string;
transaction_status: string;
fraud_status: string;
va_numbers: [{ bank: string; va_number: string }];
pdf_url: string;
finish_redirect_url: string;
}
export default async function funUpdatePaymentInvestasi(
data: Model_Midtrans_Success,
idPay: any,
) {
console.log(data)
if (data.status_code === "200") {
const res = await prisma.transaksiInvestasi.update({
where: {
id: idPay,
},
data: {
status_code: data.status_code,
status_message: data.status_message,
order_id: data.order_id,
fraud_status: data.fraud_status,
payment_type: data.payment_type,
transaction_id: data.transaction_id,
transaction_status: data.transaction_status,
transaction_time: data.transaction_time,
pdf_url: data.pdf_url,
finish_redirect_url: data.finish_redirect_url,
namaBank: data.va_numbers[0].bank,
nomorRekening: data.va_numbers[0].va_number,
},
});
if (!res) return { status: 400, message: "Gagal update transaksi" };
// const jumlah = Number(res.quantity);
// const sisa = Number(investasi?.sisaLembar);
// const hasil = sisa - jumlah;
// const updateTransaksi = await prisma.investasi.update({
// where: {
// id: investasi?.id,
// },
// data: {
// sisaLembar: hasil.toString(),
// },
// });
// console.log(updateTransaksi);
// if (!updateTransaksi)
// return { status: 400, message: "Gagal update investasi" };
revalidatePath(RouterInvestasi.main_transaksi)
return {
status: 200,
message: "Process",
};
} else {
if (data.status_code === "201") {
const res = await prisma.transaksiInvestasi.update({
where: {
id: idPay,
},
data: {
status_code: "201",
},
});
return {
message: "Success",
};
} else {
if ((!data.status_code as any) === "400")
return { status: 400, message: "Update Gagal" };
return {
status: 200,
message: "Berhasil Update",
};
}
}
}

View File

@@ -14,8 +14,8 @@ export async function getListAllPublish() {
},
},
AND: {
active: true
}
active: true,
},
},
select: {
id: true,
@@ -38,7 +38,7 @@ export async function getListAllPublish() {
MasterPembagianDeviden: true,
MasterPencarianInvestor: true,
MasterPeriodeDeviden: true,
countDown: true,
},
});

View File

@@ -19,17 +19,22 @@ export default async function getListAllTransaksiById_Investasi(
id: true,
namaBank: true,
nomorRekening: true,
totalTransfer: true,
lembarTerbeli: true,
active: true,
createdAt: true,
updatedAt: true,
authorId: true,
quantity: true,
price: true,
gross_amount: true,
merchant_name: true,
redirect_url: true,
token: true,
Author: true,
masterStatusTransaksiInvestasiId: true,
MasterStatusTransaksiInvestasi: true,
investasiId: true,
Investasi: true,
// Author:true,
},
});
@@ -59,17 +64,21 @@ export default async function getListAllTransaksiById_Investasi(
id: true,
namaBank: true,
nomorRekening: true,
totalTransfer: true,
lembarTerbeli: true,
active: true,
createdAt: true,
updatedAt: true,
authorId: true,
quantity: true,
price: true,
gross_amount: true,
merchant_name: true,
redirect_url: true,
token: true,
Author: true,
masterStatusTransaksiInvestasiId: true,
MasterStatusTransaksiInvestasi: true,
investasiId: true,
Investasi: true,
// Author:true,
},
});

View File

@@ -0,0 +1,26 @@
"use server";
import prisma from "@/app/lib/prisma";
export default async function getListTransaksiBerhasilInvestasi(
idAuthor: string
) {
const data = await prisma.transaksiInvestasi.findMany({
orderBy: {
createdAt: "desc"
},
where: {
authorId: idAuthor,
status_code: "200",
},
select: {
id: true,
Investasi: true,
Author: true,
gross_amount: true,
quantity: true,
},
});
return data;
}

View File

@@ -30,6 +30,8 @@ export default async function getOneInvestasiById(id: string) {
MasterPembagianDeviden: true,
MasterPencarianInvestor: true,
MasterPeriodeDeviden: true,
author: true,
countDown: true
},
});

View File

@@ -0,0 +1,42 @@
"use server";
import prisma from "@/app/lib/prisma";
export default async function getOneTransaksiBerhasilByIdInvestasi(
idTransaksi: string
) {
const data = await prisma.transaksiInvestasi.findUnique({
where: {
id: idTransaksi,
},
select: {
Investasi: {
select: {
author: true,
BeritaInvestasi: true,
DokumenInvestasi: true,
ProspektusInvestasi: true,
MasterPembagianDeviden: true,
MasterPencarianInvestor: true,
MasterPeriodeDeviden: true,
id: true,
title: true,
countDown: true,
imagesId: true,
roi: true,
targetDana: true,
totalLembar: true,
sisaLembar: true,
hargaLembar: true,
},
},
id: true,
gross_amount: true,
quantity: true,
},
});
return data;
}

View File

@@ -78,6 +78,7 @@ export default async function getPortoByStatusId(id: string, statusId: number) {
updatedAt: true,
targetDana: true,
MasterPencarianInvestor: true,
countDown: true,
},
});
return data;

View File

@@ -0,0 +1,113 @@
"use server";
import prisma from "@/app/lib/prisma";
import MidTrans from "midtrans-client";
// const midtransClient = require("midtrans-client");
// const snap = new midtransClient.Snap({
// isProduction: false,
// serverKey: process.env.Server_KEY,
// clientKey: process.env.Client_KEY,
// });
const snap = new MidTrans.Snap({
isProduction: false,
serverKey: process.env.Server_KEY,
clientKey: process.env.Client_KEY,
});
export default async function getTokenTransaksi(data) {
const body = await data;
// console.log(body);
const date = new Date();
const randomId = date.getTime();
const params = {
transaction_details: {
order_id: "hipmi_" + randomId,
gross_amount: body.gross_amount,
},
item_details: [
{
id: "item_hipmi_" + randomId,
name: body.item_name,
price: body.price,
quantity: body.quantity,
merchant_name: body.merchant_name,
},
],
customer_details: {
first_name: body.customer_name,
phone: body.phone,
// email: "test@midtrans.com",
},
enabled_payments: [
"permata_va",
"bca_va",
"bni_va",
"bri_va",
"cimb_va",
"other_va",
"shopeepay",
],
bca_va: {
va_number: "82340374411111",
sub_company_code: "00000",
free_text: {
inquiry: [
{
en: "text in English",
id: "text in Bahasa Indonesia",
},
],
payment: [
{
en: "text in English",
id: "text in Bahasa Indonesia",
},
],
},
},
};
const token = await new Promise(async (res) => {
try {
const transaksi = await snap.createTransaction(params);
// console.log(transaksi);
res({
status: 200,
value: transaksi,
});
} catch (error) {
// console.log(error);
res({
status: 400,
value: error,
});
}
});
if (token.status === 400) {
return { token: token };
}
const newTransaksi = await prisma.transaksiInvestasi.create({
data: {
gross_amount: "" + data.gross_amount,
merchant_name: data.merchant_name,
price: "" + data.price,
quantity: "" + data.quantity,
token: token.value.token,
redirect_url: token.value.redirect_url,
authorId: data.authorId,
investasiId: data.investasiId,
},
});
return {
token: token,
dataTransaksi: newTransaksi,
};
}

View File

@@ -11,8 +11,6 @@ export default async function getTransaksiByIdInvestasi(id: string) {
id: true,
namaBank: true,
nomorRekening: true,
lembarTerbeli: true,
totalTransfer: true,
active: true,
createdAt: true,
updatedAt: true,

View File

@@ -63,6 +63,8 @@ import UploadProspektusInvestasi from "./upload_prospektus/view";
import LayoutUploadProspektusInvestasi from "./upload_prospektus/layout";
import UploadDokumenInvestasi from "./upload_dokumen/view";
import LayoutUploadDokumenInvestasi from "./upload_dokumen/layout";
import ProsesTransaksiInvestasi from "./proses_transaksi/view";
import LayoutProsesTransaksiInvestasi from "./proses_transaksi/layout";
export {
MainInvestasi,
@@ -130,4 +132,6 @@ export {
LayoutUploadProspektusInvestasi,
UploadDokumenInvestasi,
LayoutUploadDokumenInvestasi,
ProsesTransaksiInvestasi,
LayoutProsesTransaksiInvestasi,
};

View File

@@ -50,7 +50,7 @@ export default function LayoutMainInvestasi({
},
{
id: 3,
name: "Investasi",
name: "Saham Saya",
route: RouterInvestasi.main_investasi,
icon: <IconCash />,
},
@@ -75,7 +75,7 @@ export default function LayoutMainInvestasi({
}
footer={
<Footer height={70} bg={"dark.4"}>
<Grid align="center" h={60} pt={"xs"}>
<Grid align="center" h={60} pt={"xs"} grow>
{/* Tampilan Bursa */}
{listFooter.map((e, k) => (
<Grid.Col

View File

@@ -17,135 +17,136 @@ import {
Badge,
Image,
Text,
Button,
Paper,
Progress,
Center,
} from "@mantine/core";
import { IconCircleCheck } from "@tabler/icons-react";
import moment from "moment";
import { useRouter } from "next/navigation";
import dataDummy from "../dummy/data_dummy.json";
import { MODEL_Transaksi_Investasi } from "../model/model_investasi";
import { useState } from "react";
import { Warna } from "@/app/lib/warna";
export default function InvestasiSahamTerbeli() {
export default function InvestasiSahamTerbeli({
listTransaksi,
}: {
listTransaksi: MODEL_Transaksi_Investasi[];
}) {
const router = useRouter();
const [investasi, setInvestasi] = useState(listTransaksi);
return (
<>
{dataDummy.map((e) => (
{/* {investasi.map((e) => (
<Card
// sx={{ borderStyle: "solid", borderColor: "black", borderWidth: "0.5px" }}
radius={"md"}
key={e.id}
withBorder
bg={"gray.5"}
mb={"lg"}
onClick={() =>
router.push(RouterInvestasi.detail_saham_terbeli + `${e.id}`)
}
bg={"green.3"}
>
<CardSection>
<Group position="left" mt={"sm"} px={"md"}>
<Flex align={"center"} gap={"xs"}>
<Avatar src={"/aset/avatar.png"} />
<Text>Username</Text>
</Flex>
</Group>
</CardSection>
<CardSection p={"xs"}>
<CardSection p={"md"}>
<AspectRatio ratio={16 / 9}>
{/* {e.imagesId ? (
<Image alt="" src={`/api/investasi/gambar/${e.imagesId}`} />
) : (
<Image alt="" src={"/aset/no-img.png"} />
)} */}
<Image alt="" src={"/aset/no-img.png"} />
<Paper radius={"md"}>
{e.Investasi.imagesId ? (
<Image
alt=""
src={`/api/investasi/gambar/${e.Investasi.imagesId}`}
/>
) : (
<Image alt="" src={"/aset/no-img.png"} />
)}
</Paper>
</AspectRatio>
</CardSection>
<CardSection p={"lg"}>
<Box mb={"md"}>
<Title order={4}>{e.title}</Title>
<Slider
size={10}
disabled
labelAlwaysOn
value={e.persentase}
marks={[{ value: e.persentase, label: e.persentase + `%` }]}
/>
</Box>
</CardSection>
<CardSection p={"md"}>
<Box>
<Grid>
<Grid.Col span={6}>
<Stack>
<Box>
<Text>Dana Dibutuhkan</Text>
<Text>Rp. {e.targetDana}</Text>
</Box>
<Box>
<Text>Harga Per Lembar</Text>
<Text>Rp. {e.hargaLembar}</Text>
</Box>
</Stack>
</Grid.Col>
<Grid.Col span={6}>
<Stack>
<Box>
<Text>ROI</Text>
<Text>{e.roi}%</Text>
</Box>
<Box>
<Text>Total Lembar</Text>
<Text>{e.totalLembar}</Text>
</Box>
</Stack>
</Grid.Col>
</Grid>
</Box>
</CardSection>
<Divider />
<CardSection p={"md"}>
<Group position="apart">
{e.statusSaham.id === 1 ? (
<Badge variant="dot">{e.statusSaham.status}</Badge>
) : (
<Badge variant="dot" color="red">
{e.statusSaham.status}
</Badge>
)}
{(() => {
if (
e.masterPencarianInvestorId -
moment(new Date()).diff(new Date(e.createdAt), "days") <=
0
) {
return (
<>
<Group position="center">
<IconCircleCheck color="green" />
<Text>Selesai</Text>
</Group>
</>
);
} else {
return (
<>
<Group position="right" spacing={"xs"}>
<Text>Sisa waktu:</Text>
<Text>
{e.masterPencarianInvestorId -
moment(new Date()).diff(
new Date(e.createdAt),
"days"
)}
</Text>
<Text>Hari</Text>
</Group>
</>
);
<CardSection p={"lg"}>
<Stack>
<Center>
<Title order={4}>{e.Investasi.title}</Title>
</Center>
<Progress
label={
"" +
(
((+e.Investasi.totalLembar - +e.Investasi.sisaLembar) /
+e.Investasi.totalLembar) *
100
).toFixed(1) +
"%"
}
})()}
</Group>
value={
+(
((+e.Investasi.totalLembar - +e.Investasi.sisaLembar) /
+e.Investasi.totalLembar) *
100
).toFixed(2)
}
color="teal"
size="xl"
radius="xl"
/>
</Stack>
</CardSection>
<Stack>
<CardSection px={"md"}>
<Group>
<Text>Saham Terbeli :</Text>
<Text fz={"xl"} >{new Intl.NumberFormat("id-ID", {maximumFractionDigits: 10}).format(+ e.quantity)} Lembar</Text>
</Group>
<Group>
<Text> Total Pembelian :</Text>
<Text fz={"xl"} >Rp. {new Intl.NumberFormat("id-ID", {maximumFractionDigits: 10}).format(+ e.gross_amount)}</Text>
</Group>
</CardSection>
<CardSection py={"sm"}>
<Group position="center">
<Button
radius={"xl"}
compact
bg={Warna.hijau_muda}
color="green"
onClick={() =>
router.push(
RouterInvestasi.detail_saham_terbeli + `${e.id}`
)
}
>
Details
</Button>
</Group>
</CardSection>
</Stack>
</Card>
))}
))} */}
<Paper bg={"gray.4"} p={"md"}>
<Group position="apart">
<Group>
<Avatar radius={"xl"} />
<Text>Username</Text>
</Group>
<Button bg={"green.5"} radius={"xl"}>
Detail
</Button>
</Group>
<Divider color="black.3" my={"md"} />
<Stack>
<Center>
<Title order={4}>Judul Investasi</Title>
</Center>
<Progress size={"xl"} value={40} label="40 %" radius={"xl"} />
<Image alt="" src={"/aset/no-img.png"} radius={"md"}/>
</Stack>
</Paper>
</>
);
}

View File

@@ -30,6 +30,8 @@ import { MODEL_Investasi } from "../model/model_investasi";
import _ from "lodash";
import { useState } from "react";
import { useShallowEffect } from "@mantine/hooks";
import { RouterInvestasi } from "@/app/lib/router_hipmi/router_investasi";
import { Warna } from "@/app/lib/warna";
export default function MainInvestasi({
listData,
@@ -44,6 +46,18 @@ export default function MainInvestasi({
}) {
const router = useRouter();
const [investasi, setInvestasi] = useState(listData);
const [progres, setProgres] = useState(0);
async function onProgres(data: MODEL_Investasi) {
// console.log(data)
const total = Number(data.totalLembar);
const sisa = Number(data.sisaLembar);
const beli = total - sisa;
const hasil = (beli / total) * 100;
const progres = Math.round(hasil).toFixed(2);
// console.log(progres)
return progres;
}
if (_.isEmpty(investasi))
return (
@@ -65,8 +79,7 @@ export default function MainInvestasi({
radius={"md"}
key={e.id}
mb={"lg"}
bg={"teal.4"}
onClick={() => router.push(`/dev/investasi/detail/${e.id}`)}
bg={"dark.1"}
>
<CardSection p={"md"}>
<AspectRatio ratio={16 / 9}>
@@ -85,12 +98,23 @@ export default function MainInvestasi({
<Stack>
<Title order={4}>{e.title}</Title>
<Progress
label={`${e.progress}%`}
value={Number(e.progress)}
label={
"" +
(
((+e.totalLembar - +e.sisaLembar) / +e.totalLembar) *
100
).toFixed(1) +
"%"
}
value={
+(
((+e.totalLembar - +e.sisaLembar) / +e.totalLembar) *
100
).toFixed(2)
}
color="teal"
size="xl"
radius="xl"
animate
/>
</Stack>
</CardSection>
@@ -127,9 +151,9 @@ export default function MainInvestasi({
<Text>{e.roi}%</Text>
</Box>
<Box>
<Text>Total Lembar</Text>
<Text>Sisa Lembar</Text>
<Text>
{new Intl.NumberFormat("id-ID").format(+e.totalLembar)}
{new Intl.NumberFormat("id-ID").format(+e.sisaLembar)}
</Text>
</Box>
</Stack>
@@ -139,7 +163,7 @@ export default function MainInvestasi({
</CardSection>
<Divider color="dark.4" />
<CardSection p={"md"}>
<Flex gap={"xl"} align={"center"} justify={"center"}>
<Group position="apart">
{/* <Box>
{e.SahamTerbeli === null ? (
""
@@ -149,18 +173,36 @@ export default function MainInvestasi({
</Badge>
)}
</Box> */}
<Button
radius={"xl"}
compact
bg={Warna.hijau_muda}
color="green"
onClick={() => router.push(RouterInvestasi.detail + `${e.id}`)}
>
Details
</Button>
{(() => {
if (
Number(e.MasterPencarianInvestor.name) -
moment(new Date()).diff(new Date(e.createdAt), "days") <=
moment(new Date()).diff(new Date(e.countDown), "days") <=
0
) {
return (
<>
<Group position="right">
<Group position="right" spacing={"xs"}>
<IconCircleCheck color="green" />
<Text c={"green"}>Selesai</Text>
<Text
variant="text"
c={Warna.hijau_tua}
sx={{ fontFamily: "Greycliff CF, sans-serif" }}
ta="center"
fz="md"
fw={700}
>
Waktu Habis
</Text>
</Group>
</>
);
@@ -172,7 +214,7 @@ export default function MainInvestasi({
<Text>
{Number(e.MasterPencarianInvestor.name) -
moment(new Date()).diff(
new Date(e.updatedAt),
new Date(e.countDown),
"days"
)}
</Text>
@@ -182,7 +224,7 @@ export default function MainInvestasi({
);
}
})()}
</Flex>
</Group>
</CardSection>
</Card>
))}

View File

@@ -26,22 +26,27 @@ export interface MODEL_Investasi {
masterPeriodeDevidenId: string;
masterPembagianDevidenId: string;
masterPencarianInvestorId: string;
author: MODEL_User_profile
author: MODEL_User_profile;
countDown: Date
}
export interface MODEL_Transaksi_Investasi {
id: string;
namaBank: string;
nomorRekening: string;
totalTransfer: string;
lembarTerbeli: string;
active: boolean;
createdAt: Date;
updatedAt: Date;
investasiId: string;
authorId: string;
quantity: string;
price: string;
gross_amount: string;
merchant_name: string;
redirect_url: string;
token: string;
Author: MODEL_User_profile;
masterStatusTransaksiInvestasiId: string;
MasterStatusTransaksiInvestasi: Model_Status_Transaksi_Investasi;
investasiId: string;
Investasi: MODEL_Investasi;
}

View File

@@ -24,11 +24,12 @@ import {
import _ from "lodash";
import moment from "moment";
import { useState } from "react";
import { IconCircleCheck } from "@tabler/icons-react";
import { IconChecklist, IconCircleCheck } from "@tabler/icons-react";
export default function Publish({ data }: { data: MODEL_Investasi[] }) {
const router = useRouter();
const [sisaWaktu, setSisaWaktu] = useState();
if (_.isEmpty(data))
return (
<>
@@ -74,7 +75,7 @@ export default function Publish({ data }: { data: MODEL_Investasi[] }) {
</AspectRatio>
</Grid.Col>
</Grid>
<Divider my={"xs"}/>
<Divider my={"xs"} />
<Group position="center">
{Number(e.MasterPencarianInvestor.name) -
moment(new Date()).diff(new Date(e.updatedAt), "days") <=
@@ -88,12 +89,22 @@ export default function Publish({ data }: { data: MODEL_Investasi[] }) {
{/* <Badge color="green" variant="dot">
Publish
</Badge> */}
<Text>
Sisa Waktu :{" "}
<Group>
{Number(e.MasterPencarianInvestor.name) -
moment(new Date()).diff(new Date(e.updatedAt), "days")}{" "}
hari
</Text>
moment(new Date()).diff(new Date(e.countDown), "days") <=
0 ? (
<Group>
<IconChecklist />
<Text>Selesai</Text>
</Group>
) : (
<Box>
Sisa Waktu : {}
{Number(e.MasterPencarianInvestor.name) -
moment(new Date()).diff(new Date(e.countDown), "days")} hari
</Box>
)}
</Group>
</Group>
)}
</Group>

View File

@@ -80,8 +80,8 @@ export default function PortofolioInvestasi({
<Stack>
<Button
radius={"xl"}
bg={Warna.biru}
color="blue"
bg={Warna.hijau_muda}
color="green"
leftIcon={<IconCirclePlus />}
onClick={() => router.push(RouterInvestasi.create)}
>

View File

@@ -49,29 +49,64 @@ export default function ProsesInvestasi({
);
const [transferValue, setTransferValue] = useAtom(gs_TransferValue);
async function onBeli() {
setTransferValue({
...transferValue,
totalTransfer: total as any,
lembarTerbeli: jumlah as any,
});
router.push(RouterInvestasi.metode_transfer + `${investasi.id}`);
// async function onBeli() {
// setTransferValue({
// ...transferValue,
// totalTransfer: total as any,
// lembarTerbeli: jumlah as any,
// });
// router.push(RouterInvestasi.metode_transfer + `${investasi.id}`);
// }
const date = new Date();
const randomId = date.getTime();
async function onProses() {
const body = {
transaction_details: {
order_id: "hipmi_" + `${randomId}`,
gross_amount: total,
},
item_details: [
{
id: "item_"+ `${randomId}`,
name: investasi.title,
price: Number(investasi.hargaLembar),
quantity: transferValue.lembarTerbeli,
merchant_name: "Transaksi Saham",
},
],
customer_details: {
first_name: "",
email: "test@midtrans.com",
phone: "+628123456",
},
};
}
return (
<>
{/* <pre>{JSON.stringify(transferValue, null, 2)}</pre> */}
{/* <pre>{JSON.stringify(investasi, null, 2)}</pre> */}
<Box px={"md"}>
{/* Sisa Lembar Saham */}
<Group position="apart" mb={"md"}>
<Text>Sisa Lembar Saham</Text>
<Text fz={23}>{investasi.totalLembar} </Text>
<Text fz={23}>
{new Intl.NumberFormat("id-ID", {
maximumFractionDigits: 10,
}).format(+investasi.totalLembar)}{" "}
</Text>
</Group>
{/* Harga perlembar saham */}
<Group position="apart" mb={"md"}>
<Text>Harga Perlembar</Text>
<Text fz={23}>Rp.{investasi.hargaLembar} </Text>
<Text fz={23}>
Rp.{" "}
{new Intl.NumberFormat("id-ID", {
maximumFractionDigits: 10,
}).format(+investasi.hargaLembar)}{" "}
</Text>
</Group>
{/* Lembar saham */}
@@ -118,7 +153,8 @@ export default function ProsesInvestasi({
radius={50}
bg={Warna.biru}
onClick={() => {
onBeli();
// onBeli();
onProses();
}}
>
Beli Saham

View File

@@ -0,0 +1,19 @@
"use client";
import HeaderTamplate from "@/app_modules/component/header_tamplate";
import { AppShell } from "@mantine/core";
import React from "react";
export default function LayoutProsesTransaksiInvestasi({
children,
}: {
children: React.ReactNode;
}) {
return (
<>
<AppShell header={<HeaderTamplate title="Proses Transaksi" />}>
{children}
</AppShell>
</>
);
}

View File

@@ -0,0 +1,218 @@
"use client";
import { Warna } from "@/app/lib/warna";
import {
Box,
Group,
NumberInput,
Divider,
Center,
Button,
Text,
} from "@mantine/core";
import { useFocusTrap } from "@mantine/hooks";
import { useRouter } from "next/navigation";
import { MODEL_Investasi } from "../model/model_investasi";
import { MODEL_User_profile } from "@/app_modules/home/models/user_profile";
import { useEffect, useState } from "react";
import getTokenTransaksi from "../fun/get_token_transaksi";
import toast from "react-simple-toasts";
import funUpdatePaymentInvestasi from "../fun/fun_update_payment";
import { RouterInvestasi } from "@/app/lib/router_hipmi/router_investasi";
import { useAtom } from "jotai";
import { gs_investasiFooter } from "../g_state";
import funUpdateInvestasi from "../fun/fun_update_investasi";
export default function ProsesTransaksiInvestasi({ dataInvestasi, userLogin }) {
const router = useRouter();
const focusTrapRef = useFocusTrap();
const [investasi, setInvestasi] = useState(dataInvestasi);
const [user, setUser] = useState(userLogin);
const [maxPembelian, setMaxPembelian] = useState(
Number(investasi.sisaLembar)
);
const [total, setTotal] = useState(0);
const [jumlah, setJumlah] = useState(0);
const [hotmenu, setHotmenu] = useAtom(gs_investasiFooter);
// console.log(userLogin.id);
// console.log(investasi);
async function onProses() {
const body = {
// customer_details
authorId: userLogin.id,
customer_name: userLogin.username,
phone: userLogin.nomor,
// transaction_details
gross_amount: total,
// item_details
item_name: "Saham" + " " + investasi.title,
price: +investasi.hargaLembar,
quantity: jumlah,
merchant_name: investasi.author.username,
// investasi
investasiId: investasi.id,
};
await getTokenTransaksi(body).then(async (res) => {
if (res.token.status === 200) {
// console.log(res.token.value.token)
snap.pay(res.token.value.token, {
onSuccess: async function (result) {
console.log(result);
// console.log("success");
await funUpdatePaymentInvestasi(result, res.dataTransaksi.id).then(
async (resUp) => {
if (resUp.status === 200) {
const hasil =
investasi.sisaLembar - res.dataTransaksi.quantity;
const body = {
id: investasi.id,
sisaLembar: hasil,
};
await funUpdateInvestasi(body);
toast(res.message);
router.push(RouterInvestasi.main_transaksi);
setHotmenu(3);
} else {
toast(res.message);
}
}
);
},
onPending: async function (result) {
await funUpdatePaymentInvestasi(result, res.dataTransaksi.id);
router.push(RouterInvestasi.main_transaksi);
console.log("pending");
console.log(result);
},
onError: async function (result) {
await funUpdatePaymentInvestasi(result, res.dataTransaksi.id);
router.push(RouterInvestasi.main_transaksi);
console.log("error");
console.log(result);
},
onClose: async function (result) {
if (result === undefined) {
const data = {
status_code: "400",
};
await funUpdatePaymentInvestasi(data, res.dataTransaksi.id);
router.push(RouterInvestasi.main_transaksi);
// router.push(RouterPay.home);
console.log(data);
}
},
});
} else {
toast("Gagal Membuat Token");
}
});
}
useEffect(() => {
const midTransURl = "https://app.sandbox.midtrans.com/snap/snap.js";
let script = document.createElement("script");
const midTransClientKey = process.env.Client_KEY;
script.src = midTransURl;
script.setAttribute("data-client-key", midTransClientKey);
script.async = true;
document.body.appendChild(script);
return () => {
document.body.removeChild(script);
};
}, []);
return (
<>
<Box px={"md"}>
{/* Sisa Lembar Saham */}
<Group position="apart" mb={"md"}>
<Text>Sisa Lembar Saham</Text>
<Text fz={23}>
{new Intl.NumberFormat("id-ID", {
maximumFractionDigits: 10,
}).format(+investasi.sisaLembar)}{" "}
</Text>
</Group>
{/* Harga perlembar saham */}
<Group position="apart" mb={"md"}>
<Text>Harga Perlembar</Text>
<Text fz={23}>
Rp.{" "}
{new Intl.NumberFormat("id-ID", {
maximumFractionDigits: 10,
}).format(+investasi.hargaLembar)}{" "}
</Text>
</Group>
{/* Lembar saham */}
<Group position="apart" mb={"md"}>
<Box>
<Text>Jumlah Pembelian</Text>
<Text c={"blue"} fs={"italic"} fz={10}>
minimal pembelian 10 lembar
</Text>
{/* <Text c={"red"} fs={"italic"} fz={10}>
maximal pembelian {maxPembelian} lembar
</Text> */}
</Box>
<NumberInput
type="number"
ref={focusTrapRef}
w={100}
max={maxPembelian}
onChange={(val) => {
setTotal(val * +investasi.hargaLembar);
setJumlah(val);
// console.log(val);
}}
/>
</Group>
<Divider my={"lg"} />
<Group position="apart" mb={"md"}>
<Box>
<Text>Total Harga</Text>
</Box>
<Text fz={25}>
Rp.{" "}
{new Intl.NumberFormat("id-ID", {
maximumFractionDigits: 10,
}).format(total)}
</Text>
</Group>
<Center>
{jumlah < 10 ? (
<Button w={350} radius={50} bg={"gray"} disabled>
Beli Saham
</Button>
) : (
<Button
w={350}
radius={50}
bg={Warna.biru}
onClick={() => {
onProses();
}}
>
Beli Saham
</Button>
)}
</Center>
</Box>
</>
);
}

View File

@@ -55,11 +55,11 @@ export default function StatusTransaksiInvestasi_Gagal({
</Group>
<Group position="apart">
<Text>Jumlah Transfer</Text>
<Text fw={"bold"}>Rp. {transaksi.totalTransfer}</Text>
{/* <Text fw={"bold"}>Rp. {transaksi.totalTransfer}</Text> */}
</Group>
<Group position="apart">
<Text>Jumlah Lembar</Text>
<Text fw={"bold"}>{transaksi.lembarTerbeli}</Text>
{/* <Text fw={"bold"}>{transaksi.lembarTerbeli}</Text> */}
</Group>
</Stack>
</Stack>

View File

@@ -1,7 +1,16 @@
"use client";
import { RouterInvestasi } from "@/app/lib/router_hipmi/router_investasi";
import { Badge, Center, Group, Paper, Stack, Text, Title } from "@mantine/core";
import {
Badge,
Box,
Center,
Group,
Paper,
Stack,
Text,
Title,
} from "@mantine/core";
import { useRouter } from "next/navigation";
import toast from "react-simple-toasts";
import {
@@ -14,6 +23,7 @@ import funCountDown from "../fun/fun_countdown_investasi";
import funGantiStatusTransaksi_Investasi from "../fun/fun_ganti_status_transaksi";
import { useInterval, useShallowEffect } from "@mantine/hooks";
import _ from "lodash";
import Link from "next/link";
export default function TransaksiInvestasi({
statusTransaksi,
@@ -25,7 +35,6 @@ export default function TransaksiInvestasi({
const router = useRouter();
const [status, setStatus] = useState(statusTransaksi);
const [transaksi, setTransaksi] = useState(listTransaksi);
async function onKlik(statusId: string, transaksiId: string) {
// console.log(id)
@@ -46,34 +55,38 @@ export default function TransaksiInvestasi({
}
}
if(_.isEmpty(transaksi))
return <>
<Center h={"80vh"}>
<Title order={5}>Tidak Ada Transaksi</Title>
</Center>
</>
if (_.isEmpty(transaksi))
return (
<>
<Center h={"80vh"}>
<Title order={5}>Tidak Ada Transaksi</Title>
</Center>
</>
);
return (
<>
<Stack>
{transaksi.map((e) => (
<Paper
key={e.id}
p="xs"
bg={"gray"}
onClick={() => onKlik(e.masterStatusTransaksiInvestasiId, e.id)}
>
<Group position="apart">
<Title order={6}>{e.Investasi.title}</Title>
<Title order={5}>Rp.{e.totalTransfer}</Title>
</Group>
<Group position="apart">
<Stack spacing={0}>
<Text fz={"xs"}>Bank {e.namaBank}</Text>
<Text fz={"xs"}>{moment(e.createdAt).format("ll")}</Text>
</Stack>
{(() => {
<Box key={e.id}>
<Link href={e.redirect_url} style={{textDecorationLine: "none"}}>
<Paper p="xs" bg={"gray"}>
<Group position="apart">
<Title order={6}>{e.Investasi.title}</Title>
<Title order={5}>
Rp.
{new Intl.NumberFormat("id-ID", {
maximumFractionDigits: 10,
}).format(+e.gross_amount)}
</Title>
</Group>
<Group position="apart">
<Stack spacing={0}>
{/* <Text fz={"xs"}>Bank {e.namaBank}</Text> */}
<Text fz={"xs"}>{moment(e.createdAt).format("ll")}</Text>
</Stack>
<Text>{e.quantity} Lembar</Text>
{/* {(() => {
if (e.masterStatusTransaksiInvestasiId === "1") {
return (
<>
@@ -125,9 +138,11 @@ export default function TransaksiInvestasi({
}
}
}
})()}
</Group>
</Paper>
})()} */}
</Group>
</Paper>
</Link>
</Box>
))}
</Stack>
{/* <pre>{JSON.stringify(transaksi, null, 2)}</pre> */}

View File

@@ -190,11 +190,11 @@ export default function TransferInvestasi({
>
<Grid align="center">
<Grid.Col span={8}>
<Text fw={"bold"}>Rp. {transaksi.totalTransfer}</Text>
{/* <Text fw={"bold"}>Rp. {transaksi.totalTransfer}</Text> */}
</Grid.Col>
<Grid.Col span={4}>
<Center>
<CopyButton value={transaksi.totalTransfer}>
{/* <CopyButton value={transaksi.totalTransfer}>
{({ copied, copy }) => (
<Button
variant="filled"
@@ -207,7 +207,7 @@ export default function TransferInvestasi({
{copied ? "Tersalin" : "Salin"}
</Button>
)}
</CopyButton>
</CopyButton> */}
</Center>
</Grid.Col>
</Grid>

View File

@@ -6,9 +6,5 @@
{
"id": "2",
"name": "6"
},
{
"id": "3",
"name": "12"
}
]