Fix: Investasi

Deskripsi:
- Upload gambar investasi ke storage wibu
- Upload bukti transfer ke storage wibu
# No Issue
This commit is contained in:
2024-10-15 11:06:14 +08:00
parent 3d6ec1410d
commit 5ff74b00f5
121 changed files with 4022 additions and 1139 deletions

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

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

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

View File

@@ -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 };

View File

@@ -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>

View File

@@ -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 (

View File

@@ -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>

View File

@@ -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>

View File

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

View File

@@ -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>

View File

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

View File

@@ -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"