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 {
@@ -180,22 +179,24 @@ model ProspektusInvestasi {
} }
model DokumenInvestasi { model DokumenInvestasi {
id String @id @default(cuid()) id String @id @default(cuid())
url String title String
active Boolean @default(true) url String
createdAt DateTime @default(now()) active Boolean @default(true)
updatedAt DateTime @default(now()) @updatedAt createdAt DateTime @default(now())
investasi Investasi[] updatedAt DateTime @default(now()) @updatedAt
investasi Investasi? @relation(fields: [investasiId], references: [id])
investasiId String?
} }
model BeritaInvestasi { model BeritaInvestasi {
id String @id @default(cuid()) id String @id @default(cuid())
title String title String
deskripsi String deskripsi String
active Boolean @default(true) active Boolean @default(true)
createdAt DateTime @default(now()) createdAt DateTime @default(now())
updatedAt DateTime @updatedAt updatedAt DateTime @updatedAt
ImageBerita Images? @relation(fields: [imagesId], references: [id]) ImageBerita Images? @relation(fields: [imagesId], references: [id])
imagesId String? imagesId String?
investasi Investasi @relation(fields: [investasiId], references: [id]) investasi Investasi @relation(fields: [investasiId], references: [id])
investasiId String investasiId String

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>
</>
);
}