Fix: Investasi
Deskripsi: - Upload gambar investasi ke storage wibu - Upload bukti transfer ke storage wibu # No Issue
This commit is contained in:
180
src/app_modules/investasi/_view/edit/view_edit_dokumen.tsx
Normal file
180
src/app_modules/investasi/_view/edit/view_edit_dokumen.tsx
Normal file
@@ -0,0 +1,180 @@
|
||||
import { DIRECTORY_ID } from "@/app/lib";
|
||||
import { MainColor } from "@/app_modules/_global/color";
|
||||
import {
|
||||
ComponentGlobal_CardStyles
|
||||
} from "@/app_modules/_global/component";
|
||||
import {
|
||||
funGlobal_DeleteFileById,
|
||||
funGlobal_UploadToStorage,
|
||||
} from "@/app_modules/_global/fun";
|
||||
import {
|
||||
ComponentGlobal_NotifikasiBerhasil,
|
||||
ComponentGlobal_NotifikasiPeringatan,
|
||||
} from "@/app_modules/_global/notif_global";
|
||||
import {
|
||||
Button,
|
||||
Center,
|
||||
FileButton,
|
||||
Grid,
|
||||
Group,
|
||||
Stack,
|
||||
Text,
|
||||
TextInput,
|
||||
} from "@mantine/core";
|
||||
import { IconCamera, IconCircleCheck } from "@tabler/icons-react";
|
||||
import _ from "lodash";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import { investasi_funUpdateDocument } from "../../_fun";
|
||||
import { MODEL_INVESTASI_DOKUMEN } from "../../_lib/interface";
|
||||
|
||||
export function Investasi_ViewEditDokumen({
|
||||
dataDokumen,
|
||||
}: {
|
||||
dataDokumen: MODEL_INVESTASI_DOKUMEN;
|
||||
}) {
|
||||
const router = useRouter();
|
||||
const [filePdf, setFilePdf] = useState<File | null>(null);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [data, setData] = useState(dataDokumen);
|
||||
const [title, setTitle] = useState(data.title);
|
||||
|
||||
async function onUpdate() {
|
||||
try {
|
||||
setIsLoading(true);
|
||||
if (filePdf) {
|
||||
const delfile = await funGlobal_DeleteFileById({ fileId: data.fileId });
|
||||
|
||||
if (!delfile.success) {
|
||||
ComponentGlobal_NotifikasiPeringatan("Gagal hapus file lama");
|
||||
}
|
||||
|
||||
const uploadFile = await funGlobal_UploadToStorage({
|
||||
file: filePdf,
|
||||
dirId: DIRECTORY_ID.investasi_dokumen,
|
||||
});
|
||||
|
||||
if (!uploadFile.success) {
|
||||
setIsLoading(false);
|
||||
ComponentGlobal_NotifikasiPeringatan("Gagal upload file dokumen");
|
||||
}
|
||||
|
||||
const updateWithFile = await investasi_funUpdateDocument({
|
||||
data: data,
|
||||
fileId: uploadFile.data.id,
|
||||
});
|
||||
|
||||
if (updateWithFile.status !== 200) {
|
||||
ComponentGlobal_NotifikasiPeringatan(updateWithFile.message);
|
||||
}
|
||||
ComponentGlobal_NotifikasiBerhasil(updateWithFile.message);
|
||||
} else {
|
||||
const updateNoFile = await investasi_funUpdateDocument({
|
||||
data: data,
|
||||
});
|
||||
|
||||
if (updateNoFile.status !== 200) {
|
||||
ComponentGlobal_NotifikasiPeringatan(updateNoFile.message);
|
||||
}
|
||||
ComponentGlobal_NotifikasiBerhasil(updateNoFile.message);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
} finally {
|
||||
router.back();
|
||||
setIsLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Stack spacing={"xl"} px={"sm"}>
|
||||
{/* <ComponentGlobal_BoxInformation informasi="File dokumen bersifat opsional, jika memang ada file yang bisa membantu meyakinkan investor. Anda bisa mengupload nya disini !" /> */}
|
||||
|
||||
<Stack>
|
||||
<TextInput
|
||||
label="Judul Dokumen"
|
||||
placeholder="Masukan judul dokumen"
|
||||
value={data.title}
|
||||
styles={{
|
||||
label: {
|
||||
color: "white",
|
||||
},
|
||||
}}
|
||||
onChange={(val) => setData({ ...data, title: val.target.value })}
|
||||
/>
|
||||
<ComponentGlobal_CardStyles marginBottom={"0px"}>
|
||||
{!filePdf ? (
|
||||
<Text lineClamp={1} align="center" c={"gray"}>
|
||||
Dokumen {_.startCase(title)}.pdf
|
||||
</Text>
|
||||
) : (
|
||||
<Grid align="center">
|
||||
<Grid.Col span={2}></Grid.Col>
|
||||
<Grid.Col span={"auto"}>
|
||||
<Text lineClamp={1} align="center" color="white">
|
||||
{filePdf.name}
|
||||
</Text>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={2}>
|
||||
<Center>
|
||||
<IconCircleCheck color="green" />
|
||||
</Center>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
)}
|
||||
</ComponentGlobal_CardStyles>
|
||||
|
||||
<Group position="center">
|
||||
<FileButton
|
||||
accept={"application/pdf"}
|
||||
onChange={async (files: any) => {
|
||||
try {
|
||||
const buffer = URL.createObjectURL(
|
||||
new Blob([new Uint8Array(await files.arrayBuffer())])
|
||||
);
|
||||
|
||||
setFilePdf(files);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{(props) => (
|
||||
<Button
|
||||
leftIcon={<IconCamera />}
|
||||
{...props}
|
||||
radius={"xl"}
|
||||
bg={MainColor.yellow}
|
||||
color="yellow"
|
||||
c={"black"}
|
||||
>
|
||||
Upload Dokumen
|
||||
</Button>
|
||||
)}
|
||||
</FileButton>
|
||||
</Group>
|
||||
</Stack>
|
||||
|
||||
<Button
|
||||
loaderPosition="center"
|
||||
loading={isLoading}
|
||||
disabled={data.title === ""}
|
||||
mt={50}
|
||||
radius={50}
|
||||
bg={MainColor.yellow}
|
||||
color="yellow"
|
||||
c={"black"}
|
||||
style={{
|
||||
transition: "0.5s",
|
||||
}}
|
||||
onClick={() => {
|
||||
onUpdate();
|
||||
}}
|
||||
>
|
||||
Update
|
||||
</Button>
|
||||
</Stack>
|
||||
</>
|
||||
);
|
||||
}
|
||||
328
src/app_modules/investasi/_view/edit/view_edit_investasi.tsx
Normal file
328
src/app_modules/investasi/_view/edit/view_edit_investasi.tsx
Normal file
@@ -0,0 +1,328 @@
|
||||
import { APIs, DIRECTORY_ID } from "@/app/lib";
|
||||
import { MainColor } from "@/app_modules/_global/color";
|
||||
import {
|
||||
ComponentGlobal_BoxInformation,
|
||||
ComponentGlobal_BoxUploadImage,
|
||||
ComponentGlobal_LoadImage,
|
||||
} from "@/app_modules/_global/component";
|
||||
import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/_global/notif_global";
|
||||
import { MODEL_DEFAULT_MASTER_OLD } from "@/app_modules/model_global/interface";
|
||||
import {
|
||||
AspectRatio,
|
||||
Box,
|
||||
Button,
|
||||
FileButton,
|
||||
Group,
|
||||
Image,
|
||||
Select,
|
||||
Stack,
|
||||
Text,
|
||||
TextInput,
|
||||
} from "@mantine/core";
|
||||
import { IconCamera } from "@tabler/icons-react";
|
||||
import _ from "lodash";
|
||||
import { useState } from "react";
|
||||
import { MODEL_INVESTASI } from "../../_lib/interface";
|
||||
import { investasi_funUpdateInvestasi } from "../../_fun";
|
||||
import { funGlobal_UploadToStorage } from "@/app_modules/_global/fun";
|
||||
import { Investasi_ComponentButtonUpdateDataInvestasi } from "../../_component";
|
||||
import { useShallowEffect } from "@mantine/hooks";
|
||||
|
||||
export function Investasi_ViewEditInvestasi({
|
||||
dataInvestasi,
|
||||
pencarianInvestor,
|
||||
periodeDeviden,
|
||||
pembagianDeviden,
|
||||
}: {
|
||||
dataInvestasi: any;
|
||||
pencarianInvestor: MODEL_DEFAULT_MASTER_OLD[];
|
||||
periodeDeviden: MODEL_DEFAULT_MASTER_OLD[];
|
||||
pembagianDeviden: MODEL_DEFAULT_MASTER_OLD[];
|
||||
}) {
|
||||
const [data, setData] = useState<MODEL_INVESTASI>(dataInvestasi);
|
||||
const [file, setFile] = useState<File | null>(null);
|
||||
const [img, setImg] = useState<any | null>();
|
||||
const [target, setTarget] = useState("");
|
||||
const [harga, setHarga] = useState("");
|
||||
const [totalLembar, setTotalLembar] = useState<any>(data.totalLembar);
|
||||
|
||||
async function onTotalLembar({
|
||||
target,
|
||||
harga,
|
||||
}: {
|
||||
target?: number | any;
|
||||
harga?: number | any;
|
||||
}) {
|
||||
if (target !== 0 && harga !== 0) {
|
||||
const hasil: any = target / harga;
|
||||
const result = _.floor(hasil === Infinity ? 0 : hasil);
|
||||
setTotalLembar(result.toString());
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Stack px={"sm"}>
|
||||
<Stack spacing={0}>
|
||||
<Box mb={"sm"}>
|
||||
<ComponentGlobal_BoxInformation informasi="Gambar investasi bisa berupa ilustrasi, poster atau foto terkait investasi" />
|
||||
</Box>
|
||||
<ComponentGlobal_BoxUploadImage>
|
||||
{img ? (
|
||||
<AspectRatio ratio={1 / 1} mt={5} maw={300} mx={"auto"}>
|
||||
<Image style={{ maxHeight: 250 }} alt="Avatar" src={img} />
|
||||
</AspectRatio>
|
||||
) : (
|
||||
<ComponentGlobal_LoadImage maw={300} fileId={data.imageId} />
|
||||
)}
|
||||
</ComponentGlobal_BoxUploadImage>
|
||||
{/* Upload Foto */}
|
||||
<Group position="center">
|
||||
<FileButton
|
||||
onChange={async (files: any) => {
|
||||
try {
|
||||
const buffer = URL.createObjectURL(
|
||||
new Blob([new Uint8Array(await files.arrayBuffer())])
|
||||
);
|
||||
setImg(buffer);
|
||||
setFile(files);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}}
|
||||
accept="image/png,image/jpeg"
|
||||
>
|
||||
{(props) => (
|
||||
<Button
|
||||
{...props}
|
||||
leftIcon={<IconCamera color="black" />}
|
||||
radius={50}
|
||||
bg={MainColor.yellow}
|
||||
color="yellow"
|
||||
c={"black"}
|
||||
>
|
||||
Upload Gambar
|
||||
</Button>
|
||||
)}
|
||||
</FileButton>
|
||||
</Group>
|
||||
</Stack>
|
||||
|
||||
{/* <Stack c={"white"}>
|
||||
<div>{JSON.stringify(data.targetDana)}</div>
|
||||
<div>{JSON.stringify(data.hargaLembar)}</div>
|
||||
<div>{JSON.stringify(data.totalLembar)}</div>
|
||||
<div>{JSON.stringify(totalLembar)}</div>
|
||||
</Stack> */}
|
||||
|
||||
<TextInput
|
||||
styles={{
|
||||
label: {
|
||||
color: "white",
|
||||
},
|
||||
}}
|
||||
withAsterisk
|
||||
label="Judul Investasi"
|
||||
placeholder="Judul investasi"
|
||||
maxLength={100}
|
||||
value={data.title}
|
||||
onChange={(val) => {
|
||||
setData({
|
||||
...data,
|
||||
title: val.target.value,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
|
||||
<TextInput
|
||||
styles={{
|
||||
label: {
|
||||
color: "white",
|
||||
},
|
||||
}}
|
||||
icon={<Text fw={"bold"}>Rp.</Text>}
|
||||
min={0}
|
||||
withAsterisk
|
||||
label="Dana Dibutuhkan"
|
||||
placeholder="0"
|
||||
value={target ? target : data.targetDana}
|
||||
onChange={(val) => {
|
||||
// console.log(typeof val)
|
||||
const match = val.currentTarget.value
|
||||
.replace(/\./g, "")
|
||||
.match(/^[0-9]+$/);
|
||||
|
||||
if (val.currentTarget.value === "") return setTarget(0 + "");
|
||||
if (!match?.[0]) return null;
|
||||
|
||||
const nilai = val.currentTarget.value.replace(/\./g, "");
|
||||
const targetNilai = Intl.NumberFormat("id-ID").format(+nilai);
|
||||
|
||||
onTotalLembar({
|
||||
target: +nilai,
|
||||
harga: +data.hargaLembar,
|
||||
});
|
||||
|
||||
setTarget(targetNilai);
|
||||
setData({
|
||||
...data,
|
||||
targetDana: nilai as string,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
|
||||
<TextInput
|
||||
styles={{
|
||||
label: {
|
||||
color: "white",
|
||||
},
|
||||
}}
|
||||
icon={<Text fw={"bold"}>Rp.</Text>}
|
||||
min={0}
|
||||
withAsterisk
|
||||
label="Harga Per Lembar"
|
||||
placeholder="0"
|
||||
value={harga ? harga : data.hargaLembar}
|
||||
onChange={(val) => {
|
||||
try {
|
||||
// console.log(typeof +val.currentTarget.value);
|
||||
|
||||
const match = val.currentTarget.value
|
||||
.replace(/\./g, "")
|
||||
.match(/^[0-9]+$/);
|
||||
|
||||
if (val.currentTarget.value === "") return setHarga(0 + "");
|
||||
|
||||
if (!match?.[0]) return null;
|
||||
|
||||
const nilai = val.currentTarget.value.replace(/\./g, "");
|
||||
const targetNilai = Intl.NumberFormat("id-ID").format(+nilai);
|
||||
|
||||
onTotalLembar({
|
||||
harga: +nilai,
|
||||
target: +data.targetDana,
|
||||
});
|
||||
|
||||
setHarga(targetNilai);
|
||||
setData({
|
||||
...data,
|
||||
hargaLembar: nilai as string,
|
||||
});
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
||||
<TextInput
|
||||
description="*Total lembar dihitung dari, Target Dana / Harga Perlembar"
|
||||
label="Total Lembar"
|
||||
value={harga === "0" ? "0" : target === "0" ? "0" : totalLembar}
|
||||
readOnly
|
||||
styles={{
|
||||
label: {
|
||||
color: "white",
|
||||
},
|
||||
|
||||
input: {
|
||||
backgroundColor: "whitesmoke",
|
||||
},
|
||||
}}
|
||||
/>
|
||||
|
||||
<TextInput
|
||||
styles={{
|
||||
label: {
|
||||
color: "white",
|
||||
},
|
||||
}}
|
||||
rightSection={
|
||||
<Text fw={"bold"} c={"gray"}>
|
||||
%
|
||||
</Text>
|
||||
}
|
||||
withAsterisk
|
||||
type="number"
|
||||
label={"Rasio Keuntungan / ROI %"}
|
||||
placeholder="Masukan rasio keuntungan"
|
||||
value={data.roi}
|
||||
onChange={(val) => {
|
||||
setData({
|
||||
...data,
|
||||
roi: val.target.value,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
|
||||
<Select
|
||||
styles={{
|
||||
label: {
|
||||
color: "white",
|
||||
},
|
||||
}}
|
||||
withAsterisk
|
||||
label="Pencarian Investor"
|
||||
placeholder="Pilih batas waktu"
|
||||
data={pencarianInvestor.map((e) => ({
|
||||
value: e.id,
|
||||
label: e.name + " " + "hari",
|
||||
}))}
|
||||
value={data.masterPencarianInvestorId}
|
||||
onChange={(val) => {
|
||||
setData({
|
||||
...(data as any),
|
||||
masterPencarianInvestorId: val,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
|
||||
<Select
|
||||
styles={{
|
||||
label: {
|
||||
color: "white",
|
||||
},
|
||||
}}
|
||||
withAsterisk
|
||||
label="Periode Deviden"
|
||||
placeholder="Pilih batas waktu"
|
||||
data={periodeDeviden.map((e) => ({ value: e.id, label: e.name }))}
|
||||
value={data.masterPeriodeDevidenId}
|
||||
onChange={(val) => {
|
||||
setData({
|
||||
...(data as any),
|
||||
masterPeriodeDevidenId: val,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
|
||||
<Select
|
||||
styles={{
|
||||
label: {
|
||||
color: "white",
|
||||
},
|
||||
}}
|
||||
withAsterisk
|
||||
label="Pembagian Deviden"
|
||||
placeholder="Pilih batas waktu"
|
||||
data={pembagianDeviden.map((e) => ({
|
||||
value: e.id,
|
||||
label: e.name + " " + "bulan",
|
||||
}))}
|
||||
value={data.masterPembagianDevidenId}
|
||||
onChange={(val) => {
|
||||
setData({
|
||||
...(data as any),
|
||||
masterPembagianDevidenId: val,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
|
||||
<Investasi_ComponentButtonUpdateDataInvestasi
|
||||
data={data as any}
|
||||
file={file as any}
|
||||
totalLembar={totalLembar}
|
||||
/>
|
||||
</Stack>
|
||||
</>
|
||||
);
|
||||
}
|
||||
148
src/app_modules/investasi/_view/edit/view_edit_prospektus.tsx
Normal file
148
src/app_modules/investasi/_view/edit/view_edit_prospektus.tsx
Normal file
@@ -0,0 +1,148 @@
|
||||
import { MainColor } from "@/app_modules/_global/color";
|
||||
import {
|
||||
ComponentGlobal_BoxInformation,
|
||||
ComponentGlobal_CardStyles,
|
||||
} from "@/app_modules/_global/component";
|
||||
import {
|
||||
Button,
|
||||
Center,
|
||||
FileButton,
|
||||
Grid,
|
||||
Group,
|
||||
Stack,
|
||||
Text
|
||||
} from "@mantine/core";
|
||||
import {
|
||||
IconCamera,
|
||||
IconCircleCheck
|
||||
} from "@tabler/icons-react";
|
||||
|
||||
import { DIRECTORY_ID } from "@/app/lib";
|
||||
import { funGlobal_UploadToStorage } from "@/app_modules/_global/fun";
|
||||
import {
|
||||
ComponentGlobal_NotifikasiBerhasil,
|
||||
ComponentGlobal_NotifikasiPeringatan,
|
||||
} from "@/app_modules/_global/notif_global";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import { investasi_funUpdateProspektus } from "../../_fun";
|
||||
|
||||
export function Investasi_ViewEditProspektus({
|
||||
investasiId,
|
||||
}: {
|
||||
investasiId: string;
|
||||
}) {
|
||||
const router = useRouter();
|
||||
const [filePdf, setFilePdf] = useState<File | null>(null);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
async function onUpload() {
|
||||
setIsLoading(true);
|
||||
const uploadFilePdf = await funGlobal_UploadToStorage({
|
||||
file: filePdf as any,
|
||||
dirId: DIRECTORY_ID.investasi_prospektus,
|
||||
});
|
||||
|
||||
if (!uploadFilePdf.success) {
|
||||
setIsLoading(false);
|
||||
return ComponentGlobal_NotifikasiPeringatan("Gagal upload file pdf");
|
||||
}
|
||||
|
||||
try {
|
||||
const updte = await investasi_funUpdateProspektus({
|
||||
fileId: uploadFilePdf.data.id,
|
||||
investasiId: investasiId,
|
||||
});
|
||||
|
||||
if (updte.status !== 200) {
|
||||
return ComponentGlobal_NotifikasiPeringatan("Gagal update prospektus");
|
||||
}
|
||||
|
||||
router.back();
|
||||
|
||||
return ComponentGlobal_NotifikasiBerhasil(updte.message);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Stack spacing={"sm"}>
|
||||
<ComponentGlobal_BoxInformation informasi="File prospektus wajib untuk diupload, agar calon investor paham dengan prospek investasi yang akan anda jalankan kedepan !" />
|
||||
<ComponentGlobal_CardStyles marginBottom={"0px"}>
|
||||
{!filePdf ? (
|
||||
<Text lineClamp={1} align="center" c={"gray"}>
|
||||
Upload File Prospektus
|
||||
</Text>
|
||||
) : (
|
||||
<Grid align="center">
|
||||
<Grid.Col span={2}></Grid.Col>
|
||||
<Grid.Col span={"auto"}>
|
||||
<Text lineClamp={1} align="center">
|
||||
{filePdf.name}
|
||||
</Text>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={2}>
|
||||
<Center>
|
||||
<IconCircleCheck color="green" />
|
||||
</Center>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
)}
|
||||
</ComponentGlobal_CardStyles>
|
||||
|
||||
<Group position="center">
|
||||
<FileButton
|
||||
accept={"application/pdf"}
|
||||
onChange={async (files: any) => {
|
||||
try {
|
||||
const buffer = URL.createObjectURL(
|
||||
new Blob([new Uint8Array(await files.arrayBuffer())])
|
||||
);
|
||||
|
||||
setFilePdf(files);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{(props) => (
|
||||
<Button
|
||||
leftIcon={<IconCamera />}
|
||||
{...props}
|
||||
radius={"xl"}
|
||||
bg={MainColor.yellow}
|
||||
color="yellow"
|
||||
c={"black"}
|
||||
>
|
||||
Upload File
|
||||
</Button>
|
||||
)}
|
||||
</FileButton>
|
||||
</Group>
|
||||
|
||||
<Button
|
||||
loaderPosition="center"
|
||||
loading={isLoading}
|
||||
disabled={filePdf === null}
|
||||
mt={50}
|
||||
radius={50}
|
||||
bg={MainColor.yellow}
|
||||
color="yellow"
|
||||
c={"black"}
|
||||
style={{
|
||||
transition: "0.5s",
|
||||
}}
|
||||
onClick={() => {
|
||||
onUpload();
|
||||
}}
|
||||
>
|
||||
Update
|
||||
</Button>
|
||||
</Stack>
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user