diff --git a/run.build.dev b/run.build.dev deleted file mode 100644 index 49348626..00000000 --- a/run.build.dev +++ /dev/null @@ -1 +0,0 @@ -nice -n 19 bun --env-file=.env.build run --bun build diff --git a/run.env.build.dev b/run.env.build.dev new file mode 100644 index 00000000..f8351819 --- /dev/null +++ b/run.env.build.dev @@ -0,0 +1 @@ +nice -n 19 bun --env-file=.env run --bun build diff --git a/run.env.local b/run.env.build.local similarity index 100% rename from run.env.local rename to run.env.build.local diff --git a/run.dev b/run.env.dev similarity index 100% rename from run.dev rename to run.env.dev diff --git a/run.env.start.dev b/run.env.start.dev new file mode 100644 index 00000000..e802570f --- /dev/null +++ b/run.env.start.dev @@ -0,0 +1 @@ +nice -n 19 bun --env-file=.env run --bun start \ No newline at end of file diff --git a/run.env.strat.local b/run.env.strat.local new file mode 100644 index 00000000..e69de29b diff --git a/src/app/api/forum/[id]/komentar/route.ts b/src/app/api/forum/[id]/komentar/route.ts new file mode 100644 index 00000000..404bcb16 --- /dev/null +++ b/src/app/api/forum/[id]/komentar/route.ts @@ -0,0 +1,93 @@ +import backendLogger from "@/util/backendLogger"; +import { NextResponse } from "next/server"; + +export { GET }; + +async function GET(request: Request, { params }: { params: { id: string } }) { + try { + let fixData; + const { id } = params; + const { searchParams } = new URL(request.url); + const page = searchParams.get("page"); + const takeData = 5; + const skipData = Number(page) * takeData - takeData; + + if (!page) { + fixData = await prisma.forum_Komentar.findMany({ + orderBy: { + createdAt: "desc", + }, + where: { + forum_PostingId: id, + isActive: true, + }, + select: { + id: true, + isActive: true, + komentar: true, + createdAt: true, + Author: { + select: { + id: true, + username: true, + Profile: { + select: { + name: true, + imageId: true, + }, + }, + }, + }, + authorId: true, + }, + }); + } else { + fixData = await prisma.forum_Komentar.findMany({ + take: takeData, + skip: skipData, + orderBy: { + createdAt: "desc", + }, + where: { + forum_PostingId: id, + isActive: true, + }, + select: { + id: true, + isActive: true, + komentar: true, + createdAt: true, + Author: { + select: { + id: true, + username: true, + Profile: { + select: { + name: true, + imageId: true, + }, + }, + }, + }, + authorId: true, + }, + }); + } + + return NextResponse.json({ + success: true, + message: "Berhasil mendapatkan data", + data: fixData, + }); + } catch (error) { + backendLogger.error("Error Get Forum Komentar >>", error); + return NextResponse.json( + { + success: false, + message: "API Error Get Data", + reason: (error as Error).message, + }, + { status: 500 } + ); + } +} diff --git a/src/app/dev/forum/detail/main-detail/[id]/page.tsx b/src/app/dev/forum/detail/main-detail/[id]/page.tsx index b48bb504..3905795f 100644 --- a/src/app/dev/forum/detail/main-detail/[id]/page.tsx +++ b/src/app/dev/forum/detail/main-detail/[id]/page.tsx @@ -10,21 +10,19 @@ export default async function Page({ params }: { params: { id: string } }) { let postingId = params.id; const userLoginId = await funGetUserIdByToken(); - const dataPosting = await forum_getOnePostingById(postingId); + // const dataPosting = await forum_getOnePostingById(postingId); const listKomentar = await forum_funGetAllKomentarById({ postingId: postingId, page: 1, }); - // dataPosting?.isActive === false && redirect(RouterForum.beranda); - const countKomentar = await forum_countTotalKomenById(postingId); return ( <> diff --git a/src/app/zCoba/skeleton/page.tsx b/src/app/zCoba/skeleton/page.tsx index 5e0c03ad..2e5b8aa9 100644 --- a/src/app/zCoba/skeleton/page.tsx +++ b/src/app/zCoba/skeleton/page.tsx @@ -16,24 +16,24 @@ export default function Voting_ComponentSkeletonViewPuh() { header={} > -
- -
- - - - - - - + + + - - + + + + - + + + + + +
{/* diff --git a/src/app_modules/forum/component/api_fetch_forum.ts b/src/app_modules/forum/component/api_fetch_forum.ts index 6bf3d540..08f00db1 100644 --- a/src/app_modules/forum/component/api_fetch_forum.ts +++ b/src/app_modules/forum/component/api_fetch_forum.ts @@ -1,4 +1,9 @@ -export { apiGetAllForum, apiGetOneForumById, apiGetForumkuById }; +export { + apiGetAllForum, + apiGetOneForumById, + apiGetForumkuByUserId as apiGetForumkuById, + apiGetKomentarForumById, +}; const apiGetAllForum = async ({ page, @@ -72,7 +77,7 @@ const apiGetOneForumById = async ({ id }: { id: string }) => { } }; -const apiGetForumkuById = async ({ +const apiGetForumkuByUserId = async ({ id, page, }: { @@ -111,3 +116,37 @@ const apiGetForumkuById = async ({ throw error; // Re-throw the error to handle it in the calling function } }; + +const apiGetKomentarForumById = async ({ id , page}: { id: string , page: string}) => { + try { + // Fetch token from cookie + const { token } = await fetch("/api/get-cookie").then((res) => res.json()); + if (!token) { + console.error("No token found"); + return null; + } + + const nextPage = `?page=${page}`; + const response = await fetch(`/api/forum/${id}/komentar${nextPage}`, { + 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/component/detail_component/detail_create_komentar.tsx b/src/app_modules/forum/component/detail_component/detail_create_komentar.tsx index a07eb6e0..224220aa 100644 --- a/src/app_modules/forum/component/detail_component/detail_create_komentar.tsx +++ b/src/app_modules/forum/component/detail_component/detail_create_komentar.tsx @@ -19,16 +19,20 @@ import { MODEL_FORUM_POSTING } from "../../model/interface"; import { useRouter } from "next/navigation"; import { MainColor } from "@/app_modules/_global/color/color_pallet"; import mqtt_client from "@/util/mqtt_client"; +import backendLogger from "@/util/backendLogger"; +import { clientLogger } from "@/util/clientLogger"; export default function ComponentForum_DetailCreateKomentar({ postingId, onSetKomentar, data, userLoginId, + onSetNewKomentar, }: { postingId: string; onSetKomentar: (val: any) => void; data: MODEL_FORUM_POSTING; userLoginId: string; + onSetNewKomentar: (val: boolean) => void; }) { const router = useRouter(); const [value, setValue] = useState(""); @@ -40,45 +44,52 @@ export default function ComponentForum_DetailCreateKomentar({ return null; } - const createComment = await forum_funCreateKomentar(postingId, value); - if (createComment.status === 201) { - // const loadKomentar = await forum_funGetAllKomentarById(data.id); + try { + setLoading(true); + const createComment = await forum_funCreateKomentar(postingId, value); + if (createComment.status === 201) { + // const loadData = await forum_funGetAllKomentarById({ + // postingId: data.id, + // page: 1, + // }); + // onSetKomentar(loadData); - const loadData = await forum_funGetAllKomentarById({ - postingId: data.id, - page: 1, - }); - onSetKomentar(loadData); + onSetNewKomentar(true); + setValue(""); + setIsEmpty(true); + ComponentGlobal_NotifikasiBerhasil(createComment.message, 2000); - setValue(""); - setIsEmpty(true); - ComponentGlobal_NotifikasiBerhasil(createComment.message, 2000); + if (userLoginId !== data.Author.id) { + const dataNotif = { + appId: data.id, + userId: data.authorId, + pesan: value, + kategoriApp: "FORUM", + title: "Komentar baru", + }; - if (userLoginId !== data.Author.id) { - const dataNotif = { - appId: data.id, - userId: data.authorId, - pesan: value, - kategoriApp: "FORUM", - title: "Komentar baru", - }; + const createNotifikasi = await notifikasiToUser_funCreate({ + data: dataNotif as any, + }); - const createNotifikasi = await notifikasiToUser_funCreate({ - data: dataNotif as any, - }); - - if (createNotifikasi.status === 201) { - mqtt_client.publish( - "USER", - JSON.stringify({ - userId: dataNotif.userId, - count: 1, - }) - ); + if (createNotifikasi.status === 201) { + mqtt_client.publish( + "USER", + JSON.stringify({ + userId: dataNotif.userId, + count: 1, + }) + ); + } } + } else { + setLoading(false); + ComponentGlobal_NotifikasiGagal(createComment.message); } - } else { - ComponentGlobal_NotifikasiGagal(createComment.message); + } catch (error) { + setLoading(false); + + clientLogger.error("Error create komentar forum", error); } } @@ -117,8 +128,9 @@ export default function ComponentForum_DetailCreateKomentar({ } bg={MainColor.yellow} color={"yellow"} + c="black" loaderPosition="center" - loading={loading ? true : false} + loading={loading} radius={"xl"} onClick={() => onComment()} > diff --git a/src/app_modules/forum/component/detail_component/detail_list_komentar.tsx b/src/app_modules/forum/component/detail_component/detail_list_komentar.tsx index 04c42e52..1232555b 100644 --- a/src/app_modules/forum/component/detail_component/detail_list_komentar.tsx +++ b/src/app_modules/forum/component/detail_component/detail_list_komentar.tsx @@ -1,14 +1,9 @@ "use client"; -import { - Card, - Divider, - Spoiler, - Stack, - Text -} from "@mantine/core"; +import { Card, Divider, Spoiler, Stack, Text } from "@mantine/core"; import { MODEL_FORUM_KOMENTAR } from "../../model/interface"; import ComponentForum_KomentarAuthorNameOnHeader from "../komentar_component/komentar_author_header_name"; +import { ComponentGlobal_CardStyles } from "@/app_modules/_global/component"; export default function ComponentForum_KomentarView({ data, @@ -23,65 +18,34 @@ export default function ComponentForum_KomentarView({ }) { return ( <> - - - - - - - - {data.komentar ? ( - -
- - ) : ( - "" - )} - - - + + - - - - - - - - {/* - {_.isEmpty(data) ? ( -
- - Belum ada komentar - -
- ) : ( - -
- - {" "} - Komentar - -
- {data.map((e, i) => ( - - ))} -
- )} -
*/} + + + {data.komentar ? ( + +
+ + ) : ( + "" + )} + + + ); } diff --git a/src/app_modules/forum/component/komentar_component/komentar_author_header_name.tsx b/src/app_modules/forum/component/komentar_component/komentar_author_header_name.tsx index 344c8087..46c0f76f 100644 --- a/src/app_modules/forum/component/komentar_component/komentar_author_header_name.tsx +++ b/src/app_modules/forum/component/komentar_component/komentar_author_header_name.tsx @@ -12,6 +12,7 @@ import { ComponentGlobal_LoaderAvatar } from "@/app_modules/_global/component"; import ComponentGlobal_Loader from "@/app_modules/_global/component/loader"; import { data } from "autoprefixer"; import { MODEL_PROFILE } from "@/app_modules/katalog/profile/model/interface"; +import moment from "moment"; export default function ComponentForum_KomentarAuthorNameOnHeader({ userId, @@ -84,10 +85,11 @@ export default function ComponentForum_KomentarAuthorNameOnHeader({ {tglPublish - ? tglPublish.toLocaleDateString(["id-ID"], { + ? new Intl.DateTimeFormat("id-ID", { day: "numeric", month: "short", - }) + year: "numeric", + }).format(new Date(tglPublish)) : new Date().toLocaleDateString(["id-ID"], { day: "numeric", month: "short", diff --git a/src/app_modules/forum/component/skeleton_view.tsx b/src/app_modules/forum/component/skeleton_view.tsx index 44241208..67b6c18e 100644 --- a/src/app_modules/forum/component/skeleton_view.tsx +++ b/src/app_modules/forum/component/skeleton_view.tsx @@ -1,7 +1,12 @@ import CustomSkeleton from "@/app_modules/components/CustomSkeleton"; import { Center, Grid, Group, Stack } from "@mantine/core"; -export { Forum_SkeletonCard, Forum_SkeletonForumku }; +export { + Forum_SkeletonCard, + Forum_SkeletonForumku, + Forum_SkeletonKomentar, + Forum_SkeletonListKomentar, +}; function Forum_SkeletonCard() { return ( @@ -14,7 +19,7 @@ function Forum_SkeletonCard() { ); } -function Forum_SkeletonForumku(){ +function Forum_SkeletonForumku() { return ( <> @@ -40,3 +45,29 @@ function Forum_SkeletonForumku(){ ); } + +function Forum_SkeletonKomentar() { + return ( + <> + + + + + + + + + ); +} + +function Forum_SkeletonListKomentar() { + return ( + <> + + {Array.from(new Array(2)).map((e, i) => ( + + ))} + + + ); +} diff --git a/src/app_modules/forum/detail/main_detail.tsx b/src/app_modules/forum/detail/main_detail.tsx index 2ee67ed4..c0353948 100644 --- a/src/app_modules/forum/detail/main_detail.tsx +++ b/src/app_modules/forum/detail/main_detail.tsx @@ -1,6 +1,6 @@ "use client"; -import { Box, Center, Loader, Stack, TextInput } from "@mantine/core"; +import { Box, Center, Group, Loader, Stack, TextInput } from "@mantine/core"; import _ from "lodash"; import { MODEL_FORUM_KOMENTAR, MODEL_FORUM_POSTING } from "../model/interface"; import mqtt_client from "@/util/mqtt_client"; @@ -12,41 +12,99 @@ import ComponentForum_KomentarView from "../component/detail_component/detail_li import ComponentForum_DetailForumView from "../component/detail_component/detail_view"; import { ScrollOnly } from "next-scroll-loader"; import { forum_funGetAllKomentarById } from "../fun/get/get_all_komentar_by_id"; +import { + apiGetKomentarForumById, + apiGetOneForumById, +} from "../component/api_fetch_forum"; +import { useParams } from "next/navigation"; +import { clientLogger } from "@/util/clientLogger"; +import CustomSkeleton from "@/app_modules/components/CustomSkeleton"; +import { + Forum_SkeletonKomentar, + Forum_SkeletonListKomentar, +} from "../component/skeleton_view"; +import ComponentGlobal_IsEmptyData from "@/app_modules/_global/component/is_empty_data"; export default function Forum_MainDetail({ - dataPosting, - listKomentar, userLoginId, countKomentar, }: { - dataPosting: MODEL_FORUM_POSTING; - listKomentar: MODEL_FORUM_KOMENTAR[]; userLoginId: string; countKomentar: number; }) { - const [data, setData] = useState(dataPosting); - const [lsKomentar, setLsKomentar] = useState(listKomentar); + const param = useParams<{ id: string }>(); + const [data, setData] = useState(null); + const [lsKomentar, setLsKomentar] = useState([]); const [activePage, setActivePage] = useState(1); + const [newKomentar, setNewKomentar] = useState(false); - // useShallowEffect(() => { - // onLoadKomentar({ - // onLoad(val) { - // setKomentar(val); - // }, - // }); - // }, [setKomentar]); + useShallowEffect(() => { + handleLoadData(); + }, []); - // async function onLoadKomentar({ onLoad }: { onLoad: (val: any) => void }) { - // const loadKomentar = await forum_getKomentarById(data.id); - // onLoad(loadKomentar); - // } + const handleLoadData = async () => { + try { + const response = await apiGetOneForumById({ + id: param.id, + }); + + if (response) { + setData(response.data); + } + } catch (error) { + clientLogger.error("Error get data forum", error); + setData(null); + } + }; + + useShallowEffect(() => { + handleLoadDataKomentar(); + }, [newKomentar]); + + const handleLoadDataKomentar = async () => { + try { + const response = await apiGetKomentarForumById({ + id: param.id, + page: `${activePage}`, + }); + + if (response.success) { + setLsKomentar(response.data); + } else { + setLsKomentar([]); + } + } catch (error) { + clientLogger.error("Error get data komentar forum", error); + setLsKomentar([]); + } + }; + + const handleMoreDataKomentar = async () => { + try { + const nextPage = activePage + 1; + const response = await apiGetKomentarForumById({ + id: param.id, + page: `${nextPage}`, + }); + + if (response.success) { + setActivePage(nextPage); + return response.data; + } else { + return null; + } + } catch (error) { + clientLogger.error("Error get data komentar forum", error); + return null; + } + }; useShallowEffect(() => { mqtt_client.subscribe("Forum_detail_ganti_status"); mqtt_client.on("message", (topic: any, message: any) => { const newData = JSON.parse(message.toString()); - if (newData.id === data.id) { + if (newData.id === data?.id) { const cloneData = _.clone(data); // console.log(newData.data); @@ -66,58 +124,65 @@ export default function Forum_MainDetail({ return ( <> - { - setData(val); - }} - /> - - {(data?.ForumMaster_StatusPosting?.id as any) === 1 ? ( - { - setLsKomentar(val); - }} - data={data} - userLoginId={userLoginId} - /> + {!data ? ( + ) : ( - "" + { + setData(val); + }} + /> )} - - ( -
- -
- )} - data={lsKomentar} - setData={setLsKomentar} - moreData={async () => { - const loadData = await forum_funGetAllKomentarById({ - postingId: data.id, - page: activePage + 1, - }); - setActivePage((val) => val + 1); + {!data ? ( + + ) : ( + (data?.ForumMaster_StatusPosting?.id as any) === 1 && ( + { + setLsKomentar(val); + }} + data={data} + userLoginId={userLoginId} + onSetNewKomentar={(val) => { + setNewKomentar(val); + }} + /> + ) + )} - return loadData; - }} - > - {(item) => ( - - )} -
-
+ {!lsKomentar.length ? ( + + ) : _.isEmpty(lsKomentar) ? ( + + ) : ( + + ( +
+ +
+ )} + data={lsKomentar} + setData={setLsKomentar} + moreData={handleMoreDataKomentar} + > + {(item) => ( + + )} +
+
+ )}
); diff --git a/src/middleware.ts b/src/middleware.ts index 97c69c95..c86b5904 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -31,6 +31,7 @@ const middlewareConfig: MiddlewareConfig = { "/api/auth/*", "/api/origin-url", "/api/event/*", + "/api/forum/*", // ADMIN API // >> buat dibawah sini <<