diff --git a/package.json b/package.json index a6e33e51..7fead380 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/prisma/schema.prisma b/prisma/schema.prisma index fed69d0d..971903e2 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -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[] +} diff --git a/public/aset/no-img.png b/public/aset/no-img.png new file mode 100644 index 00000000..65ec0740 Binary files /dev/null and b/public/aset/no-img.png differ diff --git a/public/investasi/4a673439-52c3-40ce-82fc-a9125083b040.jpeg b/public/investasi/4a673439-52c3-40ce-82fc-a9125083b040.jpeg new file mode 100644 index 00000000..803e3c56 Binary files /dev/null and b/public/investasi/4a673439-52c3-40ce-82fc-a9125083b040.jpeg differ diff --git a/public/investasi/5b77a1bf-0b2a-47d1-ba6a-adcd8743f80d.jpeg b/public/investasi/5b77a1bf-0b2a-47d1-ba6a-adcd8743f80d.jpeg new file mode 100644 index 00000000..326da9f2 Binary files /dev/null and b/public/investasi/5b77a1bf-0b2a-47d1-ba6a-adcd8743f80d.jpeg differ diff --git a/public/investasi/6c716813-1dd4-46b4-be88-06e189121572.png b/public/investasi/6c716813-1dd4-46b4-be88-06e189121572.png new file mode 100644 index 00000000..98983643 Binary files /dev/null and b/public/investasi/6c716813-1dd4-46b4-be88-06e189121572.png differ diff --git a/public/investasi/875ba470-cd51-4783-959a-dffb58f0aa3d.jpeg b/public/investasi/875ba470-cd51-4783-959a-dffb58f0aa3d.jpeg new file mode 100644 index 00000000..8bf49b6b Binary files /dev/null and b/public/investasi/875ba470-cd51-4783-959a-dffb58f0aa3d.jpeg differ diff --git a/public/investasi/b55259ad-372e-4da0-8988-231574515b71.jpeg b/public/investasi/b55259ad-372e-4da0-8988-231574515b71.jpeg new file mode 100644 index 00000000..0df106e4 Binary files /dev/null and b/public/investasi/b55259ad-372e-4da0-8988-231574515b71.jpeg differ diff --git a/public/investasi/c66a818f-45f0-4588-b8fd-22b769196c38.jpeg b/public/investasi/c66a818f-45f0-4588-b8fd-22b769196c38.jpeg new file mode 100644 index 00000000..326da9f2 Binary files /dev/null and b/public/investasi/c66a818f-45f0-4588-b8fd-22b769196c38.jpeg differ diff --git a/public/investasi/c8e15676-59ea-480d-b177-6a53defacb55.jpeg b/public/investasi/c8e15676-59ea-480d-b177-6a53defacb55.jpeg new file mode 100644 index 00000000..8a26aecf Binary files /dev/null and b/public/investasi/c8e15676-59ea-480d-b177-6a53defacb55.jpeg differ diff --git a/public/investasi/cecefba0-2061-4598-91dd-b6dbca552b1d.jpeg b/public/investasi/cecefba0-2061-4598-91dd-b6dbca552b1d.jpeg new file mode 100644 index 00000000..803e3c56 Binary files /dev/null and b/public/investasi/cecefba0-2061-4598-91dd-b6dbca552b1d.jpeg differ diff --git a/src/app/api/investasi/gambar/[id]/route.ts b/src/app/api/investasi/gambar/[id]/route.ts new file mode 100644 index 00000000..c684886d --- /dev/null +++ b/src/app/api/investasi/gambar/[id]/route.ts @@ -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", + }, + }); +} diff --git a/src/app/api/seeder/route.ts b/src/app/api/seeder/route.ts index 70971aac..c1c653cc 100644 --- a/src/app/api/seeder/route.ts +++ b/src/app/api/seeder/route.ts @@ -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 }); } diff --git a/src/app/dev/crowd/main/layout.tsx b/src/app/dev/crowd/main/layout.tsx new file mode 100644 index 00000000..7a50a1ba --- /dev/null +++ b/src/app/dev/crowd/main/layout.tsx @@ -0,0 +1,14 @@ +import { LayoutMainCrowd } from "@/app_modules/crowd"; +import React from "react"; + +export default async function Layout({ + children, +}: { + children: React.ReactNode; +}) { + return ( + <> + {children} + + ); +} diff --git a/src/app/dev/crowd/main/page.tsx b/src/app/dev/crowd/main/page.tsx new file mode 100644 index 00000000..7a7c3586 --- /dev/null +++ b/src/app/dev/crowd/main/page.tsx @@ -0,0 +1,9 @@ +import { MainCrowd } from "@/app_modules/crowd"; + +export default async function Page() { + return ( + <> + + + ); +} diff --git a/src/app/dev/crowd/splash/page.tsx b/src/app/dev/crowd/splash/page.tsx new file mode 100644 index 00000000..2fc01434 --- /dev/null +++ b/src/app/dev/crowd/splash/page.tsx @@ -0,0 +1,7 @@ +import { SplashCrowd } from "@/app_modules/crowd"; + +export default async function Page() { + return <> + + +} \ No newline at end of file diff --git a/src/app/dev/investasi/create/layout.tsx b/src/app/dev/investasi/create/layout.tsx new file mode 100644 index 00000000..e86d95c8 --- /dev/null +++ b/src/app/dev/investasi/create/layout.tsx @@ -0,0 +1,14 @@ +import { InvestasiCreateLayout } from "@/app_modules/investasi"; +import React from "react"; + +export default async function Layout({ + children, +}: { + children: React.ReactNode; +}) { + return ( + <> + {children} + + ); +} diff --git a/src/app/dev/investasi/create/page.tsx b/src/app/dev/investasi/create/page.tsx new file mode 100644 index 00000000..79da9d3c --- /dev/null +++ b/src/app/dev/investasi/create/page.tsx @@ -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 ( + <> + + + ); +} diff --git a/src/app/dev/investasi/main/layout.tsx b/src/app/dev/investasi/main/layout.tsx new file mode 100644 index 00000000..652b25c9 --- /dev/null +++ b/src/app/dev/investasi/main/layout.tsx @@ -0,0 +1,8 @@ +import { LayoutMainInvestasi } from "@/app_modules/investasi"; +import React from "react"; + +export default async function Layout({children}: {children: React.ReactNode}) { + return <> + {children} + +} \ No newline at end of file diff --git a/src/app/dev/investasi/main/page.tsx b/src/app/dev/investasi/main/page.tsx new file mode 100644 index 00000000..d29c804d --- /dev/null +++ b/src/app/dev/investasi/main/page.tsx @@ -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 <> + + + +} \ No newline at end of file diff --git a/src/app/dev/investasi/upload/layout.tsx b/src/app/dev/investasi/upload/layout.tsx new file mode 100644 index 00000000..f0dc3953 --- /dev/null +++ b/src/app/dev/investasi/upload/layout.tsx @@ -0,0 +1,8 @@ +import { LayoutUploadGambarInvestasi } from "@/app_modules/investasi"; +import React from "react"; + +export default async function Layout({children}: {children: React.ReactNode}) { + return<> + {children} + +} \ No newline at end of file diff --git a/src/app/dev/investasi/upload/page.tsx b/src/app/dev/investasi/upload/page.tsx new file mode 100644 index 00000000..96feb763 --- /dev/null +++ b/src/app/dev/investasi/upload/page.tsx @@ -0,0 +1,7 @@ +import { UploadGambarInvestasi } from "@/app_modules/investasi"; + +export default async function Page() { + return<> + + +} \ No newline at end of file diff --git a/src/app/lib/api.ts b/src/app/lib/api.ts index 558ce3d1..48812758 100644 --- a/src/app/lib/api.ts +++ b/src/app/lib/api.ts @@ -14,4 +14,7 @@ export const ApiHipmi = { //Portofolio create_portofolio: "/api/portofolio/create", + + //Investasi + get_gambar_investasi: "/api/investasi/gambar" }; diff --git a/src/app_modules/component/header_tamplate.tsx b/src/app_modules/component/header_tamplate.tsx new file mode 100644 index 00000000..967b7655 --- /dev/null +++ b/src/app_modules/component/header_tamplate.tsx @@ -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 ( + <> +
+ + { + if (route === null || route === undefined) { + return router.back(); + } else { + return router.push(route); + } + }} + > + + + {title} + {(() => { + if (route2 === null ||route2 === undefined) { + return ; + } else { + return ( + router.push(route2)} + > + {icon} + + ); + } + })()} + +
+ + ); +} diff --git a/src/app_modules/crowd/index.ts b/src/app_modules/crowd/index.ts new file mode 100644 index 00000000..764cbbea --- /dev/null +++ b/src/app_modules/crowd/index.ts @@ -0,0 +1,5 @@ +import MainCrowd from "./main/view"; +import LayoutMainCrowd from "./main/layout"; +import SplashCrowd from "./splash/view"; + +export {MainCrowd,LayoutMainCrowd, SplashCrowd} \ No newline at end of file diff --git a/src/app_modules/crowd/main/layout.tsx b/src/app_modules/crowd/main/layout.tsx new file mode 100644 index 00000000..d362a5d0 --- /dev/null +++ b/src/app_modules/crowd/main/layout.tsx @@ -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 ( + <> + } + > + {children} + + + ); +} diff --git a/src/app_modules/crowd/main/view.tsx b/src/app_modules/crowd/main/view.tsx new file mode 100644 index 00000000..eba52ea1 --- /dev/null +++ b/src/app_modules/crowd/main/view.tsx @@ -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 ( + <> +
+ + Selamat datang di + HIPMI Crowd Funding + + + +
+ + ); +} diff --git a/src/app_modules/crowd/splash/view.tsx b/src/app_modules/crowd/splash/view.tsx new file mode 100644 index 00000000..02c4793a --- /dev/null +++ b/src/app_modules/crowd/splash/view.tsx @@ -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 ( + <> +
+ + Welcome to, + CrowdFunding + +
+ + ); +} diff --git a/src/app_modules/home/view.tsx b/src/app_modules/home/view.tsx index 0c708cbf..48c4fbe6 100644 --- a/src/app_modules/home/view.tsx +++ b/src/app_modules/home/view.tsx @@ -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: , - }, - { - id: 2, - name: "Project Collaboration", - icon: , - }, - { - id: 3, - name: "Voting", - icon: , - }, - { - id: 4, - name: "Event", - icon: , - }, - { - id: 5, - name: "Crowd Funding", - icon: , - }, - { - id: 6, - name: "Marketplace", - icon: , - }, - { - id: 7, - name: "Job Vacancy", - icon: , - }, - { - id: 8, - name: "Business Maps", - icon: , - }, -]; + // 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: , + link: "" + }, + { + id: 2, + name: "Project Collaboration", + icon: , + link: "" + + }, + { + id: 3, + name: "Voting", + icon: , + link: "" + + }, + { + id: 4, + name: "Event", + icon: , + link: "" + + }, + { + id: 5, + name: "Crowd Funding", + icon: , + link: `/dev/crowd/splash` + + }, + { + id: 6, + name: "Marketplace", + icon: , + link: "" + + }, + { + id: 7, + name: "Job Vacancy", + icon: , + link: "" + + }, + { + id: 8, + name: "Business Maps", + icon: , + link: "" + + }, + ]; + return ( <> @@ -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) + } + }} > + + } + > + {children} + + + ); +} diff --git a/src/app_modules/investasi/create/view.tsx b/src/app_modules/investasi/create/view.tsx new file mode 100644 index 00000000..65e0cdfa --- /dev/null +++ b/src/app_modules/investasi/create/view.tsx @@ -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(null); + const [img, setImg] = useState(); + 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 ( + <> + + + {img ? ( + + ) : ( + + )} + + + { + const buffer = URL.createObjectURL( + new Blob([new Uint8Array(await files.arrayBuffer())]) + ); + setImg(buffer); + setFl(files); + }} + accept="image/png,image/jpeg" + > + {(props) => ( + + )} + + + +
+ + { + setValue({ + ...value, + title: val.target.value, + }); + }} + /> + { + setValue({ + ...value, + targetDana: val.target.value, + }); + }} + /> + { + setValue({ + ...value, + hargaLembar: val.target.value, + }); + }} + /> + { + setValue({ + ...value, + totalLembar: val.target.value, + }); + }} + /> + { + setValue({ + ...value, + roi: val.target.value, + }); + }} + /> + ({ value: e.id, label: e.name }))} + onChange={(val) => { + setValue({ + ...(value as any), + periodeDevidenId: val, + }); + }} + /> +