Transaksi

# feat:
- proses transfer
- metode pembayaran
### issue:
- data nama bank dan rekenening belum masuk
This commit is contained in:
2023-11-18 08:33:56 +08:00
parent 71834ddb2f
commit 19e870f8cd
38 changed files with 615 additions and 219 deletions

View File

@@ -11,18 +11,19 @@ datasource db {
}
model User {
id String @id @default(cuid())
username String @unique
nomor String @unique
active Boolean @default(true)
createdAt DateTime? @default(now())
updatedAt DateTime? @updatedAt
MasterUserRole MasterUserRole @relation(fields: [masterUserRoleId], references: [id])
masterUserRoleId String @default("1")
UserSession UserSession?
Profile Profile?
Investasi Investasi[]
SahamTerbeli SahamTerbeli[]
id String @id @default(cuid())
username String @unique
nomor String @unique
active Boolean @default(true)
createdAt DateTime? @default(now())
updatedAt DateTime? @updatedAt
MasterUserRole MasterUserRole @relation(fields: [masterUserRoleId], references: [id])
masterUserRoleId String @default("1")
UserSession UserSession?
Profile Profile?
Investasi Investasi[]
// Investor Investor[]
TransaksiInvestasi TransaksiInvestasi[]
}
model MasterUserRole {
@@ -124,12 +125,13 @@ model Investasi {
ProspektusInvestasi ProspektusInvestasi?
SahamTerbeli SahamTerbeli? @relation(fields: [sahamTerbeliId], references: [id])
sahamTerbeliId String?
MasterStatusInvestasi MasterStatusInvestasi? @relation(fields: [masterStatusInvestasiId], references: [id])
masterStatusInvestasiId String? @default("1")
BeritaInvestasi BeritaInvestasi[]
DokumenInvestasi DokumenInvestasi[]
// Investor Investor[]
TransaksiInvestasi TransaksiInvestasi[]
}
model MasterPencarianInvestor {
@@ -203,15 +205,41 @@ model BeritaInvestasi {
investasiId String
}
model SahamTerbeli {
id String @id @default(cuid())
totalBeli String
jumlahLembar String
active Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
author User @relation(fields: [authorId], references: [id])
authorId String
investasi Investasi[]
model MasterBank {
id String @id @default(cuid())
name String
norek String
active Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model TransaksiInvestasi {
id String @id @default(cuid())
Investasi Investasi? @relation(fields: [investasiId], references: [id])
investasiId String?
Author User? @relation(fields: [authorId], references: [id])
authorId String?
namaBank String
nomorRekening String
lembarTerbeli String
totalTransfer String
active Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
// model Investor {
// id String @id @default(cuid())
// totalBeli String
// jumlahLembar String
// active Boolean @default(true)
// createdAt DateTime @default(now())
// updatedAt DateTime @updatedAt
// Investasi Investasi? @relation(fields: [investasiId], references: [id])
// investasiId String?
// User User? @relation(fields: [userId], references: [id])
// userId String?
// }

View File

@@ -6,6 +6,7 @@ import pencarianInvestor from "./../../../bin/seeder/investasi/pencarian_investo
import periodeDeviden from "./../../../bin/seeder/investasi/periode_deviden.json";
import pembagianDeviden from "./../../../bin/seeder/investasi/pembagian_deviden.json";
import statusInvestasi from "./../../../bin/seeder/investasi/status_investasi.json";
import namaBank from "./../../../bin/seeder/investasi/nama_bank.json";
export async function GET(req: Request) {
const dev = new URL(req.url).searchParams.get("dev");
@@ -108,6 +109,24 @@ export async function GET(req: Request) {
});
}
for (let i of namaBank) {
await prisma.masterBank.upsert({
where: {
id: i.id.toString(),
},
create: {
id: i.id.toString(),
name: i.name,
norek: i.norek.toString(),
},
update: {
id: i.id.toString(),
name: i.name,
norek: i.norek.toString(),
},
});
}
return NextResponse.json({ success: true });
}

View File

@@ -2,10 +2,30 @@ import { funGetUserProfile } from "@/app_modules/fun/get_user_profile";
import { DetailInvestasi } 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)
const dataUser = await funGetUserProfile(dataInvestasi?.authorId as any)
return<>
<DetailInvestasi dataInvestasi={dataInvestasi as any} dataUser={dataUser as any}/>
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({ params }: { params: { id: string } }) {
const c = cookies().get("ssn");
const usr = JSON.parse(
await unsealData(c?.value as string, {
password: config.server.password,
})
);
const loginUserId = usr.id;
const dataInvestasi = await getOneInvestasiById(params.id);
const dataUser = await funGetUserProfile(dataInvestasi?.authorId as any);
return (
<>
<DetailInvestasi
dataInvestasi={dataInvestasi as any}
dataUser={dataUser as any}
loginUserId={loginUserId}
/>
</>
}
);
}

View File

@@ -0,0 +1,32 @@
import { MetodeTransferInvestasi } from "@/app_modules/investasi";
import getOneInvestasiById from "@/app_modules/investasi/fun/get_one_investasi_by_id";
import getMaster_NamaBank from "@/app_modules/investasi/fun/master/get_nama_bank";
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({ params }: { params: { id: string } }) {
const c = cookies().get("ssn");
const usr = JSON.parse(
await unsealData(c?.value as string, {
password: config.server.password,
})
);
const authorId = usr.id;
const dataInvestasi = await getOneInvestasiById(params.id);
const namaBank = await getMaster_NamaBank();
// console.log(namaBank)
return (
<>
<MetodeTransferInvestasi
dataInvestasi={dataInvestasi as any}
namaBank={namaBank as any}
authorId={authorId}
/>
</>
);
}

View File

@@ -1,9 +0,0 @@
import { MetodeTransferInvestasi } from "@/app_modules/investasi";
export default async function Page() {
return (
<>
<MetodeTransferInvestasi />
</>
);
}

View File

@@ -0,0 +1,11 @@
import { ProsesInvestasi } 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)
return<>
<ProsesInvestasi dataInvestasi={dataInvestasi as any}/>
</>
}

