diff --git a/package.json b/package.json
index 614f9ed1..15651cf3 100644
--- a/package.json
+++ b/package.json
@@ -20,6 +20,7 @@
"@types/node": "20.4.5",
"@types/react": "18.2.17",
"@types/react-dom": "18.2.7",
+ "@types/uuid": "^9.0.4",
"autoprefixer": "10.4.14",
"eslint": "8.45.0",
"eslint-config-next": "13.4.12",
@@ -33,6 +34,7 @@
"react-simple-toasts": "^5.10.0",
"tailwindcss": "3.3.3",
"typescript": "5.1.6",
+ "uuid": "^9.0.1",
"yaml": "^2.3.2"
}
}
diff --git a/public/img/0fb20fe0-af14-432b-87ca-094cecb4cb37.webp b/public/img/0fb20fe0-af14-432b-87ca-094cecb4cb37.webp
new file mode 100644
index 00000000..e0c75142
Binary files /dev/null and b/public/img/0fb20fe0-af14-432b-87ca-094cecb4cb37.webp differ
diff --git a/public/img/12040bbf-0319-41a0-a87e-268697f14a26.png b/public/img/12040bbf-0319-41a0-a87e-268697f14a26.png
new file mode 100644
index 00000000..6e04e0ec
Binary files /dev/null and b/public/img/12040bbf-0319-41a0-a87e-268697f14a26.png differ
diff --git a/public/img/6d767045-b70f-41ef-9775-85407302443c.png b/public/img/6d767045-b70f-41ef-9775-85407302443c.png
new file mode 100644
index 00000000..6e04e0ec
Binary files /dev/null and b/public/img/6d767045-b70f-41ef-9775-85407302443c.png differ
diff --git a/public/img/716c7533-d96b-4305-ae4f-52fb56dec512.png b/public/img/716c7533-d96b-4305-ae4f-52fb56dec512.png
new file mode 100644
index 00000000..b4ef2a39
Binary files /dev/null and b/public/img/716c7533-d96b-4305-ae4f-52fb56dec512.png differ
diff --git a/src/app/api/profile/foto/[name]/route.ts b/src/app/api/profile/foto/[name]/route.ts
new file mode 100644
index 00000000..9d4a9101
--- /dev/null
+++ b/src/app/api/profile/foto/[name]/route.ts
@@ -0,0 +1,11 @@
+import { NextRequest, NextResponse } from "next/server";
+import fs from 'fs'
+
+export async function GET(req: NextRequest, { params }: { params: { name: string } }) {
+ const fl = fs.readFileSync(`./public/img/${params.name}`)
+ return new NextResponse(fl, {
+ headers: {
+ "Content-Type": "image/png"
+ }
+ })
+}
\ No newline at end of file
diff --git a/src/app/dev/katalog/profile/upload/layout.tsx b/src/app/dev/katalog/profile/upload/layout.tsx
new file mode 100644
index 00000000..371d9700
--- /dev/null
+++ b/src/app/dev/katalog/profile/upload/layout.tsx
@@ -0,0 +1,10 @@
+import { UploadFotoProfileLayout } from "@/app_modules/katalog/profile";
+import { AppShell } from "@mantine/core";
+
+export default function Layout({ children }: { children: any }) {
+ return (
+ <>
+ {children}
+ >
+ );
+}
diff --git a/src/app/dev/katalog/profile/upload/page.tsx b/src/app/dev/katalog/profile/upload/page.tsx
new file mode 100644
index 00000000..66ced2af
--- /dev/null
+++ b/src/app/dev/katalog/profile/upload/page.tsx
@@ -0,0 +1,9 @@
+import { UploadFotoProfile } from "@/app_modules/katalog/profile";
+
+export default async function Page() {
+ return (
+ <>
+
+ >
+ );
+}
diff --git a/src/app/lib/api.ts b/src/app/lib/api.ts
index 31500caf..e35dde8a 100644
--- a/src/app/lib/api.ts
+++ b/src/app/lib/api.ts
@@ -10,4 +10,5 @@ export const ApiHipmi = {
//Profile
create_profile: "/api/profile/create",
edit_profile: "/api/profile/edit",
+ get_foto: "/api/profile/foto/",
};
diff --git a/src/app_modules/home/view.tsx b/src/app_modules/home/view.tsx
index acf582c2..9e719d9a 100644
--- a/src/app_modules/home/view.tsx
+++ b/src/app_modules/home/view.tsx
@@ -34,6 +34,8 @@ 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";
const listHalaman = [
{
@@ -81,7 +83,7 @@ const listHalaman = [
export default function HomeView() {
const router = useRouter();
const [token, setToken] = useAtom(gs_token);
- const [profile, setProfile] = useState(null);
+
useShallowEffect(() => {
getUserId();
@@ -91,13 +93,10 @@ export default function HomeView() {
setToken(data);
}
+ const [profile, setProfile] = useAtom(gs_profile);
useShallowEffect(() => {
- getUserProfile();
+ g_getProfile(setProfile);
}, []);
- async function getUserProfile() {
- const data = await getProfile();
- setProfile(data);
- }
return (
<>
diff --git a/src/app_modules/katalog/profile/edit/view.tsx b/src/app_modules/katalog/profile/edit/view.tsx
index 2c39c97d..4425460d 100644
--- a/src/app_modules/katalog/profile/edit/view.tsx
+++ b/src/app_modules/katalog/profile/edit/view.tsx
@@ -12,9 +12,9 @@ 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 { g_getProfile } from "../fun/fun_get_profile";
-export default function EditProfile({ data }: { data: any }) {
+export default function EditProfile() {
const router = useRouter();
//Get data profile
@@ -24,6 +24,8 @@ export default function EditProfile({ data }: { data: any }) {
}, []);
+
+
async function onUpdate() {
const body = profile;
if (_.values(body).includes("")) return toast("Lengkapi data");
@@ -51,8 +53,8 @@ export default function EditProfile({ data }: { data: any }) {
<>
{/* {JSON.stringify(profile)} */}
-
-
+
+
res);
- setProfile(data)
- }
\ No newline at end of file
+ await getProfile()
+ .then((res) => res)
+ .then((val) => {
+ setProfile(val);
+ });
+}
diff --git a/src/app_modules/katalog/profile/fun/get_foto_profile.ts b/src/app_modules/katalog/profile/fun/get_foto_profile.ts
new file mode 100644
index 00000000..d8d24f5a
--- /dev/null
+++ b/src/app_modules/katalog/profile/fun/get_foto_profile.ts
@@ -0,0 +1,16 @@
+"use server";
+import { myConsole } from "@/app/fun/my_console";
+import prisma from "@/app/lib/prisma";
+
+export async function getFotoProfile(id: any) {
+ const imgUrl = await prisma.images.findUnique({
+ where: {
+ id: id,
+ },
+ select: {
+ id: true,
+ url: true,
+ },
+ });
+ return imgUrl;
+}
diff --git a/src/app_modules/katalog/profile/fun/upload_foto.ts b/src/app_modules/katalog/profile/fun/upload_foto.ts
new file mode 100644
index 00000000..043bd563
--- /dev/null
+++ b/src/app_modules/katalog/profile/fun/upload_foto.ts
@@ -0,0 +1,52 @@
+"use server";
+
+import { myConsole } from "@/app/fun/my_console";
+import prisma from "@/app/lib/prisma";
+import fs from "fs";
+import _ from "lodash";
+import { cookies } from "next/headers";
+import { v4 } from "uuid";
+
+/**
+ *
+ * @param formData
+ * @returns upload gambar ke /public/img
+ */
+export async function funUploadFoto(formData: FormData, id: string) {
+ const file: any = formData.get("file");
+ const fName = file.name;
+ const fExt = _.lowerCase(file.name.split(".").pop());
+ const fRandomName = v4(fName) + "." + fExt;
+
+ myConsole(id);
+ myConsole(fExt);
+
+ const upload = await prisma.images.create({
+ data: {
+ url: fRandomName,
+ },
+ select: {
+ id: true,
+ url: true,
+ },
+ });
+
+ if (upload) {
+ await prisma.profile.update({
+ where: {
+ id: id,
+ },
+ data: {
+ imagesId: upload.id,
+ },
+ });
+ }
+
+ const upFolder = Buffer.from(await file.arrayBuffer());
+ fs.writeFileSync(`./public/img/${upload.url}`, upFolder);
+
+ return {
+ success: true,
+ data: upload,
+ };
+}
diff --git a/src/app_modules/katalog/profile/index.ts b/src/app_modules/katalog/profile/index.ts
index d4f97edc..a5081aaf 100644
--- a/src/app_modules/katalog/profile/index.ts
+++ b/src/app_modules/katalog/profile/index.ts
@@ -1,8 +1,17 @@
import ProfileLayout from "./create/layout";
import CreateProfile from "./create/view";
-import {getProfile} from "./fun/api-get-profile";
-import EditProfileLayout from './edit/layout';
-import EditProfileView from './edit/view'
+import { getProfile } from "./fun/api-get-profile";
+import EditProfileLayout from "./edit/layout";
+import EditProfileView from "./edit/view";
+import UploadFotoProfile from "./upload/view";
+import UploadFotoProfileLayout from "./upload/layout";
-
-export {ProfileLayout, CreateProfile, getProfile, EditProfileView, EditProfileLayout}
\ No newline at end of file
+export {
+ ProfileLayout,
+ CreateProfile,
+ getProfile,
+ EditProfileView,
+ EditProfileLayout,
+ UploadFotoProfile,
+ UploadFotoProfileLayout,
+};
diff --git a/src/app_modules/katalog/profile/upload/layout.tsx b/src/app_modules/katalog/profile/upload/layout.tsx
new file mode 100644
index 00000000..fc81d9d4
--- /dev/null
+++ b/src/app_modules/katalog/profile/upload/layout.tsx
@@ -0,0 +1,94 @@
+"use client";
+
+import {
+ ActionIcon,
+ AppShell,
+ FileButton,
+ Flex,
+ Footer,
+ Group,
+ Header,
+ Text,
+} from "@mantine/core";
+import { IconArrowLeft, IconUpload } from "@tabler/icons-react";
+import { useAtom } from "jotai";
+import toast from "react-simple-toasts";
+import { gs_profile } from "../state/global_state";
+import { useShallowEffect } from "@mantine/hooks";
+import { g_getProfile } from "../fun/fun_get_profile";
+import { funUploadFoto } from "../fun/upload_foto";
+import { useRouter } from "next/navigation";
+
+export default function UploadFotoProfileLayout({
+ children,
+}: {
+ children: any;
+}) {
+ const router = useRouter()
+ const [profile, setProfile] = useAtom(gs_profile);
+ useShallowEffect(() => {
+ g_getProfile(setProfile);
+ }, []);
+
+ return (
+ <>
+
+
+ router.push("/dev/katalog/view")}
+ >
+
+
+ Upload Foto Profile
+
+
+
+ }
+ footer={
+
+ }
+ >
+ {children}
+ {/* {JSON.stringify(profile)} */}
+
+ >
+ );
+}
diff --git a/src/app_modules/katalog/profile/upload/view.tsx b/src/app_modules/katalog/profile/upload/view.tsx
new file mode 100644
index 00000000..f4096940
--- /dev/null
+++ b/src/app_modules/katalog/profile/upload/view.tsx
@@ -0,0 +1,39 @@
+"use client";
+
+import { AspectRatio, FileButton, Image, Paper, Title } from "@mantine/core";
+import { useShallowEffect } from "@mantine/hooks";
+import { useAtom } from "jotai";
+import { g_getProfile } from "../fun/fun_get_profile";
+import { gs_profile } from "../state/global_state";
+import { getFotoProfile } from "../fun/get_foto_profile";
+import { useState } from "react";
+import { ApiHipmi } from "@/app/lib/api";
+import { myConsole } from "@/app/fun/my_console";
+
+export default function UploadFotoProfile() {
+ const [profile, setProfile] = useAtom(gs_profile);
+ useShallowEffect(() => {
+ g_getProfile(setProfile);
+ }, []);
+
+ const [foto, setFoto] = useState(null);
+ useShallowEffect(() => {
+ if (profile?.imagesId === undefined || profile?.imagesId === null) {
+ myConsole("Waiting data");
+ } else {
+ getFotoProfile(profile?.imagesId).then((res) => setFoto(res?.url));
+ }
+ }, [profile?.imagesId]);
+
+ return (
+ <>
+ {/* {JSON.stringify(foto)} */}
+
+
+ {foto ? : }
+
+
+ {/* {JSON.stringify(profile)} */}
+ >
+ );
+}
diff --git a/src/app_modules/katalog/view/view.tsx b/src/app_modules/katalog/view/view.tsx
index 682cbc10..6fe31f5e 100644
--- a/src/app_modules/katalog/view/view.tsx
+++ b/src/app_modules/katalog/view/view.tsx
@@ -29,7 +29,9 @@ import { getProfile } from "../profile";
import { gs_profile } from "../profile/state/global_state";
import { myConsole } from "@/app/fun/my_console";
import { useAtom } from "jotai";
-import { g_getProfile } from "../profile/fun/fun-get-profile";
+import { g_getProfile } from "../profile/fun/fun_get_profile";
+import { getFotoProfile } from "../profile/fun/get_foto_profile";
+import { ApiHipmi } from "@/app/lib/api";
export default function KatalogView() {
const router = useRouter();
@@ -40,20 +42,51 @@ export default function KatalogView() {
g_getProfile(setProfile);
}, []);
+ const [foto, setFoto] = useState(null);
+ useShallowEffect(() => {
+ if (profile?.imagesId === undefined || profile?.imagesId === null) {
+ myConsole("Waiting data");
+ } else {
+ getFotoProfile(profile?.imagesId).then((res) => setFoto(res?.url));
+ }
+ myConsole(profile?.imagesId);
+ }, [profile?.imagesId]);
+
return (
<>
+ {/* Background dan foto */}
-
+ {foto ? (
+
+ ) : (
+
+ )}
router.push("/dev/katalog/profile/upload")}
+ onClick={() => router.push("/dev/katalog/profile/upload")}
sx={{ position: "relative" }}
>
@@ -70,6 +103,7 @@ export default function KatalogView() {
+ {/* Username dan Nama */}
@@ -87,6 +121,7 @@ export default function KatalogView() {
+ {/* Info user: nomor, email dll */}
diff --git a/yarn.lock b/yarn.lock
index a2b17237..401c63e6 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -756,6 +756,11 @@
"@types/mime" "*"
"@types/node" "*"
+"@types/uuid@^9.0.4":
+ version "9.0.4"
+ resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-9.0.4.tgz#e884a59338da907bda8d2ed03e01c5c49d036f1c"
+ integrity sha512-zAuJWQflfx6dYJM62vna+Sn5aeSWhh3OB+wfUEACNcqUSc0AGc5JKl+ycL1vrH7frGTXhJchYjE1Hak8L819dA==
+
"@typescript-eslint/parser@^5.42.0":
version "5.62.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.62.0.tgz#1b63d082d849a2fcae8a569248fbe2ee1b8a56c7"
@@ -3533,6 +3538,11 @@ util-deprecate@^1.0.2, util-deprecate@~1.0.1:
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==
+uuid@^9.0.1:
+ version "9.0.1"
+ resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30"
+ integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==
+
watchpack@2.4.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d"