feat
Desc: - Fitur crowdfunding - Fitur Investasi - Fitur tambah investasi No issue
This commit is contained in:
54
src/app_modules/component/header_tamplate.tsx
Normal file
54
src/app_modules/component/header_tamplate.tsx
Normal file
@@ -0,0 +1,54 @@
|
||||
"use client";
|
||||
|
||||
import { Header, Group, ActionIcon, Text } from "@mantine/core";
|
||||
import { IconArrowLeft } from "@tabler/icons-react";
|
||||
import { useRouter } from "next/navigation";
|
||||
|
||||
export default function HeaderTamplate({
|
||||
route,
|
||||
route2,
|
||||
title,
|
||||
icon,
|
||||
}: {
|
||||
route?: any;
|
||||
route2?: any;
|
||||
title: string;
|
||||
icon?: any;
|
||||
}) {
|
||||
const router = useRouter();
|
||||
return (
|
||||
<>
|
||||
<Header height={50}>
|
||||
<Group h={50} position="apart" px={"md"}>
|
||||
<ActionIcon
|
||||
variant="transparent"
|
||||
onClick={() => {
|
||||
if (route === null || route === undefined) {
|
||||
return router.back();
|
||||
} else {
|
||||
return router.push(route);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<IconArrowLeft />
|
||||
</ActionIcon>
|
||||
<Text>{title}</Text>
|
||||
{(() => {
|
||||
if (route2 === null ||route2 === undefined) {
|
||||
return <ActionIcon disabled variant="transparent"></ActionIcon>;
|
||||
} else {
|
||||
return (
|
||||
<ActionIcon
|
||||
variant="transparent"
|
||||
onClick={() => router.push(route2)}
|
||||
>
|
||||
{icon}
|
||||
</ActionIcon>
|
||||
);
|
||||
}
|
||||
})()}
|
||||
</Group>
|
||||
</Header>
|
||||
</>
|
||||
);
|
||||
}
|
||||
5
src/app_modules/crowd/index.ts
Normal file
5
src/app_modules/crowd/index.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import MainCrowd from "./main/view";
|
||||
import LayoutMainCrowd from "./main/layout";
|
||||
import SplashCrowd from "./splash/view";
|
||||
|
||||
export {MainCrowd,LayoutMainCrowd, SplashCrowd}
|
||||
24
src/app_modules/crowd/main/layout.tsx
Normal file
24
src/app_modules/crowd/main/layout.tsx
Normal file
@@ -0,0 +1,24 @@
|
||||
"use client";
|
||||
|
||||
import HeaderTamplate from "@/app_modules/component/header_tamplate";
|
||||
import { ActionIcon, AppShell, Group, Header, Text } from "@mantine/core";
|
||||
import { IconArrowLeft } from "@tabler/icons-react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import React from "react";
|
||||
|
||||
export default function LayoutMainCrowd({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
const router = useRouter();
|
||||
return (
|
||||
<>
|
||||
<AppShell
|
||||
header={<HeaderTamplate route="/dev/home" title="Crowd Funding" />}
|
||||
>
|
||||
{children}
|
||||
</AppShell>
|
||||
</>
|
||||
);
|
||||
}
|
||||
33
src/app_modules/crowd/main/view.tsx
Normal file
33
src/app_modules/crowd/main/view.tsx
Normal file
@@ -0,0 +1,33 @@
|
||||
"use client";
|
||||
|
||||
import { Button, Center, Stack, Text, Title } from "@mantine/core";
|
||||
import { useRouter } from "next/navigation";
|
||||
import toast from "react-simple-toasts";
|
||||
|
||||
export default function MainCrowd() {
|
||||
const router = useRouter();
|
||||
return (
|
||||
<>
|
||||
<Center>
|
||||
<Stack>
|
||||
<Text>Selamat datang di</Text>
|
||||
<Text>HIPMI Crowd Funding</Text>
|
||||
<Button
|
||||
w={300}
|
||||
bg={"green"}
|
||||
onClick={() => router.push("/dev/investasi/main")}
|
||||
>
|
||||
Investasi
|
||||
</Button>
|
||||
<Button
|
||||
w={300}
|
||||
bg={"grape"}
|
||||
onClick={() => toast("Cooming Soon Feature...")}
|
||||
>
|
||||
Donasi
|
||||
</Button>
|
||||
</Stack>
|
||||
</Center>
|
||||
</>
|
||||
);
|
||||
}
|
||||
23
src/app_modules/crowd/splash/view.tsx
Normal file
23
src/app_modules/crowd/splash/view.tsx
Normal file
@@ -0,0 +1,23 @@
|
||||
"use client";
|
||||
|
||||
import { Center, Stack, Text, Title } from "@mantine/core";
|
||||
import { useShallowEffect } from "@mantine/hooks";
|
||||
import { useRouter } from "next/navigation";
|
||||
|
||||
export default function SplashCrowd() {
|
||||
const router = useRouter();
|
||||
|
||||
useShallowEffect(() => {
|
||||
setTimeout(() => router.push("/dev/crowd/main"), 2000);
|
||||
}, []);
|
||||
return (
|
||||
<>
|
||||
<Center h={"100vh"}>
|
||||
<Stack>
|
||||
<Text>Welcome to,</Text>
|
||||
<Title>CrowdFunding</Title>
|
||||
</Stack>
|
||||
</Center>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -47,48 +47,7 @@ import { funGetUserProfile } from "../fun/get_user_profile";
|
||||
import { USER_PROFILE } from "../models/user_profile";
|
||||
import AppNotif from "../notif";
|
||||
|
||||
const listHalaman = [
|
||||
{
|
||||
id: 1,
|
||||
name: "Forums",
|
||||
icon: <IconMessages size={50} />,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "Project Collaboration",
|
||||
icon: <IconAffiliate size={50} />,
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: "Voting",
|
||||
icon: <IconPackageImport size={50} />,
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: "Event",
|
||||
icon: <IconPresentation size={50} />,
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
name: "Crowd Funding",
|
||||
icon: <IconHeartHandshake size={50} />,
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
name: "Marketplace",
|
||||
icon: <IconShoppingBag size={50} />,
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
name: "Job Vacancy",
|
||||
icon: <IconBriefcase size={50} />,
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
name: "Business Maps",
|
||||
icon: <IconMap2 size={50} />,
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
// export const dynamic = "force-dynamic"
|
||||
// export const revalidate = 0
|
||||
@@ -97,6 +56,64 @@ export default function HomeView({ user }: { user: USER_PROFILE }) {
|
||||
const router = useRouter();
|
||||
const [stateUser, setStateUser] = useState(user);
|
||||
|
||||
const listHalaman = [
|
||||
{
|
||||
id: 1,
|
||||
name: "Forums",
|
||||
icon: <IconMessages size={50} />,
|
||||
link: ""
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "Project Collaboration",
|
||||
icon: <IconAffiliate size={50} />,
|
||||
link: ""
|
||||
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: "Voting",
|
||||
icon: <IconPackageImport size={50} />,
|
||||
link: ""
|
||||
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: "Event",
|
||||
icon: <IconPresentation size={50} />,
|
||||
link: ""
|
||||
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
name: "Crowd Funding",
|
||||
icon: <IconHeartHandshake size={50} />,
|
||||
link: `/dev/crowd/splash`
|
||||
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
name: "Marketplace",
|
||||
icon: <IconShoppingBag size={50} />,
|
||||
link: ""
|
||||
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
name: "Job Vacancy",
|
||||
icon: <IconBriefcase size={50} />,
|
||||
link: ""
|
||||
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
name: "Business Maps",
|
||||
icon: <IconMap2 size={50} />,
|
||||
link: ""
|
||||
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<>
|
||||
<Box>
|
||||
@@ -134,7 +151,13 @@ export default function HomeView({ user }: { user: USER_PROFILE }) {
|
||||
key={e.id}
|
||||
h={100}
|
||||
withBorder
|
||||
onClick={() => toast(e.name)}
|
||||
onClick={() => {
|
||||
if(e.link === ""){
|
||||
toast(e.name)
|
||||
} else {
|
||||
return router.push(e.link)
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Flex
|
||||
justify={"center"}
|
||||
|
||||
23
src/app_modules/investasi/create/layout.tsx
Normal file
23
src/app_modules/investasi/create/layout.tsx
Normal file
@@ -0,0 +1,23 @@
|
||||
"use client";
|
||||
|
||||
import HeaderTamplate from "@/app_modules/component/header_tamplate";
|
||||
import { AppShell } from "@mantine/core";
|
||||
import React from "react";
|
||||
|
||||
export default function InvestasiCreateLayout({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
<AppShell
|
||||
header={
|
||||
<HeaderTamplate route="/dev/investasi/main" title="Investasi Baru" />
|
||||
}
|
||||
>
|
||||
{children}
|
||||
</AppShell>
|
||||
</>
|
||||
);
|
||||
}
|
||||
209
src/app_modules/investasi/create/view.tsx
Normal file
209
src/app_modules/investasi/create/view.tsx
Normal file
@@ -0,0 +1,209 @@
|
||||
"use client";
|
||||
|
||||
import { ApiHipmi } from "@/app/lib/api";
|
||||
import { Warna } from "@/app/lib/warna";
|
||||
import { MODEL_ALL_MASTER } from "@/app_modules/models/model_AllMaster";
|
||||
import {
|
||||
AspectRatio,
|
||||
Box,
|
||||
Button,
|
||||
Center,
|
||||
FileButton,
|
||||
Group,
|
||||
Image,
|
||||
Select,
|
||||
TextInput,
|
||||
} from "@mantine/core";
|
||||
import { IconCamera } from "@tabler/icons-react";
|
||||
import _ from "lodash";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import { funCreateInvestasi } from "../fun/fun_create_investasi";
|
||||
import toast from "react-simple-toasts";
|
||||
|
||||
export default function InvestasiCreate({
|
||||
id,
|
||||
pencarianInvestor,
|
||||
periodeDeviden,
|
||||
pembagianDeviden,
|
||||
}: {
|
||||
id: string;
|
||||
pencarianInvestor: MODEL_ALL_MASTER[];
|
||||
periodeDeviden: MODEL_ALL_MASTER[];
|
||||
pembagianDeviden: MODEL_ALL_MASTER[];
|
||||
}) {
|
||||
const router = useRouter();
|
||||
const [fl, setFl] = useState<File | null>(null);
|
||||
const [img, setImg] = useState<any | null>();
|
||||
const [value, setValue] = useState({
|
||||
title: "",
|
||||
targetDana: "",
|
||||
hargaLembar: "",
|
||||
totalLembar: "",
|
||||
roi: "",
|
||||
pencarianInvestorId: "",
|
||||
periodeDevidenId: "",
|
||||
pembagianDevidenId: "",
|
||||
});
|
||||
|
||||
async function onSubmit() {
|
||||
const body = {
|
||||
authorId: id,
|
||||
title: value.title,
|
||||
targetDana: value.targetDana,
|
||||
hargaLembar: value.hargaLembar,
|
||||
totalLembar: value.totalLembar,
|
||||
roi: value.roi,
|
||||
masterPeriodeDevidenId: value.periodeDevidenId,
|
||||
masterPembagianDevidenId: value.pembagianDevidenId,
|
||||
masterPencarianInvestorId: value.pencarianInvestorId,
|
||||
};
|
||||
if (_.values(body).includes("")) return toast("Lengkapi data");
|
||||
if (!fl) return toast("File Kosong");
|
||||
|
||||
const fd = new FormData();
|
||||
fd.append("file", fl);
|
||||
|
||||
await funCreateInvestasi(fd, body as any).then((res) => {
|
||||
if (res.status === 201) {
|
||||
toast(res.message);
|
||||
return router.push("/dev/investasi/main")
|
||||
} else {
|
||||
return toast(res.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Box>
|
||||
<AspectRatio ratio={16 / 9}>
|
||||
{img ? (
|
||||
<Image alt="" src={img} />
|
||||
) : (
|
||||
<Image alt="" src={"/aset/no-img.png"} />
|
||||
)}
|
||||
</AspectRatio>
|
||||
<Group position="center" mt={"md"}>
|
||||
<FileButton
|
||||
onChange={async (files: any) => {
|
||||
const buffer = URL.createObjectURL(
|
||||
new Blob([new Uint8Array(await files.arrayBuffer())])
|
||||
);
|
||||
setImg(buffer);
|
||||
setFl(files);
|
||||
}}
|
||||
accept="image/png,image/jpeg"
|
||||
>
|
||||
{(props) => (
|
||||
<Button
|
||||
{...props}
|
||||
w={350}
|
||||
radius={50}
|
||||
// bg={Warna.biru}
|
||||
// onClick={() => router.push("/dev/investasi/upload")}
|
||||
>
|
||||
<IconCamera />
|
||||
</Button>
|
||||
)}
|
||||
</FileButton>
|
||||
</Group>
|
||||
|
||||
<Center>
|
||||
<Box mt={"md"} w={350}>
|
||||
<TextInput
|
||||
label="Judul Proyek"
|
||||
onChange={(val) => {
|
||||
setValue({
|
||||
...value,
|
||||
title: val.target.value,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<TextInput
|
||||
label="Dana Dibutuhan"
|
||||
type="number"
|
||||
onChange={(val) => {
|
||||
setValue({
|
||||
...value,
|
||||
targetDana: val.target.value,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<TextInput
|
||||
label="Harga Per Lember"
|
||||
type="number"
|
||||
onChange={(val) => {
|
||||
setValue({
|
||||
...value,
|
||||
hargaLembar: val.target.value,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<TextInput
|
||||
label="Total Lembar"
|
||||
type="number"
|
||||
onChange={(val) => {
|
||||
setValue({
|
||||
...value,
|
||||
totalLembar: val.target.value,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<TextInput
|
||||
label="Rasio Keuntungan / ROI"
|
||||
type="number"
|
||||
onChange={(val) => {
|
||||
setValue({
|
||||
...value,
|
||||
roi: val.target.value,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<Select
|
||||
label="Pencarian Investor"
|
||||
data={pencarianInvestor.map((e) => ({
|
||||
value: e.id,
|
||||
label: e.name,
|
||||
}))}
|
||||
onChange={(val) => {
|
||||
setValue({
|
||||
...(value as any),
|
||||
pencarianInvestorId: val,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<Select
|
||||
label="Periode Deviden"
|
||||
data={periodeDeviden.map((e) => ({ value: e.id, label: e.name }))}
|
||||
onChange={(val) => {
|
||||
setValue({
|
||||
...(value as any),
|
||||
periodeDevidenId: val,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<Select
|
||||
label="Pembagian Deviden"
|
||||
data={pembagianDeviden.map((e) => ({
|
||||
value: e.id,
|
||||
label: e.name,
|
||||
}))}
|
||||
onChange={(val) => {
|
||||
setValue({
|
||||
...(value as any),
|
||||
pembagianDevidenId: val,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
</Center>
|
||||
<Center my={"lg"}>
|
||||
<Button w={200} radius={50} onClick={() => onSubmit()}>
|
||||
Simpan
|
||||
</Button>
|
||||
</Center>
|
||||
</Box>
|
||||
</>
|
||||
);
|
||||
}
|
||||
74
src/app_modules/investasi/fun/fun_create_investasi.ts
Normal file
74
src/app_modules/investasi/fun/fun_create_investasi.ts
Normal file
@@ -0,0 +1,74 @@
|
||||
"use server";
|
||||
|
||||
import prisma from "@/app/lib/prisma";
|
||||
import _ from "lodash";
|
||||
import { v4 } from "uuid";
|
||||
import fs from "fs";
|
||||
import { INVESTASI } from "@/app_modules/models/investasi";
|
||||
import { revalidatePath } from "next/cache";
|
||||
|
||||
export async function funCreateInvestasi(formData: FormData, data: INVESTASI) {
|
||||
const file: any = formData.get("file");
|
||||
// console.log(file)
|
||||
const fName = file.name;
|
||||
const fExt = _.lowerCase(file.name.split(".").pop());
|
||||
const fRandomName = v4(fName) + "." + fExt;
|
||||
|
||||
const upload = await prisma.images.create({
|
||||
data: {
|
||||
url: fRandomName,
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
url: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (!upload)
|
||||
return {
|
||||
status: 400,
|
||||
message: "File Kosong",
|
||||
};
|
||||
|
||||
// if (upload) {
|
||||
// await prisma.investasi.update({
|
||||
// where: {
|
||||
// authorId: data.authorId,
|
||||
// },
|
||||
// data: {
|
||||
// imagesId: upload.id,
|
||||
// },
|
||||
// });
|
||||
// }
|
||||
|
||||
const upFolder = Buffer.from(await file.arrayBuffer());
|
||||
fs.writeFileSync(`./public/investasi/${upload.url}`, upFolder);
|
||||
|
||||
const createInvest = await prisma.investasi.create({
|
||||
data: {
|
||||
authorId: data.authorId,
|
||||
title: data.title,
|
||||
targetDana: data.targetDana,
|
||||
hargaLembar: data.hargaLembar,
|
||||
totalLembar: data.totalLembar,
|
||||
roi: data.roi,
|
||||
masterPembagianDevidenId: data.masterPembagianDevidenId,
|
||||
masterPeriodeDevidenId: data.masterPeriodeDevidenId,
|
||||
masterPencarianInvestorId: data.masterPencarianInvestorId,
|
||||
imagesId: upload.id,
|
||||
},
|
||||
});
|
||||
|
||||
if (!createInvest)
|
||||
return {
|
||||
status: 400,
|
||||
message: "Gagal Disimpan",
|
||||
};
|
||||
|
||||
revalidatePath("/dev/investasi/main");
|
||||
|
||||
return {
|
||||
status: 201,
|
||||
message: "Berhasil Disimpan",
|
||||
};
|
||||
}
|
||||
13
src/app_modules/investasi/fun/get_list_all_investasi.ts
Normal file
13
src/app_modules/investasi/fun/get_list_all_investasi.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
"use server";
|
||||
|
||||
import prisma from "@/app/lib/prisma";
|
||||
|
||||
export async function getListAllInvestasi() {
|
||||
const data = await prisma.investasi.findMany({
|
||||
orderBy: {
|
||||
createdAt: "desc"
|
||||
}
|
||||
});
|
||||
|
||||
return data;
|
||||
}
|
||||
15
src/app_modules/investasi/fun/get_pembagian_deviden.ts
Normal file
15
src/app_modules/investasi/fun/get_pembagian_deviden.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
"use server";
|
||||
|
||||
import prisma from "@/app/lib/prisma";
|
||||
|
||||
export default async function getPembagianDeviden() {
|
||||
const data = await prisma.masterPembagianDeviden.findMany({
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
active: true,
|
||||
},
|
||||
});
|
||||
|
||||
return data;
|
||||
}
|
||||
15
src/app_modules/investasi/fun/get_pencarian_investor.ts
Normal file
15
src/app_modules/investasi/fun/get_pencarian_investor.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
"use server";
|
||||
|
||||
import prisma from "@/app/lib/prisma";
|
||||
|
||||
export default async function getPencarianInvestor() {
|
||||
const data = await prisma.masterPencarianInvestor.findMany({
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
active: true
|
||||
}
|
||||
});
|
||||
|
||||
return data;
|
||||
}
|
||||
15
src/app_modules/investasi/fun/get_periode_deviden.ts
Normal file
15
src/app_modules/investasi/fun/get_periode_deviden.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
"use server";
|
||||
|
||||
import prisma from "@/app/lib/prisma";
|
||||
|
||||
export default async function getPeriodeDeviden() {
|
||||
const data = await prisma.masterPeriodeDeviden.findMany({
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
active: true,
|
||||
},
|
||||
});
|
||||
|
||||
return data;
|
||||
}
|
||||
15
src/app_modules/investasi/index.ts
Normal file
15
src/app_modules/investasi/index.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import MainInvestasi from "./main/view";
|
||||
import LayoutMainInvestasi from "./main/layout";
|
||||
import InvestasiCreate from "./create/view";
|
||||
import InvestasiCreateLayout from "./create/layout";
|
||||
import UploadGambarInvestasi from "./upload/view";
|
||||
import LayoutUploadGambarInvestasi from "./upload/layout";
|
||||
|
||||
export {
|
||||
MainInvestasi,
|
||||
LayoutMainInvestasi,
|
||||
InvestasiCreate,
|
||||
InvestasiCreateLayout,
|
||||
UploadGambarInvestasi,
|
||||
LayoutUploadGambarInvestasi,
|
||||
};
|
||||
69
src/app_modules/investasi/main/layout.tsx
Normal file
69
src/app_modules/investasi/main/layout.tsx
Normal file
@@ -0,0 +1,69 @@
|
||||
"use client";
|
||||
|
||||
import HeaderTamplate from "@/app_modules/component/header_tamplate";
|
||||
import {
|
||||
ActionIcon,
|
||||
AppShell,
|
||||
Center,
|
||||
Flex,
|
||||
Footer,
|
||||
Grid,
|
||||
Group,
|
||||
Stack,
|
||||
Text,
|
||||
} from "@mantine/core";
|
||||
import {
|
||||
IconChartHistogram,
|
||||
IconChartPieFilled,
|
||||
IconPencilPlus,
|
||||
} from "@tabler/icons-react";
|
||||
import React from "react";
|
||||
|
||||
export default function LayoutMainInvestasi({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
<AppShell
|
||||
header={
|
||||
<HeaderTamplate
|
||||
route="/dev/crowd/main"
|
||||
title="Investasi"
|
||||
icon={<IconPencilPlus />}
|
||||
route2={"/dev/investasi/create"}
|
||||
/>
|
||||
}
|
||||
footer={
|
||||
<Footer height={70} bg={"dark"}>
|
||||
<Grid align="center" h={60} pt={"xs"}>
|
||||
<Grid.Col span={6}>
|
||||
<Center>
|
||||
<Flex direction={"column"} align={"center"} w={"100%"}>
|
||||
<ActionIcon variant="transparent">
|
||||
<IconChartHistogram />
|
||||
</ActionIcon>
|
||||
<Text c={"white"}>Bursa</Text>
|
||||
</Flex>
|
||||
</Center>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={6}>
|
||||
<Center>
|
||||
<Flex direction={"column"} align={"center"} w={"100%"}>
|
||||
<ActionIcon variant="transparent">
|
||||
<IconChartPieFilled />
|
||||
</ActionIcon>
|
||||
<Text c={"white"}>Portofolio</Text>
|
||||
</Flex>
|
||||
</Center>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
</Footer>
|
||||
}
|
||||
>
|
||||
{children}
|
||||
</AppShell>
|
||||
</>
|
||||
);
|
||||
}
|
||||
104
src/app_modules/investasi/main/view.tsx
Normal file
104
src/app_modules/investasi/main/view.tsx
Normal file
@@ -0,0 +1,104 @@
|
||||
"use client";
|
||||
|
||||
import { ApiHipmi } from "@/app/lib/api";
|
||||
import { INVESTASI } from "@/app_modules/models/investasi";
|
||||
import { MODEL_ALL_MASTER } from "@/app_modules/models/model_AllMaster";
|
||||
import {
|
||||
AspectRatio,
|
||||
Box,
|
||||
Button,
|
||||
Card,
|
||||
CardSection,
|
||||
Divider,
|
||||
Grid,
|
||||
Group,
|
||||
Image,
|
||||
Paper,
|
||||
Slider,
|
||||
Stack,
|
||||
Text,
|
||||
Title,
|
||||
} from "@mantine/core";
|
||||
import { useRouter } from "next/navigation";
|
||||
|
||||
export default function MainInvestasi({
|
||||
listData,
|
||||
pencarianInvestor,
|
||||
periodeDeviden,
|
||||
pembagianDeviden,
|
||||
}: {
|
||||
listData: INVESTASI[];
|
||||
pencarianInvestor: MODEL_ALL_MASTER[];
|
||||
periodeDeviden: MODEL_ALL_MASTER[];
|
||||
pembagianDeviden: MODEL_ALL_MASTER[];
|
||||
}) {
|
||||
const router = useRouter();
|
||||
return (
|
||||
<>
|
||||
<pre>{/* {JSON.stringify(listData, null, 2)} */}</pre>
|
||||
{listData.map((e) => (
|
||||
<Card key={e.id} p={"md"} withBorder mb={"lg"}>
|
||||
<CardSection p={"xs"}>
|
||||
<AspectRatio ratio={16 / 9}>
|
||||
{e.imagesId ? (
|
||||
<Image alt="" src={`/api/investasi/gambar/${e.imagesId}`} />
|
||||
) : (
|
||||
<Image alt="" src={"/aset/no-img.png"} />
|
||||
)}
|
||||
</AspectRatio>
|
||||
</CardSection>
|
||||
|
||||
<CardSection p={"lg"}>
|
||||
<Box mt={"md"}>
|
||||
<Slider
|
||||
size={10}
|
||||
labelAlwaysOn
|
||||
marks={[
|
||||
// { value: 25, label: '25%' },
|
||||
// { value: 50, label: '50%' },
|
||||
// { value: 75, label: '75%' },
|
||||
{ value: 100, label: "100%" },
|
||||
]}
|
||||
/>
|
||||
<Title order={4}>{e.title}</Title>
|
||||
</Box>
|
||||
<Box mt={"md"}>
|
||||
<Grid>
|
||||
<Grid.Col span={6}>
|
||||
<Stack>
|
||||
<Box>
|
||||
<Text>Dana Dibutuhkan</Text>
|
||||
<Text>Rp. {e.targetDana}</Text>
|
||||
</Box>
|
||||
<Box>
|
||||
<Text>Harga Per Lembar</Text>
|
||||
<Text>Rp. {e.hargaLembar}</Text>
|
||||
</Box>
|
||||
</Stack>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={6}>
|
||||
<Stack>
|
||||
<Box>
|
||||
<Text>ROI</Text>
|
||||
<Text>{e.roi}%</Text>
|
||||
</Box>
|
||||
<Box>
|
||||
<Text>Total Lembar</Text>
|
||||
<Text>{e.totalLembar}</Text>
|
||||
</Box>
|
||||
</Stack>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
</Box>
|
||||
</CardSection>
|
||||
<Divider />
|
||||
<CardSection p={"md"}>
|
||||
<Group position="right">
|
||||
<Text>Selesai</Text>
|
||||
</Group>
|
||||
</CardSection>
|
||||
</Card>
|
||||
))}
|
||||
</>
|
||||
);
|
||||
}
|
||||
19
src/app_modules/investasi/upload/layout.tsx
Normal file
19
src/app_modules/investasi/upload/layout.tsx
Normal file
@@ -0,0 +1,19 @@
|
||||
"use client";
|
||||
|
||||
import HeaderTamplate from "@/app_modules/component/header_tamplate";
|
||||
import { AppShell } from "@mantine/core";
|
||||
import React from "react";
|
||||
|
||||
export default function LayoutUploadGambarInvestasi({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
<AppShell header={<HeaderTamplate title="Upload Gambar Investasi" />}>
|
||||
{children}
|
||||
</AppShell>
|
||||
</>
|
||||
);
|
||||
}
|
||||
39
src/app_modules/investasi/upload/view.tsx
Normal file
39
src/app_modules/investasi/upload/view.tsx
Normal file
@@ -0,0 +1,39 @@
|
||||
"use client";
|
||||
|
||||
import { Warna } from "@/app/lib/warna";
|
||||
import {
|
||||
AspectRatio,
|
||||
Button,
|
||||
Center,
|
||||
Divider,
|
||||
FileButton,
|
||||
Group,
|
||||
Image,
|
||||
Paper,
|
||||
Text,
|
||||
Title,
|
||||
} from "@mantine/core";
|
||||
import { useState } from "react";
|
||||
|
||||
export default function UploadGambarInvestasi() {
|
||||
const [img, setImg] = useState<any | null>();
|
||||
return (
|
||||
<>
|
||||
<Group position="center">
|
||||
<FileButton
|
||||
onChange={async (files : any) => {
|
||||
const buffer = URL.createObjectURL(
|
||||
new Blob([new Uint8Array( await files.arrayBuffer())])
|
||||
);
|
||||
setImg(buffer);
|
||||
}}
|
||||
accept="image/png,image/jpeg"
|
||||
>
|
||||
{(props) => <Button {...props}>Upload image</Button>}
|
||||
</FileButton>
|
||||
</Group>
|
||||
|
||||
{img && <Image alt="" src={img}/>}
|
||||
</>
|
||||
);
|
||||
}
|
||||
13
src/app_modules/models/investasi.ts
Normal file
13
src/app_modules/models/investasi.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
export interface INVESTASI {
|
||||
id: string
|
||||
authorId: string;
|
||||
title: string;
|
||||
targetDana: string;
|
||||
hargaLembar: string;
|
||||
totalLembar: string;
|
||||
roi: string;
|
||||
masterPeriodeDevidenId: string;
|
||||
masterPembagianDevidenId: string;
|
||||
masterPencarianInvestorId: string;
|
||||
imagesId: string
|
||||
}
|
||||
5
src/app_modules/models/model_AllMaster.ts
Normal file
5
src/app_modules/models/model_AllMaster.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export interface MODEL_ALL_MASTER {
|
||||
id: string,
|
||||
name: string,
|
||||
active: boolean,
|
||||
}
|
||||
Reference in New Issue
Block a user