Pembelian Saham

# feat:
- Fitur pembelian saham
- Status transaksi
- Table transaksi
- Table nama bank
### No Issue
This commit is contained in:
2023-11-21 10:08:46 +08:00
parent 19e870f8cd
commit 812f47fbf9
155 changed files with 208 additions and 359411 deletions

View File

@@ -5,7 +5,7 @@ import { randomOTP } from "@/app/fun/rondom_otp";
import { ApiHipmi } from "@/app/lib/api";
import { Warna } from "@/app/lib/warna";
import { Button, Center, Flex, Stack, TextInput, Title } from "@mantine/core";
import { getHotkeyHandler, useHotkeys } from "@mantine/hooks";
import { getHotkeyHandler, useFocusTrap, useHotkeys } from "@mantine/hooks";
import { useRouter } from "next/navigation";
import { useState } from "react";
import toast from "react-simple-toasts";
@@ -19,6 +19,7 @@ export default function Login() {
const [nomor, setNomor] = useState("");
const [inputNumber, setInputNumber] = useAtom(gs_nomor);
const [code, setCode] = useAtom(gs_otp);
const focusTrapRef = useFocusTrap();
const onLogin = async () => {
const body = {
@@ -67,6 +68,7 @@ export default function Login() {
<Title>Login</Title>
<TextInput
ref={focusTrapRef}
label="Phone Number"
w={250}
type="number"

View File

@@ -11,11 +11,13 @@ import toast from "react-simple-toasts";
import { ApiHipmi } from "@/app/lib/api";
import { useRouter } from "next/navigation";
import _ from "lodash";
import { useFocusTrap } from "@mantine/hooks";
export default function Register() {
const route = useRouter();
const [nomor, setNomor] = useAtom(gs_nomor);
const [value, setValue] = useState("");
const focusTrapRef = useFocusTrap();
const onRegister = async () => {
myConsole(value);
@@ -61,6 +63,7 @@ export default function Register() {
<Flex direction={"column"} gap={"xl"} align={"center"}>
<Flex direction={"column"}>
<TextInput
ref={focusTrapRef}
w={250}
label="Username"
placeholder="Username"

View File

@@ -20,6 +20,7 @@ import toast from "react-simple-toasts";
import { ApiHipmi } from "@/app/lib/api";
import { useRouter } from "next/navigation";
import { funGetUserProfile } from "@/app_modules/fun/get_user_profile";
import { useFocusTrap } from "@mantine/hooks";
export default function Validasi() {
const router = useRouter();
@@ -27,6 +28,7 @@ export default function Validasi() {
const [code, setCode] = useAtom(gs_otp);
const [inputCode, setInputOtp] = useState("");
const focusTrapRef = useFocusTrap();
const onValid = async () => {
// MyConsole(inputCode)
@@ -85,6 +87,7 @@ export default function Validasi() {
<Text>to {nomor}</Text>
</Flex>
<PinInput
ref={focusTrapRef}
spacing={"md"}
mt={"md"}
onChange={(val) => {

View File

@@ -57,6 +57,7 @@ export default function InvestasiCreate({
pembagianDevidenId: "",
});
async function onSubmit() {
const body = {
authorId: id,

View File

@@ -39,10 +39,12 @@ export default function DetailInvestasi({
dataInvestasi,
dataUser,
loginUserId,
progress
}: {
dataInvestasi: MODEL_Investasi;
dataUser: MODEL_User_profile;
loginUserId: string;
progress: number
}) {
const router = useRouter();
const [investasi, setInvestasi] = useState(dataInvestasi);
@@ -129,8 +131,8 @@ export default function DetailInvestasi({
{investasi.title}
</Title>
<Progress
label="0%"
value={0}
label={`${progress} %`}
value={progress}
color="teal"
size="xl"
radius="xl"
@@ -154,6 +156,10 @@ export default function DetailInvestasi({
<Text>Jadwal Pembagian</Text>
<Text>{investasi.MasterPembagianDeviden.name} bulan </Text>
</Box>
<Box>
<Text>Pembagian Deviden</Text>
<Text>{investasi.MasterPeriodeDeviden.name}</Text>
</Box>
</Stack>
</Grid.Col>
<Grid.Col span={6}>
@@ -167,8 +173,8 @@ export default function DetailInvestasi({
<Text>{investasi.totalLembar} lembar</Text>
</Box>
<Box>
<Text>Pembagian Deviden</Text>
<Text>{investasi.MasterPeriodeDeviden.name}</Text>
<Text>Sisa Lembar</Text>
<Text>{investasi.sisaLembar} lembar</Text>
</Box>
</Stack>
</Grid.Col>

View File

@@ -1,34 +0,0 @@
"use client";
import HeaderTamplate from "@/app_modules/component/header_tamplate";
import { ActionIcon, AppShell, Group, Header, Text } from "@mantine/core";
import { IconArrowLeft, IconEdit } from "@tabler/icons-react";
import { useRouter } from "next/navigation";
import router from "next/router";
import { title } from "process";
import React from "react";
export default function LayoutPortofolioDetailInvestasi({
children,
id,
}: {
children: React.ReactNode;
id: string;
}) {
const router = useRouter();
return (
<>
<AppShell
header={
<HeaderTamplate
title="Portofolio Investasi"
icon={<IconEdit />}
route2={`/dev/investasi/edit/${id}`}
/>
}
>
{children}
</AppShell>
</>
);
}

View File

@@ -1,134 +0,0 @@
"use client";
import { RouterInvestasi } from "@/app/lib/router_hipmi/router_investasi";
import {
ActionIcon,
AspectRatio,
Avatar,
Box,
Center,
Flex,
Grid,
Group,
Image,
Paper,
Slider,
Stack,
Text,
Title,
} from "@mantine/core";
import {
IconBookDownload,
IconFileDescription,
IconSpeakerphone,
} from "@tabler/icons-react";
import { useRouter } from "next/navigation";
export default function PortofolioDetailInvestasi({id}: {id: string}) {
const router = useRouter();
const listBox = [
{
id: 1,
name: "Prospektus",
icon: <IconBookDownload size={70} />,
route: RouterInvestasi.edit_prospektus,
},
{
id: 2,
name: "Dokumen",
icon: <IconFileDescription size={70} />,
route: RouterInvestasi.edit_dokumen,
},
{
id: 3,
name: "Berita",
icon: <IconSpeakerphone size={70} />,
route: RouterInvestasi.edit_berita,
},
];
return (
<>
<Center mb={'sm'}>
<Text>Sisa waktu : 20 Hari</Text>
</Center>
<Paper withBorder mb={"md"}>
<AspectRatio ratio={16 / 9}>
<Image alt="" src={"/aset/no-img.png"} />
</AspectRatio>
</Paper>
{/* Title dan Persentase */}
<Box mb={"md"}>
<Title order={4} mb={"xs"}>
Judul Proyek
</Title>
<Slider
disabled
size={10}
value={60}
marks={[{ value: 60, label: "60%" }]}
/>
</Box>
{/* Rincian Data */}
<Grid p={"md"} mb={"md"}>
<Grid.Col span={6}>
<Stack>
<Box>
<Text>Terkumpul</Text>
<Text>Rp. </Text>
</Box>
<Box>
<Text>Dana Dibutuhkan</Text>
<Text>Rp. </Text>
</Box>
<Box>
<Text>Harga Per Lembar</Text>
<Text>Rp. </Text>
</Box>
<Box>
<Text>Jadwal Pembagian</Text>
<Text>3 Bulan </Text>
</Box>
</Stack>
</Grid.Col>
<Grid.Col span={6}>
<Stack>
<Box>
<Text>Investor</Text>
<Text>4657</Text>
</Box>
<Box>
<Text>ROI</Text>
<Text>%</Text>
</Box>
<Box>
<Text>Total Lembar</Text>
<Text>0</Text>
</Box>
<Box>
<Text>Pembagian Deviden</Text>
<Text>Selamanya</Text>
</Box>
</Stack>
</Grid.Col>
</Grid>
{/* List Box */}
{/* <Grid mb={"md"}>
{listBox.map((e) => (
<Grid.Col span={"auto"} key={e.id} onClick={() => router.push(e.route + `${id}`)}>
<Paper h={100} w={100} bg={"gray.4"} withBorder py={"xs"}>
<Flex direction={"column"} align={"center"} justify={"center"}>
<Text fz={12}>{e.name}</Text>
<ActionIcon variant="transparent" size={60}>
{e.icon}
</ActionIcon>
</Flex>
</Paper>
</Grid.Col>
))}
</Grid> */}
</>
);
}

View File

@@ -12,7 +12,12 @@ export async function funCreateInvestasi(
formData: FormData,
data: MODEL_Investasi | any
) {
console.log(data)
// return {
// status: 201,
// message: "Berhasil Disimpan",
// };
const file: any = formData.get("file");
const fName = file.name;
const fExt = _.lowerCase(file.name.split(".").pop());
@@ -37,6 +42,8 @@ export async function funCreateInvestasi(
const upFolder = Buffer.from(await file.arrayBuffer());
fs.writeFileSync(`./public/investasi/${upload.url}`, upFolder);
// console.log(data)
const createInvest = await prisma.investasi.create({
data: {
authorId: data.authorId,
@@ -44,6 +51,7 @@ export async function funCreateInvestasi(
targetDana: data.targetDana.toString(),
hargaLembar: data.hargaLembar.toString(),
totalLembar: data.totalLembar.toString(),
sisaLembar: data.totalLembar.toString() ,
roi: data.roi.toString(),
masterPembagianDevidenId: data.masterPeriodeDevidenId,
masterPeriodeDevidenId: data.masterPembagianDevidenId,
@@ -53,6 +61,7 @@ export async function funCreateInvestasi(
},
});
if (!createInvest)
return {
status: 400,

View File

@@ -0,0 +1,11 @@
"use server";
export default async function funProgressBar(total: number, beli: number) {
const t = total;
const b = beli;
const progress = (b / t) * 100;
const pembulatan = Math.round(progress);
return pembulatan;
}

View File

@@ -18,6 +18,7 @@ export default async function getInvestasiByStatusId(
hargaLembar: true,
targetDana: true,
totalLembar: true,
sisaLembar: true,
roi: true,
active: true,
imagesId: true,

View File

@@ -24,6 +24,8 @@ export async function getListAllPublish() {
hargaLembar: true,
targetDana: true,
totalLembar: true,
sisaLembar: true,
progress: true,
roi: true,
active: true,
createdAt: true,

View File

@@ -14,6 +14,9 @@ export default async function getOneInvestasiById(id: string) {
hargaLembar: true,
targetDana: true,
totalLembar: true,
sisaLembar: true,
lembarTerbeli: true,
progress: true,
roi: true,
active: true,
createdAt: true,

View File

@@ -14,8 +14,6 @@ import CountDownTransaksiInvestasi from "./dialog_page/transaksi_saham/view";
import LayoutCountDownTransaksiInvestasi from "./dialog_page/transaksi_saham/layout";
import PortofolioInvestasi from "./portofolio/view";
import LayoutPortofolioInvestasi from "./portofolio/layout";
import PortofolioDetailInvestasi from "./detail_porto/view";
import LayoutPortofolioDetailInvestasi from "./detail_porto/layout";
import EditInvestasi from "./edit/view";
import LayoutEditInvestasi from "./edit/layout";
import EditIntroInvestasi from "./edit_intro/view";
@@ -83,8 +81,6 @@ export {
LayoutCountDownTransaksiInvestasi as LayoutKonfirmasiBuktiInvestasi,
PortofolioInvestasi,
LayoutPortofolioInvestasi,
PortofolioDetailInvestasi,
LayoutPortofolioDetailInvestasi,
EditInvestasi,
LayoutEditInvestasi,
EditIntroInvestasi,

View File

@@ -29,6 +29,7 @@ import { IconCheck, IconCircleCheck } from "@tabler/icons-react";
import { MODEL_Investasi } from "../model/model_investasi";
import _ from "lodash";
import { useState } from "react";
import { useShallowEffect } from "@mantine/hooks";
export default function MainInvestasi({
listData,
@@ -44,6 +45,7 @@ export default function MainInvestasi({
const router = useRouter();
const [investasi, setInvestasi] = useState(listData);
if (_.isEmpty(investasi))
return (
<>
@@ -80,8 +82,8 @@ export default function MainInvestasi({
<Stack>
<Title order={4}>{e.title}</Title>
<Progress
label="0%"
value={0}
label={`${e.progress}%`}
value={Number(e.progress)}
color="teal"
size="xl"
radius="xl"

View File

@@ -28,29 +28,7 @@ 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",
// },
// ];
import { myConsole } from "@/app/fun/my_console";
export default function MetodeTransferInvestasi({
dataInvestasi,
@@ -61,49 +39,45 @@ export default function MetodeTransferInvestasi({
namaBank: Model_Nama_Bank[];
authorId: string;
}) {
const [total, setTotal] = useState<any | null>(null);
const [investasi, setInvestasi] = useState(dataInvestasi);
const [bank, setBank] = useState(namaBank);
const [pilihBank, setPilihBank] = useState("");
const [pilihBank, setPilihBank] = useState<string | null>(null);
const router = useRouter();
const [transferValue, setTransferValue] = useAtom(gs_TransferValue);
const [transaksi, setTransaksi] = useState<MODEL_Transaksi_Investasi>();
async function onSubmit() {
// Cek Nomor Rekening
const getNorek = await getNorekInvestasi(pilihBank).then((res) => {
// 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);
}
});
}
async function onSelect(id: string) {
await getNorekInvestasi(id).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> */}
<pre>{JSON.stringify(transferValue, null, 2)}</pre>
{/* Box judul */}
<Paper bg={"gray"} p={"xs"} shadow="lg" mb={"md"}>
<Title order={5}>{investasi.title}</Title>
@@ -117,7 +91,11 @@ export default function MetodeTransferInvestasi({
description="Pilih salah satu bank"
withAsterisk
my={"md"}
onChange={setPilihBank}
onChange={(val) => {
setPilihBank(val);
onSelect(val);
}}
value={"" + pilihBank}
>
<Flex direction={"column"} gap={"lg"} mt="xs">
{bank.map((e) => (
@@ -127,10 +105,11 @@ export default function MetodeTransferInvestasi({
))}
</Flex>
</Radio.Group>
<Center>
{pilihBank === "" ? (
{pilihBank === null ? (
<Button my={"md"} w={300} disabled radius={50}>
Pilih
Pilih Bank
</Button>
) : (
<Button

View File

@@ -6,6 +6,8 @@ export interface MODEL_Investasi {
targetDana: string;
hargaLembar: string;
totalLembar: string;
sisaLembar: string,
lembarTerbeli: string
roi: string;
active: true;
createdAt: Date;
@@ -13,6 +15,7 @@ export interface MODEL_Investasi {
authorId: string;
imagesId: string;
catatan: string
progress: string,
MasterStatusInvestasi: MODEL_Status_investasi;
BeritaInvestasi: Model_Berita_Investasi[];
DokumenInvestasi: Model_Dokumen_Investasi[];

View File

@@ -19,6 +19,15 @@ import _ from "lodash";
export default function Draft({ data }: { data: MODEL_Investasi[] }) {
const router = useRouter();
if (_.isEmpty(data))
return (
<>
<Center h={"50vh"}>Tidak ada Draft</Center>
</>
);
return (
<>
{/* <pre> {JSON.stringify(data,null, 2)}</pre> */}

View File

@@ -60,7 +60,7 @@ export default function ProsesInvestasi({
return (
<>
{/* <pre>{JSON.stringify(transferValue, null, 2)}</pre> */}
<pre>{JSON.stringify(transferValue, null, 2)}</pre>
<Box px={"md"}>
{/* Sisa Lembar Saham */}
<Group position="apart" mb={"md"}>

View File

@@ -32,7 +32,7 @@ import {
} from "../model/model_investasi";
import { RouterInvestasi } from "@/app/lib/router_hipmi/router_investasi";
import { useAtom } from "jotai";
import { gs_investasiFooter } from "../g_state";
import { gs_TransferValue, gs_investasiFooter } from "../g_state";
export default function TransferInvestasi({
dataTransaksi,
@@ -47,19 +47,12 @@ export default function TransferInvestasi({
menit: "",
detik: "",
});
const PopupCD = () => (
<Text fz={"xs"} c={"white"}>
Gagal
</Text>
);
const [transferValue, setTransferValue] = useAtom(gs_TransferValue);
// 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(() => {
@@ -67,7 +60,6 @@ export default function TransferInvestasi({
// console.log(d.days(), "=", d.hours(), ":", d.minutes(), ":", d.seconds());
// }, 1000);
// return inter;
// }
@@ -84,7 +76,7 @@ export default function TransferInvestasi({
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())
// console.log(d.hours(), d.minutes(), d.seconds())
setCountDown({
...countDown,
@@ -99,7 +91,8 @@ export default function TransferInvestasi({
return (
<>
{/* <pre>{JSON.stringify(moment(transaksi.createdAt).format("LTS"))}</pre> */}
{/* <pre>{JSON.stringify(transferValue, null, 2)}</pre>
<pre>{JSON.stringify(transaksi, null,2)}</pre> */}
<Stack spacing={"lg"}>
<Stack spacing={0} mb={"xs"}>
<Text fz={12}>Mohon transfer untuk diteruskan ke :</Text>
@@ -113,13 +106,23 @@ export default function TransferInvestasi({
</Grid.Col>
<Grid.Col span={5}>
<Text fz={"xs"} fw={"bold"}>
{moment.locale()}
{moment().add(1, "days").calendar()}
</Text>
</Grid.Col>
<Grid.Col span={3} fz={"xs"}>
<Paper bg={"red"} px={"md"}>
<Center>
{countDown.jam}:{countDown.menit}:{countDown.detik}
{countDown.jam === "0" &&
countDown.menit === "0" &&
countDown.detik === "0" ? (
<Box>
<Text>Waktu habis</Text>
</Box>
) : (
<Box>
{countDown.jam}:{countDown.menit}:{countDown.detik}
</Box>
)}
</Center>
</Paper>
</Grid.Col>
@@ -155,6 +158,7 @@ export default function TransferInvestasi({
radius={50}
compact
bg={copied ? "teal" : "gray"}
color="gray"
onClick={copy}
>
{copied ? "Tersalin" : "Salin"}
@@ -189,6 +193,7 @@ export default function TransferInvestasi({
radius={50}
compact
bg={copied ? "teal" : "gray"}
color="gray"
onClick={copy}
>
{copied ? "Tersalin" : "Salin"}