View File

@@ -1,7 +0,0 @@
import { ProsesInvestasi } from "@/app_modules/investasi";
export default async function Page() {
return<>
<ProsesInvestasi/>
</>
}

View File

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

View File

@@ -1,7 +0,0 @@
import { TransferInvestasi } from "@/app_modules/investasi";
export default async function Page() {
return<>
<TransferInvestasi/>
</>
}

View File

@@ -8,7 +8,7 @@ export const RouterInvestasi = {
main_porto: "/dev/investasi/main/portofolio",
main_investasi: "/dev/investasi/main/saham_saya",
main_transaksi: "/dev/investasi/main/transaksi",
transfer: "/dev/investasi/transfer",
transfer: "/dev/investasi/transfer/",
dialog_transaksi: "/dev/investasi/dialog_page/transaksi_saham",
dialog_create: "/dev/investasi/dialog_page/create",
@@ -16,9 +16,10 @@ export const RouterInvestasi = {
portofolio: "/dev/investasi/main/portofolio",
// proses beli saham
proses_investasi: "/dev/investasi/proses_investasi/",
status_transaksi: "/dev/investasi/status_transaksi/berhasil",
status_transaksi_gagal: "/dev/investasi/status_transaksi/gagal",
metode_transfer: "/dev/investasi/metode_transfer",
metode_transfer: "/dev/investasi/metode_transfer/",
// edit //
edit: "/dev/investasi/edit/",

View File

@@ -29,7 +29,6 @@ export default async function Admin_funGetAllInvestasi() {
MasterPembagianDeviden: true,
MasterPencarianInvestor: true,
MasterPeriodeDeviden: true,
SahamTerbeli: true,
},
})
// console.log(res)

View File

