Fix: Investasi
Deskripsi: - Upload gambar investasi ke storage wibu - Upload bukti transfer ke storage wibu # No Issue
This commit is contained in:
@@ -12,15 +12,16 @@ export default function ComponentGlobal_BoxInformation({
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
{isReport ? (
|
||||
<Paper
|
||||
bg={"blue.3"}
|
||||
p={10}
|
||||
style={{
|
||||
backgroundColor: AccentColor.blue,
|
||||
border: `1px solid ${AccentColor.skyblue}`,
|
||||
}}
|
||||
>
|
||||
<Paper
|
||||
bg={"blue.3"}
|
||||
p={10}
|
||||
style={{
|
||||
backgroundColor: AccentColor.blue,
|
||||
border: `2px solid ${AccentColor.softblue}`,
|
||||
borderRadius: "10px",
|
||||
}}
|
||||
>
|
||||
{isReport ? (
|
||||
<Stack spacing={0}>
|
||||
<Text
|
||||
fz={fonsize ? fonsize : 12}
|
||||
@@ -34,16 +35,7 @@ export default function ComponentGlobal_BoxInformation({
|
||||
{informasi}
|
||||
</Text>
|
||||
</Stack>
|
||||
</Paper>
|
||||
) : (
|
||||
<Paper
|
||||
bg={"blue.3"}
|
||||
p={10}
|
||||
style={{
|
||||
backgroundColor: AccentColor.blue,
|
||||
border: `1px solid ${AccentColor.skyblue}`,
|
||||
}}
|
||||
>
|
||||
) : (
|
||||
<Group>
|
||||
<Text fz={fonsize ? fonsize : 12} c={"red"} fw={"bold"}>
|
||||
*{" "}
|
||||
@@ -52,8 +44,10 @@ export default function ComponentGlobal_BoxInformation({
|
||||
</Text>
|
||||
</Text>
|
||||
</Group>
|
||||
</Paper>
|
||||
)}
|
||||
)}
|
||||
</Paper>
|
||||
</>
|
||||
);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import { Box } from "@mantine/core";
|
||||
<Image
|
||||
style={{ maxHeight: 250 }}
|
||||
alt="Avatar"
|
||||
src={image ? image : APIs.GET({ fileId: profile.imageId as any })}/>
|
||||
src={image ? image : APIs.GET({ fileId: <imageId> })}/>
|
||||
* </AspectRatio>
|
||||
* @returns folllow like this
|
||||
*/
|
||||
@@ -22,7 +22,7 @@ export function ComponentGlobal_BoxUploadImage({
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
<ComponentGlobal_CardStyles height={height ? height : 300}>
|
||||
<ComponentGlobal_CardStyles height={height ? height : 300} >
|
||||
<Box
|
||||
style={{
|
||||
height: "100%",
|
||||
|
||||
@@ -44,11 +44,9 @@ export function ComponentGlobal_LoadImage({
|
||||
|
||||
if (isImage === null)
|
||||
return (
|
||||
// <Center h={250}>
|
||||
// <ComponentGlobal_Loader variant="dots" size={50} />
|
||||
// </Center>
|
||||
<Center>
|
||||
<Skeleton h={250} radius={"sm"} w={200} />
|
||||
|
||||
<Center h={"100%"}>
|
||||
<Skeleton h={250} radius={"sm"} w={250} />
|
||||
</Center>
|
||||
);
|
||||
|
||||
@@ -74,6 +72,7 @@ export function ComponentGlobal_LoadImage({
|
||||
opacity={isLoading ? 0.5 : 1}
|
||||
radius={radius ? radius : 0}
|
||||
alt="Image"
|
||||
height={h ? h : 250}
|
||||
maw={maw ? maw : 200}
|
||||
miw={200}
|
||||
src={url}
|
||||
|
||||
60
src/app_modules/_global/component/comp_load_image_custom.tsx
Normal file
60
src/app_modules/_global/component/comp_load_image_custom.tsx
Normal file
@@ -0,0 +1,60 @@
|
||||
"use client";
|
||||
|
||||
import { APIs } from "@/app/lib";
|
||||
import { pathAssetImage } from "@/app/lib/path_asset_image";
|
||||
import { Center, Image, Skeleton } from "@mantine/core";
|
||||
import { useShallowEffect } from "@mantine/hooks";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
|
||||
export function ComponentGlobal_LoadImageCustom({
|
||||
fileId,
|
||||
height,
|
||||
}: {
|
||||
fileId: string;
|
||||
height: number;
|
||||
}) {
|
||||
const [isImage, setIsImage] = useState<boolean | null>(null);
|
||||
const url = APIs.GET({ fileId: fileId });
|
||||
|
||||
useShallowEffect(() => {
|
||||
onLoadImage();
|
||||
}, []);
|
||||
|
||||
async function onLoadImage() {
|
||||
try {
|
||||
const res = await fetch(url);
|
||||
if (res.ok) {
|
||||
return setIsImage(true);
|
||||
}
|
||||
setIsImage(false);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
if (isImage === null)
|
||||
return <Skeleton h={height ? height : 100} w={"100%"} />;
|
||||
|
||||
return (
|
||||
<>
|
||||
{isImage ? (
|
||||
<Image alt="No Image" height={height} src={url} radius={"sm"} />
|
||||
) : (
|
||||
<Center
|
||||
bg={"white"}
|
||||
p={"sm"}
|
||||
h={height ? height : 80}
|
||||
style={{ borderRadius: "5px" }}
|
||||
>
|
||||
<Image
|
||||
alt="No Image"
|
||||
height={50}
|
||||
width={50}
|
||||
src={pathAssetImage.no_image}
|
||||
/>
|
||||
</Center>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -39,7 +39,7 @@ export function ComponentGlobal_LoadImageLandscape({
|
||||
if (!isImage)
|
||||
return (
|
||||
<>
|
||||
<Center h={200} bg={"white"} style={{ borderRadius: "10px" }}>
|
||||
<Center h={200} bg={"white"} style={{ borderRadius: "5px" }}>
|
||||
<Image
|
||||
alt="No Image"
|
||||
maw={150}
|
||||
@@ -55,6 +55,7 @@ export function ComponentGlobal_LoadImageLandscape({
|
||||
<>
|
||||
<Center>
|
||||
<Image
|
||||
|
||||
onClick={() => {
|
||||
setLoading(true);
|
||||
router.push(RouterImagePreview.main({ id: fileId }), {
|
||||
|
||||
@@ -5,6 +5,7 @@ import { ComponentGlobal_BoxUploadImage } from "./comp_box_upload_image";
|
||||
import { ComponentGlobal_CardStyles } from "./comp_card_box_and_background";
|
||||
import { ComponentGlobal_LoaderAvatar } from "./comp_load_avatar";
|
||||
import { ComponentGlobal_LoadImage } from "./comp_load_image";
|
||||
import { ComponentGlobal_LoadImageCustom } from "./comp_load_image_custom";
|
||||
import { ComponentGlobal_LoadImageLandscape } from "./comp_load_image_landscape";
|
||||
import ComponentGlobal_CardLoadingOverlay from "./comp_loading_card";
|
||||
import { ComponentGlobal_NotUserLoadImage } from "./comp_not_user_load_image";
|
||||
@@ -27,3 +28,4 @@ export { ComponentGlobal_LoaderAvatar };
|
||||
export { ComponentGlobal_AvatarAndUsername };
|
||||
export { ComponentGlobal_NotUserLoadImage };
|
||||
export { ComponentGlobal_LoadImageLandscape };
|
||||
export { ComponentGlobal_LoadImageCustom };
|
||||
|
||||
24
src/app_modules/_global/fun/delete/fun_delete_file_by_id.tsx
Normal file
24
src/app_modules/_global/fun/delete/fun_delete_file_by_id.tsx
Normal file
@@ -0,0 +1,24 @@
|
||||
export async function funGlobal_DeleteFileById({ fileId }: { fileId: string }) {
|
||||
try {
|
||||
const res = await fetch(
|
||||
`https://wibu-storage.wibudev.com/api/files/${fileId}/delete`,
|
||||
{
|
||||
method: "DELETE",
|
||||
headers: {
|
||||
Authorization: `Bearer ${process.env.WS_APIKEY}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
if (res.ok) {
|
||||
const hasil = await res.json();
|
||||
return { success: true };
|
||||
} else {
|
||||
const errorText = await res.json();
|
||||
return { success: false };
|
||||
}
|
||||
} catch (error) {
|
||||
return { success: false };
|
||||
console.error("Upload error:", error);
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
import { funGlobal_DeleteFileById } from "./delete/fun_delete_file_by_id";
|
||||
import { funGlobal_UploadToStorage } from "./upload/fun_upload_to_storage";
|
||||
|
||||
export { funGlobal_UploadToStorage };
|
||||
export { funGlobal_DeleteFileById };
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import UIGlobal_Drawer from "./ui_drawer";
|
||||
import UIGlobal_DrawerCustom from "./ui_drawer_custom";
|
||||
import UIGlobal_LayoutHeaderTamplate from "./ui_header_tamplate";
|
||||
import { UIGlobal_ImagePreview } from "./ui_image_preview";
|
||||
import UIGlobal_LayoutDefault from "./ui_layout_default";
|
||||
@@ -15,3 +16,4 @@ export { UIGlobal_SplashScreen };
|
||||
export { UIGlobal_ImagePreview };
|
||||
export { UIGlobal_NotUserImagePreview };
|
||||
export { UIGlobal_LayoutDefault };
|
||||
export { UIGlobal_DrawerCustom };
|
||||
|
||||
72
src/app_modules/_global/ui/ui_drawer_custom.tsx
Normal file
72
src/app_modules/_global/ui/ui_drawer_custom.tsx
Normal file
@@ -0,0 +1,72 @@
|
||||
"use client";
|
||||
|
||||
import { AccentColor } from "@/app_modules/_global/color";
|
||||
import {
|
||||
ActionIcon,
|
||||
Box,
|
||||
Drawer,
|
||||
Group,
|
||||
SimpleGrid,
|
||||
Stack,
|
||||
} from "@mantine/core";
|
||||
import { IconX } from "@tabler/icons-react";
|
||||
import React from "react";
|
||||
|
||||
interface MODEL_DRAWER {
|
||||
id: string;
|
||||
name: string;
|
||||
icon: string;
|
||||
path: string;
|
||||
}
|
||||
export default function UIGlobal_DrawerCustom({
|
||||
opened,
|
||||
close,
|
||||
component,
|
||||
}: {
|
||||
opened: boolean;
|
||||
close: () => void;
|
||||
component: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
<Drawer
|
||||
opened={opened}
|
||||
onClose={() => close()}
|
||||
position={"bottom"}
|
||||
size={"auto"}
|
||||
withCloseButton={false}
|
||||
styles={{
|
||||
content: {
|
||||
padding: 0,
|
||||
position: "absolute",
|
||||
margin: "auto",
|
||||
backgroundColor: "transparent",
|
||||
left: 0,
|
||||
right: 0,
|
||||
width: 500,
|
||||
},
|
||||
body: {
|
||||
backgroundColor: AccentColor.darkblue,
|
||||
borderTop: `2px solid ${AccentColor.blue}`,
|
||||
borderRight: `1px solid ${AccentColor.blue}`,
|
||||
borderLeft: `1px solid ${AccentColor.blue}`,
|
||||
borderRadius: "20px 20px 0px 0px",
|
||||
color: "white",
|
||||
paddingBottom: "5%",
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Stack spacing={"xs"}>
|
||||
<Group position="right">
|
||||
<ActionIcon onClick={close} variant="transparent">
|
||||
<IconX color="white" />
|
||||
</ActionIcon>
|
||||
</Group>
|
||||
<Box w={"100%"} >
|
||||
{component}
|
||||
</Box>
|
||||
</Stack>
|
||||
</Drawer>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
Container,
|
||||
Image,
|
||||
rem,
|
||||
ScrollArea,
|
||||
Skeleton,
|
||||
Text,
|
||||
Title,
|
||||
@@ -20,10 +21,12 @@ import { useState } from "react";
|
||||
import { MainColor } from "../color";
|
||||
import UIGlobal_LayoutHeaderTamplate from "./ui_header_tamplate";
|
||||
import { UIHeader } from "./ui_layout_tamplate";
|
||||
import ComponentGlobal_Loader from "../component/loader";
|
||||
|
||||
export function UIGlobal_ImagePreview({ fileId }: { fileId: string }) {
|
||||
const router = useRouter();
|
||||
const [isImage, setIsImage] = useState<boolean | null>(null);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
const url = APIs.GET({ fileId: fileId });
|
||||
|
||||
@@ -63,23 +66,31 @@ export function UIGlobal_ImagePreview({ fileId }: { fileId: string }) {
|
||||
hideButtonLeft
|
||||
customButtonRight={
|
||||
<ActionIcon
|
||||
onClick={() => router.back()}
|
||||
onClick={() => {
|
||||
router.back(), setIsLoading(true);
|
||||
}}
|
||||
variant="transparent"
|
||||
>
|
||||
<IconX color={MainColor.yellow} />
|
||||
{isLoading ? (
|
||||
<ComponentGlobal_Loader />
|
||||
) : (
|
||||
<IconX color={MainColor.yellow} />
|
||||
)}
|
||||
</ActionIcon>
|
||||
}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
|
||||
<Box style={{ zIndex: 0 }} h={"92vh"} pos={"static"} px={"lg"}>
|
||||
<Box style={{ zIndex: 0 }} h={"90vh"} pos={"static"} px={"lg"}>
|
||||
{isImage === null ? (
|
||||
<Skeleton height={200} radius={"sm"} />
|
||||
) : isImage ? (
|
||||
<Center>
|
||||
<Image alt="Image" src={url} maw={400} miw={200} />
|
||||
</Center>
|
||||
<ScrollArea h={"100%"}>
|
||||
<Center>
|
||||
<Image alt="Image" src={url} maw={500} miw={200} />
|
||||
</Center>
|
||||
</ScrollArea>
|
||||
) : (
|
||||
<Box
|
||||
bg={"gray"}
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
"use client";
|
||||
|
||||
import { DIRECTORY_ID } from "@/app/lib";
|
||||
import { NEW_RouterInvestasi } from "@/app/lib/router_hipmi/router_investasi";
|
||||
import { MainColor } from "@/app_modules/_global/color";
|
||||
import { funGlobal_UploadToStorage } from "@/app_modules/_global/fun";
|
||||
import {
|
||||
ComponentGlobal_NotifikasiBerhasil,
|
||||
ComponentGlobal_NotifikasiGagal,
|
||||
ComponentGlobal_NotifikasiPeringatan,
|
||||
} from "@/app_modules/_global/notif_global";
|
||||
import { notifikasiToAdmin_funCreate } from "@/app_modules/notifikasi/fun";
|
||||
import mqtt_client from "@/util/mqtt_client";
|
||||
import { Button } from "@mantine/core";
|
||||
import { useAtom } from "jotai";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import { investasi_funCreateNewInvestasi } from "../../_fun";
|
||||
import { gs_investas_menu, gs_investasi_status } from "../../g_state";
|
||||
|
||||
export function Investasi_ComponentButtonCreateNewInvestasi({
|
||||
data,
|
||||
totalLembar,
|
||||
fileImage,
|
||||
filePdf,
|
||||
}: {
|
||||
data: any;
|
||||
totalLembar: number;
|
||||
fileImage: File;
|
||||
filePdf: File;
|
||||
}) {
|
||||
const router = useRouter();
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [activeTab, setActiveTab] = useAtom(gs_investasi_status);
|
||||
const [hotMenu, setHotMenu] = useAtom(gs_investas_menu);
|
||||
|
||||
async function onSubmit() {
|
||||
setIsLoading(true);
|
||||
const body = {
|
||||
title: data.title,
|
||||
targetDana: data.targetDana,
|
||||
hargaLembar: data.hargaLembar,
|
||||
totalLembar: totalLembar,
|
||||
roi: data.roi,
|
||||
masterPeriodeDevidenId: data.periodeDevidenId,
|
||||
masterPembagianDevidenId: data.pembagianDevidenId,
|
||||
masterPencarianInvestorId: data.pencarianInvestorId,
|
||||
};
|
||||
|
||||
const uploadImage = await funGlobal_UploadToStorage({
|
||||
file: fileImage,
|
||||
dirId: DIRECTORY_ID.investasi_image,
|
||||
});
|
||||
if (!uploadImage.success) {
|
||||
setIsLoading(false);
|
||||
return ComponentGlobal_NotifikasiPeringatan("Gagal upload file gambar");
|
||||
}
|
||||
|
||||
const uploadFilePdf = await funGlobal_UploadToStorage({
|
||||
file: filePdf,
|
||||
dirId: DIRECTORY_ID.investasi_prospektus,
|
||||
});
|
||||
if (!uploadFilePdf.success) {
|
||||
setIsLoading(false);
|
||||
return ComponentGlobal_NotifikasiPeringatan("Gagal upload file pdf");
|
||||
}
|
||||
|
||||
const res = await investasi_funCreateNewInvestasi({
|
||||
data: body as any,
|
||||
fileImageId: uploadImage.data.id,
|
||||
filePdfId: uploadFilePdf.data.id,
|
||||
});
|
||||
|
||||
if (res.status === 201) {
|
||||
const dataNotif = {
|
||||
appId: res.data?.id,
|
||||
status: res.data?.MasterStatusInvestasi?.name,
|
||||
userId: res.data?.authorId,
|
||||
pesan: res.data?.title,
|
||||
kategoriApp: "INVESTASI",
|
||||
title: "Investasi baru",
|
||||
};
|
||||
|
||||
const notif = await notifikasiToAdmin_funCreate({
|
||||
data: dataNotif as any,
|
||||
});
|
||||
|
||||
if (notif.status === 201) {
|
||||
mqtt_client.publish(
|
||||
"ADMIN",
|
||||
JSON.stringify({
|
||||
count: 1,
|
||||
})
|
||||
);
|
||||
setActiveTab("Review");
|
||||
setHotMenu(1);
|
||||
setIsLoading(true);
|
||||
ComponentGlobal_NotifikasiBerhasil(res.message);
|
||||
router.push(NEW_RouterInvestasi.portofolio({ id: "2" }));
|
||||
}
|
||||
setIsLoading(false);
|
||||
} else {
|
||||
setIsLoading(false);
|
||||
ComponentGlobal_NotifikasiGagal(res.message);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Button
|
||||
my={"xl"}
|
||||
style={{
|
||||
transition: "0.5s",
|
||||
}}
|
||||
loaderPosition="center"
|
||||
loading={isLoading ? true : false}
|
||||
disabled={
|
||||
data.title === "" ||
|
||||
data.hargaLembar === 0 ||
|
||||
data.targetDana === 0 ||
|
||||
data.roi === 0 ||
|
||||
data.pencarianInvestorId === "" ||
|
||||
data.periodeDevidenId === "" ||
|
||||
data.pembagianDevidenId === "" ||
|
||||
fileImage === null ||
|
||||
filePdf === null
|
||||
? true
|
||||
: false
|
||||
}
|
||||
radius={50}
|
||||
bg={MainColor.yellow}
|
||||
color="yellow"
|
||||
c={"black"}
|
||||
onClick={() => onSubmit()}
|
||||
>
|
||||
Simpan
|
||||
</Button>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
import { MainColor } from "@/app_modules/_global/color";
|
||||
import { Button, Stack } from "@mantine/core";
|
||||
import { MODEL_INVESTASI } from "../../_lib/interface";
|
||||
import {
|
||||
ComponentGlobal_NotifikasiBerhasil,
|
||||
ComponentGlobal_NotifikasiPeringatan,
|
||||
} from "@/app_modules/_global/notif_global";
|
||||
import { DIRECTORY_ID } from "@/app/lib";
|
||||
import { funGlobal_UploadToStorage } from "@/app_modules/_global/fun";
|
||||
import _ from "lodash";
|
||||
import { investasi_funUpdateInvestasi } from "../../_fun";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
|
||||
export function Investasi_ComponentButtonUpdateDataInvestasi({
|
||||
data,
|
||||
file,
|
||||
totalLembar,
|
||||
}: {
|
||||
data: MODEL_INVESTASI;
|
||||
file: File;
|
||||
totalLembar: string;
|
||||
}) {
|
||||
const router = useRouter();
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
async function onUpdate() {
|
||||
if (totalLembar === "0")
|
||||
return ComponentGlobal_NotifikasiPeringatan("Total lembar kosong");
|
||||
|
||||
if (file !== null) {
|
||||
if (_.values(data).includes(""))
|
||||
return ComponentGlobal_NotifikasiPeringatan("Lengkapi data");
|
||||
|
||||
const uploadImage = await funGlobal_UploadToStorage({
|
||||
file: file as any,
|
||||
dirId: DIRECTORY_ID.investasi_image,
|
||||
});
|
||||
if (!uploadImage.success) {
|
||||
setIsLoading(false);
|
||||
return ComponentGlobal_NotifikasiPeringatan("Gagal upload file gambar");
|
||||
}
|
||||
|
||||
const updtWithImage = await investasi_funUpdateInvestasi({
|
||||
data: data,
|
||||
imageId: uploadImage.data.id,
|
||||
totalLembar: totalLembar,
|
||||
});
|
||||
|
||||
if (updtWithImage.status === 200) {
|
||||
setIsLoading(false);
|
||||
router.back();
|
||||
return ComponentGlobal_NotifikasiBerhasil(updtWithImage.message);
|
||||
} else {
|
||||
setIsLoading(false);
|
||||
return ComponentGlobal_NotifikasiPeringatan(updtWithImage.message);
|
||||
}
|
||||
} else {
|
||||
const updtNoImage = await investasi_funUpdateInvestasi({
|
||||
data: data,
|
||||
totalLembar: totalLembar,
|
||||
});
|
||||
|
||||
if (updtNoImage.status === 200) {
|
||||
setIsLoading(false);
|
||||
router.back();
|
||||
return ComponentGlobal_NotifikasiBerhasil(updtNoImage.message);
|
||||
} else {
|
||||
setIsLoading(false);
|
||||
return ComponentGlobal_NotifikasiPeringatan(updtNoImage.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
return (
|
||||
<Stack>
|
||||
<Button
|
||||
my={50}
|
||||
radius={50}
|
||||
bg={MainColor.yellow}
|
||||
color="yellow"
|
||||
c={"black"}
|
||||
onClick={() => {
|
||||
onUpdate();
|
||||
}}
|
||||
>
|
||||
Update
|
||||
</Button>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { RouterInvestasi_OLD } from "@/app/lib/router_hipmi/router_investasi";
|
||||
import { NEW_RouterInvestasi } from "@/app/lib/router_hipmi/router_investasi";
|
||||
import { AccentColor } from "@/app_modules/_global/color";
|
||||
import { ActionIcon, Flex, Loader, Paper, Text } from "@mantine/core";
|
||||
import { IconFileDescription } from "@tabler/icons-react";
|
||||
@@ -23,18 +23,17 @@ export function Investasi_ComponentBoxDaftarBerita({
|
||||
borderRadius: "10px",
|
||||
color: "white",
|
||||
}}
|
||||
onClick={() => {
|
||||
setLoading(true);
|
||||
router.push(
|
||||
NEW_RouterInvestasi.detail_prospektus({ id: investasiId }),
|
||||
{ scroll: false }
|
||||
);
|
||||
}}
|
||||
>
|
||||
<Flex direction={"column"} align={"center"} justify={"center"}>
|
||||
<Text fz={12}>Berita</Text>
|
||||
<ActionIcon
|
||||
radius={"xl"}
|
||||
variant="transparent"
|
||||
size={60}
|
||||
onClick={() => {
|
||||
setLoading(true);
|
||||
router.push(RouterInvestasi_OLD.daftar_berita + investasiId);
|
||||
}}
|
||||
>
|
||||
<ActionIcon radius={"xl"} variant="transparent" size={60}>
|
||||
{isLoading ? (
|
||||
<Loader color="yellow" />
|
||||
) : (
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import { RouterInvestasi_OLD } from "@/app/lib/router_hipmi/router_investasi";
|
||||
import {
|
||||
NEW_RouterInvestasi,
|
||||
RouterInvestasi_OLD,
|
||||
} from "@/app/lib/router_hipmi/router_investasi";
|
||||
import { AccentColor } from "@/app_modules/_global/color";
|
||||
import { ActionIcon, Flex, Loader, Paper, Text } from "@mantine/core";
|
||||
import { IconFileDescription } from "@tabler/icons-react";
|
||||
@@ -23,18 +26,17 @@ export function Investasi_ComponentBoxDaftarDokumen({
|
||||
borderRadius: "10px",
|
||||
color: "white",
|
||||
}}
|
||||
onClick={() => {
|
||||
setLoading(true);
|
||||
router.push(NEW_RouterInvestasi.daftar_dokumen({ id: investasiId }), {
|
||||
scroll: false,
|
||||
});
|
||||
// router.push(RouterInvestasi_OLD.detail_dokumen + investasiId, { scroll: false });
|
||||
}}
|
||||
>
|
||||
<Flex direction={"column"} align={"center"} justify={"center"}>
|
||||
<Text fz={12}>Dokumen</Text>
|
||||
<ActionIcon
|
||||
radius={"xl"}
|
||||
variant="transparent"
|
||||
size={60}
|
||||
onClick={() => {
|
||||
setLoading(true);
|
||||
router.push(RouterInvestasi_OLD.detail_dokumen + investasiId);
|
||||
}}
|
||||
>
|
||||
<ActionIcon radius={"xl"} variant="transparent" size={60}>
|
||||
{isLoading ? (
|
||||
<Loader color="yellow" />
|
||||
) : (
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { RouterInvestasi_OLD } from "@/app/lib/router_hipmi/router_investasi";
|
||||
import { NEW_RouterInvestasi } from "@/app/lib/router_hipmi/router_investasi";
|
||||
import { AccentColor } from "@/app_modules/_global/color";
|
||||
import { ActionIcon, Flex, Loader, Paper, Text } from "@mantine/core";
|
||||
import { IconBookDownload } from "@tabler/icons-react";
|
||||
@@ -6,9 +6,9 @@ import { useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
|
||||
export function Investasi_ComponentBoxProspektus({
|
||||
investasiId,
|
||||
prospektusFileId,
|
||||
}: {
|
||||
investasiId: string;
|
||||
prospektusFileId: string;
|
||||
}) {
|
||||
const router = useRouter();
|
||||
const [isLoading, setLoading] = useState(false);
|
||||
@@ -22,20 +22,18 @@ export function Investasi_ComponentBoxProspektus({
|
||||
border: `2px solid ${AccentColor.softblue}`,
|
||||
borderRadius: "10px",
|
||||
color: "white",
|
||||
|
||||
}}
|
||||
onClick={() => {
|
||||
setLoading(true);
|
||||
router.push(
|
||||
NEW_RouterInvestasi.file_prospektus({ id: prospektusFileId }),
|
||||
{ scroll: false }
|
||||
);
|
||||
}}
|
||||
>
|
||||
<Flex direction={"column"} align={"center"} justify={"center"}>
|
||||
<Text fz={12}>Prospektus</Text>
|
||||
<ActionIcon
|
||||
radius={"xl"}
|
||||
variant="transparent"
|
||||
size={60}
|
||||
onClick={() => {
|
||||
setLoading(true);
|
||||
router.push(RouterInvestasi_OLD.detail_prospektus + investasiId);
|
||||
}}
|
||||
>
|
||||
<ActionIcon radius={"xl"} variant="transparent" size={60}>
|
||||
{isLoading ? (
|
||||
<Loader color="yellow" />
|
||||
) : (
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
import { NEW_RouterInvestasi } from "@/app/lib/router_hipmi/router_investasi";
|
||||
import {
|
||||
ComponentGlobal_CardLoadingOverlay,
|
||||
ComponentGlobal_CardStyles,
|
||||
} from "@/app_modules/_global/component";
|
||||
import { Stack, Text } from "@mantine/core";
|
||||
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import { MODEL_INVESTASI_DOKUMEN } from "../../_lib/interface";
|
||||
|
||||
export function Investasi_ComponentCardDaftarDocument({
|
||||
data,
|
||||
}: {
|
||||
data: MODEL_INVESTASI_DOKUMEN;
|
||||
}) {
|
||||
const router = useRouter();
|
||||
const [visible, setVisible] = useState(false);
|
||||
return (
|
||||
<ComponentGlobal_CardStyles>
|
||||
<Stack
|
||||
justify="center"
|
||||
h={"100%"}
|
||||
onClick={() => {
|
||||
router.push(
|
||||
NEW_RouterInvestasi.file_prospektus({ id: data.fileId }),
|
||||
{ scroll: false }
|
||||
);
|
||||
setVisible(true);
|
||||
}}
|
||||
>
|
||||
<Text lineClamp={2}>{data.title}</Text>
|
||||
</Stack>
|
||||
{visible && <ComponentGlobal_CardLoadingOverlay />}
|
||||
</ComponentGlobal_CardStyles>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
import { NEW_RouterInvestasi } from "@/app/lib/router_hipmi/router_investasi";
|
||||
import {
|
||||
ComponentGlobal_CardLoadingOverlay,
|
||||
ComponentGlobal_CardStyles,
|
||||
} from "@/app_modules/_global/component";
|
||||
import {
|
||||
UIGlobal_DrawerCustom,
|
||||
UIGlobal_Modal,
|
||||
} from "@/app_modules/_global/ui";
|
||||
import {
|
||||
ActionIcon,
|
||||
Button,
|
||||
Grid,
|
||||
Group,
|
||||
SimpleGrid,
|
||||
Stack,
|
||||
Text,
|
||||
} from "@mantine/core";
|
||||
import { IconDots, IconEdit, IconTrash } from "@tabler/icons-react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import { MODEL_INVESTASI_DOKUMEN } from "../../_lib/interface";
|
||||
import ComponentGlobal_Loader from "@/app_modules/_global/component/loader";
|
||||
import {
|
||||
investasi_funDeleteDokumenById,
|
||||
investasi_funGetAllDocumentById,
|
||||
} from "../../_fun";
|
||||
import { funGlobal_DeleteFileById } from "@/app_modules/_global/fun";
|
||||
import {
|
||||
ComponentGlobal_NotifikasiBerhasil,
|
||||
ComponentGlobal_NotifikasiPeringatan,
|
||||
} from "@/app_modules/_global/notif_global";
|
||||
|
||||
export function Investasi_ComponentCardRekapDocument({
|
||||
data,
|
||||
onSetData,
|
||||
}: {
|
||||
data: MODEL_INVESTASI_DOKUMEN;
|
||||
onSetData: (val: any) => any[];
|
||||
}) {
|
||||
const router = useRouter();
|
||||
const [openDrawer, setOpenDrawer] = useState(false);
|
||||
const [isLoadingEdit, setIsLoadingEdit] = useState(false);
|
||||
|
||||
const [openModal, setOpenModal] = useState(false);
|
||||
const [isLoadingDelete, setIsLoadingDelete] = useState(false);
|
||||
const [visible, setVisible] = useState(false);
|
||||
|
||||
async function onDelete() {
|
||||
try {
|
||||
setIsLoadingDelete(true);
|
||||
const deleteFileFromStorage = await funGlobal_DeleteFileById({
|
||||
fileId: data.fileId,
|
||||
});
|
||||
|
||||
if (!deleteFileFromStorage.success) {
|
||||
ComponentGlobal_NotifikasiPeringatan("Gagal hapus file lama");
|
||||
}
|
||||
|
||||
const deleteFromDB = await investasi_funDeleteDokumenById({
|
||||
dokumenId: data.id,
|
||||
});
|
||||
|
||||
if (deleteFromDB.status !== 200) {
|
||||
ComponentGlobal_NotifikasiPeringatan(deleteFromDB.message);
|
||||
}
|
||||
ComponentGlobal_NotifikasiBerhasil(deleteFromDB.message);
|
||||
setOpenModal(false);
|
||||
|
||||
const loadData = await investasi_funGetAllDocumentById({
|
||||
investasiId: data.investasiId,
|
||||
page: 1,
|
||||
});
|
||||
|
||||
onSetData(loadData);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
} finally {
|
||||
setIsLoadingDelete(false);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<ComponentGlobal_CardStyles>
|
||||
<Grid>
|
||||
<Grid.Col
|
||||
span={"auto"}
|
||||
onClick={() => {
|
||||
router.push(
|
||||
NEW_RouterInvestasi.file_prospektus({ id: data.fileId }),
|
||||
{ scroll: false }
|
||||
);
|
||||
setVisible(true);
|
||||
}}
|
||||
>
|
||||
<Stack justify="center" h={"100%"}>
|
||||
<Text lineClamp={2}>{data.title}</Text>
|
||||
</Stack>
|
||||
</Grid.Col>
|
||||
|
||||
<Grid.Col span={"content"} onClick={() => setOpenDrawer(true)}>
|
||||
<Group grow>
|
||||
<ActionIcon variant="transparent">
|
||||
<IconDots color="white" />
|
||||
</ActionIcon>
|
||||
</Group>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
{visible && <ComponentGlobal_CardLoadingOverlay />}
|
||||
</ComponentGlobal_CardStyles>
|
||||
|
||||
<UIGlobal_DrawerCustom
|
||||
opened={openDrawer}
|
||||
close={() => setOpenDrawer(false)}
|
||||
component={
|
||||
<SimpleGrid cols={2}>
|
||||
<Stack align="center" spacing={"xs"}>
|
||||
<ActionIcon
|
||||
variant="transparent"
|
||||
c="white"
|
||||
onClick={() => {
|
||||
setIsLoadingEdit(true);
|
||||
router.push(
|
||||
NEW_RouterInvestasi.edit_dokumen({ id: data.id }),
|
||||
{ scroll: false }
|
||||
);
|
||||
}}
|
||||
>
|
||||
{isLoadingEdit ? <ComponentGlobal_Loader /> : <IconEdit />}
|
||||
</ActionIcon>
|
||||
<Text fz={"sm"} align="center" color="white">
|
||||
Edit Dokumen
|
||||
</Text>
|
||||
</Stack>
|
||||
|
||||
<Stack align="center" spacing={"xs"}>
|
||||
<ActionIcon
|
||||
variant="transparent"
|
||||
c="white"
|
||||
onClick={() => {
|
||||
setOpenModal(true);
|
||||
setOpenDrawer(false);
|
||||
}}
|
||||
>
|
||||
<IconTrash color="red" />
|
||||
</ActionIcon>
|
||||
<Text fz={"sm"} c={"red"} align="center" color="white">
|
||||
Hapus Dokumen
|
||||
</Text>
|
||||
</Stack>
|
||||
</SimpleGrid>
|
||||
}
|
||||
/>
|
||||
|
||||
<UIGlobal_Modal
|
||||
opened={openModal}
|
||||
close={() => setOpenModal(false)}
|
||||
title={"Anda yakin akan menghapus dokumen ini ?"}
|
||||
buttonKiri={
|
||||
<Button radius={"xl"} onClick={() => setOpenModal(false)}>
|
||||
Batal
|
||||
</Button>
|
||||
}
|
||||
buttonKanan={
|
||||
<Button
|
||||
loaderPosition="center"
|
||||
loading={isLoadingDelete}
|
||||
radius={"xl"}
|
||||
color={"red"}
|
||||
onClick={() => {
|
||||
onDelete();
|
||||
}}
|
||||
>
|
||||
Hapus
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
import {
|
||||
ComponentGlobal_CardStyles,
|
||||
ComponentGlobal_LoadImageLandscape,
|
||||
} from "@/app_modules/_global/component";
|
||||
import { MODEL_INVESTASI } from "@/app_modules/investasi/_lib/interface";
|
||||
import { Center, SimpleGrid, Stack, Text, Title } from "@mantine/core";
|
||||
import _ from "lodash";
|
||||
import { Investasi_ComponentBoxDaftarDokumen } from "./comp_box_daftar_dokumen";
|
||||
import { Investasi_ComponentBoxProspektus } from "./comp_box_prospektus";
|
||||
import { Investasi_ComponentTitleAndValueInDetail } from "./comp_title_and_value_in_detail";
|
||||
|
||||
export function Investasi_ComponentDetailDataNonPublish({
|
||||
data,
|
||||
}: {
|
||||
data: MODEL_INVESTASI;
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
<ComponentGlobal_CardStyles>
|
||||
<Stack spacing={"xl"}>
|
||||
<ComponentGlobal_LoadImageLandscape fileId={data.imageId} />
|
||||
|
||||
{/* Title dan Persentase */}
|
||||
<Center>
|
||||
<Title order={3} align="center">
|
||||
{_.startCase(data.title)}
|
||||
</Title>
|
||||
</Center>
|
||||
|
||||
{/* Rincian Data */}
|
||||
|
||||
<Stack>
|
||||
<Investasi_ComponentTitleAndValueInDetail
|
||||
title="Target Dana"
|
||||
value={
|
||||
<Text>
|
||||
Rp.{" "}
|
||||
{new Intl.NumberFormat("id-ID", {
|
||||
maximumSignificantDigits: 20,
|
||||
}).format(+data.targetDana)}{" "}
|
||||
</Text>
|
||||
}
|
||||
/>
|
||||
|
||||
<Investasi_ComponentTitleAndValueInDetail
|
||||
title="Harga Per Lembar"
|
||||
value={
|
||||
<Text>
|
||||
Rp.{" "}
|
||||
{new Intl.NumberFormat("id-ID", {
|
||||
maximumSignificantDigits: 10,
|
||||
}).format(+data.hargaLembar)}
|
||||
</Text>
|
||||
}
|
||||
/>
|
||||
|
||||
<Investasi_ComponentTitleAndValueInDetail
|
||||
title={<Text fs={"italic"}>Return Of Invesment (RoI)</Text>}
|
||||
value={<Text>{data.roi} %</Text>}
|
||||
/>
|
||||
|
||||
<Investasi_ComponentTitleAndValueInDetail
|
||||
title="Total Lembar"
|
||||
value={
|
||||
<Text>
|
||||
{new Intl.NumberFormat("id-ID", {
|
||||
maximumSignificantDigits: 10,
|
||||
}).format(+data.totalLembar)}{" "}
|
||||
lembar
|
||||
</Text>
|
||||
}
|
||||
/>
|
||||
|
||||
<Investasi_ComponentTitleAndValueInDetail
|
||||
title="Jadwal Pembagian"
|
||||
value={<Text>{data.MasterPembagianDeviden.name} Bulan </Text>}
|
||||
/>
|
||||
<Investasi_ComponentTitleAndValueInDetail
|
||||
title="Pembagian Deviden"
|
||||
value={<Text>{data.MasterPeriodeDeviden.name}</Text>}
|
||||
/>
|
||||
<Investasi_ComponentTitleAndValueInDetail
|
||||
title="Pencarian Investor"
|
||||
value={<Text>{data.MasterPencarianInvestor.name} Hari </Text>}
|
||||
/>
|
||||
</Stack>
|
||||
|
||||
{/* List Box */}
|
||||
<SimpleGrid
|
||||
cols={2}
|
||||
breakpoints={[
|
||||
{ maxWidth: "62rem", cols: 2, spacing: "md" },
|
||||
{ maxWidth: "48rem", cols: 2, spacing: "sm" },
|
||||
{ maxWidth: "36rem", cols: 1, spacing: "sm" },
|
||||
]}
|
||||
>
|
||||
<Investasi_ComponentBoxProspektus
|
||||
prospektusFileId={data.prospektusFileId}
|
||||
/>
|
||||
<Investasi_ComponentBoxDaftarDokumen investasiId={data?.id} />
|
||||
</SimpleGrid>
|
||||
</Stack>
|
||||
</ComponentGlobal_CardStyles>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import { Grid, Text } from "@mantine/core";
|
||||
import { data } from "autoprefixer";
|
||||
import React from "react";
|
||||
|
||||
export function Investasi_ComponentTitleAndValueInDetail({
|
||||
title,
|
||||
value,
|
||||
}: {
|
||||
title: string | React.ReactNode;
|
||||
value: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
<Grid>
|
||||
<Grid.Col span={5}>
|
||||
<Text fw={"bold"}>{title} </Text>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={1}>: </Grid.Col>
|
||||
<Grid.Col span={6}>{value}</Grid.Col>
|
||||
</Grid>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -1,5 +1,9 @@
|
||||
import { RouterInvestasi_OLD } from "@/app/lib/router_hipmi/router_investasi";
|
||||
import { ComponentGlobal_AvatarAndUsername } from "@/app_modules/_global/component";
|
||||
import {
|
||||
ComponentGlobal_AvatarAndUsername,
|
||||
ComponentGlobal_CardStyles,
|
||||
ComponentGlobal_LoadImageLandscape,
|
||||
} from "@/app_modules/_global/component";
|
||||
import { MODEL_INVOICE_INVESTASI } from "@/app_modules/investasi/_lib/interface";
|
||||
import {
|
||||
AspectRatio,
|
||||
@@ -23,20 +27,14 @@ export function Investasi_ComponentBoxDetailData({
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
<Investasi_ComponentStylesCard>
|
||||
<ComponentGlobal_CardStyles>
|
||||
<Stack>
|
||||
<ComponentGlobal_AvatarAndUsername profile={data?.Author.Profile as any} />
|
||||
<AspectRatio ratio={1 / 1} mx={0} mah={250}>
|
||||
<Image
|
||||
alt=""
|
||||
src={
|
||||
RouterInvestasi_OLD.api_gambar + `${data?.Investasi.imagesId}`
|
||||
}
|
||||
radius={"sm"}
|
||||
mah={250}
|
||||
width={"100%"}
|
||||
/>
|
||||
</AspectRatio>
|
||||
<ComponentGlobal_AvatarAndUsername
|
||||
profile={data?.Author.Profile as any}
|
||||
/>
|
||||
|
||||
<ComponentGlobal_LoadImageLandscape fileId={data.Investasi.imageId} />
|
||||
|
||||
<Title order={3} mb={"xs"} align="center">
|
||||
{data?.Investasi.title}
|
||||
</Title>
|
||||
@@ -122,7 +120,7 @@ export function Investasi_ComponentBoxDetailData({
|
||||
]}
|
||||
>
|
||||
<Investasi_ComponentBoxProspektus
|
||||
investasiId={data?.Investasi?.id}
|
||||
prospektusFileId={data.Investasi.prospektusFileId}
|
||||
/>
|
||||
<Investasi_ComponentBoxDaftarDokumen
|
||||
investasiId={data?.Investasi?.id}
|
||||
@@ -132,7 +130,7 @@ export function Investasi_ComponentBoxDetailData({
|
||||
/>
|
||||
</SimpleGrid>
|
||||
</Stack>
|
||||
</Investasi_ComponentStylesCard>
|
||||
</ComponentGlobal_CardStyles>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -12,6 +12,12 @@ import { Investasi_ComponentFooterMain } from "./main/comp_footer_main";
|
||||
import { Investasi_ComponentCardPortofolioPublish } from "./main/comp_card_portofolio_publish";
|
||||
import { Investasi_ComponentButtonUpdateBeranda } from "./main/comp_update_beranda";
|
||||
import { Investasi_ComponentCardPortofolio_NotPublish } from "./main/comp_card_portofolio_not_publish";
|
||||
import { Investasi_ComponentButtonCreateNewInvestasi } from "./button/comp_button_create_new_investasi";
|
||||
import { Investasi_ComponentTitleAndValueInDetail } from "./detail/comp_title_and_value_in_detail";
|
||||
import { Investasi_ComponentDetailDataNonPublish } from "./detail/comp_detail_data_non_publish";
|
||||
import { Investasi_ComponentButtonUpdateDataInvestasi } from "./button/comp_button_update_investasi";
|
||||
import { Investasi_ComponentCardRekapDocument } from "./detail/comp_card_rekap_document";
|
||||
import { Investasi_ComponentCardDaftarDocument } from "./detail/comp_card_daftar_document";
|
||||
|
||||
export { Investasi_ComponentFooterMain };
|
||||
export { Investasi_ComponentCardBeranda };
|
||||
@@ -27,3 +33,9 @@ export { Investasi_ComponentBoxProgress };
|
||||
export { Investasi_ComponentBoxDetailData };
|
||||
export { Investasi_ComponentCardPortofolioPublish };
|
||||
export { Investasi_ComponentCardPortofolio_NotPublish };
|
||||
export { Investasi_ComponentButtonCreateNewInvestasi };
|
||||
export { Investasi_ComponentTitleAndValueInDetail };
|
||||
export { Investasi_ComponentDetailDataNonPublish };
|
||||
export { Investasi_ComponentButtonUpdateDataInvestasi };
|
||||
export { Investasi_ComponentCardRekapDocument };
|
||||
export { Investasi_ComponentCardDaftarDocument };
|
||||
|
||||
@@ -15,16 +15,20 @@ import {
|
||||
Group,
|
||||
Image,
|
||||
Text,
|
||||
Grid,
|
||||
} from "@mantine/core";
|
||||
import { IconCircleCheck, IconXboxX } from "@tabler/icons-react";
|
||||
import moment from "moment";
|
||||
|
||||
import { MODEL_INVESTASI } from "../../_lib/interface";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import { Component, useState } from "react";
|
||||
import {
|
||||
ComponentGlobal_CardLoadingOverlay,
|
||||
ComponentGlobal_CardStyles,
|
||||
ComponentGlobal_LoadImage,
|
||||
ComponentGlobal_LoadImageCustom,
|
||||
ComponentGlobal_LoadImageLandscape,
|
||||
} from "@/app_modules/_global/component";
|
||||
|
||||
export function Investasi_ComponentCardBeranda({
|
||||
@@ -45,109 +49,89 @@ export function Investasi_ComponentCardBeranda({
|
||||
router.push(RouterInvestasi_OLD.detail + `${data?.id}`);
|
||||
}}
|
||||
>
|
||||
<CardSection py={"md"} px={"sm"}>
|
||||
<AspectRatio ratio={1 / 1} mah={250}>
|
||||
<Box style={{ borderRadius: "7px" }}>
|
||||
{data.imagesId ? (
|
||||
<Image
|
||||
radius={"sm"}
|
||||
alt="Foto"
|
||||
src={RouterInvestasi_OLD.api_gambar + `${data?.imagesId}`}
|
||||
w={200}
|
||||
<Stack>
|
||||
<Grid>
|
||||
<Grid.Col span={6}>
|
||||
<ComponentGlobal_LoadImageCustom
|
||||
height={100}
|
||||
fileId={data.imageId}
|
||||
/>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={6}>
|
||||
<Stack>
|
||||
<Text fw={"bold"} align="center" lineClamp={2}>{data?.title}</Text>
|
||||
|
||||
<Progress
|
||||
label={(+data?.progress).toFixed(2) + " %"}
|
||||
value={+data?.progress}
|
||||
color={MainColor.yellow}
|
||||
size="xl"
|
||||
radius="xl"
|
||||
styles={{
|
||||
label: { color: MainColor.black },
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<Image alt="" src={"/aset/no-img.png"} />
|
||||
)}
|
||||
</Box>
|
||||
</AspectRatio>
|
||||
</CardSection>
|
||||
|
||||
<CardSection p={"md"}>
|
||||
<Stack>
|
||||
<Title align="center" order={3}>
|
||||
{data?.title}
|
||||
</Title>
|
||||
<Progress
|
||||
label={(+data?.progress).toFixed(2) + " %"}
|
||||
value={+data?.progress}
|
||||
color={MainColor.yellow}
|
||||
size="xl"
|
||||
radius="xl"
|
||||
styles={{
|
||||
label: { color: MainColor.black },
|
||||
}}
|
||||
/>
|
||||
</Stack>
|
||||
</CardSection>
|
||||
|
||||
<CardSection p={"md"}>
|
||||
<Group position="right">
|
||||
{data?.progress === "100" ? (
|
||||
<Group position="right" spacing={"xs"}>
|
||||
<IconCircleCheck color="green" />
|
||||
<Text
|
||||
truncate
|
||||
variant="text"
|
||||
c={Warna.hijau_tua}
|
||||
sx={{ fontFamily: "Greycliff CF, sans-serif" }}
|
||||
ta="center"
|
||||
fz="md"
|
||||
fw={700}
|
||||
>
|
||||
Selesai
|
||||
</Text>
|
||||
</Group>
|
||||
) : (
|
||||
<Box>
|
||||
{+data?.MasterPencarianInvestor.name -
|
||||
moment(new Date()).diff(new Date(data?.countDown), "days") <=
|
||||
0 ? (
|
||||
<Group position="right" spacing={"xs"}>
|
||||
<IconXboxX color="red" />
|
||||
<Text
|
||||
truncate
|
||||
variant="text"
|
||||
c={Warna.merah}
|
||||
sx={{ fontFamily: "Greycliff CF, sans-serif" }}
|
||||
ta="center"
|
||||
fz="md"
|
||||
fw={700}
|
||||
>
|
||||
Waktu Habis
|
||||
</Text>
|
||||
</Group>
|
||||
) : (
|
||||
<Group position="right" spacing={"xs"}>
|
||||
<Text truncate>Sisa waktu:</Text>
|
||||
<Text truncate>
|
||||
{Number(data?.MasterPencarianInvestor.name) -
|
||||
<Group position="right">
|
||||
{data?.progress === "100" ? (
|
||||
<Group position="right" spacing={"xs"}>
|
||||
<IconCircleCheck color="green" />
|
||||
<Text
|
||||
truncate
|
||||
variant="text"
|
||||
c={Warna.hijau_tua}
|
||||
sx={{ fontFamily: "Greycliff CF, sans-serif" }}
|
||||
ta="center"
|
||||
fz="md"
|
||||
fw={700}
|
||||
>
|
||||
Selesai
|
||||
</Text>
|
||||
</Group>
|
||||
) : (
|
||||
<Box>
|
||||
{+data?.MasterPencarianInvestor.name -
|
||||
moment(new Date()).diff(
|
||||
new Date(data?.countDown),
|
||||
"days"
|
||||
)}
|
||||
</Text>
|
||||
<Text truncate>Hari</Text>
|
||||
</Group>
|
||||
)}
|
||||
</Box>
|
||||
)}
|
||||
</Group>
|
||||
</CardSection>
|
||||
) <=
|
||||
0 ? (
|
||||
<Group position="right" spacing={"xs"}>
|
||||
<IconXboxX color="red" />
|
||||
<Text
|
||||
truncate
|
||||
variant="text"
|
||||
c={Warna.merah}
|
||||
sx={{ fontFamily: "Greycliff CF, sans-serif" }}
|
||||
ta="center"
|
||||
fz="md"
|
||||
fw={700}
|
||||
>
|
||||
Waktu Habis
|
||||
</Text>
|
||||
</Group>
|
||||
) : (
|
||||
<Group position="right" spacing={"xs"}>
|
||||
<Text truncate>Sisa waktu:</Text>
|
||||
<Text truncate>
|
||||
{Number(data?.MasterPencarianInvestor.name) -
|
||||
moment(new Date()).diff(
|
||||
new Date(data?.countDown),
|
||||
"days"
|
||||
)}
|
||||
</Text>
|
||||
<Text truncate>Hari</Text>
|
||||
</Group>
|
||||
)}
|
||||
</Box>
|
||||
)}
|
||||
</Group>
|
||||
</Stack>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
</Stack>
|
||||
|
||||
{visible ? <ComponentGlobal_CardLoadingOverlay /> : ""}
|
||||
</ComponentGlobal_CardStyles>
|
||||
|
||||
{/* <Card
|
||||
style={{
|
||||
padding: "15px",
|
||||
backgroundColor: AccentColor.darkblue,
|
||||
borderRadius: "10px",
|
||||
border: `2px solid ${AccentColor.blue}`,
|
||||
color: "white",
|
||||
marginBottom: "15px",
|
||||
marginInline: "15px",
|
||||
}}
|
||||
|
||||
></Card> */}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import { RouterInvestasi_OLD } from "@/app/lib/router_hipmi/router_investasi";
|
||||
import { Grid, Stack, AspectRatio, Paper, Text, Image } from "@mantine/core";
|
||||
import {
|
||||
ComponentGlobal_CardLoadingOverlay,
|
||||
ComponentGlobal_CardStyles,
|
||||
ComponentGlobal_LoadImageCustom,
|
||||
} from "@/app_modules/_global/component";
|
||||
import { Grid, Stack, Text } from "@mantine/core";
|
||||
import _ from "lodash";
|
||||
import { MODEL_INVESTASI } from "../../_lib/interface";
|
||||
import { Investasi_ComponentStylesCard } from "../comp_card_border_and_background";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import { ComponentGlobal_CardLoadingOverlay } from "@/app_modules/_global/component";
|
||||
import { MODEL_INVESTASI } from "../../_lib/interface";
|
||||
|
||||
export function Investasi_ComponentCardPortofolio_NotPublish({
|
||||
data,
|
||||
@@ -16,12 +18,13 @@ export function Investasi_ComponentCardPortofolio_NotPublish({
|
||||
}) {
|
||||
const router = useRouter();
|
||||
const [visible, setVisible] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Investasi_ComponentStylesCard
|
||||
{/* <pre style={{color: "white"}}>{JSON.stringify(data, null, 2)}</pre> */}
|
||||
|
||||
<ComponentGlobal_CardStyles
|
||||
onClickHandler={() => {
|
||||
router.push(path + data?.id);
|
||||
router.push(path, { scroll: false });
|
||||
setVisible(true);
|
||||
}}
|
||||
>
|
||||
@@ -43,18 +46,14 @@ export function Investasi_ComponentCardPortofolio_NotPublish({
|
||||
</Grid.Col>
|
||||
|
||||
<Grid.Col span={4}>
|
||||
<AspectRatio ratio={16 / 9}>
|
||||
<Paper radius={"md"}>
|
||||
<Image
|
||||
alt=""
|
||||
src={RouterInvestasi_OLD.api_gambar + `${data.imagesId}`}
|
||||
/>
|
||||
</Paper>
|
||||
</AspectRatio>
|
||||
<ComponentGlobal_LoadImageCustom
|
||||
fileId={data.imageId}
|
||||
height={80}
|
||||
/>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
{visible && <ComponentGlobal_CardLoadingOverlay />}
|
||||
</Investasi_ComponentStylesCard>
|
||||
</ComponentGlobal_CardStyles>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ export function Investasi_ComponentCardPortofolioPublish({
|
||||
<Investasi_ComponentStylesCard
|
||||
marginBottom={"15px"}
|
||||
onClickHandler={() => {
|
||||
router.push(NEW_RouterInvestasi.detail_publish + data?.id);
|
||||
router.push(NEW_RouterInvestasi.detail_portofolio({ id: data?.id }));
|
||||
setVisible(true);
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import { RouterInvestasi_OLD } from "@/app/lib/router_hipmi/router_investasi";
|
||||
import {
|
||||
NEW_RouterInvestasi,
|
||||
RouterInvestasi_OLD,
|
||||
} from "@/app/lib/router_hipmi/router_investasi";
|
||||
import { MainColor } from "@/app_modules/_global/color/color_pallet";
|
||||
import { SimpleGrid, Stack, ActionIcon, Text } from "@mantine/core";
|
||||
import {
|
||||
@@ -21,7 +24,7 @@ const listFooter = [
|
||||
{
|
||||
id: 2,
|
||||
name: "Portofolio",
|
||||
route: RouterInvestasi_OLD.main_porto,
|
||||
route: NEW_RouterInvestasi.portofolio({ id: "1" }),
|
||||
icon: <IconChartPie />,
|
||||
},
|
||||
{
|
||||
@@ -45,14 +48,14 @@ export function Investasi_ComponentFooterMain() {
|
||||
return (
|
||||
<>
|
||||
<SimpleGrid cols={listFooter.length} h={"9vh"} mx={"xs"}>
|
||||
{listFooter.map((e, i) => (
|
||||
{listFooter.map((e: any, i) => (
|
||||
<Stack key={i} align="center" justify="center" spacing={0}>
|
||||
<ActionIcon
|
||||
// disabled={e.path === "" ? true : false}
|
||||
variant="transparent"
|
||||
c={hotMenu === i ? MainColor.yellow : "white"}
|
||||
onClick={() => {
|
||||
router.push(e.route);
|
||||
router.push(e.route, { scroll: false });
|
||||
setHotMenu(i);
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
"use server";
|
||||
|
||||
import { prisma } from "@/app/lib";
|
||||
import { NEW_RouterInvestasi } from "@/app/lib/router_hipmi/router_investasi";
|
||||
import { revalidatePath } from "next/cache";
|
||||
|
||||
type ICreateDocument = {
|
||||
investasiId: string;
|
||||
title: string;
|
||||
fileId: string;
|
||||
};
|
||||
export async function investasi_funCreateDocument({
|
||||
data,
|
||||
}: {
|
||||
data: ICreateDocument;
|
||||
}) {
|
||||
const create = await prisma.dokumenInvestasi.create({
|
||||
data: {
|
||||
investasiId: data.investasiId,
|
||||
title: data.title,
|
||||
fileId: data.fileId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!create) return { status: 400, message: "Gagal membuat dokumen" };
|
||||
revalidatePath(NEW_RouterInvestasi.rekap_dokumen({ id: data.investasiId }));
|
||||
return { status: 201, message: "Berhasil membuat dokumen" };
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
"use server";
|
||||
|
||||
import { prisma } from "@/app/lib";
|
||||
import { NEW_RouterInvestasi } from "@/app/lib/router_hipmi/router_investasi";
|
||||
import { funGetUserIdByToken } from "@/app_modules/_global/fun/get";
|
||||
import _ from "lodash";
|
||||
import { revalidatePath } from "next/cache";
|
||||
import { MODEL_INVESTASI } from "../../_lib/interface";
|
||||
|
||||
export async function investasi_funCreateNewInvestasi({
|
||||
data,
|
||||
fileImageId,
|
||||
filePdfId,
|
||||
}: {
|
||||
data: MODEL_INVESTASI;
|
||||
fileImageId: string;
|
||||
filePdfId: string;
|
||||
}) {
|
||||
const userLoginId = await funGetUserIdByToken();
|
||||
try {
|
||||
const createNew = await prisma.investasi.create({
|
||||
data: {
|
||||
authorId: userLoginId,
|
||||
title: _.startCase(data.title),
|
||||
targetDana: data.targetDana.toString(),
|
||||
hargaLembar: data.hargaLembar.toString(),
|
||||
totalLembar: data.totalLembar.toString(),
|
||||
sisaLembar: data.totalLembar.toString(),
|
||||
roi: data.roi.toString(),
|
||||
masterPembagianDevidenId: data.masterPembagianDevidenId,
|
||||
masterPeriodeDevidenId: data.masterPeriodeDevidenId,
|
||||
masterPencarianInvestorId: data.masterPencarianInvestorId,
|
||||
masterStatusInvestasiId: "2",
|
||||
imageId: fileImageId,
|
||||
prospektusFileId: filePdfId,
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
title: true,
|
||||
authorId: true,
|
||||
MasterStatusInvestasi: {
|
||||
select: {
|
||||
name: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
if (!createNew) return { status: 400, message: "Gagal Membuat Investasi" };
|
||||
revalidatePath(NEW_RouterInvestasi.portofolio({id: "2"}));
|
||||
|
||||
return {
|
||||
status: 201,
|
||||
data: createNew,
|
||||
message: "Berhasil Membuat Investasi",
|
||||
};
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
|
||||
return { status: 400, message: "Error Message" };
|
||||
}
|
||||
}
|
||||
21
src/app_modules/investasi/_fun/delete/fun_delete_dokumen.tsx
Normal file
21
src/app_modules/investasi/_fun/delete/fun_delete_dokumen.tsx
Normal file
@@ -0,0 +1,21 @@
|
||||
"use server";
|
||||
|
||||
import { prisma } from "@/app/lib";
|
||||
import { NEW_RouterInvestasi } from "@/app/lib/router_hipmi/router_investasi";
|
||||
import { revalidatePath } from "next/cache";
|
||||
|
||||
export async function investasi_funDeleteDokumenById({
|
||||
dokumenId,
|
||||
}: {
|
||||
dokumenId: string;
|
||||
}) {
|
||||
const del = await prisma.dokumenInvestasi.delete({
|
||||
where: {
|
||||
id: dokumenId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!del) return { status: 400, message: "Gagal hapus data" };
|
||||
revalidatePath(NEW_RouterInvestasi.rekap_dokumen({ id: del.investasiId as any }));
|
||||
return { status: 200, message: "Berhasil hapus data" };
|
||||
}
|
||||
67
src/app_modules/investasi/_fun/edit/fun_edit_document.tsx
Normal file
67
src/app_modules/investasi/_fun/edit/fun_edit_document.tsx
Normal file
@@ -0,0 +1,67 @@
|
||||
"use server";
|
||||
|
||||
import { prisma } from "@/app/lib";
|
||||
import { MODEL_INVESTASI_DOKUMEN } from "../../_lib/interface";
|
||||
import { NEW_RouterInvestasi } from "@/app/lib/router_hipmi/router_investasi";
|
||||
import { revalidatePath } from "next/cache";
|
||||
|
||||
export async function investasi_funUpdateDocument({
|
||||
data,
|
||||
fileId,
|
||||
}: {
|
||||
data: MODEL_INVESTASI_DOKUMEN;
|
||||
fileId?: string;
|
||||
}) {
|
||||
try {
|
||||
fileId !== undefined
|
||||
? await prisma.dokumenInvestasi.update({
|
||||
where: {
|
||||
id: data.id,
|
||||
},
|
||||
data: {
|
||||
title: data.title,
|
||||
fileId: fileId,
|
||||
},
|
||||
})
|
||||
: await prisma.dokumenInvestasi.update({
|
||||
where: {
|
||||
id: data.id,
|
||||
},
|
||||
data: {
|
||||
title: data.title,
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
} finally {
|
||||
revalidatePath(NEW_RouterInvestasi.rekap_dokumen({ id: data.investasiId }));
|
||||
return { status: 200, message: "Berhasil Update" };
|
||||
}
|
||||
|
||||
// if (fileId !== undefined) {
|
||||
// const updt = await prisma.dokumenInvestasi.update({
|
||||
// where: {
|
||||
// id: data.id,
|
||||
// },
|
||||
// data: {
|
||||
// title: data.title,
|
||||
// fileId: fileId,
|
||||
// },
|
||||
// });
|
||||
// } else {
|
||||
// const updt = await prisma.dokumenInvestasi.update({
|
||||
// where: {
|
||||
// id: data.id,
|
||||
// },
|
||||
// data: {
|
||||
// title: data.title,
|
||||
// },
|
||||
// });
|
||||
// }
|
||||
// if (!updt) return { status: 400, message: "Gagal Update" };
|
||||
// revalidatePath(NEW_RouterInvestasi.rekap_dokumen({ id: data.investasiId }));
|
||||
// return {
|
||||
// status: 200,
|
||||
// message: "Berhasil Update",
|
||||
// };
|
||||
}
|
||||
67
src/app_modules/investasi/_fun/edit/fun_edit_investasi.tsx
Normal file
67
src/app_modules/investasi/_fun/edit/fun_edit_investasi.tsx
Normal file
@@ -0,0 +1,67 @@
|
||||
"use server";
|
||||
|
||||
import { prisma } from "@/app/lib";
|
||||
import { MODEL_INVESTASI } from "../../_lib/interface";
|
||||
import _ from "lodash";
|
||||
import { revalidatePath } from "next/cache";
|
||||
import { NEW_RouterInvestasi } from "@/app/lib/router_hipmi/router_investasi";
|
||||
|
||||
export async function investasi_funUpdateInvestasi({
|
||||
data,
|
||||
imageId,
|
||||
totalLembar,
|
||||
}: {
|
||||
data: MODEL_INVESTASI;
|
||||
imageId?: string;
|
||||
totalLembar: string;
|
||||
}) {
|
||||
// console.log(data);
|
||||
// console.log(imageId);
|
||||
// console.log(totalLembar);
|
||||
|
||||
if (imageId !== undefined) {
|
||||
const updtWithImage = await prisma.investasi.update({
|
||||
where: {
|
||||
id: data.id,
|
||||
},
|
||||
data: {
|
||||
title: _.startCase(data.title),
|
||||
targetDana: data.targetDana,
|
||||
hargaLembar: data.hargaLembar,
|
||||
totalLembar: totalLembar,
|
||||
sisaLembar: totalLembar,
|
||||
roi: data.roi,
|
||||
masterPembagianDevidenId: data.masterPembagianDevidenId,
|
||||
masterPeriodeDevidenId: data.masterPeriodeDevidenId,
|
||||
masterPencarianInvestorId: data.masterPencarianInvestorId,
|
||||
imageId: imageId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!updtWithImage) return { status: 400, message: "Gagal update data" };
|
||||
revalidatePath(NEW_RouterInvestasi.detail_draft);
|
||||
return { status: 200, message: "Berhasil update" };
|
||||
} else {
|
||||
const updtNoImage = await prisma.investasi.update({
|
||||
where: {
|
||||
id: data.id,
|
||||
},
|
||||
data: {
|
||||
title: _.startCase(data.title),
|
||||
targetDana: data.targetDana,
|
||||
hargaLembar: data.hargaLembar,
|
||||
totalLembar: totalLembar,
|
||||
sisaLembar: totalLembar,
|
||||
roi: data.roi,
|
||||
masterPembagianDevidenId: data.masterPembagianDevidenId,
|
||||
masterPeriodeDevidenId: data.masterPeriodeDevidenId,
|
||||
masterPencarianInvestorId: data.masterPencarianInvestorId,
|
||||
imageId: imageId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!updtNoImage) return { status: 400, message: "Gagal update data" };
|
||||
revalidatePath(NEW_RouterInvestasi.detail_draft);
|
||||
return { status: 200, message: "Berhasil update" };
|
||||
}
|
||||
}
|
||||
29
src/app_modules/investasi/_fun/edit/fun_edit_prospektus.tsx
Normal file
29
src/app_modules/investasi/_fun/edit/fun_edit_prospektus.tsx
Normal file
@@ -0,0 +1,29 @@
|
||||
"use server";
|
||||
|
||||
import { prisma } from "@/app/lib";
|
||||
import { NEW_RouterInvestasi } from "@/app/lib/router_hipmi/router_investasi";
|
||||
import { revalidatePath } from "next/cache";
|
||||
|
||||
export async function investasi_funUpdateProspektus({
|
||||
investasiId,
|
||||
fileId,
|
||||
}: {
|
||||
investasiId: string;
|
||||
fileId: string;
|
||||
}) {
|
||||
const updte = await prisma.investasi.update({
|
||||
where: {
|
||||
id: investasiId,
|
||||
},
|
||||
data: {
|
||||
prospektusFileId: fileId,
|
||||
},
|
||||
});
|
||||
|
||||
if (!updte) return { status: 400, message: "Gagal update prospektus" };
|
||||
revalidatePath(NEW_RouterInvestasi.detail_draft);
|
||||
return {
|
||||
status: 200,
|
||||
message: "Berhasil update prospektus",
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
"use server";
|
||||
|
||||
import { prisma } from "@/app/lib";
|
||||
|
||||
export async function investasi_funGetAllDocumentById({
|
||||
investasiId,
|
||||
page,
|
||||
}: {
|
||||
investasiId: string;
|
||||
page: number
|
||||
}) {
|
||||
const takeData = 10;
|
||||
const skipData = page * takeData - takeData;
|
||||
|
||||
const data = await prisma.dokumenInvestasi.findMany({
|
||||
take: takeData,
|
||||
skip: skipData,
|
||||
orderBy: {
|
||||
updatedAt: "desc",
|
||||
},
|
||||
where: {
|
||||
investasiId: investasiId,
|
||||
active: true,
|
||||
},
|
||||
});
|
||||
|
||||
return data;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
"use server"
|
||||
|
||||
import { prisma } from "@/app/lib"
|
||||
|
||||
export async function investasi_funGetOneDocumentById({ documentId }: { documentId: string }) {
|
||||
const data = await prisma.dokumenInvestasi.findFirst({
|
||||
where: {
|
||||
id: documentId
|
||||
}
|
||||
})
|
||||
|
||||
return data
|
||||
}
|
||||
@@ -24,6 +24,7 @@ export async function investasi_funGetOneInvestasiById({
|
||||
MasterPencarianInvestor: true,
|
||||
MasterPeriodeDeviden: true,
|
||||
MasterProgresInvestasi: true,
|
||||
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
"use server";
|
||||
|
||||
import prisma from "@/app/lib/prisma";
|
||||
import { funGetUserIdByToken } from "@/app_modules/_global/fun/get";
|
||||
|
||||
export async function investasi_funGetPortofolioByStatusId({
|
||||
page,
|
||||
statusId,
|
||||
}: {
|
||||
page: number;
|
||||
statusId: string;
|
||||
}) {
|
||||
const userLoginId = await funGetUserIdByToken();
|
||||
|
||||
const takeData = 10;
|
||||
const skipData = page * takeData - takeData;
|
||||
|
||||
const data = await prisma.investasi.findMany({
|
||||
take: takeData,
|
||||
skip: skipData,
|
||||
orderBy: {
|
||||
updatedAt: "desc",
|
||||
},
|
||||
where: {
|
||||
authorId: userLoginId,
|
||||
masterStatusInvestasiId: statusId,
|
||||
},
|
||||
include: {
|
||||
MasterPencarianInvestor: true,
|
||||
},
|
||||
});
|
||||
|
||||
return data;
|
||||
}
|
||||
@@ -5,6 +5,19 @@ import { investasi_funUploadBuktiTransferById } from "./upload/fun_upload_bukti_
|
||||
import { investasi_funGetSuccessTransactionById } from "./get/fun_get_success_transaction_by_id";
|
||||
import { investasi_funGetAllPublishByUserId } from "./get/fun_get_all_investasi_by_user_id";
|
||||
import { investasi_funGetAllInvestasiNonPublishByUserId } from "./get/fun_get_all_investasi_non_publish_by_user_id";
|
||||
import { investasi_funCreateNewInvestasi } from "./create/fun_create_new_investasi";
|
||||
import { investasi_funGetPortofolioByStatusId } from "./get/fun_get_portofolio_by_status_id";
|
||||
import { investasi_funUpdateInvestasi } from "./edit/fun_edit_investasi";
|
||||
import { investasi_funUpdateProspektus } from "./edit/fun_edit_prospektus";
|
||||
import { investasi_funGetAllDocumentById } from "./get/fun_get_all_document_by_id";
|
||||
import { investasi_funCreateDocument } from "./create/fun_create_document";
|
||||
import { investasi_funGetOneDocumentById } from "./get/fun_get_one_document_by_id";
|
||||
import { investasi_funUpdateDocument } from "./edit/fun_edit_document";
|
||||
import { investasi_funDeleteDokumenById } from "./delete/fun_delete_dokumen";
|
||||
|
||||
// Create
|
||||
export { investasi_funCreateNewInvestasi };
|
||||
export { investasi_funCreateDocument };
|
||||
|
||||
// Get
|
||||
export { investasi_funGetOneInvestasiById };
|
||||
@@ -13,6 +26,17 @@ export { investasi_funGetTransaksiByUserId };
|
||||
export { investasi_funGetSuccessTransactionById };
|
||||
export { investasi_funGetAllPublishByUserId };
|
||||
export { investasi_funGetAllInvestasiNonPublishByUserId };
|
||||
export { investasi_funGetPortofolioByStatusId };
|
||||
export { investasi_funGetAllDocumentById };
|
||||
export { investasi_funGetOneDocumentById };
|
||||
|
||||
// Update
|
||||
export { investasi_funUpdateInvestasi };
|
||||
export { investasi_funUpdateProspektus };
|
||||
export { investasi_funUpdateDocument };
|
||||
|
||||
// Upload
|
||||
export { investasi_funUploadBuktiTransferById };
|
||||
|
||||
// Delete
|
||||
export { investasi_funDeleteDokumenById };
|
||||
|
||||
@@ -7,38 +7,17 @@ import fs from "fs";
|
||||
|
||||
export async function investasi_funUploadBuktiTransferById({
|
||||
invoiceId,
|
||||
file,
|
||||
fileId,
|
||||
}: {
|
||||
invoiceId: string;
|
||||
file: FormData;
|
||||
fileId: string;
|
||||
}) {
|
||||
// console.log(file);
|
||||
const gambar: any = file.get("file");
|
||||
const fileName = gambar.name;
|
||||
const fileExtension = _.lowerCase(gambar.name.split(".").pop());
|
||||
const fileRandomName = v4(fileName) + "." + fileExtension;
|
||||
|
||||
const upload = await prisma.images.create({
|
||||
data: {
|
||||
url: fileRandomName,
|
||||
label: "INVESTASI_INVOICE",
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
url: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (!upload) return { status: 400, message: "Gagal upload gambar" };
|
||||
const uploadFolder = Buffer.from(await gambar.arrayBuffer());
|
||||
fs.writeFileSync(`./public/investasi/invoice/${upload.url}`, uploadFolder);
|
||||
|
||||
const updateFile = await prisma.investasi_Invoice.update({
|
||||
where: {
|
||||
id: invoiceId,
|
||||
},
|
||||
data: {
|
||||
imagesId: upload.id,
|
||||
imageId: fileId,
|
||||
statusInvoiceId: "2",
|
||||
},
|
||||
});
|
||||
|
||||
@@ -19,7 +19,7 @@ export interface MODEL_INVESTASI {
|
||||
progress: string;
|
||||
MasterStatusInvestasi: MODEL_Status_investasi;
|
||||
BeritaInvestasi: Model_Berita_Investasi[];
|
||||
DokumenInvestasi: Model_Dokumen_Investasi[];
|
||||
DokumenInvestasi: MODEL_INVESTASI_DOKUMEN[];
|
||||
ProspektusInvestasi: MODEl_PROSPEKTUS_INVESTASI;
|
||||
MasterPembagianDeviden: Model_All_Master;
|
||||
MasterPencarianInvestor: Model_All_Master;
|
||||
@@ -32,6 +32,8 @@ export interface MODEL_INVESTASI {
|
||||
author: MODEL_PROFILE_OLD;
|
||||
countDown: Date;
|
||||
Investasi_Invoice: MODEL_INVOICE_INVESTASI[];
|
||||
imageId: string;
|
||||
prospektusFileId: string;
|
||||
}
|
||||
|
||||
export interface MODEL_Transaksi_Investasi {
|
||||
@@ -88,7 +90,7 @@ export interface MODEl_PROSPEKTUS_INVESTASI {
|
||||
investasiId: string;
|
||||
}
|
||||
|
||||
export interface Model_Dokumen_Investasi {
|
||||
export interface MODEL_INVESTASI_DOKUMEN {
|
||||
id: string;
|
||||
title: string;
|
||||
url: string;
|
||||
@@ -96,6 +98,7 @@ export interface Model_Dokumen_Investasi {
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
investasiId: string;
|
||||
fileId: string;
|
||||
}
|
||||
|
||||
export interface MODEL_MASTER_BANK {
|
||||
@@ -134,6 +137,7 @@ export interface MODEL_INVOICE_INVESTASI {
|
||||
MasterBank: MODEL_MASTER_BANK;
|
||||
StatusInvoice: MODEL_STATUS_INVOICE_INVESTASI;
|
||||
Investor: any[];
|
||||
imageId: string
|
||||
}
|
||||
|
||||
export interface MODEL_STATUS_INVOICE_INVESTASI {
|
||||
|
||||
16
src/app_modules/investasi/_ui/create/ui_create_document.tsx
Normal file
16
src/app_modules/investasi/_ui/create/ui_create_document.tsx
Normal file
@@ -0,0 +1,16 @@
|
||||
"use client"
|
||||
|
||||
import { UIGlobal_LayoutHeaderTamplate, UIGlobal_LayoutTamplate } from "@/app_modules/_global/ui"
|
||||
import { Investasi_ViewCreateDocument } from "../../_view";
|
||||
|
||||
export function Investasi_UiCreateDocument({ investasiId }: { investasiId : string}) {
|
||||
return (
|
||||
<>
|
||||
<UIGlobal_LayoutTamplate
|
||||
header={<UIGlobal_LayoutHeaderTamplate title="Tambah Dokumen" />}
|
||||
>
|
||||
<Investasi_ViewCreateDocument investasiId={investasiId}/>
|
||||
</UIGlobal_LayoutTamplate>
|
||||
</>
|
||||
);
|
||||
}
|
||||
28
src/app_modules/investasi/_ui/detail/ui_daftar_dokumen.tsx
Normal file
28
src/app_modules/investasi/_ui/detail/ui_daftar_dokumen.tsx
Normal file
@@ -0,0 +1,28 @@
|
||||
"use client";
|
||||
|
||||
import {
|
||||
UIGlobal_LayoutHeaderTamplate,
|
||||
UIGlobal_LayoutTamplate,
|
||||
} from "@/app_modules/_global/ui";
|
||||
import { Investasi_ViewDaftarDokumen } from "../../_view";
|
||||
|
||||
export function Investasi_UiDaftarDokmen({
|
||||
dataDokumen,
|
||||
investasiId,
|
||||
}: {
|
||||
dataDokumen: any[];
|
||||
investasiId: string
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
<UIGlobal_LayoutTamplate
|
||||
header={<UIGlobal_LayoutHeaderTamplate title="Daftar Dokumen" />}
|
||||
>
|
||||
<Investasi_ViewDaftarDokumen
|
||||
dataDokumen={dataDokumen}
|
||||
investasiId={investasiId}
|
||||
/>
|
||||
</UIGlobal_LayoutTamplate>
|
||||
</>
|
||||
);
|
||||
}
|
||||
102
src/app_modules/investasi/_ui/detail/ui_detail_portofolio.tsx
Normal file
102
src/app_modules/investasi/_ui/detail/ui_detail_portofolio.tsx
Normal file
@@ -0,0 +1,102 @@
|
||||
"use client";
|
||||
|
||||
import { NEW_RouterInvestasi } from "@/app/lib/router_hipmi/router_investasi";
|
||||
import {
|
||||
UIGlobal_Drawer,
|
||||
UIGlobal_LayoutHeaderTamplate,
|
||||
UIGlobal_LayoutTamplate,
|
||||
} from "@/app_modules/_global/ui";
|
||||
import { ActionIcon } from "@mantine/core";
|
||||
import {
|
||||
IconCategoryPlus,
|
||||
IconDotsVertical,
|
||||
IconEdit,
|
||||
IconFilePencil,
|
||||
} from "@tabler/icons-react";
|
||||
import { useState } from "react";
|
||||
import { MODEL_INVESTASI } from "../../_lib/interface";
|
||||
import {
|
||||
Investasi_ViewDetailDraft,
|
||||
Investasi_ViewDetailPublish,
|
||||
Investasi_ViewDetailReject,
|
||||
Investasi_ViewDetailReview,
|
||||
} from "../../_view";
|
||||
|
||||
export function Investasi_UiDetailPortofolio({
|
||||
data,
|
||||
}: {
|
||||
data: MODEL_INVESTASI;
|
||||
}) {
|
||||
const [openDrawer, setOpenDrawer] = useState(false);
|
||||
const listPage = [
|
||||
{
|
||||
id: "1",
|
||||
name: "Edit Investasi",
|
||||
icon: <IconEdit />,
|
||||
path: NEW_RouterInvestasi.edit_investasi({ id: data.id }),
|
||||
},
|
||||
{
|
||||
id: "2",
|
||||
name: "Edit Prospektus",
|
||||
icon: <IconFilePencil />,
|
||||
path: NEW_RouterInvestasi.edit_prospektus({ id: data.id }),
|
||||
},
|
||||
{
|
||||
id: "3",
|
||||
name: "Tambah & Edit Dokumen",
|
||||
icon: <IconCategoryPlus />,
|
||||
path: NEW_RouterInvestasi.rekap_dokumen({ id: data.id }),
|
||||
},
|
||||
];
|
||||
|
||||
if (data.masterStatusInvestasiId == "3")
|
||||
return (
|
||||
<>
|
||||
<UIGlobal_LayoutTamplate
|
||||
header={
|
||||
<UIGlobal_LayoutHeaderTamplate
|
||||
title={`Detail Draft`}
|
||||
customButtonRight={
|
||||
<ActionIcon
|
||||
variant="transparent"
|
||||
onClick={() => setOpenDrawer(true)}
|
||||
>
|
||||
<IconDotsVertical color="white" />
|
||||
</ActionIcon>
|
||||
}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<Investasi_ViewDetailDraft dataInvestasi={data} />
|
||||
</UIGlobal_LayoutTamplate>
|
||||
|
||||
<UIGlobal_Drawer
|
||||
opened={openDrawer}
|
||||
close={() => setOpenDrawer(false)}
|
||||
component={listPage}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
return (
|
||||
<UIGlobal_LayoutTamplate
|
||||
header={
|
||||
<UIGlobal_LayoutHeaderTamplate
|
||||
title={`Detail ${data.MasterStatusInvestasi.name}`}
|
||||
/>
|
||||
}
|
||||
>
|
||||
{data.masterStatusInvestasiId === "1" && (
|
||||
<Investasi_ViewDetailPublish dataInvestasi={data} />
|
||||
)}
|
||||
|
||||
{data.masterStatusInvestasiId === "2" && (
|
||||
<Investasi_ViewDetailReview dataInvestasi={data} />
|
||||
)}
|
||||
|
||||
{data.masterStatusInvestasiId === "4" && (
|
||||
<Investasi_ViewDetailReject dataInvestasi={data} />
|
||||
)}
|
||||
</UIGlobal_LayoutTamplate>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
"use client";
|
||||
|
||||
import {
|
||||
UIGlobal_LayoutHeaderTamplate,
|
||||
UIGlobal_LayoutTamplate,
|
||||
} from "@/app_modules/_global/ui";
|
||||
import { Investasi_ViewDetailProspektus } from "../../_view";
|
||||
|
||||
export function Investasi_UiDetailProspektus({
|
||||
dataInvestasi,
|
||||
}: {
|
||||
dataInvestasi: any;
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
<UIGlobal_LayoutTamplate
|
||||
header={<UIGlobal_LayoutHeaderTamplate title="Detail Prospektus" />}
|
||||
>
|
||||
<Investasi_ViewDetailProspektus dataInvestasi={dataInvestasi} />
|
||||
</UIGlobal_LayoutTamplate>
|
||||
</>
|
||||
);
|
||||
}
|
||||
62
src/app_modules/investasi/_ui/detail/ui_rekap_dokumen.tsx
Normal file
62
src/app_modules/investasi/_ui/detail/ui_rekap_dokumen.tsx
Normal file
@@ -0,0 +1,62 @@
|
||||
"use client";
|
||||
|
||||
import { NEW_RouterInvestasi } from "@/app/lib/router_hipmi/router_investasi";
|
||||
import {
|
||||
UIGlobal_Drawer,
|
||||
UIGlobal_LayoutHeaderTamplate,
|
||||
UIGlobal_LayoutTamplate,
|
||||
} from "@/app_modules/_global/ui";
|
||||
import { ActionIcon } from "@mantine/core";
|
||||
import { IconCirclePlus, IconDotsVertical } from "@tabler/icons-react";
|
||||
import { useState } from "react";
|
||||
import { Investasi_ViewRekapDokumen } from "../../_view";
|
||||
|
||||
export function Investasi_UiRekapDokumen({
|
||||
investasiId,
|
||||
dataDokumen,
|
||||
}: {
|
||||
investasiId: string;
|
||||
dataDokumen: any[]
|
||||
}) {
|
||||
const [openDrawer, setOpenDrawer] = useState(false);
|
||||
|
||||
const listPage = [
|
||||
{
|
||||
id: "1",
|
||||
name: "Tambah Dokumen",
|
||||
icon: <IconCirclePlus />,
|
||||
path: NEW_RouterInvestasi.create_dokumen({ id: investasiId }),
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<>
|
||||
<UIGlobal_LayoutTamplate
|
||||
header={
|
||||
<UIGlobal_LayoutHeaderTamplate
|
||||
title="Rekap Dokumen"
|
||||
customButtonRight={
|
||||
<ActionIcon
|
||||
onClick={() => setOpenDrawer(true)}
|
||||
variant="transparent"
|
||||
>
|
||||
<IconDotsVertical color="white" />
|
||||
</ActionIcon>
|
||||
}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<Investasi_ViewRekapDokumen
|
||||
dataDokumen={dataDokumen}
|
||||
investasiId={investasiId}
|
||||
/>
|
||||
</UIGlobal_LayoutTamplate>
|
||||
|
||||
<UIGlobal_Drawer
|
||||
opened={openDrawer}
|
||||
close={() => setOpenDrawer(false)}
|
||||
component={listPage}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
19
src/app_modules/investasi/_ui/edit/ui_edit_dokumen.tsx
Normal file
19
src/app_modules/investasi/_ui/edit/ui_edit_dokumen.tsx
Normal file
@@ -0,0 +1,19 @@
|
||||
"use client";
|
||||
|
||||
import {
|
||||
UIGlobal_LayoutHeaderTamplate,
|
||||
UIGlobal_LayoutTamplate,
|
||||
} from "@/app_modules/_global/ui";
|
||||
import { Investasi_ViewEditDokumen } from "../../_view";
|
||||
|
||||
export function Investasi_UiEditDokumen({ dataDokumen }: { dataDokumen: any }) {
|
||||
return (
|
||||
<>
|
||||
<UIGlobal_LayoutTamplate
|
||||
header={<UIGlobal_LayoutHeaderTamplate title="Edit Dokumen" />}
|
||||
>
|
||||
<Investasi_ViewEditDokumen dataDokumen={dataDokumen} />
|
||||
</UIGlobal_LayoutTamplate>
|
||||
</>
|
||||
);
|
||||
}
|
||||
34
src/app_modules/investasi/_ui/edit/ui_edit_investasi.tsx
Normal file
34
src/app_modules/investasi/_ui/edit/ui_edit_investasi.tsx
Normal file
@@ -0,0 +1,34 @@
|
||||
"use client";
|
||||
|
||||
import {
|
||||
UIGlobal_LayoutHeaderTamplate,
|
||||
UIGlobal_LayoutTamplate,
|
||||
} from "@/app_modules/_global/ui";
|
||||
import { Investasi_ViewEditInvestasi } from "../../_view";
|
||||
|
||||
export function Investasi_UiEditInvestasi({
|
||||
dataInvestasi,
|
||||
pembagianDeviden,
|
||||
pencarianInvestor,
|
||||
periodeDeviden,
|
||||
}: {
|
||||
dataInvestasi: any;
|
||||
pembagianDeviden: any[];
|
||||
pencarianInvestor: any[];
|
||||
periodeDeviden: any[];
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
<UIGlobal_LayoutTamplate
|
||||
header={<UIGlobal_LayoutHeaderTamplate title="Edit Investasi" />}
|
||||
>
|
||||
<Investasi_ViewEditInvestasi
|
||||
dataInvestasi={dataInvestasi}
|
||||
pembagianDeviden={pembagianDeviden}
|
||||
pencarianInvestor={pencarianInvestor}
|
||||
periodeDeviden={periodeDeviden}
|
||||
/>
|
||||
</UIGlobal_LayoutTamplate>
|
||||
</>
|
||||
);
|
||||
}
|
||||
23
src/app_modules/investasi/_ui/edit/ui_edit_prospektus.tsx
Normal file
23
src/app_modules/investasi/_ui/edit/ui_edit_prospektus.tsx
Normal file
@@ -0,0 +1,23 @@
|
||||
"use client";
|
||||
|
||||
import {
|
||||
UIGlobal_LayoutHeaderTamplate,
|
||||
UIGlobal_LayoutTamplate,
|
||||
} from "@/app_modules/_global/ui";
|
||||
import { Investasi_ViewEditProspektus } from "../../_view";
|
||||
|
||||
export function Investasi_UiEditProspektus({
|
||||
investasiId,
|
||||
}: {
|
||||
investasiId: string;
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
<UIGlobal_LayoutTamplate
|
||||
header={<UIGlobal_LayoutHeaderTamplate title="Edit Prospektus" />}
|
||||
>
|
||||
<Investasi_ViewEditProspektus investasiId={investasiId} />
|
||||
</UIGlobal_LayoutTamplate>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -1,8 +1,9 @@
|
||||
"use client";
|
||||
|
||||
import { RouterInvestasi_OLD } from "@/app/lib/router_hipmi/router_investasi";
|
||||
import { APIs } from "@/app/lib";
|
||||
import UIGlobal_LayoutHeaderTamplate from "@/app_modules/_global/ui/ui_header_tamplate";
|
||||
import UIGlobal_LayoutTamplate from "@/app_modules/_global/ui/ui_layout_tamplate";
|
||||
import { Box } from "@mantine/core";
|
||||
import { IconX } from "@tabler/icons-react";
|
||||
import dynamic from "next/dynamic";
|
||||
const PdfToImage = dynamic(
|
||||
@@ -19,12 +20,11 @@ export function Investasi_UiFileViewDokumen({
|
||||
return (
|
||||
<>
|
||||
<UIGlobal_LayoutTamplate
|
||||
header={<UIGlobal_LayoutHeaderTamplate title="" iconLeft={<IconX/>} />}
|
||||
header={<UIGlobal_LayoutHeaderTamplate title="" iconLeft={<IconX />} />}
|
||||
>
|
||||
<PdfToImage
|
||||
id={dokumenId}
|
||||
path={RouterInvestasi_OLD.api_file_dokumen}
|
||||
/>
|
||||
<Box mb={"lg"}>
|
||||
<PdfToImage id={dokumenId} path={APIs.GET_NO_PARAMS} />
|
||||
</Box>
|
||||
</UIGlobal_LayoutTamplate>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
"use client";
|
||||
|
||||
import { APIs } from "@/app/lib";
|
||||
import { RouterInvestasi_OLD } from "@/app/lib/router_hipmi/router_investasi";
|
||||
import UIGlobal_LayoutHeaderTamplate from "@/app_modules/_global/ui/ui_header_tamplate";
|
||||
import UIGlobal_LayoutTamplate from "@/app_modules/_global/ui/ui_layout_tamplate";
|
||||
import { Box } from "@mantine/core";
|
||||
import { IconX } from "@tabler/icons-react";
|
||||
import dynamic from "next/dynamic";
|
||||
const PdfToImage = dynamic(
|
||||
@@ -12,19 +14,21 @@ const PdfToImage = dynamic(
|
||||
);
|
||||
|
||||
export function Investasi_UiFileViewProspektus({
|
||||
prospekId,
|
||||
pospektusId,
|
||||
}: {
|
||||
prospekId: string;
|
||||
pospektusId: string;
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
<UIGlobal_LayoutTamplate
|
||||
header={<UIGlobal_LayoutHeaderTamplate title="" iconLeft={<IconX />} />}
|
||||
>
|
||||
<PdfToImage
|
||||
id={prospekId}
|
||||
path={RouterInvestasi_OLD.api_file_prospektus}
|
||||
/>
|
||||
<Box mb={"lg"}>
|
||||
<PdfToImage
|
||||
id={pospektusId}
|
||||
path={APIs.GET_NO_PARAMS}
|
||||
/>
|
||||
</Box>
|
||||
</UIGlobal_LayoutTamplate>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -11,6 +11,14 @@ import { Investasi_UiFileViewDokumen } from "./file_view/ui_file_view_dokumen";
|
||||
import { Investasi_UiSahamSaya } from "./main/ui_saham_saya";
|
||||
import { Investasi_UiDetailSahamSaya } from "./detail/ui_detail_saham_saya";
|
||||
import { Investasi_UiPortofolio } from "./main/ui_portofolio";
|
||||
import { Investasi_UiDetailPortofolio } from "./detail/ui_detail_portofolio";
|
||||
import { Investasi_UiDetailProspektus } from "./detail/ui_detail_prospektus";
|
||||
import { Investasi_UiDaftarDokmen } from "./detail/ui_daftar_dokumen";
|
||||
import { Investasi_UiEditDokumen } from "./edit/ui_edit_dokumen";
|
||||
import { Investasi_UiEditInvestasi } from "./edit/ui_edit_investasi";
|
||||
import { Investasi_UiEditProspektus } from "./edit/ui_edit_prospektus";
|
||||
import { Investasi_UiCreateDocument } from "./create/ui_create_document";
|
||||
import { Investasi_UiRekapDokumen } from "./detail/ui_rekap_dokumen";
|
||||
|
||||
export { Investasi_UiProsesPembelian };
|
||||
export { Investasi_UiMetodePembayaran };
|
||||
@@ -25,3 +33,11 @@ export { Investasi_UiFileViewDokumen };
|
||||
export { Investasi_UiSahamSaya };
|
||||
export { Investasi_UiDetailSahamSaya };
|
||||
export { Investasi_UiPortofolio };
|
||||
export { Investasi_UiDetailPortofolio };
|
||||
export { Investasi_UiDetailProspektus };
|
||||
export { Investasi_UiDaftarDokmen };
|
||||
export { Investasi_UiEditDokumen };
|
||||
export { Investasi_UiEditInvestasi };
|
||||
export { Investasi_UiEditProspektus };
|
||||
export { Investasi_UiCreateDocument };
|
||||
export { Investasi_UiRekapDokumen };
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
"use client";
|
||||
|
||||
import { useAtom } from "jotai";
|
||||
import { useRouter } from "next/navigation";
|
||||
import React from "react";
|
||||
import { gs_investas_menu } from "../../g_state";
|
||||
import UIGlobal_LayoutTamplate from "@/app_modules/_global/ui/ui_layout_tamplate";
|
||||
import { RouterCrowd } from "@/app/lib/router_hipmi/router_crowd";
|
||||
import UIGlobal_LayoutHeaderTamplate from "@/app_modules/_global/ui/ui_header_tamplate";
|
||||
import UIGlobal_LayoutTamplate from "@/app_modules/_global/ui/ui_layout_tamplate";
|
||||
import React from "react";
|
||||
import { Investasi_ComponentFooterMain } from "../../_component";
|
||||
|
||||
export function Investasi_UiLayoutMain({
|
||||
|
||||
@@ -1,28 +1,70 @@
|
||||
"use client";
|
||||
|
||||
import { NEW_RouterInvestasi } from "@/app/lib/router_hipmi/router_investasi";
|
||||
import { AccentColor, MainColor } from "@/app_modules/_global/color";
|
||||
import { MODEL_NEW_DEFAULT_MASTER } from "@/app_modules/model_global/interface";
|
||||
import { Stack, Tabs } from "@mantine/core";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import { Investasi_ViewPortofolio } from "../../_view";
|
||||
export function Investasi_UiPortofolio({
|
||||
listStatus,
|
||||
listDataPublish,
|
||||
listDataReview,
|
||||
listDataDraft,
|
||||
listDataReject,
|
||||
statusId,
|
||||
dataPortofolio,
|
||||
}: {
|
||||
listStatus: any[];
|
||||
listDataPublish: any[];
|
||||
listDataReview: any[];
|
||||
listDataDraft: any[];
|
||||
listDataReject: any[];
|
||||
listStatus: MODEL_NEW_DEFAULT_MASTER[];
|
||||
statusId: string;
|
||||
dataPortofolio: any[];
|
||||
}) {
|
||||
const [activeTab, setActiveTab] = useState<string | null>(statusId);
|
||||
const router = useRouter();
|
||||
const [data, setData] = useState(dataPortofolio);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Investasi_ViewPortofolio
|
||||
listStatus={listStatus}
|
||||
listDataPublish={listDataPublish}
|
||||
listDataReview={listDataReview}
|
||||
listDataDraft={listDataDraft}
|
||||
listDataReject={listDataReject}
|
||||
/>
|
||||
<Tabs
|
||||
variant="pills"
|
||||
radius="xl"
|
||||
defaultValue={activeTab}
|
||||
styles={{
|
||||
tabsList: {
|
||||
position: "sticky",
|
||||
top: 0,
|
||||
zIndex: 99,
|
||||
},
|
||||
}}
|
||||
value={activeTab}
|
||||
onTabChange={(val: any) => {
|
||||
setActiveTab(val);
|
||||
router.push(NEW_RouterInvestasi.portofolio({ id: val }));
|
||||
}}
|
||||
>
|
||||
<Stack>
|
||||
<Tabs.List grow mb={"xs"}>
|
||||
{listStatus.map((e) => (
|
||||
<Tabs.Tab
|
||||
w={"20%"}
|
||||
key={e.id}
|
||||
value={e.id}
|
||||
fw={"bold"}
|
||||
style={{
|
||||
transition: "ease 0.5s ",
|
||||
backgroundColor:
|
||||
activeTab === e.id ? MainColor.yellow : AccentColor.blue,
|
||||
color: activeTab === e.id ? "black" : "white",
|
||||
}}
|
||||
>
|
||||
{e.name}
|
||||
</Tabs.Tab>
|
||||
))}
|
||||
</Tabs.List>
|
||||
|
||||
<Investasi_ViewPortofolio
|
||||
statusId={statusId}
|
||||
dataPortofolio={data as any}
|
||||
/>
|
||||
</Stack>
|
||||
</Tabs>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
159
src/app_modules/investasi/_view/create/view_create_document.tsx
Normal file
159
src/app_modules/investasi/_view/create/view_create_document.tsx
Normal file
@@ -0,0 +1,159 @@
|
||||
import { MainColor } from "@/app_modules/_global/color";
|
||||
import {
|
||||
ComponentGlobal_BoxInformation,
|
||||
ComponentGlobal_CardStyles,
|
||||
} from "@/app_modules/_global/component";
|
||||
import {
|
||||
Stack,
|
||||
Grid,
|
||||
Center,
|
||||
Group,
|
||||
FileButton,
|
||||
Button,
|
||||
Text,
|
||||
TextInput,
|
||||
} from "@mantine/core";
|
||||
import { IconCircleCheck, IconCamera } from "@tabler/icons-react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import { investasi_funCreateDocument } from "../../_fun";
|
||||
import { funGlobal_UploadToStorage } from "@/app_modules/_global/fun";
|
||||
import { DIRECTORY_ID } from "@/app/lib";
|
||||
import {
|
||||
ComponentGlobal_NotifikasiBerhasil,
|
||||
ComponentGlobal_NotifikasiPeringatan,
|
||||
} from "@/app_modules/_global/notif_global";
|
||||
|
||||
export function Investasi_ViewCreateDocument({
|
||||
investasiId,
|
||||
}: {
|
||||
investasiId: string;
|
||||
}) {
|
||||
const router = useRouter();
|
||||
const [filePdf, setFilePdf] = useState<File | null>(null);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [title, setTitle] = useState("");
|
||||
|
||||
async function onCreate() {
|
||||
setIsLoading(true);
|
||||
const uploadFileDokumen = await funGlobal_UploadToStorage({
|
||||
file: filePdf as any,
|
||||
dirId: DIRECTORY_ID.investasi_dokumen,
|
||||
});
|
||||
if (!uploadFileDokumen.success) {
|
||||
setIsLoading(false);
|
||||
ComponentGlobal_NotifikasiPeringatan("Gagal upload file pdf");
|
||||
}
|
||||
|
||||
try {
|
||||
const create = await investasi_funCreateDocument({
|
||||
data: {
|
||||
investasiId: investasiId,
|
||||
fileId: uploadFileDokumen.data.id,
|
||||
title: title,
|
||||
},
|
||||
});
|
||||
|
||||
if (create.status !== 201)
|
||||
ComponentGlobal_NotifikasiPeringatan(create.message);
|
||||
|
||||
router.back();
|
||||
ComponentGlobal_NotifikasiBerhasil(create.message);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Stack spacing={"xl"}>
|
||||
<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"
|
||||
styles={{
|
||||
label: {
|
||||
color: "white",
|
||||
},
|
||||
}}
|
||||
onChange={(val) => setTitle(val.currentTarget.value)}
|
||||
/>
|
||||
<ComponentGlobal_CardStyles marginBottom={"0px"}>
|
||||
{!filePdf ? (
|
||||
<Text lineClamp={1} align="center" c={"gray"}>
|
||||
Upload Dokumen
|
||||
</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={filePdf === null || title === ""}
|
||||
mt={50}
|
||||
radius={50}
|
||||
bg={MainColor.yellow}
|
||||
color="yellow"
|
||||
c={"black"}
|
||||
style={{
|
||||
transition: "0.5s",
|
||||
}}
|
||||
onClick={() => {
|
||||
onCreate();
|
||||
}}
|
||||
>
|
||||
Simpan
|
||||
</Button>
|
||||
</Stack>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,232 @@
|
||||
"use client";
|
||||
|
||||
import { RouterInvestasi_OLD } from "@/app/lib/router_hipmi/router_investasi";
|
||||
import { AccentColor } from "@/app_modules/_global/color/color_pallet";
|
||||
import { MODEL_INVESTASI } from "@/app_modules/investasi/_lib/interface";
|
||||
import {
|
||||
ActionIcon,
|
||||
AspectRatio,
|
||||
Box,
|
||||
Flex,
|
||||
Grid,
|
||||
Group,
|
||||
Image,
|
||||
Paper,
|
||||
Progress,
|
||||
Stack,
|
||||
Text,
|
||||
Title,
|
||||
} from "@mantine/core";
|
||||
import {
|
||||
IconBookDownload,
|
||||
IconCircleCheck,
|
||||
IconFileDescription,
|
||||
IconSpeakerphone,
|
||||
} from "@tabler/icons-react";
|
||||
import moment from "moment";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
|
||||
export default function Investasi_ViewDetailPublish({
|
||||
dataInvestasi,
|
||||
}: {
|
||||
dataInvestasi: MODEL_INVESTASI;
|
||||
}) {
|
||||
const router = useRouter();
|
||||
const [investasi, setInvestasi] = useState(dataInvestasi);
|
||||
|
||||
const listBox = [
|
||||
{
|
||||
id: 1,
|
||||
name: "Prospektus",
|
||||
icon: <IconBookDownload size={70} color="white" />,
|
||||
route: RouterInvestasi_OLD.detail_prospektus,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "Dokumen",
|
||||
icon: <IconFileDescription size={70} color="white" />,
|
||||
route: RouterInvestasi_OLD.edit_dokumen,
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: "Berita",
|
||||
icon: <IconSpeakerphone size={70} color="white" />,
|
||||
route: RouterInvestasi_OLD.list_edit_berita,
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<Stack
|
||||
style={{
|
||||
paddingInline: "15px",
|
||||
paddingBlock: "15px",
|
||||
backgroundColor: AccentColor.darkblue,
|
||||
border: `2px solid ${AccentColor.blue}`,
|
||||
borderRadius: "10px",
|
||||
color: "white",
|
||||
marginBottom: "15px",
|
||||
}}
|
||||
>
|
||||
{Number(investasi.MasterPencarianInvestor.name) -
|
||||
moment(new Date()).diff(new Date(investasi.countDown), "days") <=
|
||||
0 ? (
|
||||
<Group
|
||||
position="center"
|
||||
mb={"sm"}
|
||||
style={{
|
||||
color: "white",
|
||||
}}
|
||||
>
|
||||
<IconCircleCheck color="green" />
|
||||
<Text c={"green"}>Selesai</Text>
|
||||
</Group>
|
||||
) : (
|
||||
<Group
|
||||
mb={"sm"}
|
||||
position="center"
|
||||
style={{
|
||||
color: "white",
|
||||
}}
|
||||
>
|
||||
<Text>
|
||||
Sisa waktu :{" "}
|
||||
{Number(investasi.MasterPencarianInvestor.name) -
|
||||
moment(new Date()).diff(
|
||||
new Date(investasi.countDown),
|
||||
"days"
|
||||
)}{" "}
|
||||
hari
|
||||
</Text>
|
||||
</Group>
|
||||
)}
|
||||
|
||||
<AspectRatio ratio={1 / 1} mx={"sm"} mah={250}>
|
||||
<Image
|
||||
alt=""
|
||||
src={RouterInvestasi_OLD.api_gambar + `${investasi.imagesId}`}
|
||||
radius={"sm"}
|
||||
height={250}
|
||||
width={"100%"}
|
||||
/>
|
||||
</AspectRatio>
|
||||
|
||||
{/* Title dan Persentase */}
|
||||
<Box mb={"md"}>
|
||||
<Title align="center" order={3} mb={"xs"}>
|
||||
{investasi.title}
|
||||
</Title>
|
||||
<Progress
|
||||
label={
|
||||
"" +
|
||||
(
|
||||
((+investasi.totalLembar - +investasi.sisaLembar) /
|
||||
+investasi.totalLembar) *
|
||||
100
|
||||
).toFixed(1) +
|
||||
"%"
|
||||
}
|
||||
value={
|
||||
+(
|
||||
((+investasi.totalLembar - +investasi.sisaLembar) /
|
||||
+investasi.totalLembar) *
|
||||
100
|
||||
).toFixed(1)
|
||||
}
|
||||
color="teal"
|
||||
size="xl"
|
||||
radius="xl"
|
||||
/>
|
||||
</Box>
|
||||
|
||||
{/* Rincian Data */}
|
||||
<Grid p={"md"} mb={"md"}>
|
||||
<Grid.Col span={6}>
|
||||
<Stack>
|
||||
<Box>
|
||||
<Text>Dana Dibutuhkan</Text>
|
||||
<Text>
|
||||
Rp.{" "}
|
||||
{new Intl.NumberFormat("id-ID", {
|
||||
maximumSignificantDigits: 10,
|
||||
}).format(+investasi.targetDana)}
|
||||
</Text>
|
||||
</Box>
|
||||
<Box>
|
||||
<Text>Harga Per Lembar</Text>
|
||||
<Text>
|
||||
Rp.{" "}
|
||||
{new Intl.NumberFormat("id-ID", {
|
||||
maximumSignificantDigits: 10,
|
||||
}).format(+investasi.hargaLembar)}
|
||||
</Text>
|
||||
</Box>
|
||||
<Box>
|
||||
<Text>Jadwal Pembagian</Text>
|
||||
<Text>{investasi.MasterPembagianDeviden.name} bulan </Text>
|
||||
</Box>
|
||||
<Box>
|
||||
<Text>Pembagian Deviden</Text>
|
||||
<Text>{investasi.MasterPeriodeDeviden.name}</Text>
|
||||
</Box>
|
||||
</Stack>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={6}>
|
||||
<Stack>
|
||||
<Box>
|
||||
<Text>ROI</Text>
|
||||
<Text>{investasi.roi}%</Text>
|
||||
</Box>
|
||||
<Box>
|
||||
<Text>Total Lembar</Text>
|
||||
<Text>
|
||||
{new Intl.NumberFormat("id-ID", {
|
||||
maximumSignificantDigits: 10,
|
||||
}).format(+investasi.totalLembar)}{" "}
|
||||
lembar
|
||||
</Text>
|
||||
</Box>
|
||||
<Box>
|
||||
<Text>Sisa Lembar</Text>
|
||||
<Text>
|
||||
{new Intl.NumberFormat("id-ID", {
|
||||
maximumSignificantDigits: 10,
|
||||
}).format(+investasi.sisaLembar)}{" "}
|
||||
lembar
|
||||
</Text>
|
||||
</Box>
|
||||
</Stack>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
|
||||
{/* List Box */}
|
||||
<Group position="apart" px={"lg"}>
|
||||
{listBox.map((e, i) => (
|
||||
<Paper
|
||||
key={i}
|
||||
style={{
|
||||
padding: "15px",
|
||||
backgroundColor: AccentColor.blue,
|
||||
border: `2px solid ${AccentColor.softblue}`,
|
||||
borderRadius: "10px",
|
||||
color: "white",
|
||||
}}
|
||||
>
|
||||
<Flex direction={"column"} align={"center"} justify={"center"}>
|
||||
<Text fz={12}>{e.name}</Text>
|
||||
<ActionIcon
|
||||
radius={"xl"}
|
||||
// loading={isLoadingBox && e?.id === boxId ? true : false}
|
||||
variant="transparent"
|
||||
size={60}
|
||||
onClick={() => router.push(e.route + `${investasi.id}`)}
|
||||
>
|
||||
{e.icon}
|
||||
</ActionIcon>
|
||||
</Flex>
|
||||
</Paper>
|
||||
))}
|
||||
</Group>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
"use client";
|
||||
|
||||
import {
|
||||
NEW_RouterInvestasi,
|
||||
RouterInvestasi_OLD,
|
||||
} from "@/app/lib/router_hipmi/router_investasi";
|
||||
import { MainColor } from "@/app_modules/_global/color/color_pallet";
|
||||
import ComponentGlobal_BoxInformation from "@/app_modules/_global/component/box_information";
|
||||
import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/_global/notif_global/notifikasi_berhasil";
|
||||
import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/_global/notif_global/notifikasi_gagal";
|
||||
import { Investasi_ComponentDetailDataNonPublish } from "@/app_modules/investasi/_component";
|
||||
import { MODEL_INVESTASI } from "@/app_modules/investasi/_lib/interface";
|
||||
import { ComponentInvestasi_DetailDataNonPublish } from "@/app_modules/investasi/component/detail/x_detai_data_non_publish";
|
||||
import { investasi_funEditStatusById } from "@/app_modules/investasi/fun/edit/fun_edit_status_by_id";
|
||||
import { gs_investasi_status } from "@/app_modules/investasi/g_state";
|
||||
import notifikasiToAdmin_funCreate from "@/app_modules/notifikasi/fun/create/create_notif_to_admin";
|
||||
import mqtt_client from "@/util/mqtt_client";
|
||||
import { Button, Stack } from "@mantine/core";
|
||||
import { useAtom } from "jotai";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
|
||||
export default function Investasi_ViewDetailDraft({
|
||||
dataInvestasi,
|
||||
}: {
|
||||
dataInvestasi: MODEL_INVESTASI;
|
||||
}) {
|
||||
const router = useRouter();
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [activeTab, setActiveTab] = useAtom(gs_investasi_status);
|
||||
|
||||
async function onAjukanReview() {
|
||||
const res = await investasi_funEditStatusById({
|
||||
investasiId: dataInvestasi.id,
|
||||
statusId: "2",
|
||||
});
|
||||
|
||||
if (res.status === 200) {
|
||||
const dataNotif = {
|
||||
appId: res.data?.id,
|
||||
userId: res.data?.authorId,
|
||||
pesan: res.data?.title,
|
||||
status: res.data?.MasterStatusInvestasi?.name,
|
||||
kategoriApp: "INVESTASI",
|
||||
title: "Mengajukan review",
|
||||
};
|
||||
|
||||
const notif = await notifikasiToAdmin_funCreate({
|
||||
data: dataNotif as any,
|
||||
});
|
||||
|
||||
if (notif.status === 201) {
|
||||
mqtt_client.publish("ADMIN", JSON.stringify({ count: 1 }));
|
||||
|
||||
setIsLoading(true);
|
||||
ComponentGlobal_NotifikasiBerhasil("Review Berhasil Diajukan");
|
||||
router.push(NEW_RouterInvestasi.portofolio({ id: dataInvestasi.id }));
|
||||
setActiveTab("Review");
|
||||
}
|
||||
} else {
|
||||
ComponentGlobal_NotifikasiGagal(res.message);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Stack mb={"lg"}>
|
||||
{dataInvestasi.catatan && (
|
||||
<ComponentGlobal_BoxInformation
|
||||
informasi={dataInvestasi.catatan}
|
||||
isReport
|
||||
/>
|
||||
)}
|
||||
<Investasi_ComponentDetailDataNonPublish data={dataInvestasi} />
|
||||
|
||||
<Stack>
|
||||
<Button
|
||||
loaderPosition="center"
|
||||
loading={isLoading}
|
||||
radius={50}
|
||||
bg={MainColor.yellow}
|
||||
color="yellow"
|
||||
c={"black"}
|
||||
onClick={() => onAjukanReview()}
|
||||
>
|
||||
Ajukan Review
|
||||
</Button>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
"use client";
|
||||
|
||||
import {
|
||||
NEW_RouterInvestasi,
|
||||
RouterInvestasi_OLD,
|
||||
} from "@/app/lib/router_hipmi/router_investasi";
|
||||
import ComponentGlobal_BoxInformation from "@/app_modules/_global/component/box_information";
|
||||
import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/_global/notif_global/notifikasi_berhasil";
|
||||
import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/_global/notif_global/notifikasi_gagal";
|
||||
import UIGlobal_Modal from "@/app_modules/_global/ui/ui_modal";
|
||||
import { Investasi_ComponentDetailDataNonPublish } from "@/app_modules/investasi/_component";
|
||||
import { MODEL_INVESTASI } from "@/app_modules/investasi/_lib/interface";
|
||||
import { ComponentInvestasi_DetailDataNonPublish } from "@/app_modules/investasi/component/detail/x_detai_data_non_publish";
|
||||
import { investasi_funEditStatusById } from "@/app_modules/investasi/fun/edit/fun_edit_status_by_id";
|
||||
import funDeleteInvestasi from "@/app_modules/investasi/fun/fun_delete_investasi";
|
||||
import { gs_investasi_status } from "@/app_modules/investasi/g_state";
|
||||
import { Button, Group, Stack } from "@mantine/core";
|
||||
import { useAtom } from "jotai";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
|
||||
export default function Investasi_ViewDetailReject({
|
||||
dataInvestasi,
|
||||
}: {
|
||||
dataInvestasi: MODEL_INVESTASI;
|
||||
}) {
|
||||
const router = useRouter();
|
||||
const [investasi, setInvestasi] = useState(dataInvestasi);
|
||||
const [activeTab, setActiveTab] = useAtom(gs_investasi_status);
|
||||
const [openModal, setOpenModal] = useState(false);
|
||||
|
||||
async function onAjukan() {
|
||||
const res = await investasi_funEditStatusById({
|
||||
investasiId: dataInvestasi.id,
|
||||
statusId: "3",
|
||||
});
|
||||
|
||||
if (res.status === 200) {
|
||||
ComponentGlobal_NotifikasiBerhasil("Project Diajukan Kembali");
|
||||
setActiveTab("Draft");
|
||||
router.push(RouterInvestasi_OLD.portofolio);
|
||||
} else {
|
||||
ComponentGlobal_NotifikasiGagal("Gagal Pengajuan");
|
||||
}
|
||||
}
|
||||
|
||||
async function onDelete() {
|
||||
await funDeleteInvestasi(investasi.id).then((res) => {
|
||||
if (res.status === 200) {
|
||||
ComponentGlobal_NotifikasiBerhasil(res.message);
|
||||
setOpenModal(false);
|
||||
router.push(NEW_RouterInvestasi.portofolio({ id: dataInvestasi.id }));
|
||||
} else {
|
||||
ComponentGlobal_NotifikasiGagal(res.message);
|
||||
}
|
||||
});
|
||||
// setActiveTab("Reject");
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* Pop up */}
|
||||
<UIGlobal_Modal
|
||||
title={"Anda Yakin Menghapus Data?"}
|
||||
opened={openModal}
|
||||
close={() => setOpenModal(false)}
|
||||
buttonKiri={
|
||||
<Button radius={"xl"} onClick={() => setOpenModal(false)}>
|
||||
Batal
|
||||
</Button>
|
||||
}
|
||||
buttonKanan={
|
||||
<Button bg={"red"} radius={"xl"} onClick={() => onDelete()}>
|
||||
Hapus
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
|
||||
<Stack>
|
||||
{/* Alasan */}
|
||||
<ComponentGlobal_BoxInformation
|
||||
informasi={investasi.catatan}
|
||||
isReport
|
||||
/>
|
||||
|
||||
<Investasi_ComponentDetailDataNonPublish data={dataInvestasi} />
|
||||
|
||||
<Group position="apart" grow>
|
||||
{/* Tombol Ajukan */}
|
||||
<Button
|
||||
mb={"xl"}
|
||||
radius={50}
|
||||
bg={"orange.7"}
|
||||
color="yellow"
|
||||
onClick={() => onAjukan()}
|
||||
>
|
||||
Edit Kembali
|
||||
</Button>
|
||||
|
||||
{/* Tombol Hapus */}
|
||||
<Button
|
||||
mb={"xl"}
|
||||
radius={50}
|
||||
bg={"red.7"}
|
||||
color="yellow"
|
||||
onClick={() => setOpenModal(true)}
|
||||
>
|
||||
Hapus
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
"use client";
|
||||
|
||||
import { NEW_RouterInvestasi, RouterInvestasi_OLD } from "@/app/lib/router_hipmi/router_investasi";
|
||||
import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/_global/notif_global/notifikasi_berhasil";
|
||||
import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/_global/notif_global/notifikasi_peringatan";
|
||||
import { Investasi_ComponentDetailDataNonPublish } from "@/app_modules/investasi/_component";
|
||||
import { MODEL_INVESTASI } from "@/app_modules/investasi/_lib/interface";
|
||||
import { investasi_funEditStatusById } from "@/app_modules/investasi/fun/edit/fun_edit_status_by_id";
|
||||
import { gs_investasi_status } from "@/app_modules/investasi/g_state";
|
||||
import notifikasiToAdmin_funCreate from "@/app_modules/notifikasi/fun/create/create_notif_to_admin";
|
||||
import mqtt_client from "@/util/mqtt_client";
|
||||
import { Button, Stack } from "@mantine/core";
|
||||
import { useAtom } from "jotai";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
|
||||
|
||||
export default function Investasi_ViewDetailReview({
|
||||
dataInvestasi,
|
||||
}: {
|
||||
dataInvestasi: MODEL_INVESTASI;
|
||||
}) {
|
||||
const router = useRouter();
|
||||
const [isLoading, setLoading] = useState(false);
|
||||
|
||||
const [activeTab, setActiveTab] = useAtom(gs_investasi_status);
|
||||
const [data, setData] = useState<MODEL_INVESTASI>(dataInvestasi);
|
||||
|
||||
async function onCancleReview() {
|
||||
const res = await investasi_funEditStatusById({
|
||||
investasiId: data.id,
|
||||
statusId: "3",
|
||||
});
|
||||
if (res.status === 200) {
|
||||
const dataNotif = {
|
||||
appId: res.data?.id,
|
||||
userId: res.data?.authorId,
|
||||
pesan: res.data?.title,
|
||||
status: res.data?.MasterStatusInvestasi?.name,
|
||||
kategoriApp: "INVESTASI",
|
||||
title: "Membatalkan review",
|
||||
};
|
||||
|
||||
const notif = await notifikasiToAdmin_funCreate({
|
||||
data: dataNotif as any,
|
||||
});
|
||||
|
||||
if (notif.status === 201) {
|
||||
mqtt_client.publish("ADMIN", JSON.stringify({ count: 1 }));
|
||||
|
||||
setLoading(true);
|
||||
ComponentGlobal_NotifikasiBerhasil("Review Dibatalkan");
|
||||
setActiveTab("Draft");
|
||||
router.push(NEW_RouterInvestasi.portofolio({id: data.id}));
|
||||
}
|
||||
} else {
|
||||
ComponentGlobal_NotifikasiPeringatan(res.message);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Stack spacing={"xl"}>
|
||||
<Investasi_ComponentDetailDataNonPublish data={data} />
|
||||
{/* Tombol Ajukan */}
|
||||
<Stack>
|
||||
<Button
|
||||
mb={"xl"}
|
||||
style={{
|
||||
transition: "0.5s",
|
||||
}}
|
||||
loaderPosition="center"
|
||||
loading={isLoading ? true : false}
|
||||
radius={50}
|
||||
bg={"orange"}
|
||||
color="yellow"
|
||||
onClick={() => onCancleReview()}
|
||||
>
|
||||
Batalkan Review
|
||||
</Button>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
import { ComponentGlobal_BoxInformation } from "@/app_modules/_global/component";
|
||||
import ComponentGlobal_IsEmptyData from "@/app_modules/_global/component/is_empty_data";
|
||||
import ComponentGlobal_Loader from "@/app_modules/_global/component/loader";
|
||||
import { Box, Center, Stack } from "@mantine/core";
|
||||
import { data } from "autoprefixer";
|
||||
import _ from "lodash";
|
||||
import { ScrollOnly } from "next-scroll-loader";
|
||||
import { investasi_funGetAllDocumentById } from "../../_fun";
|
||||
import { useState } from "react";
|
||||
import { MODEL_INVESTASI_DOKUMEN } from "../../_lib/interface";
|
||||
import { Investasi_ComponentCardDaftarDocument } from "../../_component";
|
||||
|
||||
export function Investasi_ViewDaftarDokumen({
|
||||
dataDokumen,
|
||||
investasiId,
|
||||
}: {
|
||||
dataDokumen: any[];
|
||||
investasiId: string;
|
||||
}) {
|
||||
const [data, setData] = useState<MODEL_INVESTASI_DOKUMEN[]>(dataDokumen);
|
||||
const [activePage, setActivePage] = useState(1);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Stack>
|
||||
<>
|
||||
{_.isEmpty(data) ? (
|
||||
<ComponentGlobal_IsEmptyData />
|
||||
) : (
|
||||
<Box>
|
||||
<ScrollOnly
|
||||
height="90vh"
|
||||
renderLoading={() => (
|
||||
<Center>
|
||||
<ComponentGlobal_Loader size={25} />
|
||||
</Center>
|
||||
)}
|
||||
data={data}
|
||||
setData={setData}
|
||||
moreData={async () => {
|
||||
const loadData = await investasi_funGetAllDocumentById({
|
||||
investasiId: investasiId,
|
||||
page: activePage + 1,
|
||||
});
|
||||
|
||||
setActivePage((val) => val + 1);
|
||||
|
||||
return loadData;
|
||||
}}
|
||||
>
|
||||
{(item) => (
|
||||
<Investasi_ComponentCardDaftarDocument data={item as any} />
|
||||
)}
|
||||
</ScrollOnly>
|
||||
</Box>
|
||||
)}
|
||||
</>
|
||||
</Stack>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
import { NEW_RouterInvestasi } from "@/app/lib/router_hipmi/router_investasi";
|
||||
import { MainColor } from "@/app_modules/_global/color";
|
||||
import {
|
||||
ComponentGlobal_CardLoadingOverlay,
|
||||
ComponentGlobal_CardStyles,
|
||||
} from "@/app_modules/_global/component";
|
||||
import { Center, Group, Text } from "@mantine/core";
|
||||
import { IconFileTypePdf } from "@tabler/icons-react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import { MODEL_INVESTASI } from "../../_lib/interface";
|
||||
|
||||
export function Investasi_ViewDetailProspektus({
|
||||
dataInvestasi,
|
||||
}: {
|
||||
dataInvestasi: MODEL_INVESTASI;
|
||||
}) {
|
||||
const router = useRouter();
|
||||
const [visible, setVisible] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<ComponentGlobal_CardStyles
|
||||
onClickHandler={() => {
|
||||
router.push(
|
||||
NEW_RouterInvestasi.file_prospektus({
|
||||
id: dataInvestasi.prospektusFileId,
|
||||
}),
|
||||
{ scroll: false }
|
||||
);
|
||||
setVisible(true);
|
||||
}}
|
||||
>
|
||||
<Group position="apart">
|
||||
<Text w={"80%"} lineClamp={1}>
|
||||
Prospektus {dataInvestasi?.title}
|
||||
</Text>
|
||||
<Center>
|
||||
<IconFileTypePdf style={{ color: MainColor.yellow }} />
|
||||
</Center>
|
||||
</Group>
|
||||
{visible && <ComponentGlobal_CardLoadingOverlay />}
|
||||
</ComponentGlobal_CardStyles>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
import ComponentGlobal_IsEmptyData from "@/app_modules/_global/component/is_empty_data";
|
||||
import ComponentGlobal_Loader from "@/app_modules/_global/component/loader";
|
||||
import { Box, Center } from "@mantine/core";
|
||||
import _ from "lodash";
|
||||
import { ScrollOnly } from "next-scroll-loader";
|
||||
import { useState } from "react";
|
||||
import { Investasi_ComponentCardRekapDocument } from "../../_component";
|
||||
import { investasi_funGetAllDocumentById } from "../../_fun";
|
||||
import { MODEL_INVESTASI_DOKUMEN } from "../../_lib/interface";
|
||||
import { useShallowEffect } from "@mantine/hooks";
|
||||
|
||||
export function Investasi_ViewRekapDokumen({
|
||||
dataDokumen,
|
||||
investasiId,
|
||||
}: {
|
||||
dataDokumen: any[];
|
||||
investasiId: string;
|
||||
}) {
|
||||
const [data, setData] = useState<MODEL_INVESTASI_DOKUMEN[]>(dataDokumen);
|
||||
const [activePage, setActivePage] = useState(1);
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
{_.isEmpty(data) ? (
|
||||
<ComponentGlobal_IsEmptyData />
|
||||
) : (
|
||||
<Box>
|
||||
<ScrollOnly
|
||||
height="90vh"
|
||||
renderLoading={() => (
|
||||
<Center>
|
||||
<ComponentGlobal_Loader size={25} />
|
||||
</Center>
|
||||
)}
|
||||
data={data}
|
||||
setData={setData}
|
||||
moreData={async () => {
|
||||
const loadData = await investasi_funGetAllDocumentById({
|
||||
investasiId: investasiId,
|
||||
page: activePage + 1,
|
||||
});
|
||||
|
||||
setActivePage((val) => val + 1);
|
||||
|
||||
return loadData;
|
||||
}}
|
||||
>
|
||||
{(item) => (
|
||||
<Investasi_ComponentCardRekapDocument
|
||||
data={item}
|
||||
onSetData={(val) => setData(val) as any}
|
||||
/>
|
||||
)}
|
||||
</ScrollOnly>
|
||||
</Box>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
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>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -10,6 +10,17 @@ import { Investasi_ViewInvoice } from "./transaksi/view_invoice";
|
||||
import { Investasi_ViewMetodePembayaran } from "./transaksi/view_metode_pembayaran";
|
||||
import { Investasi_ViewProsesPembelian } from "./transaksi/view_proses_pembelian";
|
||||
import { Investasi_ViewProsesTransaksi } from "./transaksi/view_proses_transaksi";
|
||||
import Investasi_ViewDetailPublish from "./detail/portofolio/view_detai_publish";
|
||||
import Investasi_ViewDetailReview from "./detail/portofolio/view_detail_review";
|
||||
import Investasi_ViewDetailDraft from "./detail/portofolio/view_detail_draft";
|
||||
import Investasi_ViewDetailReject from "./detail/portofolio/view_detail_reject";
|
||||
import { Investasi_ViewDetailProspektus } from "./detail/view_detail_prospektusl";
|
||||
import { Investasi_ViewDaftarDokumen } from "./detail/view_daftar_dokemen";
|
||||
import { Investasi_ViewEditDokumen } from "./edit/view_edit_dokumen";
|
||||
import { Investasi_ViewEditInvestasi } from "./edit/view_edit_investasi";
|
||||
import { Investasi_ViewEditProspektus } from "./edit/view_edit_prospektus";
|
||||
import { Investasi_ViewCreateDocument } from "./create/view_create_document";
|
||||
import { Investasi_ViewRekapDokumen } from "./detail/view_rekap_dokumen";
|
||||
|
||||
export { Investasi_ViewProsesPembelian };
|
||||
export { Investasi_ViewMetodePembayaran };
|
||||
@@ -22,4 +33,14 @@ export { PdfToImage as Investasi_ViewFileViewer };
|
||||
export { Investasi_ViewSahamSaya };
|
||||
export { Investasi_ViewDetailSahamSaya };
|
||||
export { Investasi_ViewPortofolio };
|
||||
|
||||
export { Investasi_ViewDetailPublish };
|
||||
export { Investasi_ViewDetailReview };
|
||||
export { Investasi_ViewDetailDraft };
|
||||
export { Investasi_ViewDetailReject };
|
||||
export { Investasi_ViewDetailProspektus };
|
||||
export { Investasi_ViewDaftarDokumen };
|
||||
export { Investasi_ViewEditDokumen };
|
||||
export { Investasi_ViewEditInvestasi };
|
||||
export { Investasi_ViewEditProspektus };
|
||||
export { Investasi_ViewCreateDocument };
|
||||
export { Investasi_ViewRekapDokumen };
|
||||
|
||||
@@ -1,23 +1,21 @@
|
||||
import { NEW_RouterInvestasi } from "@/app/lib/router_hipmi/router_investasi";
|
||||
import ComponentGlobal_IsEmptyData from "@/app_modules/_global/component/is_empty_data";
|
||||
import ComponentGlobal_Loader from "@/app_modules/_global/component/loader";
|
||||
import { Box, Center } from "@mantine/core";
|
||||
import { data } from "autoprefixer";
|
||||
import _ from "lodash";
|
||||
import { ScrollOnly } from "next-scroll-loader";
|
||||
import { Investasi_ComponentCardPortofolio_NotPublish } from "../../../_component";
|
||||
import {
|
||||
investasi_funGetAllInvestasiNonPublishByUserId,
|
||||
investasi_funGetSuccessTransactionById,
|
||||
} from "../../../_fun";
|
||||
import { useState } from "react";
|
||||
import { NEW_RouterInvestasi } from "@/app/lib/router_hipmi/router_investasi";
|
||||
import { Investasi_ComponentCardPortofolio_NotPublish } from "../../../_component";
|
||||
import { investasi_funGetAllInvestasiNonPublishByUserId } from "../../../_fun";
|
||||
|
||||
export function Investasi_ViewPortofolioDraft({
|
||||
listData,
|
||||
statusId,
|
||||
dataPortofolio,
|
||||
}: {
|
||||
listData: any[];
|
||||
statusId: string;
|
||||
dataPortofolio: any;
|
||||
}) {
|
||||
const [data, setData] = useState(listData);
|
||||
const [data, setData] = useState<any[]>(dataPortofolio);
|
||||
const [activePage, setActivePage] = useState(1);
|
||||
|
||||
return (
|
||||
@@ -49,7 +47,7 @@ export function Investasi_ViewPortofolioDraft({
|
||||
{(item) => (
|
||||
<Investasi_ComponentCardPortofolio_NotPublish
|
||||
data={item}
|
||||
path={NEW_RouterInvestasi.detail_draft}
|
||||
path={NEW_RouterInvestasi.detail_portofolio({ id: item.id })}
|
||||
/>
|
||||
)}
|
||||
</ScrollOnly>
|
||||
|
||||
@@ -1,18 +1,22 @@
|
||||
import { useState } from "react";
|
||||
import { Investasi_ComponentCardPortofolioPublish } from "../../../_component";
|
||||
import ComponentGlobal_IsEmptyData from "@/app_modules/_global/component/is_empty_data";
|
||||
import ComponentGlobal_Loader from "@/app_modules/_global/component/loader";
|
||||
import { Box, Center } from "@mantine/core";
|
||||
import _ from "lodash";
|
||||
import { ScrollOnly } from "next-scroll-loader";
|
||||
import { investasi_funGetSuccessTransactionById } from "../../../_fun";
|
||||
import { useState } from "react";
|
||||
import { Investasi_ComponentCardPortofolioPublish } from "../../../_component";
|
||||
import {
|
||||
investasi_funGetSuccessTransactionById
|
||||
} from "../../../_fun";
|
||||
|
||||
export function Investasi_ViewPortofolioPublish({
|
||||
listData,
|
||||
statusId,
|
||||
dataPortofolio,
|
||||
}: {
|
||||
listData: any[];
|
||||
statusId: string;
|
||||
dataPortofolio: any
|
||||
}) {
|
||||
const [data, setData] = useState(listData);
|
||||
const [data, setData] = useState<any[]>(dataPortofolio);
|
||||
const [activePage, setActivePage] = useState(1);
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,23 +1,21 @@
|
||||
import { NEW_RouterInvestasi } from "@/app/lib/router_hipmi/router_investasi";
|
||||
import ComponentGlobal_IsEmptyData from "@/app_modules/_global/component/is_empty_data";
|
||||
import ComponentGlobal_Loader from "@/app_modules/_global/component/loader";
|
||||
import { Box, Center } from "@mantine/core";
|
||||
import { data } from "autoprefixer";
|
||||
import _ from "lodash";
|
||||
import { ScrollOnly } from "next-scroll-loader";
|
||||
import { Investasi_ComponentCardPortofolio_NotPublish } from "../../../_component";
|
||||
import {
|
||||
investasi_funGetAllInvestasiNonPublishByUserId,
|
||||
investasi_funGetSuccessTransactionById,
|
||||
} from "../../../_fun";
|
||||
import { useState } from "react";
|
||||
import { NEW_RouterInvestasi } from "@/app/lib/router_hipmi/router_investasi";
|
||||
import { Investasi_ComponentCardPortofolio_NotPublish } from "../../../_component";
|
||||
import { investasi_funGetAllInvestasiNonPublishByUserId } from "../../../_fun";
|
||||
|
||||
export function Investasi_ViewPortofolioReject({
|
||||
listData,
|
||||
statusId,
|
||||
dataPortofolio,
|
||||
}: {
|
||||
listData: any[];
|
||||
statusId: string;
|
||||
dataPortofolio: any;
|
||||
}) {
|
||||
const [data, setData] = useState(listData);
|
||||
const [data, setData] = useState<any[]>(dataPortofolio);
|
||||
const [activePage, setActivePage] = useState(1);
|
||||
|
||||
return (
|
||||
@@ -49,7 +47,7 @@ export function Investasi_ViewPortofolioReject({
|
||||
{(item) => (
|
||||
<Investasi_ComponentCardPortofolio_NotPublish
|
||||
data={item}
|
||||
path={NEW_RouterInvestasi.detail_reject}
|
||||
path={NEW_RouterInvestasi.detail_portofolio({ id: item.id })}
|
||||
/>
|
||||
)}
|
||||
</ScrollOnly>
|
||||
|
||||
@@ -1,23 +1,21 @@
|
||||
import { NEW_RouterInvestasi } from "@/app/lib/router_hipmi/router_investasi";
|
||||
import ComponentGlobal_IsEmptyData from "@/app_modules/_global/component/is_empty_data";
|
||||
import ComponentGlobal_Loader from "@/app_modules/_global/component/loader";
|
||||
import { Box, Center } from "@mantine/core";
|
||||
import { data } from "autoprefixer";
|
||||
import _ from "lodash";
|
||||
import { ScrollOnly } from "next-scroll-loader";
|
||||
import { Investasi_ComponentCardPortofolio_NotPublish } from "../../../_component";
|
||||
import {
|
||||
investasi_funGetAllInvestasiNonPublishByUserId,
|
||||
investasi_funGetSuccessTransactionById,
|
||||
} from "../../../_fun";
|
||||
import { useState } from "react";
|
||||
import { NEW_RouterInvestasi } from "@/app/lib/router_hipmi/router_investasi";
|
||||
import { Investasi_ComponentCardPortofolio_NotPublish } from "../../../_component";
|
||||
import { investasi_funGetAllInvestasiNonPublishByUserId } from "../../../_fun";
|
||||
|
||||
export function Investasi_ViewPortofolioReview({
|
||||
listData,
|
||||
statusId,
|
||||
dataPortofolio,
|
||||
}: {
|
||||
listData: any[];
|
||||
statusId: string;
|
||||
dataPortofolio: any;
|
||||
}) {
|
||||
const [data, setData] = useState(listData);
|
||||
const [data, setData] = useState<any[]>(dataPortofolio);
|
||||
const [activePage, setActivePage] = useState(1);
|
||||
|
||||
return (
|
||||
@@ -49,7 +47,7 @@ export function Investasi_ViewPortofolioReview({
|
||||
{(item) => (
|
||||
<Investasi_ComponentCardPortofolio_NotPublish
|
||||
data={item}
|
||||
path={NEW_RouterInvestasi.detail_review}
|
||||
path={NEW_RouterInvestasi.detail_portofolio({id: item.id})}
|
||||
/>
|
||||
)}
|
||||
</ScrollOnly>
|
||||
|
||||
@@ -1,136 +1,44 @@
|
||||
import { AccentColor, MainColor } from "@/app_modules/_global/color";
|
||||
import { MODEL_NEW_DEFAULT_MASTER } from "@/app_modules/model_global/interface";
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Group,
|
||||
SimpleGrid,
|
||||
Space,
|
||||
Stack,
|
||||
Tabs,
|
||||
} from "@mantine/core";
|
||||
import { useAtom } from "jotai";
|
||||
import { useState } from "react";
|
||||
import { gs_investasi_status } from "../../g_state";
|
||||
import { Investasi_ViewPortofolioPublish } from "./portofolio/view_portofolio_publish";
|
||||
import { Investasi_ViewPortofolioReview } from "./portofolio/view_portofolio_review";
|
||||
import { Investasi_ViewPortofolioDraft } from "./portofolio/view_portofolio_draft";
|
||||
import { Investasi_ViewPortofolioPublish } from "./portofolio/view_portofolio_publish";
|
||||
import { Investasi_ViewPortofolioReject } from "./portofolio/view_portofolio_reject";
|
||||
import { Investasi_ViewPortofolioReview } from "./portofolio/view_portofolio_review";
|
||||
|
||||
export function Investasi_ViewPortofolio({
|
||||
listStatus,
|
||||
listDataPublish,
|
||||
listDataReview,
|
||||
listDataDraft,
|
||||
listDataReject,
|
||||
statusId,
|
||||
dataPortofolio,
|
||||
}: {
|
||||
listStatus: any[];
|
||||
listDataPublish: any[];
|
||||
listDataReview: any[];
|
||||
listDataDraft: any[];
|
||||
listDataReject: any[];
|
||||
statusId: string;
|
||||
dataPortofolio: any[];
|
||||
}) {
|
||||
const [activeTab, setActiveTab] = useAtom(gs_investasi_status);
|
||||
const [activeStatus, setActiveStatus] =
|
||||
useState<MODEL_NEW_DEFAULT_MASTER[]>(listStatus);
|
||||
|
||||
// return (
|
||||
// <>
|
||||
// <Box h={"82vh"}>
|
||||
// <Group grow h={"5vh"}>
|
||||
// {activeStatus.map((e) => (
|
||||
// <Box
|
||||
|
||||
// // component={Button}
|
||||
// // radius={"xl"}
|
||||
// key={e.id}
|
||||
// // onClick={() => setActiveTab(e.name)}
|
||||
// style={{
|
||||
// alignContent: "center",
|
||||
// justifyContent: "center",
|
||||
// transition: "0.5s",
|
||||
// backgroundColor:
|
||||
// activeTab === e.name ? MainColor.yellow : "gray",
|
||||
// border:
|
||||
// activeTab === e.name ? `1px solid ${AccentColor.yellow}` : "",
|
||||
// color: activeTab === e.name ? "black" : "white",
|
||||
// }}
|
||||
// >
|
||||
// {e.name}
|
||||
// </Box>
|
||||
// ))}
|
||||
// </Group>
|
||||
// <Space h={"1vh"} />
|
||||
// <Box h={"76vh"}>
|
||||
// {activeTab === "Publish" && (
|
||||
// <Investasi_ViewPortofolioPublish listData={listDataPublish} />
|
||||
// )}
|
||||
|
||||
// {activeTab === "Review" && <Investasi_ViewPortofolioReview />}
|
||||
// </Box>
|
||||
// </Box>
|
||||
// </>
|
||||
// );
|
||||
|
||||
return (
|
||||
<>
|
||||
<Tabs
|
||||
variant="pills"
|
||||
radius="xl"
|
||||
defaultValue={activeTab}
|
||||
value={activeTab}
|
||||
onTabChange={setActiveTab}
|
||||
styles={{
|
||||
tabsList: {
|
||||
// backgroundColor: MainColor.black,
|
||||
position: "sticky",
|
||||
top: 0,
|
||||
zIndex: 99,
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Stack>
|
||||
<Tabs.List grow mb={"xs"}>
|
||||
{activeStatus.map((e) => (
|
||||
<Tabs.Tab
|
||||
w={"20%"}
|
||||
key={e.id}
|
||||
value={e.name}
|
||||
fw={"bold"}
|
||||
style={{
|
||||
transition: "ease 0.5s ",
|
||||
backgroundColor:
|
||||
activeTab === e.name ? MainColor.yellow : AccentColor.blue,
|
||||
// border:
|
||||
// activeTab === e.name
|
||||
// ? `1px solid ${AccentColor.yellow}`
|
||||
// : "",
|
||||
{statusId === "1" && (
|
||||
<Investasi_ViewPortofolioPublish
|
||||
statusId={statusId}
|
||||
dataPortofolio={dataPortofolio}
|
||||
/>
|
||||
)}
|
||||
|
||||
color: activeTab === e.name ? "black" : "white",
|
||||
}}
|
||||
>
|
||||
{e.name}
|
||||
</Tabs.Tab>
|
||||
))}
|
||||
</Tabs.List>
|
||||
{statusId === "2" && (
|
||||
<Investasi_ViewPortofolioReview
|
||||
statusId={statusId}
|
||||
dataPortofolio={dataPortofolio}
|
||||
/>
|
||||
)}
|
||||
|
||||
<Tabs.Panel value="Publish">
|
||||
<Investasi_ViewPortofolioPublish listData={listDataPublish} />
|
||||
</Tabs.Panel>
|
||||
{statusId === "3" && (
|
||||
<Investasi_ViewPortofolioDraft
|
||||
statusId={statusId}
|
||||
dataPortofolio={dataPortofolio}
|
||||
/>
|
||||
)}
|
||||
|
||||
<Tabs.Panel value="Review">
|
||||
<Investasi_ViewPortofolioReview listData={listDataReview} />
|
||||
</Tabs.Panel>
|
||||
|
||||
<Tabs.Panel value="Draft">
|
||||
<Investasi_ViewPortofolioDraft listData={listDataDraft} />
|
||||
</Tabs.Panel>
|
||||
|
||||
<Tabs.Panel value="Reject">
|
||||
<Investasi_ViewPortofolioReject listData={listDataReject} />
|
||||
</Tabs.Panel>
|
||||
</Stack>
|
||||
</Tabs>
|
||||
{statusId === "4" && (
|
||||
<Investasi_ViewPortofolioReject
|
||||
statusId={statusId}
|
||||
dataPortofolio={dataPortofolio}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import { RouterAdminInvestasi } from "@/app/lib/router_admin/router_admin_investasi";
|
||||
import { AccentColor } from "@/app_modules/_global/color/color_pallet";
|
||||
import { ComponentGlobal_TampilanRupiah } from "@/app_modules/_global/component";
|
||||
import { ComponentGlobal_LoadImage, ComponentGlobal_TampilanRupiah } from "@/app_modules/_global/component";
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
@@ -157,10 +157,12 @@ export function Investasi_ViewTransaksiBerhasil({
|
||||
transitionDuration={500}
|
||||
transitionTimingFunction="linear"
|
||||
>
|
||||
<Image
|
||||
|
||||
<ComponentGlobal_LoadImage fileId={data.imageId}/>
|
||||
{/* <Image
|
||||
alt="foto"
|
||||
src={RouterAdminInvestasi.api_bukti_transfer + data?.imagesId}
|
||||
/>
|
||||
/> */}
|
||||
</Collapse>
|
||||
</Stack>
|
||||
</Paper>
|
||||
|
||||
@@ -25,6 +25,9 @@ import { MODEL_INVOICE_INVESTASI } from "../../_lib/interface";
|
||||
import { investasi_funUploadBuktiTransferById } from "../../_fun";
|
||||
import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/_global/notif_global/notifikasi_berhasil";
|
||||
import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/_global/notif_global/notifikasi_gagal";
|
||||
import { funGlobal_UploadToStorage } from "@/app_modules/_global/fun";
|
||||
import { DIRECTORY_ID } from "@/app/lib";
|
||||
import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/_global/notif_global";
|
||||
|
||||
export function Investasi_ViewInvoice({
|
||||
dataInvoice,
|
||||
@@ -37,13 +40,19 @@ export function Investasi_ViewInvoice({
|
||||
const [file, setFile] = useState<File | null>(null);
|
||||
|
||||
async function onUpload() {
|
||||
const gambar = new FormData();
|
||||
gambar.append("file", file as any);
|
||||
const uploadFileToStorage = await funGlobal_UploadToStorage({
|
||||
file: file as any,
|
||||
dirId: DIRECTORY_ID.investasi_bukti_transfer,
|
||||
});
|
||||
|
||||
if (!uploadFileToStorage.success)
|
||||
return ComponentGlobal_NotifikasiPeringatan("Gagal upload bukti transfer")
|
||||
|
||||
const res = await investasi_funUploadBuktiTransferById({
|
||||
invoiceId: data.id,
|
||||
file: gambar,
|
||||
fileId: uploadFileToStorage.data.id,
|
||||
});
|
||||
|
||||
if (res.status !== 200) return ComponentGlobal_NotifikasiGagal(res.message);
|
||||
ComponentGlobal_NotifikasiBerhasil(res.message);
|
||||
setLoading(true);
|
||||
@@ -202,7 +211,6 @@ export function Investasi_ViewInvoice({
|
||||
onChange={async (files: any | null) => {
|
||||
try {
|
||||
setFile(files);
|
||||
// onUpload({ invoiceId: data.id, file: files });
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
@@ -10,15 +10,14 @@ import {
|
||||
Group,
|
||||
NumberInput,
|
||||
Text,
|
||||
TextInput,
|
||||
} from "@mantine/core";
|
||||
import { useFocusTrap, useLocalStorage } from "@mantine/hooks";
|
||||
import { useAtom } from "jotai";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import { NEW_RouterInvestasi } from "../../../../app/lib/router_hipmi/router_investasi";
|
||||
import { MODEL_INVESTASI } from "../../_lib/interface";
|
||||
import { gs_investas_menu } from "../../g_state";
|
||||
import { NEW_RouterInvestasi } from "../../../../app/lib/router_hipmi/router_investasi";
|
||||
|
||||
export function Investasi_ViewProsesPembelian({
|
||||
dataInvestasi,
|
||||
@@ -37,7 +36,7 @@ export function Investasi_ViewProsesPembelian({
|
||||
key: "jumlah_investasi",
|
||||
defaultValue: 0,
|
||||
});
|
||||
const [hotmenu, setHotmenu] = useAtom(gs_investas_menu);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -111,14 +110,16 @@ export function Investasi_ViewProsesPembelian({
|
||||
|
||||
<Center>
|
||||
<Button
|
||||
loaderPosition="center"
|
||||
loading={isLoading}
|
||||
disabled={jumlah < 10}
|
||||
w={350}
|
||||
radius={50}
|
||||
onClick={() => {
|
||||
// onProses();
|
||||
router.push(NEW_RouterInvestasi.metode_pembayaran + data.id, {
|
||||
scroll: false,
|
||||
});
|
||||
setIsLoading(true)
|
||||
}}
|
||||
bg={MainColor.yellow}
|
||||
color="yellow"
|
||||
|
||||
@@ -1,159 +0,0 @@
|
||||
import { RouterInvestasi_OLD } from "@/app/lib/router_hipmi/router_investasi";
|
||||
import { AccentColor } from "@/app_modules/_global/color/color_pallet";
|
||||
import {
|
||||
Stack,
|
||||
Box,
|
||||
AspectRatio,
|
||||
Center,
|
||||
Title,
|
||||
Grid,
|
||||
Paper,
|
||||
Flex,
|
||||
ActionIcon,
|
||||
Image,
|
||||
Text,
|
||||
SimpleGrid,
|
||||
} from "@mantine/core";
|
||||
import _ from "lodash";
|
||||
import { MODEL_INVESTASI } from "../../_lib/interface";
|
||||
import { IconBookDownload, IconFileDescription } from "@tabler/icons-react";
|
||||
import { useRouter } from "next/navigation";
|
||||
|
||||
export function ComponentInvestasi_DetailDataNonPublish({
|
||||
data,
|
||||
}: {
|
||||
data: MODEL_INVESTASI;
|
||||
}) {
|
||||
const router = useRouter();
|
||||
const listBox = [
|
||||
{
|
||||
id: 1,
|
||||
name: "Prospektus",
|
||||
icon: <IconBookDownload size={70} />,
|
||||
route: RouterInvestasi_OLD.detail_prospektus,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "Dokumen",
|
||||
icon: <IconFileDescription size={70} />,
|
||||
route: RouterInvestasi_OLD.detail_dokumen,
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<>
|
||||
<Stack
|
||||
style={{
|
||||
paddingInline: "15px",
|
||||
paddingBlock: "15px",
|
||||
backgroundColor: AccentColor.darkblue,
|
||||
border: `2px solid ${AccentColor.blue}`,
|
||||
borderRadius: "10px",
|
||||
color: "white",
|
||||
}}
|
||||
>
|
||||
<AspectRatio ratio={1 / 1} mx={"sm"} mah={300}>
|
||||
<Image
|
||||
alt=""
|
||||
src={RouterInvestasi_OLD.api_gambar + `${data.imagesId}`}
|
||||
radius={"sm"}
|
||||
height={300}
|
||||
width={"100%"}
|
||||
/>
|
||||
</AspectRatio>
|
||||
|
||||
{/* Title dan Persentase */}
|
||||
<Center>
|
||||
<Title order={3} align="center">
|
||||
{_.startCase(data.title)}
|
||||
</Title>
|
||||
</Center>
|
||||
|
||||
{/* Rincian Data */}
|
||||
<Grid p={"md"}>
|
||||
<Grid.Col span={6}>
|
||||
<Stack>
|
||||
<Box>
|
||||
<Text>Dana Dibutuhkan</Text>
|
||||
<Text>
|
||||
Rp.{" "}
|
||||
{new Intl.NumberFormat("id-ID", {
|
||||
maximumSignificantDigits: 20,
|
||||
}).format(+data.targetDana)}
|
||||
</Text>
|
||||
</Box>
|
||||
<Box>
|
||||
<Text>Harga Per Lembar</Text>
|
||||
<Text>
|
||||
Rp.{" "}
|
||||
{new Intl.NumberFormat("id-ID", {
|
||||
maximumSignificantDigits: 10,
|
||||
}).format(+data.hargaLembar)}
|
||||
</Text>
|
||||
</Box>
|
||||
<Box>
|
||||
<Text>Jadwal Pembagian</Text>
|
||||
<Text>{data.MasterPembagianDeviden.name} Bulan </Text>
|
||||
</Box>
|
||||
<Box>
|
||||
<Text>Pencarian Investor</Text>
|
||||
<Text>{data.MasterPencarianInvestor.name} Hari </Text>
|
||||
</Box>
|
||||
</Stack>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={6}>
|
||||
<Stack>
|
||||
<Box>
|
||||
<Text>ROI</Text>
|
||||
<Text>{data.roi} %</Text>
|
||||
</Box>
|
||||
<Box>
|
||||
<Text>Total Lembar</Text>
|
||||
<Text>
|
||||
{new Intl.NumberFormat("id-ID", {
|
||||
maximumSignificantDigits: 10,
|
||||
}).format(+data.totalLembar)}{" "}
|
||||
lembar
|
||||
</Text>
|
||||
</Box>
|
||||
<Box>
|
||||
<Text>Pembagian Deviden</Text>
|
||||
<Text>{data.MasterPeriodeDeviden.name}</Text>
|
||||
</Box>
|
||||
</Stack>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
|
||||
{/* List Box */}
|
||||
<SimpleGrid cols={2}>
|
||||
{listBox.map((e) => (
|
||||
<Center key={e.id}>
|
||||
<Paper
|
||||
style={{
|
||||
width: 100,
|
||||
padding: "15px",
|
||||
backgroundColor: AccentColor.blue,
|
||||
border: `2px solid ${AccentColor.softblue}`,
|
||||
borderRadius: "10px",
|
||||
color: "white",
|
||||
}}
|
||||
onClick={() => router.push(e.route + `${data.id}`)}
|
||||
>
|
||||
<Stack spacing={0} align="center">
|
||||
<Text fz={12}>{e.name}</Text>
|
||||
<ActionIcon
|
||||
variant="transparent"
|
||||
size={60}
|
||||
style={{ color: "white" }}
|
||||
>
|
||||
{e.icon}
|
||||
</ActionIcon>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Center>
|
||||
))}
|
||||
</SimpleGrid>
|
||||
</Stack>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
import {
|
||||
ComponentGlobal_CardStyles,
|
||||
ComponentGlobal_LoadImageLandscape,
|
||||
} from "@/app_modules/_global/component";
|
||||
import {
|
||||
Center,
|
||||
SimpleGrid,
|
||||
Stack,
|
||||
Text,
|
||||
Title
|
||||
} from "@mantine/core";
|
||||
import _ from "lodash";
|
||||
import {
|
||||
Investasi_ComponentBoxDaftarDokumen,
|
||||
Investasi_ComponentBoxProspektus,
|
||||
Investasi_ComponentTitleAndValueInDetail,
|
||||
} from "../../_component";
|
||||
import { MODEL_INVESTASI } from "../../_lib/interface";
|
||||
|
||||
export function ComponentInvestasi_DetailDataNonPublish({
|
||||
data,
|
||||
}: {
|
||||
data: MODEL_INVESTASI;
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
<ComponentGlobal_CardStyles>
|
||||
<Stack spacing={"xl"}>
|
||||
<ComponentGlobal_LoadImageLandscape fileId={data.imageId} />
|
||||
|
||||
{/* Title dan Persentase */}
|
||||
<Center>
|
||||
<Title order={3} align="center">
|
||||
{_.startCase(data.title)}
|
||||
</Title>
|
||||
</Center>
|
||||
|
||||
{/* Rincian Data */}
|
||||
|
||||
<Stack>
|
||||
<Investasi_ComponentTitleAndValueInDetail
|
||||
title="Target Dana"
|
||||
value={
|
||||
<Text>
|
||||
Rp.{" "}
|
||||
{new Intl.NumberFormat("id-ID", {
|
||||
maximumSignificantDigits: 20,
|
||||
}).format(+data.targetDana)}{" "}
|
||||
</Text>
|
||||
}
|
||||
/>
|
||||
|
||||
<Investasi_ComponentTitleAndValueInDetail
|
||||
title="Harga Per Lembar"
|
||||
value={
|
||||
<Text>
|
||||
Rp.{" "}
|
||||
{new Intl.NumberFormat("id-ID", {
|
||||
maximumSignificantDigits: 10,
|
||||
}).format(+data.hargaLembar)}
|
||||
</Text>
|
||||
}
|
||||
/>
|
||||
|
||||
<Investasi_ComponentTitleAndValueInDetail
|
||||
title={<Text fs={"italic"}>Return Of Value (RoI)</Text>}
|
||||
value={<Text>{data.roi} %</Text>}
|
||||
/>
|
||||
|
||||
<Investasi_ComponentTitleAndValueInDetail
|
||||
title="Total Lembar"
|
||||
value={
|
||||
<Text>
|
||||
{new Intl.NumberFormat("id-ID", {
|
||||
maximumSignificantDigits: 10,
|
||||
}).format(+data.totalLembar)}{" "}
|
||||
lembar
|
||||
</Text>
|
||||
}
|
||||
/>
|
||||
|
||||
<Investasi_ComponentTitleAndValueInDetail
|
||||
title="Jadwal Pembagian"
|
||||
value={<Text>{data.MasterPembagianDeviden.name} Bulan </Text>}
|
||||
/>
|
||||
<Investasi_ComponentTitleAndValueInDetail
|
||||
title="Pembagian Deviden"
|
||||
value={<Text>{data.MasterPeriodeDeviden.name}</Text>}
|
||||
/>
|
||||
<Investasi_ComponentTitleAndValueInDetail
|
||||
title="Pencarian Investor"
|
||||
value={<Text>{data.MasterPencarianInvestor.name} Hari </Text>}
|
||||
/>
|
||||
</Stack>
|
||||
|
||||
{/* List Box */}
|
||||
|
||||
<SimpleGrid
|
||||
cols={2}
|
||||
breakpoints={[
|
||||
{ maxWidth: "62rem", cols: 2, spacing: "md" },
|
||||
{ maxWidth: "48rem", cols: 2, spacing: "sm" },
|
||||
{ maxWidth: "36rem", cols: 1, spacing: "sm" },
|
||||
]}
|
||||
>
|
||||
{/* <Investasi_ComponentBoxProspektus investasiId={data.id} /> */}
|
||||
{/* <Investasi_ComponentBoxDaftarDokumen investasiId={data.id} /> */}
|
||||
</SimpleGrid>
|
||||
</Stack>
|
||||
</ComponentGlobal_CardStyles>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -1,43 +1,34 @@
|
||||
"use client";
|
||||
|
||||
import { RouterInvestasi_OLD } from "@/app/lib/router_hipmi/router_investasi";
|
||||
import { MainColor } from "@/app_modules/_global/color/color_pallet";
|
||||
import {
|
||||
AccentColor,
|
||||
MainColor,
|
||||
} from "@/app_modules/_global/color/color_pallet";
|
||||
ComponentGlobal_BoxInformation,
|
||||
ComponentGlobal_BoxUploadImage,
|
||||
ComponentGlobal_CardStyles,
|
||||
} from "@/app_modules/_global/component";
|
||||
import {
|
||||
ComponentGlobal_WarningMaxUpload,
|
||||
maksimalUploadFile,
|
||||
} from "@/app_modules/_global/component/waring_popup";
|
||||
import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/_global/notif_global/notifikasi_berhasil";
|
||||
import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/_global/notif_global/notifikasi_gagal";
|
||||
import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/_global/notif_global/notifikasi_peringatan";
|
||||
import { MODEL_DEFAULT_MASTER_OLD } from "@/app_modules/model_global/model_default_master";
|
||||
import notifikasiToAdmin_funCreate from "@/app_modules/notifikasi/fun/create/create_notif_to_admin";
|
||||
import mqtt_client from "@/util/mqtt_client";
|
||||
import {
|
||||
AspectRatio,
|
||||
Box,
|
||||
Button,
|
||||
Center,
|
||||
Divider,
|
||||
FileButton,
|
||||
Grid,
|
||||
Group,
|
||||
Image,
|
||||
Paper,
|
||||
Select,
|
||||
Stack,
|
||||
Text,
|
||||
TextInput,
|
||||
} from "@mantine/core";
|
||||
import { IconCamera, IconUpload } from "@tabler/icons-react";
|
||||
import { useAtom } from "jotai";
|
||||
import { IconCamera, IconCircleCheck, IconFileTypePdf, IconUpload } from "@tabler/icons-react";
|
||||
import _ from "lodash";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import { funCreateInvestasi } from "../fun/fun_create_investasi";
|
||||
import { gs_investas_menu, gs_investasi_status } from "../g_state";
|
||||
import { ComponentGlobal_BoxUploadImage } from "@/app_modules/_global/component";
|
||||
import { Investasi_ComponentButtonCreateNewInvestasi } from "../_component";
|
||||
|
||||
export default function InvestasiCreate({
|
||||
pencarianInvestor,
|
||||
@@ -48,16 +39,11 @@ export default function InvestasiCreate({
|
||||
periodeDeviden: MODEL_DEFAULT_MASTER_OLD[];
|
||||
pembagianDeviden: MODEL_DEFAULT_MASTER_OLD[];
|
||||
}) {
|
||||
const router = useRouter();
|
||||
const [file, setFile] = useState<File | null>(null);
|
||||
const [fileImage, setFileImage] = useState<File | null>(null);
|
||||
const [img, setImg] = useState<any | null>();
|
||||
const [pdf, setPdf] = useState<File | null>(null);
|
||||
const [filePdf, setFilePdf] = useState<any | null>(null);
|
||||
|
||||
const [changeColor, setChangeColor] = useAtom(gs_investas_menu);
|
||||
const [activeTab, setActiveTab] = useAtom(gs_investasi_status);
|
||||
const [filePdf, setFilePdf] = useState<File | null>(null);
|
||||
const [fPdf, setFPdf] = useState<any | null>(null);
|
||||
const [totalLembar, setTotalLembar] = useState(0);
|
||||
const [isLoading, setLoading] = useState(false);
|
||||
|
||||
const [value, setValue] = useState({
|
||||
title: "",
|
||||
@@ -71,76 +57,27 @@ export default function InvestasiCreate({
|
||||
const [target, setTarget] = useState("");
|
||||
const [harga, setHarga] = useState("");
|
||||
|
||||
async function onSubmit() {
|
||||
const body = {
|
||||
title: value.title,
|
||||
targetDana: value.targetDana,
|
||||
hargaLembar: value.hargaLembar,
|
||||
totalLembar: totalLembar,
|
||||
roi: value.roi,
|
||||
masterPeriodeDevidenId: value.periodeDevidenId,
|
||||
masterPembagianDevidenId: value.pembagianDevidenId,
|
||||
masterPencarianInvestorId: value.pencarianInvestorId,
|
||||
};
|
||||
|
||||
// if (_.values(body).includes("")) return toast("Lengkapi data");
|
||||
if (!file) return ComponentGlobal_NotifikasiPeringatan("Gambar Kosong");
|
||||
if (!pdf) return ComponentGlobal_NotifikasiPeringatan("File Kosong");
|
||||
|
||||
const gmbr = new FormData();
|
||||
gmbr.append("file", file as any);
|
||||
|
||||
const flPdf = new FormData();
|
||||
flPdf.append("file", pdf as any);
|
||||
|
||||
const res = await funCreateInvestasi(gmbr, flPdf, body as any);
|
||||
if (res.status === 201) {
|
||||
const dataNotif = {
|
||||
appId: res.data?.id,
|
||||
status: res.data?.MasterStatusInvestasi?.name,
|
||||
userId: res.data?.authorId,
|
||||
pesan: res.data?.title,
|
||||
kategoriApp: "INVESTASI",
|
||||
title: "Investasi baru",
|
||||
};
|
||||
|
||||
const notif = await notifikasiToAdmin_funCreate({
|
||||
data: dataNotif as any,
|
||||
});
|
||||
|
||||
if (notif.status === 201) {
|
||||
mqtt_client.publish(
|
||||
"ADMIN",
|
||||
JSON.stringify({
|
||||
count: 1,
|
||||
})
|
||||
);
|
||||
setChangeColor(1);
|
||||
setActiveTab("Review");
|
||||
setLoading(true);
|
||||
ComponentGlobal_NotifikasiBerhasil(res.message);
|
||||
router.push(RouterInvestasi_OLD.portofolio);
|
||||
}
|
||||
} else {
|
||||
ComponentGlobal_NotifikasiGagal(res.message);
|
||||
}
|
||||
}
|
||||
|
||||
async function onTotalLembar({
|
||||
target,
|
||||
harga,
|
||||
}: {
|
||||
target: number;
|
||||
harga: number;
|
||||
target?: number | any;
|
||||
harga?: number | any;
|
||||
}) {
|
||||
const hasil: any = target / harga;
|
||||
setTotalLembar(_.floor(hasil === Infinity ? 0 : hasil));
|
||||
if (target !== 0 && harga !== 0) {
|
||||
const hasil: any = target / harga;
|
||||
setTotalLembar(_.floor(hasil === Infinity ? 0 : hasil));
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Stack px={"xs"}>
|
||||
<Stack px={"xs"} spacing={40}>
|
||||
{/* Upload Image */}
|
||||
<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} mah={265} mx={"auto"}>
|
||||
@@ -162,7 +99,7 @@ export default function InvestasiCreate({
|
||||
</ComponentGlobal_BoxUploadImage>
|
||||
|
||||
{/* Upload Foto */}
|
||||
<Group position="center" mb={"md"}>
|
||||
<Group position="center">
|
||||
<FileButton
|
||||
onChange={async (files: any) => {
|
||||
try {
|
||||
@@ -175,7 +112,7 @@ export default function InvestasiCreate({
|
||||
ComponentGlobal_WarningMaxUpload({});
|
||||
} else {
|
||||
setImg(buffer);
|
||||
setFile(files);
|
||||
setFileImage(files);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
@@ -200,8 +137,31 @@ export default function InvestasiCreate({
|
||||
</Stack>
|
||||
|
||||
{/* Upload File */}
|
||||
<Group position="center">
|
||||
{!pdf ? (
|
||||
<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>
|
||||
|
||||
{/* {!pdf ? (
|
||||
<Paper
|
||||
w={"100%"}
|
||||
style={{
|
||||
@@ -227,256 +187,240 @@ export default function InvestasiCreate({
|
||||
>
|
||||
<Text lineClamp={1}>{pdf.name}</Text>
|
||||
</Paper>
|
||||
)}
|
||||
)} */}
|
||||
{/* {JSON.stringify(filePdf)} */}
|
||||
<FileButton
|
||||
accept={"application/pdf"}
|
||||
onChange={async (files: any) => {
|
||||
try {
|
||||
const buffer = URL.createObjectURL(
|
||||
new Blob([new Uint8Array(await files.arrayBuffer())])
|
||||
);
|
||||
|
||||
if (files.size > maksimalUploadFile) {
|
||||
ComponentGlobal_WarningMaxUpload({});
|
||||
} else {
|
||||
setFilePdf(buffer);
|
||||
setPdf(files);
|
||||
<Group position="center">
|
||||
<FileButton
|
||||
accept={"application/pdf"}
|
||||
onChange={async (files: any) => {
|
||||
try {
|
||||
const buffer = URL.createObjectURL(
|
||||
new Blob([new Uint8Array(await files.arrayBuffer())])
|
||||
);
|
||||
setFPdf(buffer);
|
||||
setFilePdf(files);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{(props) => (
|
||||
<Button
|
||||
leftIcon={<IconCamera />}
|
||||
{...props}
|
||||
radius={"xl"}
|
||||
bg={MainColor.yellow}
|
||||
color="yellow"
|
||||
c={"black"}
|
||||
>
|
||||
Upload File
|
||||
</Button>
|
||||
)}
|
||||
</FileButton>
|
||||
</Group>
|
||||
</Stack>
|
||||
|
||||
<Stack>
|
||||
<TextInput
|
||||
styles={{
|
||||
label: {
|
||||
color: "white",
|
||||
},
|
||||
}}
|
||||
>
|
||||
{(props) => (
|
||||
<Button
|
||||
leftIcon={<IconUpload size={12} />}
|
||||
{...props}
|
||||
radius={"xl"}
|
||||
bg={MainColor.yellow}
|
||||
color="yellow"
|
||||
c={"black"}
|
||||
>
|
||||
Upload File
|
||||
</Button>
|
||||
)}
|
||||
</FileButton>
|
||||
</Group>
|
||||
<TextInput
|
||||
styles={{
|
||||
label: {
|
||||
color: "white",
|
||||
},
|
||||
}}
|
||||
withAsterisk
|
||||
label="Judul Investasi"
|
||||
placeholder="Judul investasi"
|
||||
maxLength={100}
|
||||
onChange={(val) => {
|
||||
setValue({
|
||||
...value,
|
||||
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}
|
||||
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);
|
||||
|
||||
setTarget(targetNilai);
|
||||
setValue({
|
||||
...value,
|
||||
targetDana: +nilai,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
|
||||
<TextInput
|
||||
styles={{
|
||||
label: {
|
||||
color: "white",
|
||||
},
|
||||
}}
|
||||
icon={<Text fw={"bold"}>Rp.</Text>}
|
||||
min={0}
|
||||
withAsterisk
|
||||
label="Harga Per Lembar"
|
||||
placeholder="0"
|
||||
value={harga}
|
||||
onChange={(val) => {
|
||||
try {
|
||||
// console.log(typeof +val.currentTarget.value);
|
||||
withAsterisk
|
||||
label="Judul Investasi"
|
||||
placeholder="Judul investasi"
|
||||
maxLength={100}
|
||||
onChange={(val) => {
|
||||
setValue({
|
||||
...value,
|
||||
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}
|
||||
onChange={(val) => {
|
||||
// console.log(typeof val)
|
||||
const match = val.currentTarget.value
|
||||
.replace(/\./g, "")
|
||||
.match(/^[0-9]+$/);
|
||||
|
||||
if (val.currentTarget.value === "") return setHarga(0 + "");
|
||||
|
||||
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: value.targetDana,
|
||||
harga: +nilai,
|
||||
target: +nilai,
|
||||
harga: +value.hargaLembar,
|
||||
});
|
||||
|
||||
setHarga(targetNilai);
|
||||
setTarget(targetNilai);
|
||||
setValue({
|
||||
...value,
|
||||
hargaLembar: +nilai,
|
||||
targetDana: +nilai,
|
||||
});
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
}}
|
||||
/>
|
||||
|
||||
<Stack spacing={3} style={{ color: "white" }}>
|
||||
<Text fz={"sm"} fw={500}>
|
||||
Total Lembar
|
||||
</Text>
|
||||
<Stack spacing={0}>
|
||||
<Text>{totalLembar}</Text>
|
||||
<Divider />
|
||||
</Stack>
|
||||
<Text fz={10} fs={"italic"}>
|
||||
*Total lembar dihitung dari, Target Dana : Harga Perlembar
|
||||
</Text>
|
||||
<TextInput
|
||||
styles={{
|
||||
label: {
|
||||
color: "white",
|
||||
},
|
||||
}}
|
||||
icon={<Text fw={"bold"}>Rp.</Text>}
|
||||
min={0}
|
||||
withAsterisk
|
||||
label="Harga Per Lembar"
|
||||
placeholder="0"
|
||||
value={harga}
|
||||
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: +value.targetDana,
|
||||
});
|
||||
|
||||
setHarga(targetNilai);
|
||||
setValue({
|
||||
...value,
|
||||
hargaLembar: +nilai,
|
||||
});
|
||||
} 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",
|
||||
},
|
||||
}}
|
||||
/>
|
||||
|
||||
<TextInput
|
||||
styles={{
|
||||
label: {
|
||||
color: "white",
|
||||
},
|
||||
}}
|
||||
rightSection={
|
||||
<Text fw={"bold"} c={"gray"}>
|
||||
%
|
||||
</Text>
|
||||
}
|
||||
withAsterisk
|
||||
type="number"
|
||||
label={"Rasio Keuntungan / ROI %"}
|
||||
placeholder="Masukan rasio keuntungan"
|
||||
onChange={(val) => {
|
||||
setValue({
|
||||
...value,
|
||||
roi: _.toNumber(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",
|
||||
}))}
|
||||
onChange={(val) => {
|
||||
setValue({
|
||||
...(value as any),
|
||||
pencarianInvestorId: val,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
|
||||
<Select
|
||||
styles={{
|
||||
label: {
|
||||
color: "white",
|
||||
},
|
||||
}}
|
||||
withAsterisk
|
||||
label="Periode Deviden"
|
||||
placeholder="Pilih batas waktu"
|
||||
data={periodeDeviden.map((e) => ({ value: e.id, label: e.name }))}
|
||||
onChange={(val) => {
|
||||
setValue({
|
||||
...(value as any),
|
||||
periodeDevidenId: 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",
|
||||
}))}
|
||||
onChange={(val) => {
|
||||
setValue({
|
||||
...(value as any),
|
||||
pembagianDevidenId: val,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</Stack>
|
||||
|
||||
<TextInput
|
||||
styles={{
|
||||
label: {
|
||||
color: "white",
|
||||
},
|
||||
}}
|
||||
rightSection={
|
||||
<Text fw={"bold"} c={"gray"}>
|
||||
%
|
||||
</Text>
|
||||
}
|
||||
withAsterisk
|
||||
type="number"
|
||||
label={"Rasio Keuntungan / ROI %"}
|
||||
placeholder="Masukan rasio keuntungan"
|
||||
onChange={(val) => {
|
||||
setValue({
|
||||
...value,
|
||||
roi: _.toNumber(val.target.value),
|
||||
});
|
||||
}}
|
||||
<Investasi_ComponentButtonCreateNewInvestasi
|
||||
data={value}
|
||||
totalLembar={totalLembar}
|
||||
fileImage={fileImage as any}
|
||||
filePdf={filePdf as any}
|
||||
/>
|
||||
|
||||
<Select
|
||||
styles={{
|
||||
label: {
|
||||
color: "white",
|
||||
},
|
||||
}}
|
||||
withAsterisk
|
||||
label="Pencarian Investor"
|
||||
placeholder="Pilih batas waktu"
|
||||
data={pencarianInvestor.map((e) => ({
|
||||
value: e.id,
|
||||
label: e.name + " " + "hari",
|
||||
}))}
|
||||
onChange={(val) => {
|
||||
setValue({
|
||||
...(value as any),
|
||||
pencarianInvestorId: val,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<Select
|
||||
styles={{
|
||||
label: {
|
||||
color: "white",
|
||||
},
|
||||
}}
|
||||
withAsterisk
|
||||
label="Periode Deviden"
|
||||
placeholder="Pilih batas waktu"
|
||||
data={periodeDeviden.map((e) => ({ value: e.id, label: e.name }))}
|
||||
onChange={(val) => {
|
||||
setValue({
|
||||
...(value as any),
|
||||
periodeDevidenId: 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",
|
||||
}))}
|
||||
onChange={(val) => {
|
||||
setValue({
|
||||
...(value as any),
|
||||
pembagianDevidenId: val,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
|
||||
<Button
|
||||
my={"xl"}
|
||||
style={{
|
||||
transition: "0.5s",
|
||||
}}
|
||||
loaderPosition="center"
|
||||
loading={isLoading ? true : false}
|
||||
disabled={
|
||||
value.title === "" ||
|
||||
value.hargaLembar === 0 ||
|
||||
value.targetDana === 0 ||
|
||||
value.roi === 0 ||
|
||||
value.pencarianInvestorId === "" ||
|
||||
value.periodeDevidenId === "" ||
|
||||
value.pembagianDevidenId === "" ||
|
||||
file === null ||
|
||||
filePdf === null
|
||||
? true
|
||||
: false
|
||||
}
|
||||
radius={50}
|
||||
bg={MainColor.yellow}
|
||||
color="yellow"
|
||||
c={"black"}
|
||||
onClick={() => onSubmit()}
|
||||
>
|
||||
Simpan
|
||||
</Button>
|
||||
</Stack>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -28,12 +28,13 @@ import { useLocalStorage } from "@mantine/hooks";
|
||||
import {
|
||||
IconBookDownload,
|
||||
IconFileDescription,
|
||||
IconSpeakerphone
|
||||
IconSpeakerphone,
|
||||
} from "@tabler/icons-react";
|
||||
import moment from "moment";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import { MODEL_INVESTASI } from "../_lib/interface";
|
||||
import { ComponentGlobal_LoadImageLandscape } from "@/app_modules/_global/component";
|
||||
|
||||
export default function DetailInvestasi({
|
||||
dataInvestasi,
|
||||
@@ -79,16 +80,6 @@ export default function DetailInvestasi({
|
||||
];
|
||||
|
||||
async function onSubmit() {
|
||||
// OLD
|
||||
// router.push(RouterInvestasi_OLD.proses_transaksi + `${data.id}`);
|
||||
// setTransaksiValue({
|
||||
// ...transaksiValue,
|
||||
// lembarTerbeli: "",
|
||||
// namaBank: "",
|
||||
// nomorRekening: "",
|
||||
// totalTransfer: "",
|
||||
// });
|
||||
|
||||
setLoadingButton(true);
|
||||
|
||||
//NEW
|
||||
@@ -167,7 +158,7 @@ export default function DetailInvestasi({
|
||||
}
|
||||
/> */}
|
||||
|
||||
<AspectRatio ratio={1 / 1} mx={"sm"} mah={250}>
|
||||
{/* <AspectRatio ratio={1 / 1} mx={"sm"} mah={250}>
|
||||
<Image
|
||||
alt=""
|
||||
src={RouterInvestasi_OLD.api_gambar + `${data.imagesId}`}
|
||||
@@ -175,7 +166,9 @@ export default function DetailInvestasi({
|
||||
height={250}
|
||||
width={"100%"}
|
||||
/>
|
||||
</AspectRatio>
|
||||
</AspectRatio> */}
|
||||
|
||||
<ComponentGlobal_LoadImageLandscape fileId={data.imageId} />
|
||||
|
||||
{/* Title dan Progress */}
|
||||
<Box mb={"md"}>
|
||||
|
||||
@@ -37,7 +37,7 @@ export default function DetailDokumenInvestasi({
|
||||
marginBottom: "15px",
|
||||
}}
|
||||
onClick={() => {
|
||||
router.push(NEW_RouterInvestasi.file_view_dokumen + e.id, {
|
||||
router.push(NEW_RouterInvestasi.OLD_file_view_dokumen + e.id, {
|
||||
scroll: false,
|
||||
});
|
||||
}}
|
||||
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
import { useAtom } from "jotai";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import { ComponentInvestasi_DetailDataNonPublish } from "../../component/detail/detai_data_non_publish";
|
||||
import { ComponentInvestasi_DetailDataNonPublish } from "../../component/detail/x_detai_data_non_publish";
|
||||
import { investasi_funEditStatusById } from "../../fun/edit/fun_edit_status_by_id";
|
||||
import { gs_investasi_status } from "../../g_state";
|
||||
import { MODEL_INVESTASI } from "../../_lib/interface";
|
||||
|
||||
@@ -1,22 +1,24 @@
|
||||
"use client"
|
||||
"use client";
|
||||
|
||||
import AppComponentGlobal_LayoutTamplate from "@/app_modules/_global/component_layout_tamplate"
|
||||
import ComponentGlobal_HeaderTamplate from "@/app_modules/_global/header_tamplate"
|
||||
import UIGlobal_LayoutHeaderTamplate from "@/app_modules/_global/ui/ui_header_tamplate"
|
||||
import UIGlobal_LayoutTamplate from "@/app_modules/_global/ui/ui_layout_tamplate"
|
||||
import { AppShell } from "@mantine/core"
|
||||
import React from "react"
|
||||
import AppComponentGlobal_LayoutTamplate from "@/app_modules/_global/component_layout_tamplate";
|
||||
import ComponentGlobal_HeaderTamplate from "@/app_modules/_global/header_tamplate";
|
||||
import UIGlobal_LayoutHeaderTamplate from "@/app_modules/_global/ui/ui_header_tamplate";
|
||||
import UIGlobal_LayoutTamplate from "@/app_modules/_global/ui/ui_layout_tamplate";
|
||||
import { AppShell } from "@mantine/core";
|
||||
import React from "react";
|
||||
|
||||
export default function LayoutDetailPublishInvestasi({children}: {children: React.ReactNode}){
|
||||
return<>
|
||||
|
||||
<UIGlobal_LayoutTamplate
|
||||
header={
|
||||
<UIGlobal_LayoutHeaderTamplate title="Detail Publish"/>
|
||||
}
|
||||
>
|
||||
export default function LayoutDetailPublishInvestasi({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
<UIGlobal_LayoutTamplate
|
||||
header={<UIGlobal_LayoutHeaderTamplate title="Detail Publish" />}
|
||||
>
|
||||
{children}
|
||||
</UIGlobal_LayoutTamplate>
|
||||
|
||||
</UIGlobal_LayoutTamplate>
|
||||
</>
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,16 +6,14 @@ import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/_global/notif_
|
||||
import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/_global/notif_global/notifikasi_gagal";
|
||||
import UIGlobal_Modal from "@/app_modules/_global/ui/ui_modal";
|
||||
import { Button, Group, Stack } from "@mantine/core";
|
||||
import { IconBookDownload, IconFileDescription } from "@tabler/icons-react";
|
||||
import { useAtom } from "jotai";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import { ComponentInvestasi_DetailDataNonPublish } from "../../component/detail/detai_data_non_publish";
|
||||
import funDeleteInvestasi from "../../fun/fun_delete_investasi";
|
||||
import funGantiStatusInvestasi from "../../fun/fun_ganti_status";
|
||||
import { gs_investasi_status } from "../../g_state";
|
||||
import { MODEL_INVESTASI } from "../../_lib/interface";
|
||||
import { ComponentInvestasi_DetailDataNonPublish } from "../../component/detail/x_detai_data_non_publish";
|
||||
import { investasi_funEditStatusById } from "../../fun/edit/fun_edit_status_by_id";
|
||||
import funDeleteInvestasi from "../../fun/fun_delete_investasi";
|
||||
import { gs_investasi_status } from "../../g_state";
|
||||
|
||||
export default function DetailRejectInvestasi({
|
||||
dataInvestasi,
|
||||
|
||||
@@ -11,7 +11,7 @@ import notifikasiToAdmin_funCreate from "@/app_modules/notifikasi/fun/create/cre
|
||||
import mqtt_client from "@/util/mqtt_client";
|
||||
import { useState } from "react";
|
||||
import { MODEL_INVESTASI } from "../../_lib/interface";
|
||||
import { ComponentInvestasi_DetailDataNonPublish } from "../../component/detail/detai_data_non_publish";
|
||||
import { ComponentInvestasi_DetailDataNonPublish } from "../../component/detail/x_detai_data_non_publish";
|
||||
import { investasi_funEditStatusById } from "../../fun/edit/fun_edit_status_by_id";
|
||||
|
||||
export default function DetailReviewInvestasi({
|
||||
@@ -59,11 +59,12 @@ export default function DetailReviewInvestasi({
|
||||
|
||||
return (
|
||||
<>
|
||||
<Stack spacing={"xl"} mb={"lg"}>
|
||||
<Stack spacing={"xl"} >
|
||||
<ComponentInvestasi_DetailDataNonPublish data={data} />
|
||||
{/* Tombol Ajukan */}
|
||||
<Stack>
|
||||
<Button
|
||||
mb={"xl"}
|
||||
style={{
|
||||
transition: "0.5s",
|
||||
}}
|
||||
|
||||
@@ -51,7 +51,7 @@ export default function DetailPropektus({
|
||||
}}
|
||||
onClick={() =>
|
||||
router.push(
|
||||
NEW_RouterInvestasi.file_view_prospektus +
|
||||
NEW_RouterInvestasi.OLD_file_view_prospektus +
|
||||
`${data.ProspektusInvestasi.id}`,
|
||||
{ scroll: false }
|
||||
)
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
"use client"
|
||||
|
||||
import AppComponentGlobal_LayoutTamplate from "@/app_modules/_global/component_layout_tamplate"
|
||||
import ComponentGlobal_HeaderTamplate from "@/app_modules/_global/header_tamplate"
|
||||
import { AppShell } from "@mantine/core"
|
||||
import React from "react"
|
||||
|
||||
export default function LayoutEditInvestasi({children}: {children: React.ReactNode}){
|
||||
return<>
|
||||
<AppComponentGlobal_LayoutTamplate header={<ComponentGlobal_HeaderTamplate title="Edit Portofolio Investasi"/>}>
|
||||
{children}
|
||||
</AppComponentGlobal_LayoutTamplate>
|
||||
</>
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import { RouterInvestasi_OLD } from "@/app/lib/router_hipmi/router_investasi";
|
||||
import { ComponentGlobal_CardLoadingOverlay } from "@/app_modules/_global/component";
|
||||
import { Center, Grid, Paper, Stack, Title } from "@mantine/core";
|
||||
import { IconChevronRight } from "@tabler/icons-react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
|
||||
export default function EditInvestasi({ id }: { id: string }) {
|
||||
const router = useRouter();
|
||||
const [isLoading, setLoading] = useState(false);
|
||||
const [listId, setListId] = useState(0);
|
||||
|
||||
const listEdit = [
|
||||
{
|
||||
id: 1,
|
||||
name: "Intro",
|
||||
route: RouterInvestasi_OLD.edit_intro,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "Prospektus",
|
||||
route: RouterInvestasi_OLD.edit_prospektus,
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: "Dokumen",
|
||||
route: RouterInvestasi_OLD.edit_dokumen,
|
||||
},
|
||||
// {
|
||||
// id: 4,
|
||||
// name: "Berita",
|
||||
// route: RouterInvestasi.list_edit_berita,
|
||||
// },
|
||||
];
|
||||
return (
|
||||
<>
|
||||
{listEdit.map((e) => (
|
||||
<Paper
|
||||
shadow="lg"
|
||||
key={e.id}
|
||||
w={"100%"}
|
||||
bg={"gray.4"}
|
||||
mb={"md"}
|
||||
onClick={() => {
|
||||
setLoading(true);
|
||||
setListId(e.id);
|
||||
router.push(e.route + `${id}`);
|
||||
}}
|
||||
>
|
||||
{isLoading && e.id === listId ? (
|
||||
<ComponentGlobal_CardLoadingOverlay />
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
<Grid justify="center" h={70} px={"sm"}>
|
||||
<Grid.Col span={10} h={"100%"}>
|
||||
<Stack h={"100%"} justify="center">
|
||||
<Title order={4} fw={"bold"}>
|
||||
{e.name}
|
||||
</Title>
|
||||
</Stack>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={2}>
|
||||
<Center h={"100%"}>
|
||||
<IconChevronRight />
|
||||
</Center>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
</Paper>
|
||||
))}
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -323,6 +323,7 @@ export default function EditIntroInvestasi({
|
||||
});
|
||||
}}
|
||||
/>
|
||||
|
||||
<Select
|
||||
styles={{
|
||||
label: {
|
||||
|
||||
@@ -31,7 +31,7 @@ export default async function funEditInvestasi(
|
||||
});
|
||||
|
||||
if (!updateImage) return { status: 400, message: "Gagal upload gambar" };
|
||||
const upFolder = Buffer.from(await file.arrayBuffer());
|
||||
const upFolder : any = Buffer.from(await file.arrayBuffer());
|
||||
fs.writeFileSync(`./public/investasi/${updateImage.url}`, upFolder);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@ export default async function getOneInvestasiById(id: string) {
|
||||
id: id,
|
||||
},
|
||||
select: {
|
||||
imageId: true,
|
||||
prospektusFileId: true,
|
||||
id: true,
|
||||
author: {
|
||||
select: {
|
||||
|
||||
@@ -7,8 +7,8 @@ export default async function getPencarianInvestor() {
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
active: true
|
||||
}
|
||||
active: true,
|
||||
},
|
||||
});
|
||||
|
||||
return data;
|
||||
|
||||
@@ -1,7 +1,15 @@
|
||||
import { atom } from "jotai";
|
||||
import { atomWithStorage } from "jotai/utils";
|
||||
|
||||
/**
|
||||
* @param {number} key | 0 - 4
|
||||
* @type number
|
||||
*/
|
||||
export const gs_investas_menu = atomWithStorage<number>("changeColor", 0);
|
||||
|
||||
/**
|
||||
* @param key | "Publish", "Review", "Draft", "Reject"
|
||||
* @type string
|
||||
*/
|
||||
export const gs_investasi_status = atomWithStorage<any | string>(
|
||||
"gs_TabPortoInvestasi",
|
||||
"Publish"
|
||||
|
||||
@@ -12,8 +12,6 @@ import CountDownTransaksiInvestasi from "./dialog_page/transaksi_saham/view";
|
||||
import LayoutCountDownTransaksiInvestasi from "./dialog_page/transaksi_saham/layout";
|
||||
import PortofolioInvestasi from "./portofolio/view";
|
||||
import LayoutPortofolioInvestasi from "./portofolio/layout";
|
||||
import EditInvestasi from "./edit/view";
|
||||
import LayoutEditInvestasi from "./edit/layout";
|
||||
import EditIntroInvestasi from "./edit_intro/view";
|
||||
import LayoutEditIntroInvestasi from "./edit_intro/layout";
|
||||
import EditProspektusInvestasi from "./edit_propektus/view";
|
||||
@@ -79,8 +77,6 @@ export {
|
||||
LayoutCountDownTransaksiInvestasi as LayoutKonfirmasiBuktiInvestasi,
|
||||
PortofolioInvestasi,
|
||||
LayoutPortofolioInvestasi,
|
||||
EditInvestasi,
|
||||
LayoutEditInvestasi,
|
||||
EditIntroInvestasi,
|
||||
LayoutEditIntroInvestasi,
|
||||
EditProspektusInvestasi,
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
"use client";
|
||||
|
||||
import { RouterPortofolio } from "@/app/lib/router_hipmi/router_katalog";
|
||||
import { RouterMap } from "@/app/lib/router_hipmi/router_map";
|
||||
import { APIs } from "@/app/lib";
|
||||
import {
|
||||
AccentColor,
|
||||
MainColor,
|
||||
} from "@/app_modules/_global/color/color_pallet";
|
||||
import {
|
||||
ComponentGlobal_BoxUploadImage,
|
||||
ComponentGlobal_LoadImage,
|
||||
} from "@/app_modules/_global/component";
|
||||
import ComponentGlobal_BoxInformation from "@/app_modules/_global/component/box_information";
|
||||
import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/_global/notif_global/notifikasi_berhasil";
|
||||
import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/_global/notif_global/notifikasi_gagal";
|
||||
import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/_global/notif_global/notifikasi_peringatan";
|
||||
import {
|
||||
AspectRatio,
|
||||
@@ -19,12 +20,9 @@ import {
|
||||
Image,
|
||||
Paper,
|
||||
Stack,
|
||||
Text,
|
||||
TextInput,
|
||||
Title,
|
||||
} from "@mantine/core";
|
||||
import { IconCamera } from "@tabler/icons-react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import Map, {
|
||||
AttributionControl,
|
||||
@@ -32,15 +30,9 @@ import Map, {
|
||||
NavigationControl,
|
||||
ScaleControl,
|
||||
} from "react-map-gl";
|
||||
import { map_funEditMap } from "../fun/edit/fun_edit_map";
|
||||
import { ComponentMap_ButtonUpdateDataMap } from "../_component";
|
||||
import { defaultMapZoom } from "../lib/default_lat_long";
|
||||
import { MODEL_MAP } from "../lib/interface";
|
||||
import { APIs } from "@/app/lib";
|
||||
import {
|
||||
ComponentGlobal_BoxUploadImage,
|
||||
ComponentGlobal_LoadImage,
|
||||
} from "@/app_modules/_global/component";
|
||||
import { ComponentMap_ButtonUpdateDataMap } from "../_component";
|
||||
|
||||
export function UiMap_EditMap({
|
||||
mapboxToken,
|
||||
|
||||
Reference in New Issue
Block a user