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
ProspektusInvestasi ProspektusInvestasi?
DokumenInvestasi DokumenInvestasi? @relation(fields: [dokumenInvestasiId], references: [id])
dokumenInvestasiId String?
SahamTerbeli SahamTerbeli? @relation(fields: [sahamTerbeliId], references: [id])
sahamTerbeliId String?
MasterStatusInvestasi MasterStatusInvestasi? @relation(fields: [masterStatusInvestasiId], references: [id])
masterStatusInvestasiId String? @default("1")
BeritaInvestasi BeritaInvestasi[]
DokumenInvestasi DokumenInvestasi[]
}
model MasterPencarianInvestor {
@@ -180,22 +179,24 @@ model ProspektusInvestasi {
}
model DokumenInvestasi {
id String @id @default(cuid())
url String
active Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
investasi Investasi[]
id String @id @default(cuid())
title String
url String
active Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
investasi Investasi? @relation(fields: [investasiId], references: [id])
investasiId String?
}
model BeritaInvestasi {
id String @id @default(cuid())
id String @id @default(cuid())
title String
deskripsi String
active Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
ImageBerita Images? @relation(fields: [imagesId], references: [id])
active Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
ImageBerita Images? @relation(fields: [imagesId], references: [id])
imagesId String?
investasi Investasi @relation(fields: [investasiId], references: [id])
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 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<>
<LayoutEditDokumenInvestasi>{children}</LayoutEditDokumenInvestasi>
<LayoutEditDokumenInvestasi idInves={params.id}>{children}</LayoutEditDokumenInvestasi>
</>
}

View File

@@ -1,7 +1,10 @@
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<>
<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/",
//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";
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 LayoutEditDokumenInvestasi({
children,
idInves,
}: {
children: React.ReactNode;
idInves: string
}) {
return (
<>
<AppShell header={<HeaderTamplate title="Edit Dokumen" />}>
<AppShell
header={
<HeaderTamplate
title="Edit Dokumen"
icon={<IconEdit />}
route2={RouterInvestasi.upload_dokumen + `${idInves}`}
/>
}
>
{children}
</AppShell>
</>

View File

@@ -1,22 +1,57 @@
"use client"
"use client";
import { Paper, Grid, Center, Title, Divider, Button, Text } from "@mantine/core";
import { IconChevronRight } from "@tabler/icons-react";
import {
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 { 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(){
const [edit, setEdit] = useState(false);
export default function EditDokumenInvestasi({
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 (
<>
{edit ? (
<Link
href={"https://pii.or.id/uploads/dummies.pdf"}
target="_blank"
style={{ textDecorationLine: "none" }}
>
<Paper w={"100%"} h={50} bg={"gray"} mb={"md"}>
{/* <pre>{JSON.stringify(dokukem, null, 2)}</pre> */}
{!_.isEmpty(dokumen.DokumenInvestasi) ? (
dokumen.DokumenInvestasi.map((e) => (
<Paper key={e.id} w={"100%"} h={50} bg={"gray"} mb={"md"}>
<Grid
align="center"
justify="center"
@@ -24,17 +59,29 @@ export default function EditDokumenInvestasi(){
px={"sm"}
onClick={() => ""}
>
<Grid.Col span={10}>
<Text>Nama File.pdf</Text>
<Grid.Col span={8}>
<Text>{e.title}</Text>
</Grid.Col>
<Grid.Col span={2}>
<Center>
<IconChevronRight />
</Center>
<Grid.Col span={4}>
<Group position="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>
</Paper>
</Link>
))
) : (
<Center>
<Title order={4}>Tidak ada file</Title>
@@ -42,12 +89,6 @@ export default function EditDokumenInvestasi(){
)}
<Divider mt={"lg"} />
<Center>
<Button mt={"md"} compact radius={50}>
Upload
</Button>
</Center>
</>
);
}
}

View File

@@ -1,7 +1,6 @@
"use server";
import prisma from "@/app/lib/prisma";
import { revalidatePath } from "next/cache";
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,
idInves: string
) {
// console.log(formData)
const file: any = formData.get("file");
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 UploadProspektusInvestasi from "./upload_prospektus/view";
import LayoutUploadProspektusInvestasi from "./upload_prospektus/layout";
import UploadDokumenInvestasi from "./upload_dokumen/view";
import LayoutUploadDokumenInvestasi from "./upload_dokumen/layout";
export {
MainInvestasi,
@@ -130,4 +132,6 @@ export {
LayoutStatusTransaksiInvestasi_Gagal,
UploadProspektusInvestasi,
LayoutUploadProspektusInvestasi,
UploadDokumenInvestasi,
LayoutUploadDokumenInvestasi,
};

View File

@@ -12,7 +12,7 @@ export interface MODEL_Investasi {
imagesId: string;
MasterStatusInvestasi: MODEL_Status_investasi;
BeritaInvestasi: Model_Berita_Investasi[];
DokumenInvestasi: null;
DokumenInvestasi: Model_Dokumen_Investasi[];
ProspektusInvestasi: Model_Prospektus_Investasi;
MasterPembagianDeviden: Model_All_Master;
MasterPencarianInvestor: Model_All_Master;
@@ -42,7 +42,7 @@ export interface Model_Berita_Investasi {
updatedAt: Date;
}
export interface Model_Prospektus_Investasi {
interface Model_Prospektus_Investasi {
id: string
url: string
active: boolean;
@@ -50,3 +50,13 @@ export interface Model_Prospektus_Investasi {
updatedAt: Date
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>
</>
);
}