feat
Desc: - Fitur crowdfunding - Fitur Investasi - Fitur tambah investasi No issue
@@ -12,6 +12,7 @@
|
||||
"@emotion/react": "^11.11.1",
|
||||
"@emotion/server": "^11.11.0",
|
||||
"@mantine/core": "^6.0.17",
|
||||
"@mantine/dropzone": "^7.1.3",
|
||||
"@mantine/hooks": "^6.0.17",
|
||||
"@mantine/next": "^6.0.17",
|
||||
"@prisma/client": "^5.0.0",
|
||||
|
||||
@@ -21,6 +21,7 @@ model User {
|
||||
masterUserRoleId String @default("1")
|
||||
UserSession UserSession?
|
||||
Profile Profile?
|
||||
Investasi Investasi[]
|
||||
}
|
||||
|
||||
model MasterUserRole {
|
||||
@@ -60,12 +61,13 @@ model Profile {
|
||||
}
|
||||
|
||||
model Images {
|
||||
id String @id @default(cuid())
|
||||
id String @id @default(cuid())
|
||||
url String
|
||||
active Boolean @default(true)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @default(now()) @updatedAt
|
||||
active Boolean @default(true)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @default(now()) @updatedAt
|
||||
Profile Profile?
|
||||
Investasi Investasi?
|
||||
}
|
||||
|
||||
model Katalog {
|
||||
@@ -73,12 +75,12 @@ model Katalog {
|
||||
namaBisnis String
|
||||
alamatKantor String
|
||||
tlpn String
|
||||
deskripsi String
|
||||
deskripsi String
|
||||
active Boolean @default(true)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @default(now()) @updatedAt
|
||||
Profile Profile? @relation(fields: [profileId], references: [id])
|
||||
profileId String?
|
||||
profileId String?
|
||||
MasterBidangBisnis MasterBidangBisnis @relation(fields: [masterBidangBisnisId], references: [id])
|
||||
masterBidangBisnisId String
|
||||
}
|
||||
@@ -91,3 +93,54 @@ model MasterBidangBisnis {
|
||||
updatedAt DateTime @default(now()) @updatedAt
|
||||
Katalog Katalog[]
|
||||
}
|
||||
|
||||
model Investasi {
|
||||
id String @id @default(cuid())
|
||||
title String
|
||||
targetDana String
|
||||
hargaLembar String
|
||||
totalLembar String
|
||||
roi String
|
||||
active Boolean @default(true)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @default(now()) @updatedAt
|
||||
author User? @relation(fields: [authorId], references: [id])
|
||||
authorId String?
|
||||
|
||||
MasterPeriodeDeviden MasterPeriodeDeviden? @relation(fields: [masterPeriodeDevidenId], references: [id])
|
||||
masterPeriodeDevidenId String?
|
||||
MasterPembagianDeviden MasterPembagianDeviden? @relation(fields: [masterPembagianDevidenId], references: [id])
|
||||
masterPembagianDevidenId String?
|
||||
MasterPencarianInvestor MasterPencarianInvestor? @relation(fields: [masterPencarianInvestorId], references: [id])
|
||||
masterPencarianInvestorId String?
|
||||
|
||||
ImageInvestasi Images? @relation(fields: [imagesId], references: [id])
|
||||
imagesId String? @unique
|
||||
}
|
||||
|
||||
model MasterPencarianInvestor {
|
||||
id String @id @default(cuid())
|
||||
name String
|
||||
active Boolean @default(true)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @default(now()) @updatedAt
|
||||
investasi Investasi[]
|
||||
}
|
||||
|
||||
model MasterPeriodeDeviden {
|
||||
id String @id @default(cuid())
|
||||
name String
|
||||
active Boolean @default(true)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @default(now()) @updatedAt
|
||||
investasi Investasi[]
|
||||
}
|
||||
|
||||
model MasterPembagianDeviden {
|
||||
id String @id @default(cuid())
|
||||
name String
|
||||
active Boolean @default(true)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @default(now()) @updatedAt
|
||||
investasi Investasi[]
|
||||
}
|
||||
|
||||
BIN
public/aset/no-img.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
public/investasi/4a673439-52c3-40ce-82fc-a9125083b040.jpeg
Normal file
|
After Width: | Height: | Size: 156 KiB |
BIN
public/investasi/5b77a1bf-0b2a-47d1-ba6a-adcd8743f80d.jpeg
Normal file
|
After Width: | Height: | Size: 217 KiB |
BIN
public/investasi/6c716813-1dd4-46b4-be88-06e189121572.png
Normal file
|
After Width: | Height: | Size: 202 KiB |
BIN
public/investasi/875ba470-cd51-4783-959a-dffb58f0aa3d.jpeg
Normal file
|
After Width: | Height: | Size: 156 KiB |
BIN
public/investasi/b55259ad-372e-4da0-8988-231574515b71.jpeg
Normal file
|
After Width: | Height: | Size: 132 KiB |
BIN
public/investasi/c66a818f-45f0-4588-b8fd-22b769196c38.jpeg
Normal file
|
After Width: | Height: | Size: 217 KiB |
BIN
public/investasi/c8e15676-59ea-480d-b177-6a53defacb55.jpeg
Normal file
|
After Width: | Height: | Size: 439 KiB |
BIN
public/investasi/cecefba0-2061-4598-91dd-b6dbca552b1d.jpeg
Normal file
|
After Width: | Height: | Size: 156 KiB |
39
src/app/api/investasi/gambar/[id]/route.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import fs from "fs";
|
||||
import prisma from "@/app/lib/prisma";
|
||||
|
||||
export async function GET(
|
||||
req: NextRequest,
|
||||
{ params }: { params: { id: string } }
|
||||
) {
|
||||
|
||||
|
||||
console.log(params.id)
|
||||
const data = await prisma.images.findUnique({
|
||||
where: {
|
||||
id: params.id,
|
||||
},
|
||||
select: {
|
||||
url: true,
|
||||
},
|
||||
});
|
||||
|
||||
console.log(data)
|
||||
|
||||
// return data
|
||||
|
||||
if (!fs.existsSync(`./public/investasi/${data?.url}`)) {
|
||||
const fl = fs.readFileSync(`./public/aset/no-img.png`);
|
||||
return new NextResponse(fl, {
|
||||
headers: {
|
||||
"Content-Type": "image/png",
|
||||
},
|
||||
});
|
||||
}
|
||||
const fl = fs.readFileSync(`./public/investasi/${data?.url}`);
|
||||
return new NextResponse(fl, {
|
||||
headers: {
|
||||
"Content-Type": "image/png",
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -2,6 +2,9 @@ import prisma from "@/app/lib/prisma";
|
||||
import { NextResponse } from "next/server";
|
||||
import userRole from "../../../bin/seeder/user_role.json";
|
||||
import bidangBisnis from "../../../bin/seeder/bidang_bisnis.json";
|
||||
import pencarianInvestor from "./../../../bin/seeder/investasi/pencarian_investor.json";
|
||||
import periodeDeviden from "./../../../bin/seeder/investasi/periode_deviden.json";
|
||||
import pembagianDeviden from "./../../../bin/seeder/investasi/pembagian_deviden.json";
|
||||
|
||||
export async function GET(req: Request) {
|
||||
const dev = new URL(req.url).searchParams.get("dev");
|
||||
@@ -37,6 +40,55 @@ export async function GET(req: Request) {
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
for (let i of pencarianInvestor) {
|
||||
await prisma.masterPencarianInvestor.upsert({
|
||||
where: {
|
||||
id: i.id.toString(),
|
||||
},
|
||||
update: {
|
||||
id: i.id.toString(),
|
||||
name: i.name,
|
||||
},
|
||||
create: {
|
||||
id: i.id.toString(),
|
||||
name: i.name,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
for (let i of pembagianDeviden) {
|
||||
await prisma.masterPembagianDeviden.upsert({
|
||||
where: {
|
||||
id: i.id.toString(),
|
||||
},
|
||||
update: {
|
||||
id: i.id.toString(),
|
||||
name: i.name,
|
||||
},
|
||||
create: {
|
||||
id: i.id.toString(),
|
||||
name: i.name,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
for (let i of periodeDeviden) {
|
||||
await prisma.masterPeriodeDeviden.upsert({
|
||||
where: {
|
||||
id: i.id.toString(),
|
||||
},
|
||||
update: {
|
||||
id: i.id.toString(),
|
||||
name: i.name,
|
||||
},
|
||||
create: {
|
||||
id: i.id.toString(),
|
||||
name: i.name,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return NextResponse.json({ success: true });
|
||||
}
|
||||
|
||||
|
||||
14
src/app/dev/crowd/main/layout.tsx
Normal file
@@ -0,0 +1,14 @@
|
||||
import { LayoutMainCrowd } from "@/app_modules/crowd";
|
||||
import React from "react";
|
||||
|
||||
export default async function Layout({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
<LayoutMainCrowd>{children}</LayoutMainCrowd>
|
||||
</>
|
||||
);
|
||||
}
|
||||
9
src/app/dev/crowd/main/page.tsx
Normal file
@@ -0,0 +1,9 @@
|
||||
import { MainCrowd } from "@/app_modules/crowd";
|
||||
|
||||
export default async function Page() {
|
||||
return (
|
||||
<>
|
||||
<MainCrowd />
|
||||
</>
|
||||
);
|
||||
}
|
||||
7
src/app/dev/crowd/splash/page.tsx
Normal file
@@ -0,0 +1,7 @@
|
||||
import { SplashCrowd } from "@/app_modules/crowd";
|
||||
|
||||
export default async function Page() {
|
||||
return <>
|
||||
<SplashCrowd/>
|
||||
</>
|
||||
}
|
||||
14
src/app/dev/investasi/create/layout.tsx
Normal file
@@ -0,0 +1,14 @@
|
||||
import { InvestasiCreateLayout } from "@/app_modules/investasi";
|
||||
import React from "react";
|
||||
|
||||
export default async function Layout({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
<InvestasiCreateLayout>{children}</InvestasiCreateLayout>
|
||||
</>
|
||||
);
|
||||
}
|
||||
37
src/app/dev/investasi/create/page.tsx
Normal file
@@ -0,0 +1,37 @@
|
||||
import { InvestasiCreate } from "@/app_modules/investasi";
|
||||
import { unsealData } from "iron-session";
|
||||
import { cookies } from "next/headers";
|
||||
import yaml from "yaml";
|
||||
import fs from "fs";
|
||||
import { funCreateInvestasi } from "@/app_modules/investasi/fun/fun_create_investasi";
|
||||
import getPencarianInvestor from "@/app_modules/investasi/fun/get_pencarian_investor";
|
||||
import getPeriodeDeviden from "@/app_modules/investasi/fun/get_periode_deviden";
|
||||
import getPembagianDeviden from "@/app_modules/investasi/fun/get_pembagian_deviden";
|
||||
|
||||
const config = yaml.parse(fs.readFileSync("config.yaml").toString());
|
||||
|
||||
export default async function Page() {
|
||||
const c = cookies().get("ssn");
|
||||
const tkn = JSON.parse(
|
||||
await unsealData(c?.value as string, {
|
||||
password: config.server.password,
|
||||
})
|
||||
);
|
||||
|
||||
const pencarianInvestor = await getPencarianInvestor();
|
||||
const periodeDeviden = await getPeriodeDeviden();
|
||||
const pembagianDeviden = await getPembagianDeviden();
|
||||
|
||||
// console.log(pembagianDeviden)
|
||||
|
||||
return (
|
||||
<>
|
||||
<InvestasiCreate
|
||||
id={tkn.id}
|
||||
pencarianInvestor={pencarianInvestor as any}
|
||||
periodeDeviden={periodeDeviden as any}
|
||||
pembagianDeviden={pembagianDeviden as any}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
8
src/app/dev/investasi/main/layout.tsx
Normal file
@@ -0,0 +1,8 @@
|
||||
import { LayoutMainInvestasi } from "@/app_modules/investasi";
|
||||
import React from "react";
|
||||
|
||||
export default async function Layout({children}: {children: React.ReactNode}) {
|
||||
return <>
|
||||
<LayoutMainInvestasi>{children}</LayoutMainInvestasi>
|
||||
</>
|
||||
}
|
||||
24
src/app/dev/investasi/main/page.tsx
Normal file
@@ -0,0 +1,24 @@
|
||||
import { MainInvestasi } from "@/app_modules/investasi";
|
||||
import { getListAllInvestasi } from "@/app_modules/investasi/fun/get_list_all_investasi";
|
||||
import getPembagianDeviden from "@/app_modules/investasi/fun/get_pembagian_deviden";
|
||||
import getPencarianInvestor from "@/app_modules/investasi/fun/get_pencarian_investor";
|
||||
import getPeriodeDeviden from "@/app_modules/investasi/fun/get_periode_deviden";
|
||||
|
||||
export default async function Page() {
|
||||
const data = await getListAllInvestasi()
|
||||
const pencarianInvestor = await getPencarianInvestor();
|
||||
const periodeDeviden = await getPeriodeDeviden();
|
||||
const pembagianDeviden = await getPembagianDeviden();
|
||||
|
||||
// console.log(data)
|
||||
return <>
|
||||
<MainInvestasi
|
||||
listData={data as any}
|
||||
pencarianInvestor={pencarianInvestor as any}
|
||||
periodeDeviden={periodeDeviden as any}
|
||||
pembagianDeviden={pembagianDeviden as any}
|
||||
|
||||
/>
|
||||
</>
|
||||
|
||||
}
|
||||
8
src/app/dev/investasi/upload/layout.tsx
Normal file
@@ -0,0 +1,8 @@
|
||||
import { LayoutUploadGambarInvestasi } from "@/app_modules/investasi";
|
||||
import React from "react";
|
||||
|
||||
export default async function Layout({children}: {children: React.ReactNode}) {
|
||||
return<>
|
||||
<LayoutUploadGambarInvestasi>{children}</LayoutUploadGambarInvestasi>
|
||||
</>
|
||||
}
|
||||
7
src/app/dev/investasi/upload/page.tsx
Normal file
@@ -0,0 +1,7 @@
|
||||
import { UploadGambarInvestasi } from "@/app_modules/investasi";
|
||||
|
||||
export default async function Page() {
|
||||
return<>
|
||||
<UploadGambarInvestasi/>
|
||||
</>
|
||||
}
|
||||
@@ -14,4 +14,7 @@ export const ApiHipmi = {
|
||||
|
||||
//Portofolio
|
||||
create_portofolio: "/api/portofolio/create",
|
||||
|
||||
//Investasi
|
||||
get_gambar_investasi: "/api/investasi/gambar"
|
||||
};
|
||||
|
||||
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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -0,0 +1,5 @@
|
||||
export interface MODEL_ALL_MASTER {
|
||||
id: string,
|
||||
name: string,
|
||||
active: boolean,
|
||||
}
|
||||
14
src/bin/seeder/investasi/pembagian_deviden.json
Normal file
@@ -0,0 +1,14 @@
|
||||
[
|
||||
{
|
||||
"id": 1,
|
||||
"name": "3 bulan"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "6 bulan"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "1 tahun"
|
||||
}
|
||||
]
|
||||
19
src/bin/seeder/investasi/pencarian_investor.json
Normal file
@@ -0,0 +1,19 @@
|
||||
[
|
||||
{
|
||||
"id": 1,
|
||||
"name": "30 hari"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "60 hari"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "90 hari"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "120 hari"
|
||||
}
|
||||
]
|
||||
|
||||
10
src/bin/seeder/investasi/periode_deviden.json
Normal file
@@ -0,0 +1,10 @@
|
||||
[
|
||||
{
|
||||
"id": 1,
|
||||
"name": "Selamanya"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "Satu tahun"
|
||||
}
|
||||
]
|
||||
14
yarn.lock
@@ -287,6 +287,13 @@
|
||||
react-remove-scroll "^2.5.5"
|
||||
react-textarea-autosize "8.3.4"
|
||||
|
||||
"@mantine/dropzone@^7.1.3":
|
||||
version "7.1.3"
|
||||
resolved "https://registry.yarnpkg.com/@mantine/dropzone/-/dropzone-7.1.3.tgz#02851a45fc7278b63f8b628f0fc35f75a6650563"
|
||||
integrity sha512-7MnXTtlQlL9Q0GluRUKv8AWFDfPv7jv74K+F08Y5bKiQHYR8OzIW4Pc+Vk4Ea9I8/EzoKLWarF0Bn2KkgoO4Lw==
|
||||
dependencies:
|
||||
react-dropzone-esm "15.0.1"
|
||||
|
||||
"@mantine/hooks@^6.0.17":
|
||||
version "6.0.17"
|
||||
resolved "https://registry.yarnpkg.com/@mantine/hooks/-/hooks-6.0.17.tgz#dc942c87e6dcfa14a70e4e4a162c22eeb4ff3724"
|
||||
@@ -2913,6 +2920,13 @@ react-dom@18.2.0:
|
||||
loose-envify "^1.1.0"
|
||||
scheduler "^0.23.0"
|
||||
|
||||
react-dropzone-esm@15.0.1:
|
||||
version "15.0.1"
|
||||
resolved "https://registry.yarnpkg.com/react-dropzone-esm/-/react-dropzone-esm-15.0.1.tgz#8c689638aaa9feb5b2a429dd565acfa6792263e5"
|
||||
integrity sha512-RdeGpqwHnoV/IlDFpQji7t7pTtlC2O1i/Br0LWkRZ9hYtLyce814S71h5NolnCZXsIN5wrZId6+8eQj2EBnEzg==
|
||||
dependencies:
|
||||
prop-types "^15.8.1"
|
||||
|
||||
react-is@^16.13.1, react-is@^16.7.0:
|
||||
version "16.13.1"
|
||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
|
||||
|
||||