diff --git a/prisma/schema.prisma b/prisma/schema.prisma
index e4edf771..46f70188 100644
--- a/prisma/schema.prisma
+++ b/prisma/schema.prisma
@@ -44,18 +44,19 @@ model UserSession {
}
model Profile {
- id String @id @default(cuid())
+ id String @id @default(cuid())
name String
- email String @unique
+ email String @unique
alamat String
jenisKelamin String
- active Boolean @default(true)
- createdAt DateTime @default(now())
- updatedAt DateTime @default(now()) @updatedAt
- User User? @relation(fields: [userId], references: [id])
- userId String? @unique
- ImageProfile Images? @relation(fields: [imagesId], references: [id])
- imagesId String? @unique
+ active Boolean @default(true)
+ createdAt DateTime @default(now())
+ updatedAt DateTime @default(now()) @updatedAt
+ User User? @relation(fields: [userId], references: [id])
+ userId String? @unique
+ ImageProfile Images? @relation(fields: [imagesId], references: [id])
+ imagesId String? @unique
+ Katalog Katalog[]
}
model Images {
@@ -66,3 +67,27 @@ model Images {
updatedAt DateTime @default(now()) @updatedAt
Profile Profile?
}
+
+model Katalog {
+ id String @id @default(cuid())
+ namaBisnis String
+ alamatKantor String
+ tlpn String
+ deskripssi String
+ active Boolean @default(true)
+ createdAt DateTime @default(now())
+ updatedAt DateTime @default(now()) @updatedAt
+ Profile Profile? @relation(fields: [profileId], references: [id])
+ profileId String?
+ MasterBidangBisnis MasterBidangBisnis @relation(fields: [masterBidangBisnisId], references: [id])
+ masterBidangBisnisId String
+}
+
+model MasterBidangBisnis {
+ id String @id
+ name String
+ active Boolean @default(true)
+ createdAt DateTime @default(now())
+ updatedAt DateTime @default(now()) @updatedAt
+ Katalog Katalog[]
+}
diff --git a/public/img/0fb20fe0-af14-432b-87ca-094cecb4cb37.webp b/public/img/072b192a-fe0a-4601-82e5-ac02144e48ce.webp
similarity index 100%
rename from public/img/0fb20fe0-af14-432b-87ca-094cecb4cb37.webp
rename to public/img/072b192a-fe0a-4601-82e5-ac02144e48ce.webp
diff --git a/public/img/07a4e82b-1919-4bde-af66-d280d340c85e.webp b/public/img/07a4e82b-1919-4bde-af66-d280d340c85e.webp
new file mode 100644
index 00000000..e0c75142
Binary files /dev/null and b/public/img/07a4e82b-1919-4bde-af66-d280d340c85e.webp differ
diff --git a/public/img/716c7533-d96b-4305-ae4f-52fb56dec512.png b/public/img/3db9b189-72dd-4a9c-947c-1833f18695c0.png
similarity index 100%
rename from public/img/716c7533-d96b-4305-ae4f-52fb56dec512.png
rename to public/img/3db9b189-72dd-4a9c-947c-1833f18695c0.png
diff --git a/public/img/12040bbf-0319-41a0-a87e-268697f14a26.png b/public/img/5481c365-3f7d-47af-bb0d-82fcbb064f92.png
similarity index 100%
rename from public/img/12040bbf-0319-41a0-a87e-268697f14a26.png
rename to public/img/5481c365-3f7d-47af-bb0d-82fcbb064f92.png
diff --git a/public/img/6d767045-b70f-41ef-9775-85407302443c.png b/public/img/a92db9b4-33c1-41a0-882e-ae82a5dc0534.png
similarity index 100%
rename from public/img/6d767045-b70f-41ef-9775-85407302443c.png
rename to public/img/a92db9b4-33c1-41a0-882e-ae82a5dc0534.png
diff --git a/public/img/fee57417-24f2-425d-99d7-18a7ec5e4b37.png b/public/img/fee57417-24f2-425d-99d7-18a7ec5e4b37.png
new file mode 100644
index 00000000..6e04e0ec
Binary files /dev/null and b/public/img/fee57417-24f2-425d-99d7-18a7ec5e4b37.png differ
diff --git a/src/app/api/portofolio/create/route.ts b/src/app/api/portofolio/create/route.ts
new file mode 100644
index 00000000..2a89f55e
--- /dev/null
+++ b/src/app/api/portofolio/create/route.ts
@@ -0,0 +1,24 @@
+import { myConsole } from "@/app/fun/my_console";
+import prisma from "@/app/lib/prisma";
+import { NextResponse } from "next/server";
+
+export async function POST(req: Request) {
+ if (req.method === "POST") {
+ const body = await req.json();
+ // myConsole(body);
+
+ const data = await prisma.katalog.create({
+ data: {
+ profileId: body.profileId,
+ namaBisnis: body.namaBisnis,
+ alamatKantor: body.alamatKantor,
+ tlpn: body.tlpn,
+ deskripssi: body.deskripssi,
+ masterBidangBisnisId: body.masterBidangBisnisId,
+ },
+ });
+
+ return NextResponse.json({ status: 201, success: true });
+ }
+ return NextResponse.json({ success: false });
+}
diff --git a/src/app/api/profile/create/route.ts b/src/app/api/profile/create/route.ts
index 6f984be7..012231e5 100644
--- a/src/app/api/profile/create/route.ts
+++ b/src/app/api/profile/create/route.ts
@@ -5,7 +5,7 @@ import { NextResponse } from "next/server";
export async function POST(req: Request) {
if (req.method === "POST") {
const body = await req.json();
- myConsole(body);
+ // myConsole(body);
const data = await prisma.profile.create({
data: {
diff --git a/src/app/api/profile/foto/[name]/route.ts b/src/app/api/profile/foto/[name]/route.ts
index 9d4a9101..c1d3a267 100644
--- a/src/app/api/profile/foto/[name]/route.ts
+++ b/src/app/api/profile/foto/[name]/route.ts
@@ -1,11 +1,22 @@
import { NextRequest, NextResponse } from "next/server";
-import fs from 'fs'
+import fs from "fs";
-export async function GET(req: NextRequest, { params }: { params: { name: string } }) {
- const fl = fs.readFileSync(`./public/img/${params.name}`)
+export async function GET(
+ req: NextRequest,
+ { params }: { params: { name: string } }
+) {
+ if (!fs.existsSync(`./public/img/${params.name}`)) {
+ const fl = fs.readFileSync(`./public/aset/avatar.png`);
return new NextResponse(fl, {
- headers: {
- "Content-Type": "image/png"
- }
- })
-}
\ No newline at end of file
+ headers: {
+ "Content-Type": "image/png",
+ },
+ });
+ }
+ const fl = fs.readFileSync(`./public/img/${params.name}`);
+ 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 16990102..70971aac 100644
--- a/src/app/api/seeder/route.ts
+++ b/src/app/api/seeder/route.ts
@@ -1,6 +1,7 @@
import prisma from "@/app/lib/prisma";
-import userRole from "../../../bin/seeder/user_role.json";
import { NextResponse } from "next/server";
+import userRole from "../../../bin/seeder/user_role.json";
+import bidangBisnis from "../../../bin/seeder/bidang_bisnis.json";
export async function GET(req: Request) {
const dev = new URL(req.url).searchParams.get("dev");
@@ -20,8 +21,24 @@ export async function GET(req: Request) {
},
});
}
+
+ for (let i of bidangBisnis) {
+ await prisma.masterBidangBisnis.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 });
}
return NextResponse.json({ success: false });
-}
\ No newline at end of file
+}
diff --git a/src/app/dev/katalog/portofolio/create/layout.tsx b/src/app/dev/katalog/portofolio/create/layout.tsx
new file mode 100644
index 00000000..42df5deb
--- /dev/null
+++ b/src/app/dev/katalog/portofolio/create/layout.tsx
@@ -0,0 +1,8 @@
+import { PortofolioLayout } from "@/app_modules/katalog/portofolio";
+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/katalog/portofolio/create/page.tsx b/src/app/dev/katalog/portofolio/create/page.tsx
new file mode 100644
index 00000000..a8badd70
--- /dev/null
+++ b/src/app/dev/katalog/portofolio/create/page.tsx
@@ -0,0 +1,17 @@
+import { myConsole } from "@/app/fun/my_console";
+import { CreatePortofolio } from "@/app_modules/katalog/portofolio";
+import { getBidangBisnis } from "@/app_modules/katalog/portofolio/api/get-bidang-bisnis";
+import { getProfile } from "@/app_modules/katalog/profile";
+
+export default async function Page() {
+ const bidangBisnis = await getBidangBisnis();
+ const id = await getProfile();
+ const profileId = id?.id;
+
+ return (
+ <>
+ {JSON.stringify(profileId)}
+
+ >
+ );
+}
diff --git a/src/app/dev/katalog/view/page.tsx b/src/app/dev/katalog/view/page.tsx
index 62de781d..7d34f1a6 100644
--- a/src/app/dev/katalog/view/page.tsx
+++ b/src/app/dev/katalog/view/page.tsx
@@ -1,12 +1,14 @@
+import { loadListPortofolio } from "@/app_modules/katalog/portofolio/fun/fun_get_all_portofolio";
import { getProfile } from "@/app_modules/katalog/profile";
import { KatalogView } from "@/app_modules/katalog/view";
export default async function Page() {
const data = await getProfile();
+ const listPorto = await loadListPortofolio(data?.id as string)
return (
<>
{/* {JSON.stringify(data)} */}
-
+
>
);
}
diff --git a/src/app/fun/my_console.ts b/src/app/fun/my_console.ts
index c6dd9398..2c626bd5 100644
--- a/src/app/fun/my_console.ts
+++ b/src/app/fun/my_console.ts
@@ -1,5 +1,5 @@
export function myConsole(value: any) {
- const onData = false
+ const onData = true
if (onData) {
console.log(value);
}
diff --git a/src/app/lib/api.ts b/src/app/lib/api.ts
index e35dde8a..558ce3d1 100644
--- a/src/app/lib/api.ts
+++ b/src/app/lib/api.ts
@@ -11,4 +11,7 @@ export const ApiHipmi = {
create_profile: "/api/profile/create",
edit_profile: "/api/profile/edit",
get_foto: "/api/profile/foto/",
+
+ //Portofolio
+ create_portofolio: "/api/portofolio/create",
};
diff --git a/src/app_modules/home/view.tsx b/src/app_modules/home/view.tsx
index 9e719d9a..f0ef46ac 100644
--- a/src/app_modules/home/view.tsx
+++ b/src/app_modules/home/view.tsx
@@ -34,8 +34,12 @@ import { getProfile } from "../katalog/profile";
import { useRouter } from "next/navigation";
import { useAtom } from "jotai";
import { gs_token } from "./state/global_state";
-import { g_getProfile } from "../katalog/profile/fun/fun_get_profile";
-import { gs_profile } from "../katalog/profile/state/global_state";
+import { loadDataProfile } from "../katalog/profile/fun/fun_get_profile";
+import { gs_fotoProfile, gs_profile } from "../katalog/profile/state/global_state";
+import { loadListPortofolio } from "../katalog/portofolio/fun/fun_get_all_portofolio";
+import { gs_ListPortofolio } from "../katalog/portofolio/state/global_state";
+import { myConsole } from "@/app/fun/my_console";
+import { getFotoProfile } from "../katalog/profile/api/get-foto-profile";
const listHalaman = [
{
@@ -95,9 +99,23 @@ export default function HomeView() {
const [profile, setProfile] = useAtom(gs_profile);
useShallowEffect(() => {
- g_getProfile(setProfile);
+ loadDataProfile(setProfile);
}, []);
+ const [foto, setFoto] = useAtom(gs_fotoProfile);
+ useShallowEffect(() => {
+ if (profile?.imagesId === undefined) {
+ return myConsole("Waiting data");
+ } else {
+ getFotoProfile(profile?.imagesId).then((v) => setFoto(v?.url));
+ }
+ }, [profile?.imagesId]);
+
+ const [listPorto, setListPorto] = useAtom(gs_ListPortofolio)
+ useShallowEffect(() => {
+ loadListPortofolio(profile?.id).then((res) => setListPorto(res));
+ }, [profile?.id]);
+
return (
<>
{/*
{JSON.stringify(profile, null, 2)} */}
diff --git a/src/app_modules/katalog/portofolio/api/get-bidang-bisnis.ts b/src/app_modules/katalog/portofolio/api/get-bidang-bisnis.ts
new file mode 100644
index 00000000..4130f24d
--- /dev/null
+++ b/src/app_modules/katalog/portofolio/api/get-bidang-bisnis.ts
@@ -0,0 +1,9 @@
+"use server"
+
+import { myConsole } from "@/app/fun/my_console"
+import prisma from "@/app/lib/prisma"
+
+export async function getBidangBisnis() {
+ const data = await prisma.masterBidangBisnis.findMany()
+ return data
+}
\ No newline at end of file
diff --git a/src/app_modules/katalog/portofolio/api/get-portofolio.ts b/src/app_modules/katalog/portofolio/api/get-portofolio.ts
new file mode 100644
index 00000000..59ec8f6e
--- /dev/null
+++ b/src/app_modules/katalog/portofolio/api/get-portofolio.ts
@@ -0,0 +1,34 @@
+"use server";
+
+import { myConsole } from "@/app/fun/my_console";
+import prisma from "@/app/lib/prisma";
+
+/**
+ *
+ * @param id - profileId
+ * @returns list portofolio by Id
+ */
+export default async function getListPortofolio(id: string) {
+ // myConsole(id);
+
+ const data = await prisma.katalog.findMany({
+ where: {
+ profileId: id,
+ },
+ select: {
+ id: true,
+ namaBisnis: true,
+ alamatKantor: true,
+ tlpn: true,
+ deskripssi: true,
+ active: true,
+ masterBidangBisnisId: true,
+ },
+ });
+
+ if (!data) {
+ throw new Error("Failed to fetch data");
+ }
+
+ return data;
+}
diff --git a/src/app_modules/katalog/portofolio/create/layout.tsx b/src/app_modules/katalog/portofolio/create/layout.tsx
new file mode 100644
index 00000000..e5e6e58c
--- /dev/null
+++ b/src/app_modules/katalog/portofolio/create/layout.tsx
@@ -0,0 +1,31 @@
+"use client";
+
+import { ActionIcon, AppShell, Group, Header, Text } from "@mantine/core";
+import { IconArrowLeft } from "@tabler/icons-react";
+import { useRouter } from "next/navigation";
+
+export default function PortofolioLayout({ children }: { children: any }) {
+ const router = useRouter();
+ return (
+ <>
+
+
+ router.push("/dev/katalog/view")}
+ >
+
+
+ Buat Portofolio
+
+
+
+ }
+ >
+ {children}
+
+ >
+ );
+}
diff --git a/src/app_modules/katalog/portofolio/create/view.tsx b/src/app_modules/katalog/portofolio/create/view.tsx
new file mode 100644
index 00000000..0ff7a01d
--- /dev/null
+++ b/src/app_modules/katalog/portofolio/create/view.tsx
@@ -0,0 +1,127 @@
+"use client";
+
+import { myConsole } from "@/app/fun/my_console";
+import { ApiHipmi } from "@/app/lib/api";
+import { Warna } from "@/app/lib/warna";
+import { Button, Select, Stack, TextInput, Title } from "@mantine/core";
+import _ from "lodash";
+import { useRouter } from "next/navigation";
+import { useState } from "react";
+import toast from "react-simple-toasts";
+
+export default function CreatePortofolio({
+ data,
+ profileId,
+}: {
+ data: any;
+ profileId: any;
+}) {
+ const router = useRouter();
+ const [value, setValue] = useState({
+ namaBisnis: "",
+ bidangBisnisId: "",
+ alamatKantor: "",
+ tlpn: "",
+ deskripssi: "",
+ });
+
+ async function onSubmit() {
+ const body = {
+ profileId: profileId,
+ namaBisnis: value.namaBisnis,
+ masterBidangBisnisId: value.bidangBisnisId,
+ alamatKantor: value.alamatKantor,
+ tlpn: value.tlpn,
+ deskripssi: value.deskripssi,
+ };
+
+ if (_.values(body).includes("")) return toast("Lengkapi Data");
+
+ await fetch(ApiHipmi.create_portofolio, {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify(body),
+ })
+ .then((res) => res.json())
+ .then((val) => {
+ myConsole(val)
+ if (val.status == 201) {
+ toast("Berhasil disimpan");
+ return router.push("/dev/katalog/view");
+ } else {
+ return toast("Gagal disimpa");
+ }
+ });
+ }
+
+ return (
+ <>
+ {/* {JSON.stringify(data)} */}
+
+ {
+ setValue({
+ ...value,
+ namaBisnis: val.target.value,
+ });
+ }}
+ />
+
+
+ {/* {JSON.stringify(data, null, 2)} */}
+ >
+ );
+}
diff --git a/src/app_modules/katalog/portofolio/fun/fun_get_all_portofolio.ts b/src/app_modules/katalog/portofolio/fun/fun_get_all_portofolio.ts
new file mode 100644
index 00000000..cc540f58
--- /dev/null
+++ b/src/app_modules/katalog/portofolio/fun/fun_get_all_portofolio.ts
@@ -0,0 +1,16 @@
+import toast from "react-simple-toasts";
+import getListPortofolio from "../api/get-portofolio";
+
+/**
+ *
+ * @param id - profileId
+ * @returns load list portofolio by Id
+ */
+export async function loadListPortofolio(id: string) {
+ if (id === null) {
+ return toast("Id null");
+ } else {
+ const data = await getListPortofolio(id).then((res) => res);
+ return data
+ }
+}
diff --git a/src/app_modules/katalog/portofolio/index.ts b/src/app_modules/katalog/portofolio/index.ts
new file mode 100644
index 00000000..3496c641
--- /dev/null
+++ b/src/app_modules/katalog/portofolio/index.ts
@@ -0,0 +1,5 @@
+import CreatePortofolio from "./create/view";
+import PortofolioLayout from "./create/layout";
+import PortofolioView from "./list_view/view";
+
+export {CreatePortofolio, PortofolioLayout, PortofolioView}
\ No newline at end of file
diff --git a/src/app_modules/katalog/portofolio/list_view/view.tsx b/src/app_modules/katalog/portofolio/list_view/view.tsx
new file mode 100644
index 00000000..fec26322
--- /dev/null
+++ b/src/app_modules/katalog/portofolio/list_view/view.tsx
@@ -0,0 +1,66 @@
+"use client";
+import { Box, Center, Grid, Paper, Text, Title } from "@mantine/core";
+import { useShallowEffect } from "@mantine/hooks";
+import { useState } from "react";
+import { loadListPortofolio } from "../fun/fun_get_all_portofolio";
+import _ from "lodash";
+import { IconCaretRightFilled } from "@tabler/icons-react";
+import { loadDataProfile } from "../../profile/fun/fun_get_profile";
+import { useAtom } from "jotai";
+import { gs_profile } from "../../profile/state/global_state";
+import getListPortofolio from "../api/get-portofolio";
+import { gs_ListPortofolio } from "../state/global_state";
+
+export default function PortofolioView({
+ profileId,
+ porto,
+}: {
+ profileId: any;
+ porto: any;
+}) {
+ const [profile, setProfile] = useAtom(gs_profile);
+ useShallowEffect(() => {
+ loadDataProfile(setProfile);
+ }, []);
+
+ const [listPorto, setListPorto] = useAtom(gs_ListPortofolio)
+ useShallowEffect(() => {
+ loadListPortofolio(profile?.id).then((res) => setListPorto(res));
+ }, [profile?.id]);
+
+
+ return (
+ <>
+ {/* {JSON.stringify(profile.id)}
+
+ {JSON.stringify(listPorto)} */}
+
+ Portofolio
+
+
+ {(() => {
+ if (listPorto) {
+ return (
+ <>
+ {_.map(listPorto).map((e: any) => (
+
+
+
+ {e.namaBisnis}
+
+
+
+
+
+
+ ))}
+ >
+ );
+ } else {
+ return <>>;
+ }
+ })()}
+
+ >
+ );
+}
diff --git a/src/app_modules/katalog/portofolio/state/global_state.ts b/src/app_modules/katalog/portofolio/state/global_state.ts
new file mode 100644
index 00000000..dd75aafe
--- /dev/null
+++ b/src/app_modules/katalog/portofolio/state/global_state.ts
@@ -0,0 +1,3 @@
+import { atomWithStorage } from "jotai/utils";
+
+export const gs_ListPortofolio = atomWithStorage("gs_ListPortofolio", null)
\ No newline at end of file
diff --git a/src/app_modules/katalog/profile/fun/get_foto_profile.ts b/src/app_modules/katalog/profile/api/get-foto-profile.ts
similarity index 100%
rename from src/app_modules/katalog/profile/fun/get_foto_profile.ts
rename to src/app_modules/katalog/profile/api/get-foto-profile.ts
diff --git a/src/app_modules/katalog/profile/fun/api-get-profile.ts b/src/app_modules/katalog/profile/api/get-profile.ts
similarity index 100%
rename from src/app_modules/katalog/profile/fun/api-get-profile.ts
rename to src/app_modules/katalog/profile/api/get-profile.ts
diff --git a/src/app_modules/katalog/profile/edit/view.tsx b/src/app_modules/katalog/profile/edit/view.tsx
index 4425460d..9f7a80d5 100644
--- a/src/app_modules/katalog/profile/edit/view.tsx
+++ b/src/app_modules/katalog/profile/edit/view.tsx
@@ -12,20 +12,17 @@ import { useRouter } from "next/navigation";
import { useState } from "react";
import toast from "react-simple-toasts";
import { gs_profile } from "../state/global_state";
-import { g_getProfile } from "../fun/fun_get_profile";
+import { loadDataProfile } from "../fun/fun_get_profile";
-export default function EditProfile() {
+export default function EditProfile({ data }: { data: any }) {
const router = useRouter();
//Get data profile
- const [profile, setProfile] = useAtom(gs_profile);
+ const [profile, setProfile] = useAtom(gs_profile)
useShallowEffect(() => {
- g_getProfile(setProfile);
+ loadDataProfile(setProfile);
}, []);
-
-
-
async function onUpdate() {
const body = profile;
if (_.values(body).includes("")) return toast("Lengkapi data");
@@ -42,24 +39,27 @@ export default function EditProfile() {
myConsole(val);
if (val.status == 200) {
toast("Data tersimpan");
- return router.push("/dev/katalog/view");
+ loadDataProfile(setProfile)
+ return setTimeout(() => router.push("/dev/katalog/view"), 1000);
} else {
return toast("Gagal update !!!");
}
});
}
+ if(!profile) return <>>
+
return (
<>
{/* {JSON.stringify(profile)} */}
-
-
+
+
{
setProfile({
...profile,
@@ -71,7 +71,7 @@ export default function EditProfile() {
{
myConsole(val.target.value);
setProfile({
@@ -84,7 +84,7 @@ export default function EditProfile() {
{
myConsole(val.target.value);
setProfile({
@@ -96,7 +96,7 @@ export default function EditProfile() {