@@ -8,7 +8,7 @@ import funEditInvestasi from "@/app_modules/investasi/fun/fun_edit_investasi";
import funGantiStatusInvestasi from "@/app_modules/investasi/fun/fun_ganti_status";
import { gs_StatusPortoInvestasi } from "@/app_modules/investasi/g_state";
import { MODEL_Investasi } from "@/app_modules/investasi/model/model_investasi";
import { MODEL_User_profile } from "@/app_modules/models/user_profile";
import { MODEL_User_profile } from "@/app_modules/home/models/user_profile";
import {
Group,
Flex,

View File

@@ -44,7 +44,7 @@ import { gs_ListPortofolio } from "../katalog/portofolio/state/global_state";
import { myConsole } from "@/app/fun/my_console";
import { getFotoProfile } from "../katalog/profile/api/get-foto-profile";
import { funGetUserProfile } from "../fun/get_user_profile";
import { MODEL_User_profile } from "../models/user_profile";
import { MODEL_User_profile } from "./models/user_profile";
import AppNotif from "../notif";
// export const dynamic = "force-dynamic"

View File

@@ -30,19 +30,24 @@ import { useRouter } from "next/navigation";
import { useState } from "react";
import { MODEL_Investasi } from "../model/model_investasi";
import moment from "moment";
import { MODEL_User_profile } from "@/app_modules/models/user_profile";
import { MODEL_User_profile } from "@/app_modules/home/models/user_profile";
import { RouterUserProfile } from "@/app/lib/router_hipmi/router_user_profile";
import { gs_TransferValue } from "../g_state";
import { useAtom } from "jotai";
export default function DetailInvestasi({
dataInvestasi,
dataUser,
loginUserId,
}: {
dataInvestasi: MODEL_Investasi;
dataUser: MODEL_User_profile;
loginUserId: string;
}) {
const router = useRouter();
const [investasi, setInvestasi] = useState(dataInvestasi);
const [user, setUser] = useState(dataUser);
const [transaksiValue, setTransaksiValue] = useAtom(gs_TransferValue);
const listBox = [
{
@@ -65,6 +70,18 @@ export default function DetailInvestasi({
},
];
async function onSubmit() {
router.push(RouterInvestasi.proses_investasi + `${investasi.id}`);
setTransaksiValue({
...transaksiValue,
lembarTerbeli: "",
namaBank: "",
nomorRekening: "",
totalTransfer: "",
});
}
return (
<>
{/* Foto username dan sisa waktu */}
@@ -99,7 +116,10 @@ export default function DetailInvestasi({
<Paper withBorder mb={"md"} p={"xs"}>
<AspectRatio ratio={16 / 9}>
<Image alt="" src={RouterInvestasi.api_gambar + `${investasi.imagesId}`} />
<Image
alt=""
src={RouterInvestasi.api_gambar + `${investasi.imagesId}`}
/>
</AspectRatio>
</Paper>
@@ -108,11 +128,18 @@ export default function DetailInvestasi({
<Title order={4} mb={"xs"}>
{investasi.title}
</Title>
<Progress label="0%" value={0} color="teal" size="xl" radius="xl" animate/>
<Progress
label="0%"
value={0}
color="teal"
size="xl"
radius="xl"
animate
/>
</Box>
{/* Rincian Data */}
<Grid p={"md"} mb={"md"}>
{/* Rincian Data */}
<Grid p={"md"} mb={"md"}>
<Grid.Col span={6}>
<Stack>
<Box>
@@ -167,16 +194,26 @@ export default function DetailInvestasi({
))}
</Grid>
<Center mb={"md"}>
<Button
radius={50}
w={350}
bg={Warna.biru}
onClick={() => router.push("/dev/investasi/proses_investasi")}
>
Investasi
</Button>
</Center>
{loginUserId === investasi.authorId ? (
<Center mb={"md"}>
<Button disabled radius={50} w={350}>
Investasi Ini Milik Anda
</Button>
</Center>
) : (
<Center mb={"md"}>
<Button
radius={50}
w={350}
bg={Warna.biru}
onClick={() => {
onSubmit()
}}
>
Investasi
</Button>
</Center>
)}
</>
);
}

View File

@@ -0,0 +1,28 @@
"use server";
import prisma from "@/app/lib/prisma";
import { MODEL_Transaksi_Investasi } from "../model/model_investasi";
export default async function funCreateTransaksiInvestasi(
data: MODEL_Transaksi_Investasi,
invesId: string,
authorId: string
) {
const res = await prisma.transaksiInvestasi.create({
data: {
namaBank: data.namaBank,
nomorRekening: data.nomorRekening,
lembarTerbeli: "" + data.lembarTerbeli,
totalTransfer: "" + data.totalTransfer,
investasiId: invesId,
authorId: authorId,
},
});
if (!res) return { status: 400, message: "Gagal disimpan" };
return {
status: 201,
message: "Berhasil disimpan",
res
};
}

View File

@@ -26,7 +26,6 @@ export default async function funLoadDataInvestasi(id: string) {
MasterPembagianDeviden: true,
MasterPencarianInvestor: true,
MasterPeriodeDeviden: true,
SahamTerbeli: true,
},
});

View File

@@ -28,7 +28,6 @@ export default async function getInvestasiByStatusId(
MasterPembagianDeviden: true,
MasterPencarianInvestor: true,
MasterPeriodeDeviden: true,
SahamTerbeli: true,
},
},
},

View File

@@ -36,7 +36,7 @@ export async function getListAllPublish() {
MasterPembagianDeviden: true,
MasterPencarianInvestor: true,
MasterPeriodeDeviden: true,
SahamTerbeli: true,
},
});

