diff --git a/src/app/api/profile/[id]/route.ts b/src/app/api/profile/[id]/route.ts new file mode 100644 index 00000000..5346b985 --- /dev/null +++ b/src/app/api/profile/[id]/route.ts @@ -0,0 +1,111 @@ +import { prisma } from "@/app/lib"; +import { funGetUserIdByToken } from "@/app_modules/_global/fun/get"; +import backendLogger from "@/util/backendLogger"; +import { NextResponse } from "next/server"; + +export { GET, PUT }; +async function GET(request: Request, { params }: { params: { id: string } }) { + if (request.method !== "GET") { + return NextResponse.json( + { success: false, message: "Method not allowed" }, + { status: 405 } + ); + } + + try { + let fixData; + const { id } = params; + + fixData = await prisma.profile.findFirst({ + where: { + id: id, + }, + include: { + User: true, + }, + }); + + return NextResponse.json( + { + success: true, + message: "Success get profile", + data: fixData, + }, + { status: 200 } + ); + } catch (error) { + backendLogger.error("Error get profile", error); + return NextResponse.json( + { + success: false, + message: "Error get profile", + reason: (error as Error).message, + }, + { status: 500 } + ); + } +} + +async function PUT(request: Request) { + if (request.method !== "PUT") { + return NextResponse.json( + { success: false, message: "Method not allowed" }, + { status: 405 } + ); + } + + try { + const body = await request.json(); + const { data } = body; + + const cekEmail = await prisma.profile.findUnique({ + where: { + email: data.email, + }, + }); + + if (cekEmail && cekEmail.id != data.id) + return NextResponse.json( + { success: false, message: "Email sudah digunakan" }, + { status: 400 } + ); + + const updateData = await prisma.profile.update({ + where: { + id: data.id, + }, + data: { + name: data.name, + email: data.email, + alamat: data.alamat, + jenisKelamin: data.jenisKelamin, + }, + }); + + if (!updateData) { + return NextResponse.json( + { success: false, message: "Gagal update" }, + { + status: 400, + } + ); + } + + return NextResponse.json( + { success: true, message: "Berhasil edit profile" }, + { status: 200 } + ); + } catch (error) { + backendLogger.error("Error edit profile", error); + return NextResponse.json( + { + success: false, + message: "Error edit profile", + reason: (error as Error).message, + }, + { status: 500 } + ); + } finally { + await prisma.$disconnect(); + } +} diff --git a/src/app/dev/profile/edit/[id]/page.tsx b/src/app/dev/profile/edit/[id]/page.tsx index 1941dc84..b1ec31b1 100644 --- a/src/app/dev/profile/edit/[id]/page.tsx +++ b/src/app/dev/profile/edit/[id]/page.tsx @@ -1,13 +1,10 @@ import EditProfile from "@/app_modules/katalog/profile/edit/view"; -import { Profile_getOneProfileAndUserById } from "@/app_modules/katalog/profile/fun/get/get_one_user_profile"; -export default async function Page({ params }: { params: { id: string } }) { - let profileId = params.id; - const dataProfile = await Profile_getOneProfileAndUserById(profileId); +export default async function Page() { return ( <> - + ); } diff --git a/src/app_modules/katalog/profile/_component/skeleton_view.tsx b/src/app_modules/katalog/profile/_component/skeleton_view.tsx new file mode 100644 index 00000000..7a897c09 --- /dev/null +++ b/src/app_modules/katalog/profile/_component/skeleton_view.tsx @@ -0,0 +1,17 @@ +import CustomSkeleton from "@/app_modules/components/CustomSkeleton"; +import { Stack } from "@mantine/core"; + +export { Profile_SkeletonViewEdit }; + +function Profile_SkeletonViewEdit() { + return ( + <> + + {Array.from({ length: 4 }).map((_, i) => ( + + ))} + + + + ); +} \ No newline at end of file diff --git a/src/app_modules/katalog/profile/edit/view.tsx b/src/app_modules/katalog/profile/edit/view.tsx index fbc03f80..c2a26512 100644 --- a/src/app_modules/katalog/profile/edit/view.tsx +++ b/src/app_modules/katalog/profile/edit/view.tsx @@ -6,52 +6,69 @@ import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/_global/noti import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/_global/notif_global/notifikasi_berhasil"; import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/_global/notif_global/notifikasi_gagal"; import { clientLogger } from "@/util/clientLogger"; -import { Button, Loader, Select, Stack, TextInput } from "@mantine/core"; +import { Button, Select, Stack, TextInput } from "@mantine/core"; +import { useShallowEffect } from "@mantine/hooks"; import _ from "lodash"; -import { useRouter } from "next/navigation"; +import { useParams, useRouter } from "next/navigation"; import { useState } from "react"; import { emailRegex } from "../../component/regular_expressions"; -import { Profile_funEditById } from "../fun/update/fun_edit_profile_by_id"; +import { Profile_SkeletonViewEdit } from "../_component/skeleton_view"; +import { + apiGetOneProfileById, + apiUpdateProfile, +} from "../lib/api_fetch_profile"; import { MODEL_PROFILE } from "../model/interface"; -export default function EditProfile({ data }: { data: MODEL_PROFILE }) { +export default function EditProfile() { const router = useRouter(); + const params = useParams<{ id: string }>(); + const profileId = params.id; //Get data profile - const [dataProfile, setDataProfile] = useState(data); + const [data, setData] = useState(null); const [loading, setLoading] = useState(false); - async function onUpdate() { - const body = dataProfile; + useShallowEffect(() => { + onLoadData(); + }, []); + async function onLoadData() { + try { + const respone = await apiGetOneProfileById({ id: profileId }); + + if (respone) { + setData(respone.data); + } + } catch (error) { + clientLogger.error("Error get data profile", error); + } + } + + async function onUpdate() { // console.log(body) - if (_.values(body).includes("")) + if (_.values(data).includes("")) return ComponentGlobal_NotifikasiPeringatan("Lengkapi data"); - if (!body.email.match(emailRegex)) + if (!data?.email.match(emailRegex)) return ComponentGlobal_NotifikasiPeringatan("Format email salah"); try { setLoading(true); - const res = await Profile_funEditById(body); - if (res.status === 200) { - ComponentGlobal_NotifikasiBerhasil(res.message); + const respone = await apiUpdateProfile({ data: data }); + + if (respone && respone.success == true) { + ComponentGlobal_NotifikasiBerhasil(respone.message); router.back(); } else { setLoading(false); - ComponentGlobal_NotifikasiGagal(res.message); + ComponentGlobal_NotifikasiGagal(respone.message); } } catch (error) { setLoading(false); - clientLogger.error("Error update foto profile", error); + clientLogger.error("Error client update profile", error); } } - if (!dataProfile) - return ( - <> - - - ); + if (!data) return ; return ( <> @@ -108,16 +125,16 @@ export default function EditProfile({ data }: { data: MODEL_PROFILE }) { placeholder="nama" maxLength={50} error={ - dataProfile?.name === "" ? ( + data?.name === "" ? ( ) : ( "" ) } - value={dataProfile?.name} + value={data?.name} onChange={(val) => { - setDataProfile({ - ...dataProfile, + setData({ + ...data, name: val.target.value, }); }} @@ -136,19 +153,18 @@ export default function EditProfile({ data }: { data: MODEL_PROFILE }) { label="Email" placeholder="email" error={ - dataProfile?.email === "" ? ( + data?.email === "" ? ( - ) : dataProfile?.email?.length > 0 && - !dataProfile?.email.match(emailRegex) ? ( + ) : data?.email?.length > 0 && !data?.email.match(emailRegex) ? ( ) : ( "" ) } - value={dataProfile?.email} + value={data?.email} onChange={(val) => { - setDataProfile({ - ...dataProfile, + setData({ + ...data, email: val.target.value, }); }} @@ -166,18 +182,18 @@ export default function EditProfile({ data }: { data: MODEL_PROFILE }) { withAsterisk label="Alamat" placeholder="alamat" - value={dataProfile.alamat} + value={data.alamat} maxLength={100} error={ - dataProfile?.alamat === "" ? ( + data?.alamat === "" ? ( ) : ( "" ) } onChange={(val) => { - setDataProfile({ - ...dataProfile, + setData({ + ...data, alamat: val.target.value, }); }} @@ -194,14 +210,14 @@ export default function EditProfile({ data }: { data: MODEL_PROFILE }) { }} withAsterisk label="Jenis Kelamin" - value={dataProfile?.jenisKelamin} + value={data?.jenisKelamin} data={[ { value: "Laki-laki", label: "Laki-laki" }, { value: "Perempuan", label: "Perempuan" }, ]} onChange={(val: any) => { - setDataProfile({ - ...dataProfile, + setData({ + ...data, jenisKelamin: val, }); }} @@ -213,14 +229,13 @@ export default function EditProfile({ data }: { data: MODEL_PROFILE }) { bg={MainColor.yellow} color="yellow" c={"black"} - loading={loading ? true : false} + loading={loading} loaderPosition="center" onClick={() => onUpdate()} > Update - ); } diff --git a/src/app_modules/katalog/profile/fun/get/get_one_user_profile.ts b/src/app_modules/katalog/profile/fun/get/get_one_user_profile.ts deleted file mode 100644 index af986a3e..00000000 --- a/src/app_modules/katalog/profile/fun/get/get_one_user_profile.ts +++ /dev/null @@ -1,16 +0,0 @@ -"use server"; - -import prisma from "@/app/lib/prisma"; - -export async function Profile_getOneProfileAndUserById(profileId: string) { - const data = await prisma.profile.findFirst({ - where: { - id: profileId, - }, - include: { - User: true, - }, - }); - // console.log(data) - return data; -} diff --git a/src/app_modules/katalog/profile/lib/api_fetch_profile.ts b/src/app_modules/katalog/profile/lib/api_fetch_profile.ts new file mode 100644 index 00000000..2f2440dd --- /dev/null +++ b/src/app_modules/katalog/profile/lib/api_fetch_profile.ts @@ -0,0 +1,38 @@ +import { MODEL_PROFILE } from "../model/interface"; + +export { apiUpdateProfile, apiGetOneProfileById }; + +const apiGetOneProfileById = async ({ id }: { id: string }) => { + const { token } = await fetch("/api/get-cookie").then((res) => res.json()); + if (!token) return await token.json().catch(() => null); + + const res = await fetch(`/api/profile/${id}`, { + method: "GET", + headers: { + "Content-Type": "application/json", + Accept: "application/json", + "Access-Control-Allow-Origin": "*", + Authorization: `Bearer ${token}`, + }, + }); + + return await res.json().catch(() => null); +}; + +const apiUpdateProfile = async ({ data }: { data: MODEL_PROFILE }) => { + const { token } = await fetch("/api/get-cookie").then((res) => res.json()); + if (!token) return await token.json().catch(() => null); + + const res = await fetch(`/api/profile/${data.id}`, { + method: "PUT", + body: JSON.stringify({ data }), + headers: { + "Content-Type": "application/json", + Accept: "application/json", + "Access-Control-Allow-Origin": "*", + Authorization: `Bearer ${token}`, + }, + }); + + return await res.json().catch(() => null); +}; diff --git a/src/middleware.ts b/src/middleware.ts index 47e2d063..1d574b67 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -32,6 +32,7 @@ const middlewareConfig: MiddlewareConfig = { "/api/auth/*", "/api/origin-url", "/api/event/*", + "/api/profile/*", // "/api/master/*", // "/api/image/*", // "/api/user/*",