Dokumen investasi

# feat:
- Tampilan upload dokuman
- Function upload
- Function delete
- Function get data dokumen
### No issue
This commit is contained in:
2023-11-08 16:40:22 +08:00
parent a119eb2918
commit 14c0fb4e21
21 changed files with 90111 additions and 49 deletions

View File

@@ -122,14 +122,13 @@ model Investasi {
imagesId String? @unique imagesId String? @unique
ProspektusInvestasi ProspektusInvestasi? ProspektusInvestasi ProspektusInvestasi?
DokumenInvestasi DokumenInvestasi? @relation(fields: [dokumenInvestasiId], references: [id])
dokumenInvestasiId String?
SahamTerbeli SahamTerbeli? @relation(fields: [sahamTerbeliId], references: [id]) SahamTerbeli SahamTerbeli? @relation(fields: [sahamTerbeliId], references: [id])
sahamTerbeliId String? sahamTerbeliId String?
MasterStatusInvestasi MasterStatusInvestasi? @relation(fields: [masterStatusInvestasiId], references: [id]) MasterStatusInvestasi MasterStatusInvestasi? @relation(fields: [masterStatusInvestasiId], references: [id])
masterStatusInvestasiId String? @default("1") masterStatusInvestasiId String? @default("1")
BeritaInvestasi BeritaInvestasi[] BeritaInvestasi BeritaInvestasi[]
DokumenInvestasi DokumenInvestasi[]
} }
model MasterPencarianInvestor { model MasterPencarianInvestor {
@@ -181,11 +180,13 @@ model ProspektusInvestasi {
model DokumenInvestasi { model DokumenInvestasi {
id String @id @default(cuid()) id String @id @default(cuid())
title String
url String url String
active Boolean @default(true) active Boolean @default(true)
createdAt DateTime @default(now()) createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt updatedAt DateTime @default(now()) @updatedAt
investasi Investasi[] investasi Investasi? @relation(fields: [investasiId], references: [id])
investasiId String?
} }
model BeritaInvestasi { model BeritaInvestasi {

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,8 +1,8 @@
import { LayoutEditDokumenInvestasi } from "@/app_modules/investasi"; import { LayoutEditDokumenInvestasi } from "@/app_modules/investasi";
import React from "react"; 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<> return<>
<LayoutEditDokumenInvestasi>{children}</LayoutEditDokumenInvestasi> <LayoutEditDokumenInvestasi idInves={params.id}>{children}</LayoutEditDokumenInvestasi>
</> </>
} }

View File

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

View File

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

View File

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

View File

@@ -38,5 +38,7 @@ export const RouterInvestasi = {
list_edit_berita: "/dev/investasi/list_edit_berita/", list_edit_berita: "/dev/investasi/list_edit_berita/",
//upload //upload
upload_prospektus: "/dev/investasi/upload_prospektus/" upload_prospektus: "/dev/investasi/upload_prospektus/",
upload_dokumen: "/dev/investasi/upload_dokumen/"
}; };

View File

@@ -1,17 +1,29 @@
"use client"; "use client";
import { RouterInvestasi } from "@/app/lib/router_hipmi/router_investasi";
import HeaderTamplate from "@/app_modules/component/header_tamplate"; import HeaderTamplate from "@/app_modules/component/header_tamplate";
import { AppShell } from "@mantine/core"; import { AppShell } from "@mantine/core";
import { IconEdit } from "@tabler/icons-react";
import React from "react"; import React from "react";
export default function LayoutEditDokumenInvestasi({ export default function LayoutEditDokumenInvestasi({
children, children,
idInves,
}: { }: {
children: React.ReactNode; children: React.ReactNode;
idInves: string
}) { }) {
return ( return (
<> <>
<AppShell header={<HeaderTamplate title="Edit Dokumen" />}> <AppShell
header={
<HeaderTamplate
title="Edit Dokumen"
icon={<IconEdit />}
route2={RouterInvestasi.upload_dokumen + `${idInves}`}
/>
}
>
{children} {children}
</AppShell> </AppShell>
</> </>

View File

@@ -1,22 +1,57 @@
"use client" "use client";
import { Paper, Grid, Center, Title, Divider, Button, Text } from "@mantine/core"; import {
import { IconChevronRight } from "@tabler/icons-react"; Paper,
Grid,
Center,
Title,
Divider,
Button,
Text,
ActionIcon,
Group,
} from "@mantine/core";
import {
IconChevronRight,
IconTrash,
IconWorldShare,
} from "@tabler/icons-react";
import Link from "next/link"; import Link from "next/link";
import { useState } from "react"; import { useState } from "react";
import { MODEL_Investasi } from "../model/model_investasi";
import _ from "lodash";
import funDeleteDokumenInvestasi from "../fun/fun_delete_dokumen";
import toast from "react-simple-toasts";
import funLoadDataInvestasi from "../fun/fun_load_data";
export default function EditDokumenInvestasi(){ export default function EditDokumenInvestasi({
const [edit, setEdit] = useState(false); dataInvestasi,
}: {
dataInvestasi: MODEL_Investasi;
}) {
const [dokumen, setDokumen] = useState(dataInvestasi);
async function onDelete(id: string) {
await funDeleteDokumenInvestasi(id)
.then( async (res) => {
if(res.status === 200){
toast(res.message)
const load = await funLoadDataInvestasi(dokumen.id)
setDokumen(load as any)
} else {
toast(res.message)
}
})
}
return ( return (
<> <>
{edit ? ( {/* <pre>{JSON.stringify(dokukem, null, 2)}</pre> */}
<Link
href={"https://pii.or.id/uploads/dummies.pdf"} {!_.isEmpty(dokumen.DokumenInvestasi) ? (
target="_blank" dokumen.DokumenInvestasi.map((e) => (
style={{ textDecorationLine: "none" }} <Paper key={e.id} w={"100%"} h={50} bg={"gray"} mb={"md"}>
>
<Paper w={"100%"} h={50} bg={"gray"} mb={"md"}>
<Grid <Grid
align="center" align="center"
justify="center" justify="center"
@@ -24,17 +59,29 @@ export default function EditDokumenInvestasi(){
px={"sm"} px={"sm"}
onClick={() => ""} onClick={() => ""}
> >
<Grid.Col span={10}> <Grid.Col span={8}>
<Text>Nama File.pdf</Text> <Text>{e.title}</Text>
</Grid.Col> </Grid.Col>
<Grid.Col span={2}>
<Center> <Grid.Col span={4}>
<IconChevronRight /> <Group position="center">
</Center> <Link
href={`/file/${e.url}`}
target="_blank"
>
<ActionIcon variant="transparent">
<IconWorldShare color="green" />
</ActionIcon>
</Link>
<ActionIcon variant="transparent" onClick={() => onDelete(e.id)}>
<IconTrash color="red" />
</ActionIcon>
</Group>
</Grid.Col> </Grid.Col>
</Grid> </Grid>
</Paper> </Paper>
</Link> ))
) : ( ) : (
<Center> <Center>
<Title order={4}>Tidak ada file</Title> <Title order={4}>Tidak ada file</Title>
@@ -42,12 +89,6 @@ export default function EditDokumenInvestasi(){
)} )}
<Divider mt={"lg"} /> <Divider mt={"lg"} />
<Center>
<Button mt={"md"} compact radius={50}>
Upload
</Button>
</Center>
</> </>
); );
} }

View File

@@ -1,7 +1,6 @@
"use server"; "use server";
import prisma from "@/app/lib/prisma"; import prisma from "@/app/lib/prisma";
import { revalidatePath } from "next/cache";
export default async function funDeleteBeritaInvestasi(id: string, idInvestasi: string) { export default async function funDeleteBeritaInvestasi(id: string, idInvestasi: string) {

View File

@@ -0,0 +1,20 @@
"use server";
import prisma from "@/app/lib/prisma";
export default async function funDeleteDokumenInvestasi(idDokumen: string) {
const res = await prisma.dokumenInvestasi.delete({
where: {
id: idDokumen,
},
});
if (!res) return { status: 400, message: "Gagal hapus" };
return {
status: 200,
message: "Dokumen terhapus",
};
}

View File

@@ -0,0 +1,39 @@
"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 funUploadDokumenInvestasi(
formData: FormData,
data: any
) {
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.dokumenInvestasi.create({
data: {
investasiId: data.idInves,
title: data.title,
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_dokumen);
return {
status: 201,
message: "File tersimpan ",
};
}

View File

@@ -11,7 +11,6 @@ export default async function funUploadProspektusInvestasi(
formData: FormData, formData: FormData,
idInves: string idInves: string
) { ) {
// console.log(formData)
const file: any = formData.get("file"); const file: any = formData.get("file");
const fName = file.name; const fName = file.name;

View File

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

View File

@@ -12,7 +12,7 @@ export interface MODEL_Investasi {
imagesId: string; imagesId: string;
MasterStatusInvestasi: MODEL_Status_investasi; MasterStatusInvestasi: MODEL_Status_investasi;
BeritaInvestasi: Model_Berita_Investasi[]; BeritaInvestasi: Model_Berita_Investasi[];
DokumenInvestasi: null; DokumenInvestasi: Model_Dokumen_Investasi[];
ProspektusInvestasi: Model_Prospektus_Investasi; ProspektusInvestasi: Model_Prospektus_Investasi;
MasterPembagianDeviden: Model_All_Master; MasterPembagianDeviden: Model_All_Master;
MasterPencarianInvestor: Model_All_Master; MasterPencarianInvestor: Model_All_Master;
@@ -42,7 +42,7 @@ export interface Model_Berita_Investasi {
updatedAt: Date; updatedAt: Date;
} }
export interface Model_Prospektus_Investasi { interface Model_Prospektus_Investasi {
id: string id: string
url: string url: string
active: boolean; active: boolean;
@@ -50,3 +50,13 @@ export interface Model_Prospektus_Investasi {
updatedAt: Date updatedAt: Date
investasiId: string investasiId: string
} }
interface Model_Dokumen_Investasi {
id: string
title: 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 LayoutUploadDokumenInvestasi({
children,
}: {
children: React.ReactNode;
}) {
return (
<>
<AppShell header={<HeaderTamplate title="Upload Dokumen" />}>
{children}
</AppShell>
</>
);
}

View File

@@ -0,0 +1,118 @@
"use client";
import { Warna } from "@/app/lib/warna";
import {
Group,
FileButton,
Button,
Box,
Paper,
AspectRatio,
Image,
Stack,
Center,
TextInput,
} 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";
import _ from "lodash";
import funUploadDokumenInvestasi from "../fun/fun_upload_dokumen";
export default function UploadDokumenInvestasi({
idInves,
}: {
idInves: string;
}) {
const router = useRouter();
const [file, setFile] = useState<any | null>(null);
const [pdf, setPdf] = useState<File | null>(null);
const [title, setTitle] = useState("");
async function onUpload() {
const body = {
idInves: idInves,
title: title,
};
if (_.values(body).includes("")) return toast("Lengkapi nama dokumen");
if (!pdf) return toast("File Kosong");
const fd = new FormData();
fd.append("file", pdf as any);
await funUploadDokumenInvestasi(fd, body).then((res) => {
console.log(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())])
);
setFile(buffer);
setPdf(file);
}}
accept={"/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>
<TextInput
label="Nama dokumen"
withAsterisk
onChange={(val) => {
setTitle(val.target.value);
}}
/>
<Center>
<Button
w={300}
radius={50}
bg={Warna.biru}
onClick={() => onUpload()}
>
Simpan
</Button>
</Center>
</Stack>
</>
);
}