Prospektus Investasi

# feat:
- Halaman upload
- Function upload
- Get data prospektus
### No issue
This commit is contained in:
2023-11-08 14:37:15 +08:00
parent b662b714ad
commit a119eb2918
29 changed files with 316 additions and 66 deletions

BIN
public/aset/no-file.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
public/aset/pdf-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 268 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 268 KiB

View File

@@ -1,8 +1,8 @@
import { LayoutEditProspektusInvestasi } from "@/app_modules/investasi";
import React from "react";
export default async function Layout({children}: {children: React.ReactNode}) {
export default async function Layout({children, params}: {children: React.ReactNode, params: {id: string}}) {
return<>
<LayoutEditProspektusInvestasi>{children}</LayoutEditProspektusInvestasi>
<LayoutEditProspektusInvestasi idInves={params.id}>{children}</LayoutEditProspektusInvestasi>
</>
}

View File

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

View File

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

View File

@@ -0,0 +1,5 @@
import { UploadProspektusInvestasi } from "@/app_modules/investasi";
export default async function Page({ params }: { params: { id: string } }) {
return <UploadProspektusInvestasi idInves={params.id} />;
}

View File

@@ -36,4 +36,7 @@ export const RouterInvestasi = {
berita: "/dev/investasi/berita/",
create_berita: "/dev/investasi/create_berita/",
list_edit_berita: "/dev/investasi/list_edit_berita/",
//upload
upload_prospektus: "/dev/investasi/upload_prospektus/"
};

View File

@@ -1,17 +1,21 @@
"use client";
import { RouterInvestasi } from "@/app/lib/router_hipmi/router_investasi";
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 LayoutEditProspektusInvestasi({
children,
idInves
}: {
children: React.ReactNode;
idInves: string
}) {
return (
<>
<AppShell header={<HeaderTamplate title="Edit Prospektus" />}>
<AppShell header={<HeaderTamplate title="Edit Prospektus" icon={<IconEdit/>}route2={RouterInvestasi.upload_prospektus + `${idInves}`} />}>
{children}
</AppShell>
</>

View File

@@ -8,54 +8,67 @@ import {
Divider,
Button,
Text,
Group,
FileButton,
FileInput,
Image,
AspectRatio,
Flex,
Stack,
Box,
} from "@mantine/core";
import { IconChevronRight } from "@tabler/icons-react";
import { IconChevronRight, IconFileTypePdf } from "@tabler/icons-react";
import Link from "next/link";
import { useState } from "react";
import { MODEL_Investasi } from "../model/model_investasi";
export default function EditProspektusInvestasi() {
const [edit, setEdit] = useState(true);
export default function EditProspektusInvestasi({
dataInvestasi,
}: {
dataInvestasi: MODEL_Investasi;
}) {
const [prospek, setProspek] = useState<MODEL_Investasi>(dataInvestasi);
return (
<>
{edit ? (
<Link
href={"/aset/dummy_file.pdf"}
target="_blank"
style={{ textDecorationLine: "none" }}
>
<Paper w={"100%"} h={50} bg={"gray"} mb={"md"}>
<Grid
align="center"
justify="center"
h={50}
px={"sm"}
onClick={() => ""}
>
<Grid.Col span={10}>
<Text>Nama File.pdf</Text>
</Grid.Col>
<Grid.Col span={2}>
<Center>
<IconChevronRight />
</Center>
</Grid.Col>
</Grid>
</Paper>
</Link>
) : (
<Center>
<Title order={4}>Tidak ada file</Title>
</Center>
)}
{/* <pre>{JSON.stringify(prospek, null, 2)}</pre> */}
<Divider mt={"lg"} />
<Center>
<Button mt={"md"} compact radius={50}>
Upload
</Button>
</Center>
<Stack>
{prospek.ProspektusInvestasi != null ? (
<Link
href={`/file/${prospek.ProspektusInvestasi.url}`}
target="_blank"
style={{ textDecorationLine: "none" }}
>
<Paper w={"100%"} bg={"gray"} mb={"md"}>
<Grid
align="center"
justify="center"
h={50}
px={"sm"}
onClick={() => ""}
>
<Grid.Col span={10}>
<Group>
<IconFileTypePdf />
<Text>Prospektus_{prospek.title}</Text>
</Group>
</Grid.Col>
<Grid.Col span={2}>
<Center>
<IconChevronRight />
</Center>
</Grid.Col>
</Grid>
</Paper>
</Link>
) : (
<Center>
<Title order={4}>Tidak ada file</Title>
</Center>
)}
<Divider my={"lg"} />
</Stack>
</>
);
}

View File

@@ -0,0 +1,32 @@
"use server";
import prisma from "@/app/lib/prisma";
export default async function funLoadDataInvestasi(id: string) {
const data = await prisma.investasi.findUnique({
where: {
id: id,
},
select: {
id: true,
title: true,
authorId: true,
hargaLembar: true,
targetDana: true,
totalLembar: true,
roi: true,
active: true,
imagesId: true,
MasterStatusInvestasi: true,
BeritaInvestasi: true,
DokumenInvestasi: true,
ProspektusInvestasi: true,
MasterPembagianDeviden: true,
MasterPencarianInvestor: true,
MasterPeriodeDeviden: true,
SahamTerbeli: true,
},
});
return data;
}

View File

@@ -0,0 +1,45 @@
"use server";
import prisma from "@/app/lib/prisma";
import _ from "lodash";
import { v4 } from "uuid";
import fs from "fs"
import { revalidatePath } from "next/cache";
import { RouterInvestasi } from "@/app/lib/router_hipmi/router_investasi";
export default async function funUploadProspektusInvestasi(
formData: FormData,
idInves: string
) {
// console.log(formData)
const file: any = formData.get("file");
const fName = file.name;
const fExt = _.lowerCase(file.name.split(".").pop());
// console.log(fName)
// console.log(fExt)
const fRandomName = v4(fName) + "." + fExt;
const uploadFile = await prisma.prospektusInvestasi.upsert({
where: {
investasiId: idInves,
},
update: {
url: fRandomName,
},
create: {
investasiId: idInves,
url: fRandomName,
},
});
if(!uploadFile) return {status: 400, message: "Gagal Upload"}
const upFolder = Buffer.from(await file.arrayBuffer())
fs.writeFileSync(`./public/file/${uploadFile.url}`, upFolder)
revalidatePath(RouterInvestasi.edit_prospektus)
return {
status: 201,
message: "File tersimpan "
}
}

View File

@@ -46,7 +46,7 @@ import DialogPageCreateInvestasi from "./dialog_page/create/view";
import LayoutDialogPageCreateInvestasi from "./dialog_page/create/layout";
import CreateBeritaInvestasi from "./create_berita/view";
import LayoutCreateBeritaInvestasi from "./create_berita/layout";
import ListEditBeritaInvestasi from "./list_edit_berita/page";
import ListEditBeritaInvestasi from "./list_edit_berita/view";
import LayoutListEditBeritaInvestasi from "./list_edit_berita/layout";
import InvestasiSahamTerbeli from "./main/saham_saya";
import DetailDraftInvestasi from "./detail_portofolio/draft/page";
@@ -61,6 +61,8 @@ import TransaksiInvestasi from "./transaksi/page";
import LayoutTransaksiInvestasi from "./transaksi/layout";
import StatusTransaksiInvestasi_Gagal from "./status_transaksi/gagal/view";
import LayoutStatusTransaksiInvestasi_Gagal from "./status_transaksi/gagal/layout";
import UploadProspektusInvestasi from "./upload_prospektus/view";
import LayoutUploadProspektusInvestasi from "./upload_prospektus/layout";
export {
MainInvestasi,
@@ -125,5 +127,7 @@ export {
TransaksiInvestasi,
LayoutTransaksiInvestasi,
StatusTransaksiInvestasi_Gagal,
LayoutStatusTransaksiInvestasi_Gagal
LayoutStatusTransaksiInvestasi_Gagal,
UploadProspektusInvestasi,
LayoutUploadProspektusInvestasi,
};

View File

@@ -26,6 +26,7 @@ import { useState } from "react";
import _ from "lodash";
import deleteBeritaInvestasi from "../fun/fun_delete_berita";
import getOneInvestasiById from "../fun/get_one_investasi_by_id";
import funLoadDataInvestasi from "../fun/fun_load_data";
export default function ListEditBeritaInvestasi({
dataInvestasi,
@@ -36,10 +37,10 @@ export default function ListEditBeritaInvestasi({
const [investasi, setInvestasi] = useState<MODEL_Investasi>(dataInvestasi);
async function onDelete(idBerita: string, idInvestasi: string) {
await deleteBeritaInvestasi(idBerita, idInvestasi).then((res) => {
await deleteBeritaInvestasi(idBerita, idInvestasi).then( async(res) => {
if (res.status === 200) {
const data : MODEL_Investasi | any = getOneInvestasiById(idInvestasi)
setInvestasi(data as MODEL_Investasi);
const loadData = await funLoadDataInvestasi(idInvestasi);
setInvestasi(loadData as any)
toast(res.message);
} else {
toast(res.message);

View File

@@ -9,14 +9,14 @@ export interface MODEL_Investasi {
createdAt: Date;
updatedAt: Date;
authorId: string;
imagesId: string,
MasterStatusInvestasi: MODEL_Status_investasi
BeritaInvestasi: Model_Berita_Investasi[],
imagesId: string;
MasterStatusInvestasi: MODEL_Status_investasi;
BeritaInvestasi: Model_Berita_Investasi[];
DokumenInvestasi: null;
ProspektusInvestasi: null;
MasterPembagianDeviden: Model_All_Master
MasterPencarianInvestor: Model_All_Master
MasterPeriodeDeviden: Model_All_Master
ProspektusInvestasi: Model_Prospektus_Investasi;
MasterPembagianDeviden: Model_All_Master;
MasterPencarianInvestor: Model_All_Master;
MasterPeriodeDeviden: Model_All_Master;
SahamTerbeli: null;
}
@@ -27,18 +27,26 @@ export interface MODEL_Status_investasi {
}
interface Model_All_Master {
id: string
name: string
active: boolean
id: string;
name: string;
active: boolean;
}
export interface Model_Berita_Investasi {
id: string;
title: string,
deskripsi: string,
imagesId: string,
active: boolean,
title: string;
deskripsi: string;
imagesId: string;
active: boolean;
createdAt: Date;
updatedAt: Date;
}
export interface Model_Prospektus_Investasi {
id: string
url: string
active: boolean;
createdAt: Date
updatedAt: Date
investasiId: string
}

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 LayoutUploadProspektusInvestasi({
children,
}: {
children: React.ReactNode;
}) {
return (
<>
<AppShell header={<HeaderTamplate title="Upload Prospektus" />}>
{children}
</AppShell>
</>
);
}

View File

@@ -0,0 +1,103 @@
"use client";
import { Warna } from "@/app/lib/warna";
import {
Group,
FileButton,
Button,
Box,
Paper,
AspectRatio,
Image,
Stack,
Center,
} from "@mantine/core";
import { useRouter } from "next/navigation";
import { useState } from "react";
import toast from "react-simple-toasts";
import funUploadProspektusInvestasi from "../fun/fun_upload_prospek";
import funLoadDataInvestasi from "../fun/fun_load_data";
export default function UploadProspektusInvestasi({
idInves,
}: {
idInves: string;
}) {
const router = useRouter();
const [file, setFile] = useState<any | null>(null);
const [pdf, setPdf] = useState<File | null>(null);
async function onUpload() {
if (!pdf) return toast("File Kosong");
const fd = new FormData();
fd.append("file", pdf as any);
await funUploadProspektusInvestasi(fd, idInves).then((res) => {
if (res.status === 201) {
toast("Berhasil upload");
router.back();
} else {
toast(res.message);
}
});
}
return (
<>
<Stack>
<Group position="center" px={"md"}>
<FileButton
onChange={async (file: any) => {
const buffer = URL.createObjectURL(
new Blob([new Uint8Array(await file.arrayBuffer())])
);
console.log(buffer);
setFile(buffer);
setPdf(file);
}}
accept="image/pdf"
>
{(props) => (
<Button
{...props}
bg={Warna.hijau_muda}
color="green"
radius={50}
>
Upload File
</Button>
)}
</FileButton>
</Group>
<Box my={"lg"}>
{!file ? (
<Paper radius={20}>
<AspectRatio ratio={2 / 4} mah={300} maw={200} mx={"auto"}>
<Image alt="" src={"/aset/no-file.png"} />
</AspectRatio>
</Paper>
) : (
<Paper radius={20}>
<AspectRatio ratio={2 / 4} mah={300} maw={200} mx={"auto"}>
<Image alt="" src={"/aset/pdf-icon.png"} />
</AspectRatio>
</Paper>
)}
</Box>
<Center>
<Button
w={300}
radius={50}
bg={Warna.biru}
onClick={() => onUpload()}
>
Simpan
</Button>
</Center>
</Stack>
</>
);
}