Bursa Investasi

# feat:
- Tampilan portofolio selesai
- Hapus investasi
- Function get data publish
### no issue
This commit is contained in:
2023-11-15 16:14:27 +08:00
parent 989c9eed32
commit e2e30c2af0
44 changed files with 910 additions and 414 deletions

View File

@@ -1,6 +1,9 @@
"use server"
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 { revalidatePath } from "next/cache"
export default async function funRejectInvestasi(data: any) {
// console.log(data)
@@ -14,6 +17,8 @@ export default async function funRejectInvestasi(data: any) {
})
if(!res) return {status: 400, message: "Gagal reject"}
revalidatePath(RouterAdminInvestasi.main_investasi)
return {
status: 200,
message: "Reject berhasil"

View File

@@ -1,7 +1,8 @@
import SplashScreen from "./splash/view";
import Login from "./login/view";
import Validasi from "./validasi/view";
import LayoutValidasi from "./validasi/layout";
import Register from "./register/view";
import Logout from "./logout/view";
export { SplashScreen, Login, Validasi, Register, Logout };
export { SplashScreen, Login, Validasi, Register, Logout, LayoutValidasi };

View File

@@ -43,7 +43,7 @@ export default function Login() {
router.push(RouterAdminDashboard.splash_admin);
} else {
if (val.status == 200) {
toast(val.message);
toast("Nomor OTP terkirim");
setCode(val.body.otp);
setInputNumber(val.body.nomor);
router.push("/dev/auth/validasi");

View File

@@ -1,13 +1,14 @@
"use client";
import { myConsole } from "@/app/fun/my_console";
import { ApiHipmi } from "@/app/lib/api";
import { ActionIcon, Button } from "@mantine/core";
import { ActionIcon, Button, Group, Modal } from "@mantine/core";
import { useRouter } from "next/navigation";
import { useAtom } from "jotai";
import { gs_nomor, gs_otp } from "../state/state";
import { IconLogout } from "@tabler/icons-react";
import { Warna } from "@/app/lib/warna";
import { gs_token } from "@/app_modules/home/state/global_state";
import { useDisclosure } from "@mantine/hooks";
export default function Logout() {
const router = useRouter();
@@ -15,6 +16,7 @@ export default function Logout() {
const [code, setCode] = useAtom(gs_otp);
const [token, setToken] = useAtom(gs_token);
const [opened, { toggle }] = useDisclosure(false);
const onLogout = async () => {
// MyConsole("keluar");
@@ -25,7 +27,7 @@ export default function Logout() {
if (val.status == 200) {
setnomor(null);
setCode(null);
setToken(null)
setToken(null);
return router.push("/dev/auth/login");
}
@@ -34,9 +36,25 @@ export default function Logout() {
return (
<>
<ActionIcon variant="transparent">
<IconLogout color={Warna.merah} onClick={() => onLogout()}/>
</ActionIcon>
<Modal opened={opened} onClose={toggle} centered title="Yakin ingin keluar ?">
<Group align="center" position="center">
<Button compact onClick={toggle} radius={50}>
Batal
</Button>
<Button
compact
radius={50}
bg={Warna.merah}
color="red"
onClick={() => onLogout()}
>
Keluar
</Button>
</Group>
</Modal>
<ActionIcon variant="transparent">
<IconLogout color={Warna.merah} onClick={toggle} />
</ActionIcon>
</>
);
}

View File

@@ -0,0 +1,31 @@
"use client";
import { ActionIcon, AppShell, Group, Header } from "@mantine/core";
import { IconChevronLeft } from "@tabler/icons-react";
import { useRouter } from "next/navigation";
import React from "react";
export default function LayoutValidasi({
children,
}: {
children: React.ReactNode;
}) {
const router = useRouter()
return (
<>
<AppShell
header={
<Header height={50} sx={{borderStyle: "none"}} px={"md"}>
<Group h={50} align="center">
<ActionIcon variant="transparent" onClick={() => router.back()} >
<IconChevronLeft />
</ActionIcon>
</Group>
</Header>
}
>
{children}
</AppShell>
</>
);
}

View File

@@ -2,6 +2,7 @@
import { useAtom } from "jotai";
import {
ActionIcon,
Button,
Center,
Flex,
@@ -14,7 +15,7 @@ import { gs_nomor, gs_otp } from "../state/state";
import { Warna } from "@/app/lib/warna";
import { useState } from "react";
import { myConsole } from "@/app/fun/my_console";
import { IconCircleLetterH } from "@tabler/icons-react";
import { IconChevronLeft, IconCircleLetterH } from "@tabler/icons-react";
import toast from "react-simple-toasts";
import { ApiHipmi } from "@/app/lib/api";
import { useRouter } from "next/navigation";
@@ -62,13 +63,14 @@ export default function Validasi() {
<>
{/* {JSON.stringify(nomor)}
{JSON.stringify(code)} */}
<Flex
align={"center"}
justify={"center"}
direction={"column"}
gap={50}
h={"100vh"}
h={"80vh"}
>
<Title order={4}>Validasi Kode OTP</Title>
<IconCircleLetterH size={150} />

View File

@@ -34,6 +34,7 @@ export default function BeritaInvestasi({
berita.BeritaInvestasi.map((e) => (
<Paper
key={e.id}
mb={"md"}
w={"100%"}
bg={"gray"}
p={"sm"}

View File

@@ -14,6 +14,7 @@ import {
Group,
Image,
Paper,
Progress,
Slider,
Stack,
Text,
@@ -21,13 +22,28 @@ import {
} from "@mantine/core";
import {
IconBookDownload,
IconCircleCheck,
IconFileDescription,
IconSpeakerphone,
} from "@tabler/icons-react";
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 { RouterUserProfile } from "@/app/lib/router_hipmi/router_user_profile";
export default function DetailInvestasi({id}: {id: string}) {
export default function DetailInvestasi({
dataInvestasi,
dataUser,
}: {
dataInvestasi: MODEL_Investasi;
dataUser: MODEL_User_profile;
}) {
const router = useRouter();
const [investasi, setInvestasi] = useState(dataInvestasi);
const [user, setUser] = useState(dataUser);
const listBox = [
{
id: 1,
@@ -39,7 +55,7 @@ export default function DetailInvestasi({id}: {id: string}) {
id: 2,
name: "Dokumen",
icon: <IconFileDescription size={70} />,
route: RouterInvestasi.detail_dokumen
route: RouterInvestasi.detail_dokumen,
},
{
id: 3,
@@ -51,72 +67,81 @@ export default function DetailInvestasi({id}: {id: string}) {
return (
<>
{/* Foto username dan sisa waktu */}
<Group position="apart" mb={"md"}>
<Flex align={"center"} gap={"xs"}>
<Avatar src={"/aset/avatar.png"} />
<Text>Username</Text>
<Avatar
radius={50}
src={
RouterUserProfile.api_foto + `${user.Profile?.ImageProfile?.url}`
}
/>
<Text>{user.username}</Text>
</Flex>
<Text>Sisa waktu : 20 Hari</Text>
{Number(investasi.MasterPencarianInvestor.name) -
moment(new Date()).diff(new Date(investasi.updatedAt), "days") <=
0 ? (
<Group position="right">
<IconCircleCheck color="green" />
<Text c={"green"}>Selesai</Text>
</Group>
) : (
<Group position="right" spacing={"xs"}>
<Text>Sisa waktu:</Text>
<Text>
{Number(investasi.MasterPencarianInvestor.name) -
moment(new Date()).diff(new Date(investasi.updatedAt), "days")}
</Text>
<Text>Hari</Text>
</Group>
)}
</Group>
<Paper withBorder mb={"md"}>
<Paper withBorder mb={"md"} p={"xs"}>
<AspectRatio ratio={16 / 9}>
<Image alt="" src={"/aset/no-img.png"} />
<Image alt="" src={RouterInvestasi.api_gambar + `${investasi.imagesId}`} />
</AspectRatio>
</Paper>
{/* Title dan Persentase */}
{/* Title dan Progress */}
<Box mb={"md"}>
<Title order={4} mb={"xs"}>
Judul Proyek
{investasi.title}
</Title>
<Slider
disabled
size={10}
value={60}
marks={[{ value: 60, label: "60%" }]}
/>
<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>
<Text>Terkumpul</Text>
<Text>Rp. </Text>
</Box>
<Box>
<Text>Dana Dibutuhkan</Text>
<Text>Rp. </Text>
<Text>Rp. {investasi.targetDana}</Text>
</Box>
<Box>
<Text>Harga Per Lembar</Text>
<Text>Rp. </Text>
<Text>Rp. {investasi.hargaLembar}</Text>
</Box>
<Box>
<Text>Jadwal Pembagian</Text>
<Text>3 Bulan </Text>
<Text>{investasi.MasterPembagianDeviden.name} 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>
<Text>{investasi.roi}%</Text>
</Box>
<Box>
<Text>Total Lembar</Text>
<Text>0</Text>
<Text>{investasi.totalLembar} lembar</Text>
</Box>
<Box>
<Text>Pembagian Deviden</Text>
<Text>Selamanya</Text>
<Text>{investasi.MasterPeriodeDeviden.name}</Text>
</Box>
</Stack>
</Grid.Col>
@@ -125,7 +150,11 @@ export default function DetailInvestasi({id}: {id: string}) {
{/* List Box */}
<Grid mb={"md"}>
{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.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>

View File

@@ -14,6 +14,7 @@ import {
Group,
Image,
Paper,
Progress,
Slider,
Stack,
Text,
@@ -21,22 +22,32 @@ import {
} from "@mantine/core";
import {
IconBookDownload,
IconCircleCheck,
IconFileDescription,
IconSpeakerphone,
} from "@tabler/icons-react";
import { useAtom } from "jotai";
import { useRouter } from "next/navigation";
import toast from "react-simple-toasts";
import { MODEL_Investasi } from "../../model/model_investasi";
import { useState } from "react";
import moment from "moment";
import _ from "lodash";
export default function DetailPublishInvestasi() {
export default function DetailPublishInvestasi({
dataInvestasi,
}: {
dataInvestasi: MODEL_Investasi;
}) {
const router = useRouter();
const [investasi, setInvestasi] = useState(dataInvestasi);
const listBox = [
{
id: 1,
name: "Prospektus",
icon: <IconBookDownload size={70} />,
route: RouterInvestasi.edit_prospektus,
route: RouterInvestasi.detail_prospektus,
},
{
id: 2,
@@ -48,73 +59,81 @@ export default function DetailPublishInvestasi() {
id: 3,
name: "Berita",
icon: <IconSpeakerphone size={70} />,
route: RouterInvestasi.edit_berita,
route: RouterInvestasi.list_edit_berita,
},
];
return (
<>
<Center mb={"sm"}>
<Text>Sisa waktu : 20 Hari</Text>
</Center>
{Number(investasi.MasterPencarianInvestor.name) -
moment(new Date()).diff(new Date(investasi.updatedAt), "days") <=
0 ? (
<Group position="right">
<IconCircleCheck color="green" />
<Text c={"green"}>Selesai</Text>
</Group>
) : (
<Group mb={"sm"} position="center">
<Text>
Sisa waktu :{" "}
{Number(investasi.MasterPencarianInvestor.name) -
moment(new Date()).diff(
new Date(investasi.updatedAt),
"days"
)}{" "}
hari
</Text>
</Group>
)}
<Paper withBorder mb={"md"}>
<AspectRatio ratio={16 / 9}>
<Image alt="" src={"/aset/no-img.png"} />
<Image
alt=""
src={RouterInvestasi.api_gambar + `${investasi.imagesId}`}
/>
</AspectRatio>
</Paper>
{/* Title dan Persentase */}
<Box mb={"md"}>
<Title order={4} mb={"xs"}>
Judul Proyek
{investasi.title}
</Title>
<Slider
disabled
size={10}
value={60}
marks={[{ value: 60, label: "60%" }]}
/>
<Progress color="lime" radius="xl" size="xl" value={0} label="0 %" />
</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>
<Text>Rp. {investasi.targetDana}</Text>
</Box>
<Box>
<Text>Harga Per Lembar</Text>
<Text>Rp. </Text>
<Text>Rp. {investasi.hargaLembar}</Text>
</Box>
<Box>
<Text>Jadwal Pembagian</Text>
<Text>3 Bulan </Text>
<Text>{investasi.MasterPembagianDeviden.name} 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>
<Text>{investasi.roi}%</Text>
</Box>
<Box>
<Text>Total Lembar</Text>
<Text>0</Text>
<Text>{investasi.totalLembar} lembar</Text>
</Box>
<Box>
<Text>Pembagian Deviden</Text>
<Text>Selamanya</Text>
<Text>{investasi.MasterPeriodeDeviden.name}</Text>
</Box>
</Stack>
</Grid.Col>
@@ -126,7 +145,7 @@ export default function DetailPublishInvestasi() {
<Grid.Col
span={"auto"}
key={e.id}
onClick={() => router.push(e.route + `${1}`)}
onClick={() => router.push(e.route + `${investasi.id}`)}
>
<Paper h={100} w={100} bg={"gray.4"} withBorder py={"xs"}>
<Flex direction={"column"} align={"center"} justify={"center"}>

View File

@@ -1,23 +1,30 @@
"use client"
"use client";
import HeaderTamplate from "@/app_modules/component/header_tamplate"
import { AppShell } from "@mantine/core"
import { IconEdit } from "@tabler/icons-react"
import React from "react"
import HeaderTamplate from "@/app_modules/component/header_tamplate";
import { AppShell } from "@mantine/core";
import { IconEdit } from "@tabler/icons-react";
import React from "react";
export default function LayoutDetailRejecttInvestasi({children}: {children: React.ReactNode}){
return<>
<AppShell
header={
<HeaderTamplate title="Detail Reject"
icon={<IconEdit />}
route2={`/dev/investasi/edit/${1}`}
/>
}
>
export default function LayoutDetailRejecttInvestasi({
children,
idInves,
}: {
children: React.ReactNode;
idInves: string;
}) {
return (
<>
<AppShell
header={
<HeaderTamplate
title="Detail Reject"
icon={<IconEdit />}
route2={`/dev/investasi/edit/${idInves}`}
/>
}
>
{children}
</AppShell>
</AppShell>
</>
}
);
}

View File

@@ -14,6 +14,7 @@ import {
Grid,
Group,
Image,
Modal,
Paper,
Slider,
Stack,
@@ -29,10 +30,21 @@ import { useAtom } from "jotai";
import { useRouter } from "next/navigation";
import { gs_StatusPortoInvestasi } from "../../g_state";
import toast from "react-simple-toasts";
import { MODEL_Investasi } from "../../model/model_investasi";
import { useState } from "react";
import funGantiStatusInvestasi from "../../fun/fun_ganti_status";
import funDeleteInvestasi from "../../fun/fun_delete_investasi";
import { useDisclosure } from "@mantine/hooks";
export default function DetailRejectInvestasi() {
export default function DetailRejectInvestasi({
dataInvestasi,
}: {
dataInvestasi: MODEL_Investasi;
}) {
const router = useRouter();
const [investasi, setInvestasi] = useState(dataInvestasi);
const [activeTab, setActiveTab] = useAtom(gs_StatusPortoInvestasi);
const [opened, { toggle }] = useDisclosure(false);
const listBox = [
{
@@ -56,31 +68,53 @@ export default function DetailRejectInvestasi() {
];
async function onAjukan() {
toast("Project Diajukan Kembali");
router.push(RouterInvestasi.portofolio);
setActiveTab("Review");
await funGantiStatusInvestasi(investasi.id, "2").then((res) => {
if (res.status === 200) {
toast("Project Diajukan Kembali");
router.push(RouterInvestasi.portofolio);
setActiveTab("Review");
} else {
toast("Gagal Pengajuan");
}
});
}
async function onBatal() {
toast("Project Dibatalkan");
router.push(RouterInvestasi.portofolio);
setActiveTab("Reject");
await funDeleteInvestasi(investasi.id).then((res) => {
if (res.status === 200) {
toast(res.message);
toggle();
router.push(RouterInvestasi.portofolio);
} else {
toast(res.message);
}
});
// setActiveTab("Reject");
}
return (
<>
{/* Pop up */}
<Modal
opened={opened}
onClose={toggle}
centered
title="Yakin menghapus data"
>
<Group position="center">
<Button onClick={toggle}>Batal</Button>
<Button bg={Warna.merah} onClick={() => onBatal()}>
Hapus
</Button>
</Group>
</Modal>
{/* Alasan */}
<Box mb={"sm"}>
<Title order={6}>Alasan :</Title>
<Box>
<Paper>
<Text>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Ab
necessitatibus dolores, doloribus porro quis velit unde voluptatem
delectus, nesciunt laboriosam non quae numquam sed tenetur! Minus
earum odio possimus dolore?
</Text>
<Text>{investasi.catatan}</Text>
</Paper>
</Box>
</Box>
@@ -94,6 +128,7 @@ export default function DetailRejectInvestasi() {
radius={50}
bg={"orange.7"}
color="yellow"
compact
onClick={() => onAjukan()}
>
Ajukan Kembali
@@ -101,17 +136,19 @@ export default function DetailRejectInvestasi() {
</Center>
</Grid.Col>
{/* Tombol Hapus */}
<Grid.Col span={6}>
<Center>
{" "}
<Button
compact
mb={"xl"}
radius={50}
bg={"red.7"}
color="yellow"
onClick={() => onBatal()}
onClick={() => toggle()}
>
Batalkan Project
Hapus Project
</Button>
</Center>
</Grid.Col>
@@ -119,22 +156,18 @@ export default function DetailRejectInvestasi() {
<Paper withBorder mb={"md"}>
<AspectRatio ratio={16 / 9}>
<Image alt="" src={"/aset/no-img.png"} />
<Image
alt=""
src={RouterInvestasi.api_gambar + `${investasi.imagesId}`}
/>
</AspectRatio>
</Paper>
{/* Title dan Persentase */}
<Box mb={"md"}>
<Title order={4} mb={"xs"}>
Judul Proyek
{investasi.title}
</Title>
<Slider
disabled
size={10}
value={60}
marks={[{ value: 60, label: "60%" }]}
/>
</Box>
{/* Rincian Data */}
@@ -143,15 +176,19 @@ export default function DetailRejectInvestasi() {
<Stack>
<Box>
<Text>Dana Dibutuhkan</Text>
<Text>Rp. </Text>
<Text>Rp. {investasi.targetDana}</Text>
</Box>
<Box>
<Text>Harga Per Lembar</Text>
<Text>Rp. </Text>
<Text>Rp. {investasi.hargaLembar}</Text>
</Box>
<Box>
<Text>Jadwal Pembagian</Text>
<Text>3 Bulan </Text>
<Text>{investasi.MasterPembagianDeviden.name} Bulan </Text>
</Box>
<Box>
<Text>Pencarian Investor</Text>
<Text>{investasi.MasterPencarianInvestor.name} Hari </Text>
</Box>
</Stack>
</Grid.Col>
@@ -159,22 +196,22 @@ export default function DetailRejectInvestasi() {
<Stack>
<Box>
<Text>ROI</Text>
<Text>%</Text>
<Text>{investasi.roi} %</Text>
</Box>
<Box>
<Text>Total Lembar</Text>
<Text>0</Text>
<Text>{investasi.totalLembar} lembar</Text>
</Box>
<Box>
<Text>Pembagian Deviden</Text>
<Text>Selamanya</Text>
<Text>{investasi.MasterPeriodeDeviden.name}</Text>
</Box>
</Stack>
</Grid.Col>
</Grid>
{/* List Box */}
<Grid mb={"md"}>
{/* <Grid mb={"md"}>
{listBox.map((e) => (
<Grid.Col
span={"auto"}
@@ -191,9 +228,7 @@ export default function DetailRejectInvestasi() {
</Paper>
</Grid.Col>
))}
</Grid>
</Grid> */}
</>
);
}

View File

@@ -25,11 +25,11 @@ export default function DetailPropektus({
target="_blank"
style={{ textDecorationLine: "none" }}
>
<Paper w={"100%"} h={50} bg={"gray"} mb={"md"}>
<Paper w={"100%"} bg={"gray"} mb={"md"}>
<Grid
align="center"
justify="center"
h={50}
px={"sm"}
onClick={() => ""}
>

View File

@@ -5,17 +5,27 @@ import HeaderTamplate from "@/app_modules/component/header_tamplate";
import { AppShell } from "@mantine/core";
import { IconEdit } from "@tabler/icons-react";
import React from "react";
import getOneInvestasiById from "../fun/get_one_investasi_by_id";
import { MODEL_Investasi } from "../model/model_investasi";
export default function LayoutEditProspektusInvestasi({
children,
idInves
dataInvestasi,
}: {
children: React.ReactNode;
idInves: string
dataInvestasi: MODEL_Investasi;
}) {
return (
<>
<AppShell header={<HeaderTamplate title="Edit Prospektus" icon={<IconEdit/>}route2={RouterInvestasi.upload_prospektus + `${idInves}`} />}>
<AppShell
header={
<HeaderTamplate
title="Edit Prospektus"
icon={<IconEdit />}
route2={RouterInvestasi.upload_prospektus + `${dataInvestasi.id}`}
/>
}
>
{children}
</AppShell>
</>

View File

@@ -49,13 +49,13 @@ export default function EditProspektusInvestasi({
px={"sm"}
onClick={() => ""}
>
<Grid.Col span={10}>
<Grid.Col span={11}>
<Group>
{/* <IconFileTypePdf /> */}
<Text lineClamp={1}>Prospektus_{prospek.title}</Text>
</Group>
</Grid.Col>
<Grid.Col span={2}>
<Grid.Col span={1}>
<Center>
<IconChevronRight />
</Center>
@@ -68,7 +68,7 @@ export default function EditProspektusInvestasi({
<Title order={4}>Tidak ada file</Title>
</Center>
)}
<Divider my={"lg"} />
{/* <Divider my={"lg"} /> */}
</Stack>
</>
);

View File

@@ -0,0 +1,26 @@
"use server";
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 { revalidatePath } from "next/cache";
export default async function funDeleteInvestasi(id: string) {
const res = await prisma.investasi.delete({
where: {
id: id,
},
});
if (!res) return { status: 400, message: "Gagal Hapus Data" };
revalidatePath(RouterInvestasi.portofolio)
revalidatePath(RouterAdminInvestasi.main_investasi)
return {
status: 200,
message: "Berhasil Hapus",
};
}

View File

@@ -2,6 +2,7 @@
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 { revalidatePath } from "next/cache";
export default async function funGantiStatusInvestasi(id: string, val: string) {
@@ -16,7 +17,7 @@ export default async function funGantiStatusInvestasi(id: string, val: string) {
if(!data) return {status: 400}
revalidatePath("/dev/investasi/main/portofolio")
revalidatePath(RouterInvestasi.portofolio)
revalidatePath(RouterAdminInvestasi.main_investasi)
return {

View File

@@ -2,9 +2,13 @@
import prisma from "@/app/lib/prisma";
export default async function getInvestasiById(id: string) {
export default async function getInvestasiByStatusId(
id: string,
) {
const data = await prisma.user.findUnique({
where: { id: id },
where: {
id: id,
},
select: {
Investasi: {
select: {

View File

@@ -1,13 +0,0 @@
"use server";
import prisma from "@/app/lib/prisma";
export async function getListAllInvestasi() {
const data = await prisma.investasi.findMany({
orderBy: {
createdAt: "desc"
}
});
return data;
}

View File

@@ -0,0 +1,44 @@
"use server";
import prisma from "@/app/lib/prisma";
export async function getListAllPublish() {
const data = await prisma.investasi.findMany({
orderBy: {
updatedAt: "desc",
},
where: {
MasterStatusInvestasi: {
name: {
equals: "Publish",
},
},
AND: {
active: true
}
},
select: {
id: true,
title: true,
authorId: true,
hargaLembar: true,
targetDana: true,
totalLembar: true,
roi: true,
active: true,
createdAt: true,
updatedAt: true,
imagesId: true,
MasterStatusInvestasi: true,
BeritaInvestasi: true,
DokumenInvestasi: true,
ProspektusInvestasi: true,
MasterPembagianDeviden: true,
MasterPencarianInvestor: true,
MasterPeriodeDeviden: true,
SahamTerbeli: true,
},
});
return data;
}

View File

@@ -16,6 +16,9 @@ export default async function getOneInvestasiById(id: string) {
totalLembar: true,
roi: true,
active: true,
createdAt: true,
updatedAt: true,
catatan: true,
imagesId: true,
MasterStatusInvestasi: true,
BeritaInvestasi: true,

View File

@@ -0,0 +1,104 @@
"use server";
import prisma from "@/app/lib/prisma";
export default async function getPortoByStatusId(id: string, statusId: number) {
// Draft
if (statusId === 1) {
const data = await prisma.investasi.findMany({
orderBy: {
updatedAt: "desc",
},
where: {
authorId: id,
MasterStatusInvestasi: {
name: "Draft",
},
},
select: {
id: true,
title: true,
imagesId: true,
// hargaLembar: true,
// targetDana: true,
// totalLembar: true,
// roi: true,
// active: true,
// MasterStatusInvestasi: true,
// BeritaInvestasi: true,
// DokumenInvestasi: true,
// ProspektusInvestasi: true,
// MasterPembagianDeviden: true,
// MasterPencarianInvestor: true,
// MasterPeriodeDeviden: true,
// SahamTerbeli: true,
},
});
return data;
}
// Review
if (statusId === 2) {
const data = await prisma.investasi.findMany({
orderBy: {
createdAt: "desc",
},
where: {
authorId: id,
MasterStatusInvestasi: {
name: "Review",
},
},
select: {
id: true,
title: true,
imagesId: true,
},
});
return data;
}
// Publish
if (statusId === 3) {
const data = await prisma.investasi.findMany({
orderBy: {
updatedAt: "desc",
},
where: {
authorId: id,
MasterStatusInvestasi: {
name: "Publish",
},
},
select: {
id: true,
title: true,
imagesId: true,
updatedAt: true,
MasterPencarianInvestor: true,
},
});
return data;
}
// Reject
if (statusId === 4) {
const data = await prisma.investasi.findMany({
orderBy: {
updatedAt: "desc",
},
where: {
authorId: id,
MasterStatusInvestasi: {
name: "Reject",
},
},
select: {
id: true,
title: true,
imagesId: true,
},
});
return data;
}
}

View File

@@ -10,10 +10,12 @@ import {
Card,
CardSection,
Divider,
Flex,
Grid,
Group,
Image,
Paper,
Progress,
Slider,
Stack,
Text,
@@ -24,6 +26,8 @@ import dataDummy from "../dummy/data_dummy.json";
import moment from "moment";
import { IconCheck, IconCircleCheck } from "@tabler/icons-react";
import { MODEL_Investasi } from "../model/model_investasi";
import _ from "lodash";
import { useState } from "react";
export default function MainInvestasi({
listData,
@@ -31,17 +35,19 @@ export default function MainInvestasi({
periodeDeviden,
pembagianDeviden,
}: {
listData: MODEL_Investasi[]
listData: MODEL_Investasi[];
pencarianInvestor: MODEL_DEFAULT_MASTER[];
periodeDeviden: MODEL_DEFAULT_MASTER[];
pembagianDeviden: MODEL_DEFAULT_MASTER[];
}) {
const router = useRouter();
const [investasi, setInvestasi] = useState(listData);
return (
<>
{/* <pre>{JSON.stringify(listData, null, 2)}</pre> */}
{dataDummy.map((e) => (
{investasi.map((e) => (
<Card
key={e.id}
withBorder
@@ -58,17 +64,12 @@ export default function MainInvestasi({
</AspectRatio>
</CardSection>
{/* Progress dan titlr */}
<CardSection p={"lg"}>
<Box mb={"md"}>
<Stack >
<Title order={4}>{e.title}</Title>
<Slider
size={10}
disabled
labelAlwaysOn
value={e.persentase}
marks={[{ value: e.persentase, label: e.persentase + `%` }]}
/>
</Box>
<Progress label="0%" value={0} color="teal" size="xl" radius="xl" animate/>
</Stack>
</CardSection>
<CardSection p={"md"}>
<Box>
@@ -102,9 +103,9 @@ export default function MainInvestasi({
</CardSection>
<Divider />
<CardSection p={"md"}>
<Group position="apart" px={"sm"}>
<Flex gap={"xl"} align={"center"} justify={"center"}>
<Box>
{e.saham_beli === 0 ? (
{e.SahamTerbeli === null ? (
""
) : (
<Badge variant="dot" color="teal">
@@ -112,9 +113,10 @@ export default function MainInvestasi({
</Badge>
)}
</Box>
{(() => {
if (
e.masterPencarianInvestorId -
Number(e.MasterPencarianInvestor.name) -
moment(new Date()).diff(new Date(e.createdAt), "days") <=
0
) {
@@ -132,9 +134,9 @@ export default function MainInvestasi({
<Group position="right" spacing={"xs"}>
<Text>Sisa waktu:</Text>
<Text>
{e.masterPencarianInvestorId -
{Number(e.MasterPencarianInvestor.name) -
moment(new Date()).diff(
new Date(e.createdAt),
new Date(e.updatedAt),
"days"
)}
</Text>
@@ -144,7 +146,7 @@ export default function MainInvestasi({
);
}
})()}
</Group>
</Flex>
</CardSection>
</Card>
))}

View File

@@ -0,0 +1,61 @@
import { RouterInvestasi } from "@/app/lib/router_hipmi/router_investasi";
import {
Card,
CardSection,
AspectRatio,
Box,
Title,
Divider,
Group,
Badge,
Image,
Text,
Center,
} from "@mantine/core";
import { useRouter } from "next/navigation";
import { MODEL_Investasi } from "../model/model_investasi";
import _ from "lodash";
export default function Draft({ data }: { data: MODEL_Investasi[] }) {
const router = useRouter();
return (
<>
{/* <pre> {JSON.stringify(data,null, 2)}</pre> */}
{data.map((e) =>
<Card
key={e.id}
withBorder
mb={40}
bg={"gray.5"}
onClick={() =>
router.push(RouterInvestasi.detail_draft + `${e.id}`)
}
>
<CardSection p={"xs"}>
<AspectRatio ratio={16 / 9}>
<Image
alt=""
src={RouterInvestasi.api_gambar + `${e.imagesId}`}
/>
</AspectRatio>
</CardSection>
<CardSection p={"lg"}>
<Box>
<Title order={4}>{e.title}</Title>
</Box>
</CardSection>
<Divider />
<CardSection p={"md"}>
<Group position="center">
<Badge color="yellow" variant="dot">
Draft
</Badge>
</Group>
</CardSection>
</Card>
)}
</>
);
}

View File

@@ -0,0 +1,96 @@
import { RouterInvestasi } from "@/app/lib/router_hipmi/router_investasi";
import {
Card,
CardSection,
AspectRatio,
Box,
Title,
Slider,
Divider,
Group,
Badge,
Image,
Text,
Center,
} from "@mantine/core";
import { useRouter } from "next/navigation";
import {
MODEL_Investasi,
MODEL_Status_investasi,
} from "../model/model_investasi";
import _ from "lodash";
import moment from "moment";
import { useState } from "react";
import { IconCircleCheck } from "@tabler/icons-react";
export default function Publish({ data }: { data: MODEL_Investasi[] }) {
const router = useRouter();
const [sisaWaktu, setSisaWaktu] = useState();
if (_.isEmpty(data))
return (
<>
<Center h={"50vh"}>Tidak ada Publish</Center>
</>
);
return (
<>
{data.map((e) => (
<Card
key={e.id}
withBorder
mb={40}
bg={"gray.5"}
onClick={() =>
router.push(RouterInvestasi.detail_publish + `${e.id}`)
}
>
<CardSection p={"xs"}>
<AspectRatio ratio={16 / 9}>
<Image
alt=""
src={RouterInvestasi.api_gambar + `${e.imagesId}`}
/>
</AspectRatio>
</CardSection>
<CardSection p={"lg"}>
<Box mb={"md"}>
<Title order={4}>{e.title}</Title>
{/* <Slider
size={10}
disabled
labelAlwaysOn
value={60}
marks={[{ value: 60, label: 60 + `%` }]}
/> */}
</Box>
</CardSection>
<Divider />
<CardSection p={"md"}>
{Number(e.MasterPencarianInvestor.name) -
moment(new Date()).diff(new Date(e.updatedAt), "days") <=
0 ? (
<Group position="right">
<IconCircleCheck color="green" />
<Text c={"green"}>Selesai</Text>
</Group>
) : (
<Group position="apart">
<Badge color="green" variant="dot">
Publish
</Badge>
<Text>
Sisa Waktu :{" "}
{Number(e.MasterPencarianInvestor.name) -
moment(new Date()).diff(new Date(e.updatedAt), "days")}{" "}
hari
</Text>
</Group>
)}
</CardSection>
</Card>
))}
</>
);
}

View File

@@ -0,0 +1,71 @@
import { RouterInvestasi } from "@/app/lib/router_hipmi/router_investasi";
import {
Card,
CardSection,
AspectRatio,
Box,
Title,
Divider,
Group,
Badge,
Image,
Text,
Center,
} from "@mantine/core";
import { useRouter } from "next/navigation";
import {
MODEL_Investasi,
MODEL_Status_investasi,
} from "../model/model_investasi";
import { useState } from "react";
import _ from "lodash";
export default function Reject({ data }: { data: MODEL_Investasi[] }) {
const [investasi, setInvestasi] = useState(data);
const router = useRouter();
if (_.isEmpty(data))
return (
<>
<Center h={"50vh"}>Tidak ada Reject</Center>
</>
);
return (
<>
{investasi.map((e) => (
<Card
key={e.id}
withBorder
mb={40}
bg={"gray.5"}
onClick={() => router.push(RouterInvestasi.detail_reject + `${e.id}`)}
>
<CardSection p={"xs"}>
<AspectRatio ratio={16 / 9}>
<Image
alt=""
src={RouterInvestasi.api_gambar + `${e.imagesId}`}
/>
</AspectRatio>
</CardSection>
<CardSection p={"lg"}>
<Box>
<Title order={4}>{e.title}</Title>
</Box>
</CardSection>
<Divider />
<CardSection p={"md"}>
<Group position="center">
<Badge color="red" variant="dot">
Reject
</Badge>
</Group>
</CardSection>
</Card>
))}
</>
);
}

View File

@@ -0,0 +1,67 @@
import { RouterInvestasi } from "@/app/lib/router_hipmi/router_investasi";
import {
Card,
CardSection,
AspectRatio,
Box,
Title,
Divider,
Group,
Badge,
Image,
Center,
Text,
} from "@mantine/core";
import { useRouter } from "next/navigation";
import {
MODEL_Status_investasi,
MODEL_Investasi,
} from "../model/model_investasi";
import _ from "lodash";
export default function Review({ data }: { data: MODEL_Investasi[] }) {
const router = useRouter();
if (_.isEmpty(data))
return (
<>
<Center h={"50vh"}>Tidak ada Review</Center>
</>
);
return (
<>
{data.map((e) => (
<Card
key={e.id}
withBorder
mb={40}
bg={"gray.5"}
onClick={() => router.push(RouterInvestasi.detail_review + `${e.id}`)}
>
<CardSection p={"xs"}>
<AspectRatio ratio={16 / 9}>
<Image
alt=""
src={RouterInvestasi.api_gambar + `${e.imagesId}`}
/>
</AspectRatio>
</CardSection>
<CardSection p={"lg"}>
<Box>
<Title order={4}>{e.title}</Title>
</Box>
</CardSection>
<Divider />
<CardSection p={"md"}>
<Group position="center">
<Badge color="yellow" variant="dot">
Review
</Badge>
</Group>
</CardSection>
</Card>
))}
</>
);
}

View File

@@ -47,18 +47,26 @@ import {
MODEL_Status_investasi,
} from "../model/model_investasi";
import _ from "lodash";
import Draft from "./draft";
import Review from "./review";
import Publish from "./publish";
import Reject from "./reject";
export default function PortofolioInvestasi({
dataInvestasi,
listStatusInvestasi,
dataDraft,
dataReview,
dataPublish,
dataReject,
}: {
dataInvestasi: any
listStatusInvestasi: any;
dataDraft: any;
dataReview: any;
dataPublish: any;
dataReject: any;
}) {
const router = useRouter();
const [activeTab, setActiveTab] = useAtom(gs_StatusPortoInvestasi);
const [investasi, setInvestasi] = useState<MODEL_Investasi[]>(dataInvestasi);
const [status_inves, setStatus_inves] =
useState<MODEL_Status_investasi[]>(listStatusInvestasi);
@@ -85,190 +93,18 @@ export default function PortofolioInvestasi({
</Tabs.List>
<Divider my={"xs"} />
<Tabs.Panel key={"1"} value="Draft">
<Draft data={investasi as any} />
<Draft data={dataDraft as any} />
</Tabs.Panel>
<Tabs.Panel key={"2"} value="Review">
<Review status={status_inves as any} data={investasi as any} />
<Review data={dataReview as any} />
</Tabs.Panel>
<Tabs.Panel key={"3"} value="Publish">
<Publish status={status_inves as any} />
<Publish data={dataPublish as any} />
</Tabs.Panel>
<Tabs.Panel key={"4"} value="Reject">
<Reject status={status_inves as any} />
<Reject data={dataReject as any} />
</Tabs.Panel>
</Tabs>
</>
);
}
function Draft({ data }: { data: MODEL_Investasi[] }) {
const router = useRouter();
return (
<>
{data.map((e) =>
e.MasterStatusInvestasi.id === "1" ? (
<Card
key={e.id}
withBorder
mb={40}
bg={"gray.5"}
onClick={() =>
router.push(RouterInvestasi.detail_draft + `${e.id}`)
}
>
<CardSection p={"xs"}>
<AspectRatio ratio={16 / 9}>
<Image
alt=""
src={RouterInvestasi.api_gambar + `${e.imagesId}`}
/>
</AspectRatio>
</CardSection>
<CardSection p={"lg"}>
<Box>
<Title order={4}>{e.title}</Title>
</Box>
</CardSection>
<Divider />
<CardSection p={"md"}>
<Group position="center">
<Badge color="yellow" variant="dot">
Draft
</Badge>
</Group>
</CardSection>
</Card>
) : (
""
)
)}
</>
);
}
function Review({
status,
data,
}: {
status: MODEL_Status_investasi;
data: MODEL_Investasi[];
}) {
const router = useRouter();
return (
<>
{data.map((e) =>
e.MasterStatusInvestasi.id === "2" ? (
<Card
key={e.id}
withBorder
mb={40}
bg={"gray.5"}
onClick={() => router.push(RouterInvestasi.detail_review + `${e.id}`)}
>
<CardSection p={"xs"}>
<AspectRatio ratio={16 / 9}>
<Image
alt=""
src={RouterInvestasi.api_gambar + `${e.imagesId}`}
/>
</AspectRatio>
</CardSection>
<CardSection p={"lg"}>
<Box>
<Title order={4}>{e.title}</Title>
</Box>
</CardSection>
<Divider />
<CardSection p={"md"}>
<Group position="center">
<Badge color="yellow" variant="dot">
Review
</Badge>
</Group>
</CardSection>
</Card>
) : (
""
)
)}
</>
);
}
function Publish({ status }: { status: MODEL_Status_investasi }) {
const router = useRouter();
return (
<>
<Card
withBorder
mb={40}
bg={"gray.5"}
onClick={() => router.push(RouterInvestasi.detail_publish)}
>
<CardSection p={"xs"}>
<AspectRatio ratio={16 / 9}>
<Image alt="" src={"/aset/no-img.png"} />
</AspectRatio>
</CardSection>
<CardSection p={"lg"}>
<Box mb={"md"}>
<Title order={4}>Judul Investasi</Title>
<Slider
size={10}
disabled
labelAlwaysOn
value={60}
marks={[{ value: 60, label: 60 + `%` }]}
/>
</Box>
</CardSection>
<Divider />
<CardSection p={"md"}>
<Group position="apart">
<Badge color="green" variant="dot">
{status.name}
</Badge>
<Text>Sisa Waktu : 30 Hari</Text>
</Group>
</CardSection>
</Card>
</>
);
}
function Reject({ status }: { status: MODEL_Status_investasi }) {
const router = useRouter();
return (
<>
<Card
withBorder
mb={40}
bg={"gray.5"}
onClick={() => router.push(RouterInvestasi.detail_reject)}
>
<CardSection p={"xs"}>
<AspectRatio ratio={16 / 9}>
<Image alt="" src={"/aset/no-img.png"} />
</AspectRatio>
</CardSection>
<CardSection p={"lg"}>
<Box>
<Title order={4}>Judul Investasi</Title>
</Box>
</CardSection>
<Divider />
<CardSection p={"md"}>
<Group position="center">
<Badge color="red" variant="dot">
{status.name}
</Badge>
</Group>
</CardSection>
</Card>
</>
);
}