From 01942ef86981614689bcec3e0014b430d513a6af Mon Sep 17 00:00:00 2001 From: Bagasbanuna02 Date: Mon, 17 Feb 2025 10:36:20 +0800 Subject: [PATCH 1/4] tambahan .env.local --- run.env.local | 1 + run.prisma.env.local | 3 +++ src/app_modules/auth/invalid_user/view.tsx | 9 ++++++++- src/app_modules/forum/create/index.tsx | 6 ++---- 4 files changed, 14 insertions(+), 5 deletions(-) create mode 100644 run.env.local create mode 100644 run.prisma.env.local diff --git a/run.env.local b/run.env.local new file mode 100644 index 00000000..3e93d529 --- /dev/null +++ b/run.env.local @@ -0,0 +1 @@ +bun --env-file=.env.local run --bun dev \ No newline at end of file diff --git a/run.prisma.env.local b/run.prisma.env.local new file mode 100644 index 00000000..57a64842 --- /dev/null +++ b/run.prisma.env.local @@ -0,0 +1,3 @@ +bun --env-file=.env.local prisma db push +bun --env-file=.env.local prisma db seed +bun --env-file=.env.local run --bun build \ No newline at end of file diff --git a/src/app_modules/auth/invalid_user/view.tsx b/src/app_modules/auth/invalid_user/view.tsx index 737c74b1..fddda4a7 100644 --- a/src/app_modules/auth/invalid_user/view.tsx +++ b/src/app_modules/auth/invalid_user/view.tsx @@ -2,11 +2,13 @@ import { MainColor } from "@/app_modules/_global/color"; import { UIGlobal_LayoutDefault } from "@/app_modules/_global/ui"; -import { Button, Stack, Text, Title } from "@mantine/core"; +import { Button, Stack, Title } from "@mantine/core"; import { useRouter } from "next/navigation"; +import { useState } from "react"; export default function InvalidUser() { const router = useRouter(); + const [isLoading, setIsLoading] = useState(false); const deleteCookie = async () => { const sessionKey = process.env.NEXT_PUBLIC_BASE_SESSION_KEY!; if (!sessionKey) { @@ -14,12 +16,15 @@ export default function InvalidUser() { } try { + setIsLoading(true); await fetch("/api/auth/logout", { method: "GET", }); router.push("/login"); } catch (error) { console.error("Gagal menghapus cookie:", error); + } finally { + setIsLoading(false); } }; @@ -32,6 +37,8 @@ export default function InvalidUser() { Invalid User + + + ); +} diff --git a/src/app_modules/forum/component/card_loader.tsx b/src/app_modules/forum/component/card_loader.tsx deleted file mode 100644 index e3660996..00000000 --- a/src/app_modules/forum/component/card_loader.tsx +++ /dev/null @@ -1,25 +0,0 @@ -"use client"; - -import { Overlay, Center, Loader } from "@mantine/core"; - -export default function ComponentForum_CardLoadingOverlay({ - size, - variant, -}: { - size?: number; - variant?: any; -}) { - return ( - <> - -
- -
-
- - ); -} diff --git a/src/app_modules/forum/component/loading_drawer.tsx b/src/app_modules/forum/component/loading_drawer.tsx deleted file mode 100644 index 3a1a53ac..00000000 --- a/src/app_modules/forum/component/loading_drawer.tsx +++ /dev/null @@ -1,22 +0,0 @@ -"use client"; - -import { Center, Group, LoadingOverlay, Skeleton } from "@mantine/core"; - -export default function ComponentForum_LoadingDrawer() { - const customLoad = ( -
- - {Array(3) - .fill(0) - .map((e, i) => ( - - ))} - -
- ); - return ( - <> - {customLoad} - - ); -} diff --git a/src/app_modules/forum/component/main_component/card_more_button.tsx b/src/app_modules/forum/component/main_component/card_more_button.tsx index a248c564..bda87f56 100644 --- a/src/app_modules/forum/component/main_component/card_more_button.tsx +++ b/src/app_modules/forum/component/main_component/card_more_button.tsx @@ -37,6 +37,7 @@ import { AccentColor, MainColor, } from "@/app_modules/_global/color/color_pallet"; +import { clientLogger } from "@/util/clientLogger"; export default function ComponentForum_BerandaMoreButton({ authorId, @@ -255,11 +256,11 @@ function ButtonDelete({ const [loading, setLoading] = useState(false); async function onDelete() { - setOpenDel(false); - await forum_funDeletePostingById(postingId as any).then(async (res) => { - if (res.status === 200) { - ComponentGlobal_NotifikasiBerhasil(`Postingan Terhapus`, 2000); - setLoading(true); + try { + setLoading(true); + const deleteData = await forum_funDeletePostingById(postingId as any); + if (deleteData.status === 200) { + setOpenDel(false); const cloneData = _.clone(allData); const hapusData = cloneData.filter((e) => e.id !== postingId); @@ -272,10 +273,16 @@ function ButtonDelete({ data: hapusData, }) ); + + ComponentGlobal_NotifikasiBerhasil(`Postingan Terhapus`, 2000); } else { - ComponentGlobal_NotifikasiGagal(res.message); + setLoading(false); + ComponentGlobal_NotifikasiGagal(deleteData.message); } - }); + } catch (error) { + setLoading(false); + clientLogger.error("Error get data forum", error); + } } return ( <> @@ -324,120 +331,132 @@ function ButtonStatus({ const [loading, setLoading] = useState(false); async function onTutupForum() { - setOpenStatus(false); - - const upateStatusClose = await forum_funEditStatusPostingById( - postingId as any, - 2 - ); - if (upateStatusClose.status === 200) { - ComponentGlobal_NotifikasiBerhasil(`Forum Ditutup`, 2000); + try { setLoading(true); - - const cloneData = _.clone(allData); - const loadData = cloneData.map( - (e) => ( - e.id === postingId, - { - ...e, - ForumMaster_StatusPosting: { - id: e.id === postingId ? 2 : e.ForumMaster_StatusPosting.id, - status: - e.id === postingId - ? "Close" - : e.ForumMaster_StatusPosting.status, - }, - } - ) - ); - onLoadData(loadData); - - // - mqtt_client.publish( - "Forum_ganti_status", - JSON.stringify({ - id: postingId, - data: loadData, - }) + const upateStatusClose = await forum_funEditStatusPostingById( + postingId as any, + 2 ); - const findData = cloneData.find((val) => val.id === postingId); - const updateDetail = { - ...findData, - ForumMaster_StatusPosting: { - id: 2, - status: "Close", - }, - }; + if (upateStatusClose.status === 200) { + setOpenStatus(false); + ComponentGlobal_NotifikasiBerhasil(`Forum Ditutup`, 2000); - mqtt_client.publish( - "Forum_detail_ganti_status", - JSON.stringify({ - id: postingId, - data: updateDetail.ForumMaster_StatusPosting, - }) - ); - } else { - ComponentGlobal_NotifikasiGagal(upateStatusClose.message); + const cloneData = _.clone(allData); + const loadData = cloneData.map( + (e) => ( + e.id === postingId, + { + ...e, + ForumMaster_StatusPosting: { + id: e.id === postingId ? 2 : e.ForumMaster_StatusPosting.id, + status: + e.id === postingId + ? "Close" + : e.ForumMaster_StatusPosting.status, + }, + } + ) + ); + onLoadData(loadData); + + // + mqtt_client.publish( + "Forum_ganti_status", + JSON.stringify({ + id: postingId, + data: loadData, + }) + ); + + const findData = cloneData.find((val) => val.id === postingId); + const updateDetail = { + ...findData, + ForumMaster_StatusPosting: { + id: 2, + status: "Close", + }, + }; + + mqtt_client.publish( + "Forum_detail_ganti_status", + JSON.stringify({ + id: postingId, + data: updateDetail.ForumMaster_StatusPosting, + }) + ); + } else { + setLoading(false); + ComponentGlobal_NotifikasiGagal(upateStatusClose.message); + } + } catch (error) { + setLoading(false); + clientLogger.error("Error get data forum", error); } } async function onBukaForum() { - setOpenStatus(false); - - const updateStatusOpen = await forum_funEditStatusPostingById( - postingId as any, - 1 - ); - if (updateStatusOpen.status === 200) { - ComponentGlobal_NotifikasiBerhasil(`Forum Dibuka`, 2000); + try { setLoading(true); - - const cloneData = _.clone(allData); - const loadData = cloneData.map( - (e) => ( - e.id === postingId, - { - ...e, - ForumMaster_StatusPosting: { - id: e.id === postingId ? 1 : e.ForumMaster_StatusPosting.id, - status: - e.id === postingId - ? "Open" - : e.ForumMaster_StatusPosting.status, - }, - } - ) + const updateStatusOpen = await forum_funEditStatusPostingById( + postingId as any, + 1 ); - mqtt_client.publish( - "Forum_ganti_status", - JSON.stringify({ - id: postingId, - data: loadData, - }) - ); + if (updateStatusOpen.status === 200) { + setOpenStatus(false); + ComponentGlobal_NotifikasiBerhasil(`Forum Dibuka`, 2000); - onLoadData(loadData); + const cloneData = _.clone(allData); + const loadData = cloneData.map( + (e) => ( + e.id === postingId, + { + ...e, + ForumMaster_StatusPosting: { + id: e.id === postingId ? 1 : e.ForumMaster_StatusPosting.id, + status: + e.id === postingId + ? "Open" + : e.ForumMaster_StatusPosting.status, + }, + } + ) + ); - const findData = cloneData.find((val) => val.id === postingId); - const updateDetail = { - ...findData, - ForumMaster_StatusPosting: { - id: 1, - status: "Open", - }, - }; + mqtt_client.publish( + "Forum_ganti_status", + JSON.stringify({ + id: postingId, + data: loadData, + }) + ); - mqtt_client.publish( - "Forum_detail_ganti_status", - JSON.stringify({ - id: postingId, - data: updateDetail.ForumMaster_StatusPosting, - }) - ); - } else { - ComponentGlobal_NotifikasiGagal(updateStatusOpen.message); + onLoadData(loadData); + + const findData = cloneData.find((val) => val.id === postingId); + const updateDetail = { + ...findData, + ForumMaster_StatusPosting: { + id: 1, + status: "Open", + }, + }; + + mqtt_client.publish( + "Forum_detail_ganti_status", + JSON.stringify({ + id: postingId, + data: updateDetail.ForumMaster_StatusPosting, + }) + ); + } else { + setLoading(false); + ComponentGlobal_NotifikasiGagal(updateStatusOpen.message); + } + } catch (error) { + setLoading(false); + clientLogger.error("Error get data forum", error); } } @@ -461,7 +480,7 @@ function ButtonStatus({ {statusId === 1 ? ( - - - ); -} From 882fb8922b26170e11a573eb8f18f4a8e009599d Mon Sep 17 00:00:00 2001 From: Bagasbanuna02 Date: Mon, 17 Feb 2025 15:33:31 +0800 Subject: [PATCH 3/4] fix edit forum deskripsi: - fix edit forum --- src/app/api/forum/[id]/route.ts | 54 +++++++ src/app/dev/forum/edit/posting/[id]/page.tsx | 7 +- .../forum/component/api_fetch_forum.ts | 34 ++++- src/app_modules/forum/edit/posting/index.tsx | 135 ++++++++++-------- .../forum/fun/edit/fun_edit_posting_by_id.ts | 28 ++-- 5 files changed, 181 insertions(+), 77 deletions(-) create mode 100644 src/app/api/forum/[id]/route.ts diff --git a/src/app/api/forum/[id]/route.ts b/src/app/api/forum/[id]/route.ts new file mode 100644 index 00000000..9a18775f --- /dev/null +++ b/src/app/api/forum/[id]/route.ts @@ -0,0 +1,54 @@ +import backendLogger from "@/util/backendLogger"; +import { NextResponse } from "next/server"; + +export { GET }; + +async function GET(request: Request, { params }: { params: { id: string } }) { + try { + const { id } = params; + + const data = await prisma.forum_Posting.findUnique({ + where: { + id: id, + }, + select: { + id: true, + diskusi: true, + isActive: true, + createdAt: true, + authorId: true, + Author: { + select: { + id: true, + username: true, + Profile: true, + }, + }, + + _count: { + select: { + Forum_Komentar: true, + }, + }, + ForumMaster_StatusPosting: true, + forumMaster_StatusPostingId: true, + }, + }); + + return NextResponse.json({ + success: true, + message: "Success get data", + data: data, + }); + } catch (error) { + backendLogger.error("Error get data forum", error); + return NextResponse.json( + { + success: false, + message: "Error get data forum", + reason: (error as Error).message, + }, + { status: 500 } + ); + } +} diff --git a/src/app/dev/forum/edit/posting/[id]/page.tsx b/src/app/dev/forum/edit/posting/[id]/page.tsx index 292059f4..726a9ff6 100644 --- a/src/app/dev/forum/edit/posting/[id]/page.tsx +++ b/src/app/dev/forum/edit/posting/[id]/page.tsx @@ -1,13 +1,10 @@ import { Forum_EditPosting } from "@/app_modules/forum"; -import { forum_getOnePostingById } from "@/app_modules/forum/fun/get/get_one_posting_by_id"; -export default async function Page({ params }: { params: { id: string } }) { - let postingId = params.id; - const dataPosting = await forum_getOnePostingById(postingId) +export default async function Page() { return ( <> - + ); } diff --git a/src/app_modules/forum/component/api_fetch_forum.ts b/src/app_modules/forum/component/api_fetch_forum.ts index 0db2b443..50338352 100644 --- a/src/app_modules/forum/component/api_fetch_forum.ts +++ b/src/app_modules/forum/component/api_fetch_forum.ts @@ -1,4 +1,4 @@ -export { apiGetAllForum }; +export { apiGetAllForum, apiGetOneForumById }; const apiGetAllForum = async ({ page, @@ -39,3 +39,35 @@ const apiGetAllForum = async ({ throw error; // Re-throw the error to handle it in the calling function } }; + +const apiGetOneForumById = async ({ id }: { id: string }) => { + try { + const { token } = await fetch("/api/get-cookie").then((res) => res.json()); + if (!token) { + console.error("No token found"); + return null; + } + + const response = await fetch(`/api/forum/${id}`, { + method: "GET", + headers: { + "Content-Type": "application/json", + Accept: "application/json", + Authorization: `Bearer ${token}`, + }, + }); + + // Check if the response is OK + if (!response.ok) { + const errorData = await response.json().catch(() => null); + console.error("Failed to get all forum:", response.statusText, errorData); + throw new Error(errorData?.message || "Failed to get all forum"); + } + + // Return the JSON response + return await response.json(); + } catch (error) { + console.error("Error get all forum", error); + throw error; // Re-throw the error to handle it in the calling function + } +}; diff --git a/src/app_modules/forum/edit/posting/index.tsx b/src/app_modules/forum/edit/posting/index.tsx index d17d721e..5a7ae6f2 100644 --- a/src/app_modules/forum/edit/posting/index.tsx +++ b/src/app_modules/forum/edit/posting/index.tsx @@ -1,35 +1,23 @@ "use client"; -import { - ActionIcon, - Button, - Center, - Group, - Loader, - Paper, - Stack, -} from "@mantine/core"; -import "react-quill/dist/quill.snow.css"; -import "react-quill/dist/quill.bubble.css"; -import { IconPhotoUp } from "@tabler/icons-react"; +import { Button, Group, Paper, Stack } from "@mantine/core"; import { useShallowEffect } from "@mantine/hooks"; -import { useRouter } from "next/navigation"; -import ComponentGlobal_V2_LoadingPage from "@/app_modules/_global/loading_page_v2"; +import { useParams, useRouter } from "next/navigation"; +import "react-quill/dist/quill.bubble.css"; +import "react-quill/dist/quill.snow.css"; -import dynamic from "next/dynamic"; -import React, { useState } from "react"; -import { useAtom } from "jotai"; -import { gs_forum_loading_edit_posting } from "../../global_state"; -import { MODEL_FORUM_POSTING } from "../../model/interface"; -import { forum_funEditPostingById } from "../../fun/edit/fun_edit_posting_by_id"; +import { MainColor } from "@/app_modules/_global/color/color_pallet"; +import ComponentGlobal_InputCountDown from "@/app_modules/_global/component/input_countdown"; import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/_global/notif_global/notifikasi_berhasil"; import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/_global/notif_global/notifikasi_gagal"; import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/_global/notif_global/notifikasi_peringatan"; -import ComponentGlobal_InputCountDown from "@/app_modules/_global/component/input_countdown"; -import { - AccentColor, - MainColor, -} from "@/app_modules/_global/color/color_pallet"; +import CustomSkeleton from "@/app_modules/components/CustomSkeleton"; +import { clientLogger } from "@/util/clientLogger"; +import dynamic from "next/dynamic"; +import { useState } from "react"; +import { apiGetOneForumById } from "../../component/api_fetch_forum"; +import { forum_funEditPostingById } from "../../fun/edit/fun_edit_posting_by_id"; +import { MODEL_FORUM_POSTING } from "../../model/interface"; const ReactQuill = dynamic( () => { return import("react-quill"); @@ -37,23 +25,35 @@ const ReactQuill = dynamic( { ssr: false } ); -export default function Forum_EditPosting({ - dataPosting, -}: { - dataPosting: MODEL_FORUM_POSTING; -}) { - const [value, setValue] = useState(dataPosting); +const maxLength = 500; + +export default function Forum_EditPosting() { + const param = useParams<{ id: string }>(); + const [data, setData] = useState(null); const [reload, setReload] = useState(false); useShallowEffect(() => { if (window && window.document) setReload(true); }, []); - if (!reload) - return ( - <> - - - ); + useShallowEffect(() => { + handleLoadData(); + }, []); + + const handleLoadData = async () => { + try { + const response = await apiGetOneForumById({ + id: param.id, + }); + + if (response.success) { + setData(response.data); + } + } catch (error) { + clientLogger.error("Error get data forum", error); + } + }; + + if (!reload || !data) return ; return ( <> @@ -63,10 +63,21 @@ export default function Forum_EditPosting({ theme="bubble" placeholder="Apa yang sedang ingin dibahas ?" style={{ height: 150 }} - value={value.diskusi} + value={data.diskusi} onChange={(val) => { - setValue({ - ...value, + const input = val; + const text = input.replace(/<[^>]+>/g, "").trim(); // Remove HTML tags and trim whitespace + + if (text.length === 0) { + setData({ + ...data, + diskusi: "", + }); + + return; + } + setData({ + ...data, diskusi: val, }); }} @@ -74,15 +85,12 @@ export default function Forum_EditPosting({ - {/* - - */} - + {/*
*/} @@ -104,15 +112,21 @@ function ButtonAction({ if (diskusi === "


" || diskusi === "") return ComponentGlobal_NotifikasiPeringatan("Masukan postingan anda"); - await forum_funEditPostingById(postingId, diskusi).then((res) => { - if (res.status === 200) { - setLoading(true); - ComponentGlobal_NotifikasiBerhasil(res.message); - setTimeout(() => router.back(), 1000); + try { + setLoading(true); + const update = await forum_funEditPostingById(postingId, diskusi); + + if (update.status === 200) { + ComponentGlobal_NotifikasiBerhasil(update.message); + router.back(); } else { - ComponentGlobal_NotifikasiGagal(res.message); + ComponentGlobal_NotifikasiGagal(update.message); } - }); + } catch (error) { + clientLogger.error("Error update forum", error); + } finally { + setLoading(false); + } } return ( @@ -120,23 +134,24 @@ function ButtonAction({