View File

@@ -0,0 +1,21 @@
"use server";
import prisma from "@/app/lib/prisma";
export default async function getNorekInvestasi(id: string) {
const res = await prisma.masterBank.findUnique({
where: { id: id },
select: {
name: true,
norek: true,
},
});
if(!res) return {status: 400, message: "Nomor rekeneing tidak tersedia"}
return {
res,
status: 200,
message: "Berhasil"
}
}

View File

@@ -27,7 +27,6 @@ export default async function getOneInvestasiById(id: string) {
MasterPembagianDeviden: true,
MasterPencarianInvestor: true,
MasterPeriodeDeviden: true,
SahamTerbeli: true,
},
});

View File

@@ -0,0 +1,25 @@
"use server"
import prisma from "@/app/lib/prisma"
export default async function getTransaksiInvestasi(id: string) {
const data = await prisma.transaksiInvestasi.findUnique({
where: {
id: id
},
select: {
id: true,
namaBank: true,
nomorRekening: true,
lembarTerbeli: true,
totalTransfer: true,
active: true,
createdAt: true,
updatedAt: true,
Author: true,
Investasi: true
}
})
return data
}

View File

@@ -0,0 +1,8 @@
"use server"
import prisma from "@/app/lib/prisma"
export default async function getMaster_NamaBank() {
const data = await prisma.masterBank.findMany()
return data
}

View File

@@ -1,4 +1,15 @@
import { atom } from "jotai";
import { atomWithStorage } from "jotai/utils";
export const gs_investasiFooter = atomWithStorage<number>("changeColor", 0)
export const gs_StatusPortoInvestasi = atomWithStorage<any | string>("gs_TabPortoInvestasi" , "Draft")
export const gs_investasiFooter = atomWithStorage<number>("changeColor", 0);
export const gs_StatusPortoInvestasi = atomWithStorage<any | string>(
"gs_TabPortoInvestasi",
"Draft"
);
export const gs_TransferValue = atomWithStorage("gs_TransferValue", {
lembarTerbeli: "",
totalTransfer: "",
namaBank: "",
nomorRekening: "",
});

View File

