diff --git a/src/app/(application)/profile/edit/page.tsx b/src/app/(application)/profile/edit/page.tsx index 6ca9661..da3e588 100644 --- a/src/app/(application)/profile/edit/page.tsx +++ b/src/app/(application)/profile/edit/page.tsx @@ -1,8 +1,8 @@ -import { ViewEditProfile } from "@/module/user" +import { EditProfile } from "@/module/user" function Page() { return ( - + ) } diff --git a/src/app/(application)/profile/page.tsx b/src/app/(application)/profile/page.tsx index 2c27402..b747f4e 100644 --- a/src/app/(application)/profile/page.tsx +++ b/src/app/(application)/profile/page.tsx @@ -1,8 +1,8 @@ -import { ViewProfile } from "@/module/user"; +import { Profile } from "@/module/user"; function Page() { return ( - + ) } diff --git a/src/app/api/user/profile/[id]/route.ts b/src/app/api/user/profile/[id]/route.ts new file mode 100644 index 0000000..1dc7be6 --- /dev/null +++ b/src/app/api/user/profile/[id]/route.ts @@ -0,0 +1,59 @@ +import { prisma } from "@/module/_global"; +import { funGetUserByCookies } from "@/module/auth"; +import { NextResponse } from "next/server"; + + +// UPDATE PROFILE BY COOKIES +export async function PUT(request: Request, context: { params: { id: string } }) { + try { + const user = await funGetUserByCookies() + if (user.id == undefined) { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }); + } + const { id } = context.params; + const data = await request.json(); + const cek = await prisma.user.count({ + where: { + id: id, + nik: data.nik, + email: data.email, + phone: data.phone + } + }) + if (cek == 0) { + return NextResponse.json( + { + success: false, + message: "Gagal mendapatkan profile, data tidak ditemukan", + }, + { status: 404 } + ); + } + + const result = await prisma.user.update({ + where: { + id: id, + }, + data: { + nik: data.nik, + name: data.name, + email: data.email, + phone: data.phone, + gender: data.gender, + }, + }); + + return NextResponse.json( + { + success: true, + message: "Berhasil mendapatkan profile", + result, + }, + { status: 200 } + ); + + } catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Gagal mendapatkan anggota, coba lagi nanti", reason: (error as Error).message, }, { status: 500 }); + } +} \ No newline at end of file diff --git a/src/app/api/user/profile/route.ts b/src/app/api/user/profile/route.ts new file mode 100644 index 0000000..63f8172 --- /dev/null +++ b/src/app/api/user/profile/route.ts @@ -0,0 +1,82 @@ +import { prisma } from "@/module/_global"; +import { funGetUserByCookies } from "@/module/auth"; +import _ from "lodash"; +import { NextResponse } from "next/server"; + + +// GET PROFILE BY COOKIES +export async function GET(request: Request) { + try { + const user = await funGetUserByCookies() + if (user.id == undefined) { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }); + } + const data = await prisma.user.findUnique({ + where: { + id: user.id + }, + select: { + id: true, + name: true, + email: true, + phone: true, + nik: true, + gender: true, + idGroup: true, + idPosition: true, + Group: { + select: { + name: true + } + }, + Position: { + select: { + name: true + } + } + } + }) + const { ...userData } = data; + const group = data?.Group.name + const position = data?.Position.name + + const result = { ...userData, group, position }; + + const omitData = _.omit(result, ["Group", "Position",]) + + return NextResponse.json({ success: true, data: omitData }); + } catch (error) { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }); + } + +} + +// UPDATE PROFILE BY COOKIES +export async function PUT(request: Request) { + try { + const user = await funGetUserByCookies() + if (user.id == undefined) { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }); + } + + const body = await request.json(); + const { name, email, phone, nik, gender } = body; + const data = await prisma.user.update({ + where: { + id: user.id + }, + data: { + name: name, + email: email, + phone: phone, + nik: nik, + gender: gender + } + }) + + return NextResponse.json({ success: true, message: "Berhasil ubah profile", data: data }); + } catch (error) { + return NextResponse.json({ success: false, message: "Gagal ubah profile" }, { status: 401 }); + } +} + diff --git a/src/module/_global/layout/layout_modal.tsx b/src/module/_global/layout/layout_modal.tsx index 7d1e779..93f0e44 100644 --- a/src/module/_global/layout/layout_modal.tsx +++ b/src/module/_global/layout/layout_modal.tsx @@ -19,7 +19,7 @@ export default function LayoutModal({ opened, onClose, description, onYes }: { o {description} - + diff --git a/src/module/discussion/ui/detail_discussion.tsx b/src/module/discussion/ui/detail_discussion.tsx index 1364b06..68658be 100644 --- a/src/module/discussion/ui/detail_discussion.tsx +++ b/src/module/discussion/ui/detail_discussion.tsx @@ -93,47 +93,90 @@ export default function DetailDiscussion({ id, idDivision }: { id: string, idDiv )) : - - - {isData?.username ? - - - - - {isData?.username} - - {isData?.status === 1 ? "BUKA" : "TUTUP"} - - : "" - } - {isData?.createdAt} - - - - + {isData?.totalComments == 0 ? + + - {isData?.desc} - - - - - {isData?.totalComments ? - - {isData?.totalComments} Komentar - : ""} + {isData?.username ? + + + + + {isData?.username} + + {isData?.status === 1 ? "BUKA" : "TUTUP"} + + : "" + } + {isData?.createdAt} + + + + + {isData?.desc} + + + + + {isData?.totalComments ? + + {isData?.totalComments} Komentar + : ""} - - + + : + + + {isData?.username ? + + + + + {isData?.username} + + {isData?.status === 1 ? "BUKA" : "TUTUP"} + + : "" + } + {isData?.createdAt} + + + + + {isData?.desc} + + + + + {isData?.totalComments ? + + {isData?.totalComments} Komentar + : ""} + + + + } + } - + {isLoad ? Array(2) .fill(0) @@ -167,7 +210,7 @@ export default function DetailDiscussion({ id, idDivision }: { id: string, idDiv )) : isData?.DivisionDisscussionComment.map((v, i) => { return ( - + { fetchData() }, [param.id]) - + const isMobile = useMediaQuery('(max-width: 399px)'); return ( @@ -69,7 +69,7 @@ export default function FeatureDetailDivision() { Tugas {feature?.tugas} Tugas - + {!isMobile && } @@ -94,7 +94,7 @@ export default function FeatureDetailDivision() { Dokumen {feature?.dokumen} File - + {!isMobile && } @@ -119,7 +119,7 @@ export default function FeatureDetailDivision() { Diskusi {feature?.diskusi} Diskusi - + {!isMobile && } @@ -144,7 +144,7 @@ export default function FeatureDetailDivision() { Kalender {feature?.kalender} Acara - + {!isMobile && } diff --git a/src/module/document/ui/navbar_document_division.tsx b/src/module/document/ui/navbar_document_division.tsx index 6e1365d..7d8f917 100644 --- a/src/module/document/ui/navbar_document_division.tsx +++ b/src/module/document/ui/navbar_document_division.tsx @@ -238,14 +238,14 @@ export default function NavbarDocumentDivision() { zIndex: 999, }}> - + 0) ? 'white' : 'grey'} /> - 0) ? 'white' : 'grey'}>Unduh + 0) ? 'white' : 'grey'}>Unduh setIsDelete(true)} justify={'center'} align={'center'} direction={'column'}> 0 && !shareSelected) ? 'white' : 'grey'} /> - 0 && !shareSelected) ? 'white' : 'grey'}>Hapus + 0 && !shareSelected) ? 'white' : 'grey'}>Hapus { if (selectedFiles.length == 1) { @@ -253,15 +253,15 @@ export default function NavbarDocumentDivision() { } }} justify={'center'} align={'center'} direction={'column'}> - Ganti Nama + Ganti Nama setShare(true)} justify={'center'} align={'center'} direction={'column'}> 0 && !shareSelected) ? 'white' : 'grey'} /> - 0 && !shareSelected) ? 'white' : 'grey'}>Bagikan + 0 && !shareSelected) ? 'white' : 'grey'}>Bagikan setMore(true)} justify={'center'} align={'center'} direction={'column'}> 0 && !shareSelected) ? 'white' : 'grey'} /> - 0 && !shareSelected) ? 'white' : 'grey'}>Lainnya + 0 && !shareSelected) ? 'white' : 'grey'}>Lainnya @@ -269,15 +269,13 @@ export default function NavbarDocumentDivision() { )} - setOpen(true)} variant="light" bg={WARNA.bgIcon} size="lg" radius="lg" aria-label="Settings"> } /> - - diff --git a/src/module/user/index.ts b/src/module/user/index.ts index af89e21..e898624 100644 --- a/src/module/user/index.ts +++ b/src/module/user/index.ts @@ -1,11 +1,13 @@ import { TypeUser } from './lib/type_user'; import createLogUser from "./log/fun/createLogUser"; -import ViewEditProfile from "./profile/view/view_edit_profile"; import ViewProfile from "./profile/view/view_profile"; import { funGetAllmember } from './member/lib/api_member'; +import Profile from './profile/ui/profile'; +import EditProfile from './profile/ui/edit_profile'; export { ViewProfile }; -export { ViewEditProfile }; export { createLogUser }; export type { TypeUser } export { funGetAllmember } +export { Profile } +export { EditProfile } diff --git a/src/module/user/member/ui/create_member.tsx b/src/module/user/member/ui/create_member.tsx index fbd6c08..b07d12b 100644 --- a/src/module/user/member/ui/create_member.tsx +++ b/src/module/user/member/ui/create_member.tsx @@ -273,8 +273,8 @@ export default function CreateMember() { onBlur={() => setTouched({ ...touched, nik: true })} error={ touched.nik && ( - listData.nik == "" ? "NIK Tidak Boleh Kosong" : - listData.nik.length < 16 ? "NIK Harus 16 Karakter" : null + listData.nik === "" ? "NIK Tidak Boleh Kosong" : + listData.nik.length !== 16 ? "NIK Harus 16 Karakter" : null ) } /> diff --git a/src/module/user/member/ui/edit_member.tsx b/src/module/user/member/ui/edit_member.tsx index af68033..ba64dbc 100644 --- a/src/module/user/member/ui/edit_member.tsx +++ b/src/module/user/member/ui/edit_member.tsx @@ -250,10 +250,10 @@ export default function EditMember({ id }: { id: string }) { onBlur={() => setTouched({ ...touched, nik: true })} error={ touched.nik && ( - data.nik == "" ? "NIK Tidak Boleh Kosong" : - data.nik.length < 16 ? "NIK Harus 16 Karakter" : null + data.nik === "" ? "NIK Tidak Boleh Kosong" : + data.nik.length !== 16 ? "NIK Harus 16 Karakter" : null ) - } + } /> - - - - - - - - - - { + setData({ ...data, gender: val }) + setTouched({ ...touched, gender: false }) + }} + value={data.gender} + onBlur={() => setTouched({ ...touched, gender: true })} + error={ + touched.gender && ( + data.gender == "" ? "Gender Tidak Boleh Kosong" : null + ) + } + /> + + + + + setValModal(false)} + description="Apakah Anda yakin ingin + melakukan perubahan data?" + onYes={(val) => { onEditProfile(val) }} /> + + ) +} + diff --git a/src/module/user/profile/ui/profile.tsx b/src/module/user/profile/ui/profile.tsx new file mode 100644 index 0000000..dc435c1 --- /dev/null +++ b/src/module/user/profile/ui/profile.tsx @@ -0,0 +1,135 @@ +"use client" +import { LayoutIconBack, LayoutNavbarHome, SkeletonDetailProfile, WARNA } from "@/module/_global"; +import { ActionIcon, Anchor, Box, Button, Flex, Group, Skeleton, Stack, Text } from "@mantine/core"; +import { BsInfo } from "react-icons/bs"; +import { HiUser } from "react-icons/hi2"; +import { RiIdCardFill } from "react-icons/ri"; +import { FaSquarePhone } from "react-icons/fa6"; +import { MdEmail } from "react-icons/md"; +import { InfoTitleProfile } from "../component/ui/ui_profile"; +import { IoMaleFemale } from "react-icons/io5"; +import toast from "react-hot-toast"; +import { LuLogOut } from "react-icons/lu"; +import LayoutModal from "@/module/_global/layout/layout_modal"; +import { useState } from "react"; +import { funGetProfileByCookies } from "../lib/api_profile"; +import { useShallowEffect } from "@mantine/hooks"; +import { IProfileById } from "../lib/type_profile"; +import { useRouter } from "next/navigation"; + +export default function Profile() { + const [openModal, setOpenModal] = useState(false); + const [isData, setData] = useState() + const router = useRouter() + const [loading, setLoading] = useState(true) + + async function getData() { + try { + setLoading(true) + const res = await funGetProfileByCookies() + setData(res.data) + setLoading(false) + } catch (error) { + console.error(error); + } finally { + setLoading(false) + } + } + + useShallowEffect(() => { + getData() + }, []) + + async function onLogout(val: boolean) { + try { + if (val) { + await fetch('/api/auth/logout', { + method: 'DELETE', + }); + toast.success('Logout Success') + window.location.href = '/'; + } + + setOpenModal(false) + + } catch (error) { + console.error(error); + } + } + return ( + <> + + + + + + { setOpenModal(true) }} variant="light" bg={WARNA.bgIcon} size="lg" radius="lg" aria-label="Info"> + + + + + + {loading ? + + : + <> + {isData?.name} + {isData?.group} - {isData?.position} + + } + + + {loading + ? + + : + + + Informasi + router.push(`/profile/edit/`)}>Edit + + + + + NIK + + {isData?.nik} + + + + + No Telepon + + {isData?.phone} + + + + + Email + + {isData?.email} + + + + + Gender + + + {isData?.gender === 'M' ? 'Laki-laki' : isData?.gender === 'F' ? 'Perempuan' : ''} + + + + + } + + setOpenModal(false)} + description="Apakah Anda yakin ingin Keluar?" + onYes={(val) => onLogout(val)} /> + + ) +} + diff --git a/src/module/user/profile/view/view_edit_profile.tsx b/src/module/user/profile/view/view_edit_profile.tsx deleted file mode 100644 index 4f93b49..0000000 --- a/src/module/user/profile/view/view_edit_profile.tsx +++ /dev/null @@ -1,7 +0,0 @@ -import EditProfile from "../component/edit_profile"; - -export default function ViewEditProfile() { - return ( - - ) -} \ No newline at end of file