@@ -122,7 +122,7 @@ export default function MainInvestasi({
<Divider />
<CardSection p={"md"}>
<Flex gap={"xl"} align={"center"} justify={"center"}>
<Box>
{/* <Box>
{e.SahamTerbeli === null ? (
""
) : (
@@ -130,7 +130,7 @@ export default function MainInvestasi({
Saham Anda
</Badge>
)}
</Box>
</Box> */}
{(() => {
if (

View File

@@ -18,53 +18,96 @@ import { useShallowEffect } from "@mantine/hooks";
import { useRouter } from "next/navigation";
import { useState } from "react";
import toast from "react-simple-toasts";
import {
MODEL_Investasi,
MODEL_Transaksi_Investasi,
Model_Nama_Bank,
} from "../model/model_investasi";
import { useAtom } from "jotai";
import { gs_TransferValue } from "../g_state";
import getNorekInvestasi from "../fun/get_norek";
import _ from "lodash";
import funCreateTransaksiInvestasi from "../fun/fun_create_transaksi";
const listNoRekening = [
{
id: 1,
name: "BRI",
norek: "9065456754325643",
},
{
id: 2,
name: "BCA",
norek: "2304235678854332",
},
{
id: 3,
name: "BNI",
norek: "1104786754324564",
},
{
id: 4,
name: "BSI",
norek: "7076543567898976",
},
];
// const listNoRekening = [
// {
// id: 1,
// name: "BRI",
// norek: "9065456754325643",
// },
// {
// id: 2,
// name: "BCA",
// norek: "2304235678854332",
// },
// {
// id: 3,
// name: "BNI",
// norek: "1104786754324564",
// },
// {
// id: 4,
// name: "BSI",
// norek: "7076543567898976",
// },
// ];
export default function MetodeTransferInvestasi() {
export default function MetodeTransferInvestasi({
dataInvestasi,
namaBank,
authorId,
}: {
dataInvestasi: MODEL_Investasi;
namaBank: Model_Nama_Bank[];
authorId: string;
}) {
const [total, setTotal] = useState<any | null>(null);
const [checked, setChecked] = useState(false);
const [bank, setBank] = useState("");
const [investasi, setInvestasi] = useState(dataInvestasi);
const [bank, setBank] = useState(namaBank);
const [pilihBank, setPilihBank] = useState("");
const router = useRouter();
useShallowEffect(() => {
if (typeof window !== undefined) {
const data = localStorage.getItem("total_harga");
setTotal(data);
}
}, []);
const [transferValue, setTransferValue] = useAtom(gs_TransferValue);
const [transaksi, setTransaksi] = useState<MODEL_Transaksi_Investasi>();
async function onSubmit() {
router.push(RouterInvestasi.transfer);
localStorage.setItem("bank", bank);
// Cek Nomor Rekening
const getNorek = await getNorekInvestasi(pilihBank).then((res) => {
if (res.status === 200) {
setTransferValue({
...transferValue,
namaBank: res.res?.name as any,
nomorRekening: res.res?.norek as any,
});
return res.status;
} else {
toast(res.message);
}
});
if (getNorek === 200) {
// Create Transaksi
await funCreateTransaksiInvestasi(
transferValue as any,
investasi.id,
authorId
).then(async (res) => {
if (res.status === 201) {
toast(res.message);
router.push(RouterInvestasi.transfer + `${res.res?.id}`);
} else {
toast(res.message);
}
});
}
}
return (
<>
{/* <pre>{JSON.stringify(transferValue, null, 2)}</pre> */}
{/* Box judul */}
<Paper h={70} bg={"gray"} p={"xs"} shadow="lg" mb={"md"}>
<Title order={5}>Judul Proyek Investasi</Title>
<Text fz={"sm"}>Total Transfer : Rp.{total}</Text>
<Paper bg={"gray"} p={"xs"} shadow="lg" mb={"md"}>
<Title order={5}>{investasi.title}</Title>
<Text fz={"sm"}>Total Transfer : Rp.{transferValue.totalTransfer}</Text>
</Paper>
{/* Metode transfer */}
@@ -74,19 +117,18 @@ export default function MetodeTransferInvestasi() {
description="Pilih salah satu bank"
withAsterisk
my={"md"}
onChange={setBank}
onChange={setPilihBank}
>
<Flex direction={"column"} gap={"lg"} mt="xs">
{listNoRekening.map((e) => (
{bank.map((e) => (
<Box key={e.id}>
<Radio value={e.norek} label={e.name}/>
<Radio value={e.id} label={e.name} />
</Box>
))}
</Flex>
</Radio.Group>
<Center>
{bank === "" ? (
{pilihBank === "" ? (
<Button my={"md"} w={300} disabled radius={50}>
Pilih
</Button>
@@ -100,7 +142,7 @@ export default function MetodeTransferInvestasi() {
onSubmit();
}}
>
Pilih
Lanjutkan Untuk Transfer
</Button>
)}
</Center>

View File

@@ -1,3 +1,5 @@
import { MODEL_User_profile } from "@/app_modules/home/models/user_profile";
export interface MODEL_Investasi {
id: string;
title: string;
@@ -18,7 +20,19 @@ export interface MODEL_Investasi {
MasterPembagianDeviden: Model_All_Master;
MasterPencarianInvestor: Model_All_Master;
MasterPeriodeDeviden: Model_All_Master;
SahamTerbeli: null;
}
export interface MODEL_Transaksi_Investasi {
id: string;
lembarTerbeli: string,
totalTransfer: string,
namaBank: string,
nomorRekening: string
active: true;
createdAt: Date;
updatedAt: Date;
Author: MODEL_User_profile,
Investasi: MODEL_Investasi
}
export interface MODEL_Status_investasi {
@@ -61,3 +75,12 @@ export interface Model_Dokumen_Investasi {
updatedAt: Date
investasiId: string
}
export interface Model_Nama_Bank {
id: string,
name: string,
norek: string,
active: boolean,
createdAt: Date,
updatedAt: Date
}

View File

@@ -14,7 +14,7 @@ import {
Text,
Title,
} from "@mantine/core";
import { useCounter, useShallowEffect } from "@mantine/hooks";
import { useCounter, useFocusTrap, useShallowEffect } from "@mantine/hooks";
import {
IconMinus,
IconNumber10Small,
@@ -25,61 +25,75 @@ import _ from "lodash";
import { useRouter } from "next/navigation";
import { useState } from "react";
import toast from "react-simple-toasts";
import { MODEL_Investasi } from "../model/model_investasi";
import { error } from "console";
import { useAtom } from "jotai";
import { gs_TransferValue } from "../g_state";
export default function ProsesInvestasi() {
export default function ProsesInvestasi({
dataInvestasi,
}: {
dataInvestasi: MODEL_Investasi;
}) {
const router = useRouter();
// const [count, handlers] = useCounter(0, { min: 1, max: 1000 });
const [sisaLembar, setSisaLembar] = useState(5000);
const [hargaLembar, setHargaLembar] = useState(1000);
const [beli, setBeli] = useState(0);
const focusTrapRef = useFocusTrap();
const [jumlah, setJumlah] = useState(0);
const [hargaLembar, setHargaLembar] = useState<number>(
Number(dataInvestasi.hargaLembar)
);
const [total, setTotal] = useState(0);
// const formatter = new Intl.NumberFormat("", {
// style: 'currency',
// currency: 'RP',
// });
async function onProses() {
if (beli === 0) return toast("Masukan jumlah pembelian saham");
if (beli < 10) return toast("Minimal pemebelian 10 Lembar");
const hasil = hargaLembar * beli;
setTotal(hasil);
}
const [investasi, setInvestasi] = useState(dataInvestasi);
const [maxPembelian, setMaxPembelian] = useState<number>(
Number(dataInvestasi.totalLembar)
);
const [transferValue, setTransferValue] = useAtom(gs_TransferValue);
async function onBeli() {
router.push(RouterInvestasi.metode_transfer);
localStorage.setItem("total_harga", total as any);
setTransferValue({
...transferValue,
totalTransfer: total as any,
lembarTerbeli: jumlah as any,
});
router.push(RouterInvestasi.metode_transfer + `${investasi.id}`);
}
return (
<>
{/* <pre>{JSON.stringify(transferValue, null, 2)}</pre> */}
<Box px={"md"}>
{/* Sisa Lembar Saham */}
<Group position="apart" mb={"md"}>
<Text>Sisa Lembar Saham</Text>
<Text fz={23}>{sisaLembar} </Text>
<Text fz={23}>{investasi.totalLembar} </Text>
</Group>
{/* Harga perlembar saham */}
<Group position="apart" mb={"md"}>
<Text>Harga Perlembar</Text>
<Text fz={23}>Rp.{hargaLembar} </Text>
<Text fz={23}>Rp.{investasi.hargaLembar} </Text>
</Group>
{/* Lembar saham */}
<Group position="apart" mb={"md"}>
<Box>
<Text>Jumlah Pembelian</Text>
<Text fs={"italic"} fz={"xs"}>
<Text c={"orange"} 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}
value={beli}
max={maxPembelian}
onChange={(val: number) => {
setTotal(val * hargaLembar);
setJumlah(val);
// console.log(val);
}}
/>
</Group>
@@ -92,8 +106,9 @@ export default function ProsesInvestasi() {
</Box>
<Text fz={25}>Rp.{total} </Text>
</Group>
<Center>
{total < 10000 ? (
{jumlah < 10 ? (
<Button w={350} radius={50} bg={"gray"} disabled>
Beli Saham
</Button>
@@ -111,6 +126,8 @@ export default function ProsesInvestasi() {
)}
</Center>
</Box>
{/* <pre>{JSON.stringify(investasi, null, 2)}</pre> */}
</>
);
}

View File

@@ -44,24 +44,11 @@ export default function LayoutTransferInvestasi({
</Group>
</Header>
}
footer={
<Footer height={70} sx={{ borderStyle: "none" }}>
<Center>
<Button
radius={50}
w={300}
bg={Warna.biru}
onClick={() => {
router.push(RouterInvestasi.dialog_transaksi);
setHotMenu(1);
// router.push(RouterInvestasi.status_transaksi);
}}
>
Sudah Transfer
</Button>
</Center>
</Footer>
}
// footer={
// <Footer height={70} sx={{ borderStyle: "none" }}>
// </Footer>
// }
>
{children}
</AppShell>

View File

@@ -7,6 +7,7 @@ import {
Box,
Button,
Center,
CopyButton,
Divider,
FileButton,
Flex,
@@ -25,44 +26,85 @@ import { useRouter } from "next/navigation";
import { useState } from "react";
import Countdown from "react-countdown";
import {
MODEL_Investasi,
MODEL_Transaksi_Investasi,
} from "../model/model_investasi";
import { RouterInvestasi } from "@/app/lib/router_hipmi/router_investasi";
import { useAtom } from "jotai";
import { gs_investasiFooter } from "../g_state";
export default function TransferInvestasi() {
export default function TransferInvestasi({
dataTransaksi,
}: {
dataTransaksi: MODEL_Transaksi_Investasi;
}) {
const router = useRouter();
const [fl, setFl] = useState<File | null>(null);
const [img, setImg] = useState<any | null>(null);
const [total, setTotal] = useState<any | null>(null);
const [bank, setBank] = useState<any | null>(null);
const [transaksi, setTransaksi] = useState(dataTransaksi);
const [hotMenu, setHotMenu] = useAtom(gs_investasiFooter);
const [countDown, setCountDown] = useState({
jam: "",
menit: "",
detik: "",
});
const PopupCD = () => (
<Text fz={"xs"} c={"white"}>
Gagal
</Text>
);
// useShallowEffect(() => {
// const inter = apa_kabar("2023-11-18");
// return () => clearInterval(inter);
// }, []);
// function apa_kabar(date: string) {
// let d = moment.duration(moment(date).diff(new Date()));
// const inter = setInterval(() => {
// d = moment.duration(+d - 1000, "milliseconds");
// console.log(d.days(), "=", d.hours(), ":", d.minutes(), ":", d.seconds());
// }, 1000);
// return inter;
// }
useShallowEffect(() => {
if (typeof window !== undefined) {
const totalHarga = localStorage.getItem("total_harga");
const pilihBank = localStorage.getItem("bank");
setTotal(totalHarga);
setBank(pilihBank);
}
const mulai = moment(transaksi.createdAt).format();
const selesai = moment(transaksi.createdAt).add(1, "days").format();
const inter = funCountDown(mulai as any, selesai as any);
return () => clearInterval(inter);
}, []);
const PopupCD = () => <Text fz={"xs"} c={"white"}>Gagal</Text>;
const countD = ({ hours, minutes, seconds, completed }: any) => {
if (completed) {
return PopupCD();
} else {
return (
<>
{hours}:{minutes}:{seconds}
</>
);
}
};
function funCountDown(mulai: Date, selesai: Date) {
// console.log(selesai)
let d = moment.duration(moment(selesai).diff(new Date()));
const inter = setInterval(() => {
d = moment.duration(+d - 1000, "milliseconds");
// console.log(d.hours(),":", d.minutes(),":", d.seconds())
setCountDown({
...countDown,
jam: "" + d.hours(),
menit: "" + d.minutes(),
detik: "" + d.seconds(),
});
}, 1000);
return inter;
}
return (
<>
{/* <pre>{JSON.stringify(moment(transaksi.createdAt).format("LTS"))}</pre> */}
<Stack spacing={"lg"}>
<Stack spacing={0} mb={"xs"}>
<Title order={5}>Mohon transfer ke Xendit</Title>
<Text fz={12}>Mohon transfer untuk diteruskan ke :</Text>
<Group align="center">
<Text>untuk diteruskan ke </Text>
<Title order={5}>Nama Pemilik Proyek</Title>
<Title order={5}>{transaksi.Investasi.title}</Title>
</Group>
<Divider my={"md"} />
<Grid>
@@ -70,14 +112,16 @@ export default function TransferInvestasi() {
<Text fz={"xs"}>Transfer sebelum</Text>
</Grid.Col>
<Grid.Col span={5}>
<Text fz={"xs"} fw={"bold"}>{moment().local().add(1, "day").calendar()}</Text>
<Text fz={"xs"} fw={"bold"}>
{moment.locale()}
</Text>
</Grid.Col>
<Grid.Col span={3} fz={"xs"} >
<Paper bg={"red"} px={"md"}>
<Center>
<Countdown date={Date.now() + 86400000} renderer={countD} />
</Center>
</Paper>
<Grid.Col span={3} fz={"xs"}>
<Paper bg={"red"} px={"md"}>
<Center>
{countDown.jam}:{countDown.menit}:{countDown.detik}
</Center>
</Paper>
</Grid.Col>
</Grid>
</Stack>
@@ -88,25 +132,35 @@ export default function TransferInvestasi() {
<Group>
<Avatar size={"md"} variant="filled" />
<Stack spacing={0}>
<Text>Nama Bank</Text>
<Text>Bank {transaksi.namaBank}</Text>
<Text>PT. Xendit Jakarta</Text>
</Stack>
</Group>
<Paper
bg={"gray"}
bg={"gray.3"}
sx={{ alignContent: "center" }}
p={"sm"}
radius={10}
>
<Grid align="center">
<Grid.Col span={8}>
<Text fw={"bold"}>{bank}</Text>
<Text fw={"bold"}>{transaksi.nomorRekening}</Text>
</Grid.Col>
<Grid.Col span={4}>
<Center>
<Button compact variant="outline" color="dark" radius={50}>
Salin
</Button>
<CopyButton value={transaksi.nomorRekening}>
{({ copied, copy }) => (
<Button
variant="filled"
radius={50}
compact
bg={copied ? "teal" : "gray"}
onClick={copy}
>
{copied ? "Tersalin" : "Salin"}
</Button>
)}
</CopyButton>
</Center>
</Grid.Col>
</Grid>
@@ -115,22 +169,32 @@ export default function TransferInvestasi() {
{/* Nomor rekening */}
<Stack spacing={5}>
<Text>Jumlah Transfer</Text>
<Text>Total Transfer</Text>
<Paper
bg={"gray"}
bg={"gray.3"}
sx={{ alignContent: "center" }}
p={"sm"}
radius={10}
>
<Grid align="center">
<Grid.Col span={8}>
<Text fw={"bold"}>Rp. {total}</Text>
<Text fw={"bold"}>Rp. {transaksi.totalTransfer}</Text>
</Grid.Col>
<Grid.Col span={4}>
<Center>
<Button compact variant="outline" color="dark" radius={50}>
Salin
</Button>
<CopyButton value={transaksi.totalTransfer}>
{({ copied, copy }) => (
<Button
variant="filled"
radius={50}
compact
bg={copied ? "teal" : "gray"}
onClick={copy}
>
{copied ? "Tersalin" : "Salin"}
</Button>
)}
</CopyButton>
</Center>
</Grid.Col>
</Grid>
@@ -142,6 +206,22 @@ export default function TransferInvestasi() {
</Stack>
</Stack>
</Stack>
{/* Tombol Sudah Transfer */}
<Center mt={100}>
<Button
radius={50}
w={300}
bg={Warna.biru}
onClick={() => {
router.push(RouterInvestasi.dialog_transaksi);
setHotMenu(1);
// router.push(RouterInvestasi.status_transaksi);
}}
>
Sudah Transfer
</Button>
</Center>
</>
);
}

View File

@@ -34,7 +34,7 @@ import { getFotoProfile } from "../profile/api/get-foto-profile";
import { ApiHipmi } from "@/app/lib/api";
import { ListPortofolioView } from "../portofolio";
import { User } from "@prisma/client";
import { MODEL_User_profile } from "@/app_modules/models/user_profile";
import { MODEL_User_profile } from "@/app_modules/home/models/user_profile";
import { LIST_PORTOFOLIO } from "@/app_modules/models/portofolio";
export default function KatalogView({ user, listPorto }: { user: MODEL_User_profile, listPorto: LIST_PORTOFOLIO }) {

View File

@@ -13,7 +13,7 @@ import { useState } from "react";
import toast from "react-simple-toasts";
import { gs_profile } from "../state/global_state";
import { loadDataProfile } from "../fun/fun_get_profile";
import { MODEL_User_profile } from "@/app_modules/models/user_profile";
import { MODEL_User_profile } from "@/app_modules/home/models/user_profile";
import funEditProfile from "../fun/fun_edit_profile";
export default function EditProfile({ data }: { data: MODEL_User_profile }) {

View File

@@ -1,7 +1,7 @@
"use server";
import prisma from "@/app/lib/prisma";
import { MODEL_User_profile } from "@/app_modules/models/user_profile";
import { MODEL_User_profile } from "@/app_modules/home/models/user_profile";
export default async function funEditProfile(data: MODEL_User_profile) {
const res = await prisma.profile.update({

View File

@@ -32,7 +32,7 @@ import { loadDataProfile } from "../fun/fun_get_profile";
import { getFotoProfile } from "../api/get-foto-profile";
import { gs_fotoProfile, gs_profile } from "../state/global_state";
import { getProfile } from "..";
import { MODEL_User_profile } from "@/app_modules/models/user_profile";
import { MODEL_User_profile } from "@/app_modules/home/models/user_profile";
import { funGetUserProfile } from "@/app_modules/fun/get_user_profile";
export default function ProfileView({ user }: { user: MODEL_User_profile }) {

View File

@@ -0,0 +1,22 @@
[
{
"id": 1,
"name": "BRI",
"norek": "9065456754325643"
},
{
"id": 2,
"name": "BCA",
"norek": "2304235678854332"
},
{
"id": 3,
"name": "BNI",
"norek": "1104786754324564"
},
{
"id": 4,
"name": "BSI",
"norek": "7076543567898976"
}
]