From d539678c1b57dc61915e59d76f6dbcbc2f8b9550 Mon Sep 17 00:00:00 2001 From: nico Date: Thu, 30 Jan 2025 14:40:16 +0800 Subject: [PATCH] API Dashboard Admin --- .../admin/investasi/dashboard/[name]/route.ts | 29 ++++++ .../admin/main_dashboard/portofolio/route.ts | 31 ++++++ .../api/admin/main_dashboard/user/route.ts | 42 ++++++++ src/app/api/event/[id]/route.ts | 2 - src/app/dev/admin/main/dashboard/page.tsx | 6 +- .../skeleton/customSkeletonAdmin.tsx | 34 +++++++ .../skeleton/main_dashboard_skeleton.tsx | 53 ++++++++++ .../lib/api_fetch_main_dashboard.ts | 30 ++++++ .../admin/main_dashboard/main/view.tsx | 99 +++++++++++++------ src/app_modules/components/CustomSkeleton.tsx | 1 - 10 files changed, 292 insertions(+), 35 deletions(-) create mode 100644 src/app/api/admin/investasi/dashboard/[name]/route.ts create mode 100644 src/app/api/admin/main_dashboard/portofolio/route.ts create mode 100644 src/app/api/admin/main_dashboard/user/route.ts create mode 100644 src/app_modules/admin/_admin_global/_component/skeleton/customSkeletonAdmin.tsx create mode 100644 src/app_modules/admin/_admin_global/_component/skeleton/main_dashboard_skeleton.tsx create mode 100644 src/app_modules/admin/main_dashboard/lib/api_fetch_main_dashboard.ts diff --git a/src/app/api/admin/investasi/dashboard/[name]/route.ts b/src/app/api/admin/investasi/dashboard/[name]/route.ts new file mode 100644 index 00000000..8ed70f14 --- /dev/null +++ b/src/app/api/admin/investasi/dashboard/[name]/route.ts @@ -0,0 +1,29 @@ +import { prisma } from "@/app/lib"; +import backendLogger from "@/util/backendLogger"; +import { NextResponse } from "next/server"; + +export async function GET(request: Request) { + try { + const data = await prisma.investasi.count({ + where: { + active: true + }, + }) + return NextResponse.json({ + message: "Data Investasi", + data: data, + }, + { status: 200 } + ) + } catch (error) { + backendLogger.error("Error Get Count Investasi Main Dashboard") + return NextResponse.json({ + message: "Error Get Count Investasi Main Dashboard", + reason: (error as Error).message + }, + { status: 500 } + ) + } finally { + await prisma.$disconnect(); + } +} diff --git a/src/app/api/admin/main_dashboard/portofolio/route.ts b/src/app/api/admin/main_dashboard/portofolio/route.ts new file mode 100644 index 00000000..fa56632d --- /dev/null +++ b/src/app/api/admin/main_dashboard/portofolio/route.ts @@ -0,0 +1,31 @@ +import { prisma } from "@/app/lib"; +import backendLogger from "@/util/backendLogger"; +import { NextResponse } from "next/server"; + +export async function GET(request: Request) { + try { + const data = await prisma.portofolio.count({ + where: { + active: true + } + }); + return NextResponse.json({ + success: true, + message: "Data portofolio", + data: data + }, + { status: 200 } + ); + } catch (error) { + backendLogger.error("Error Get Count Portofolio Main Dashboard") + return NextResponse.json({ + success: false, + message: "Error Get Count Portofolio Main Dashboard", + data: null + }, + { status: 500 } + ); + } finally { + await prisma.$disconnect(); + } +} \ No newline at end of file diff --git a/src/app/api/admin/main_dashboard/user/route.ts b/src/app/api/admin/main_dashboard/user/route.ts new file mode 100644 index 00000000..2470f74b --- /dev/null +++ b/src/app/api/admin/main_dashboard/user/route.ts @@ -0,0 +1,42 @@ +import { prisma } from "@/app/lib"; +import backendLogger from "@/util/backendLogger"; +import { NextResponse } from "next/server"; + +export async function GET(request: Request) { + const method = request.method; + if (method !== "GET") { + return NextResponse.json( + { success: false, message: "Method not allowed" }, + { status: 405 } + ); + } + try { + const data = await prisma.user.count({ + where: { + active: true + }, + + + }) + return NextResponse.json({ + success: true, + message: "Data user", + data: data + }, + { status: 200 } + ) + } catch (error) { + backendLogger.error("Error Get Count User Main Dashboard") + return NextResponse.json({ + success: false, + message: "Gagal mendapatkan data", + reason: (error as Error).message + }, + { status: 500 } + ) + + } finally { + await prisma.$disconnect(); + } + +} \ No newline at end of file diff --git a/src/app/api/event/[id]/route.ts b/src/app/api/event/[id]/route.ts index 516b15d0..cde5cdba 100644 --- a/src/app/api/event/[id]/route.ts +++ b/src/app/api/event/[id]/route.ts @@ -33,7 +33,6 @@ export async function GET( }); await prisma.$disconnect(); - return NextResponse.json({ success: true, message: "Berhasil mendapatkan data", @@ -41,7 +40,6 @@ export async function GET( }); } catch (error) { await prisma.$disconnect(); - return NextResponse.json( { success: false, message: "Gagal mendapatkan data" }, { status: 500 } diff --git a/src/app/dev/admin/main/dashboard/page.tsx b/src/app/dev/admin/main/dashboard/page.tsx index e046e03a..51820acf 100644 --- a/src/app/dev/admin/main/dashboard/page.tsx +++ b/src/app/dev/admin/main/dashboard/page.tsx @@ -3,12 +3,12 @@ import { AdminMainDashboard_CountPOrtofolio } from "@/app_modules/admin/main_das import { AdminMainDashboard_CountUser } from "@/app_modules/admin/main_dashboard/fun/count/fun_count_user"; export default async function Page() { - const countUser = await AdminMainDashboard_CountUser(); - const countPorto = await AdminMainDashboard_CountPOrtofolio(); + // const countUser = await AdminMainDashboard_CountUser(); + // const countPorto = await AdminMainDashboard_CountPOrtofolio(); // await new Promise((a, b) => { // setTimeout(a, 4000); // }); - return ; + return ; } diff --git a/src/app_modules/admin/_admin_global/_component/skeleton/customSkeletonAdmin.tsx b/src/app_modules/admin/_admin_global/_component/skeleton/customSkeletonAdmin.tsx new file mode 100644 index 00000000..a1461a53 --- /dev/null +++ b/src/app_modules/admin/_admin_global/_component/skeleton/customSkeletonAdmin.tsx @@ -0,0 +1,34 @@ +import { Skeleton, SkeletonProps, createStyles } from '@mantine/core'; + +interface CustomSkeletonProps extends SkeletonProps { + isLoading?: boolean; + className?: string; +} + +const useStyles = createStyles((theme) => ({ + skeleton: { + '&::before': { + backgroundColor: "#1F5B9E", + }, + '&::after': { + backgroundColor: "#0F3055", + }, + }, +})); + +const CustomSkeletonAdmin: React.FC = ({ + isLoading = true, + className, + ...props +}) => { + const { classes, cx } = useStyles(); + return ( + + ); +}; + +export default CustomSkeletonAdmin; \ No newline at end of file diff --git a/src/app_modules/admin/_admin_global/_component/skeleton/main_dashboard_skeleton.tsx b/src/app_modules/admin/_admin_global/_component/skeleton/main_dashboard_skeleton.tsx new file mode 100644 index 00000000..47a7d59e --- /dev/null +++ b/src/app_modules/admin/_admin_global/_component/skeleton/main_dashboard_skeleton.tsx @@ -0,0 +1,53 @@ +import { MainColor, AccentColor } from '@/app_modules/_global/color'; +import { AdminColor } from '@/app_modules/_global/color/color_pallet'; +import { Flex, Grid, Paper, Stack, Text, ThemeIcon, Title } from '@mantine/core'; +import React from 'react'; +import CustomSkeletonAdmin from './customSkeletonAdmin'; +import ComponentAdminGlobal_HeaderTamplate from '../../header_tamplate'; +import { IconFileText, IconUsers } from '@tabler/icons-react'; + +function MainDashboardSkeleton() { + const listBox = [ + { + id: 1, + name: "User", + jumlah: "", + link: "", + icon: + }, + { + id: 2, + name: "Portofolio", + jumlah: "countPortofolio", + link: "", + icon: + }, + ]; + return ( + <> + + + + {listBox.map((e) => ( + + + + {e.name} + + + {e.icon} + + + + + ))} + + + {/* */} + + + + + ); +} +export default MainDashboardSkeleton; diff --git a/src/app_modules/admin/main_dashboard/lib/api_fetch_main_dashboard.ts b/src/app_modules/admin/main_dashboard/lib/api_fetch_main_dashboard.ts new file mode 100644 index 00000000..0f01f7fa --- /dev/null +++ b/src/app_modules/admin/main_dashboard/lib/api_fetch_main_dashboard.ts @@ -0,0 +1,30 @@ +export const apiGetCountUserActive = async () => { + const { token } = await fetch("/api/get-cookie").then((res) => res.json()); + if (!token) return await token.json().catch(() => null); + + const response = await fetch(`/api/admin/main_dashboard/user`, { + headers: { + "Content-Type": "application/json", + Accept: "application/json", + "Access-Control-Allow-Origin": "*", + Authorization: `Bearer ${token}`, + }, + }); + + return await response.json().catch(() => null); +} +export const apiGetCountPortofolio = async () => { + const { token } = await fetch("/api/get-cookie").then((res) => res.json()); + if (!token) return await token.json().catch(() => null); + + const response = await fetch(`/api/admin/main_dashboard/portofolio`, { + headers: { + "Content-Type": "application/json", + Accept: "application/json", + "Access-Control-Allow-Origin": "*", + Authorization: `Bearer ${token}`, + }, + }); + + return await response.json().catch(() => null); +} \ No newline at end of file diff --git a/src/app_modules/admin/main_dashboard/main/view.tsx b/src/app_modules/admin/main_dashboard/main/view.tsx index 7539343f..2d8fc67c 100644 --- a/src/app_modules/admin/main_dashboard/main/view.tsx +++ b/src/app_modules/admin/main_dashboard/main/view.tsx @@ -4,14 +4,50 @@ import { AccentColor, AdminColor, MainColor } from "@/app_modules/_global/color/ import { Divider, Flex, Grid, Group, Paper, Stack, Text, ThemeIcon, Title } from "@mantine/core"; import { IconFileText, IconUsers } from "@tabler/icons-react"; import ComponentAdminGlobal_HeaderTamplate from "../../_admin_global/header_tamplate"; +import { useState } from "react"; +import { useShallowEffect } from "@mantine/hooks"; +import { apiGetCountPortofolio, apiGetCountUserActive } from "../lib/api_fetch_main_dashboard"; +import { NextResponse } from "next/server"; +import { clientLogger } from "@/util/clientLogger"; +import MainDashboardSkeleton from "../../_admin_global/_component/skeleton/main_dashboard_skeleton"; + +export default function AdminMain() { + const [countUser, setCountUser] = useState(null); + const [countPortofolio, setCountPortofolio] = useState(null); + + useShallowEffect(() => { + onLoadDataUser(); + onLoadDataPortofolio(); + }, []); + + async function onLoadDataUser() { + try { + const response = await apiGetCountUserActive(); + if (response) { + // console.log(response.data); + // console.log(typeof response.data); + // console.log( response); + setCountUser(response.data); + } + + } catch (error) { + clientLogger.error("Error get count user data", error); + } + } + + async function onLoadDataPortofolio() { + try { + const response = await apiGetCountPortofolio(); + if (response) { + // console.log("Response Portofolio",response); + setCountPortofolio(response.data); + } + + } catch (error) { + clientLogger.error("Error get count portofolio data", error); + } + } -export default function AdminMain({ - countUser, - countPorto, -}: { - countUser: number; - countPorto: number; -}) { const listBox = [ { id: 1, @@ -23,39 +59,44 @@ export default function AdminMain({ { id: 2, name: "Portofolio", - jumlah: countPorto, + jumlah: countPortofolio, link: "", - icon: + icon: }, ]; + return ( <> - - - {/* Main Dashboard + {!countUser && !countPortofolio ? ( + + ) : ( + + + {/* Main Dashboard */} - - {listBox.map((e) => ( - - + + {listBox.map((e) => ( + + - {e.name} - - {e.jumlah} - {e.icon} - + {e.name} + + {e.jumlah} + {e.icon} + - - - ))} + + + ))} - - {/* */} - - - + + {/* */} + + + + )} ); } diff --git a/src/app_modules/components/CustomSkeleton.tsx b/src/app_modules/components/CustomSkeleton.tsx index e6da0679..7d094445 100644 --- a/src/app_modules/components/CustomSkeleton.tsx +++ b/src/app_modules/components/CustomSkeleton.tsx @@ -1,5 +1,4 @@ import { Skeleton, SkeletonProps, createStyles } from '@mantine/core'; -import { AccentColor } from '../_global/color'; interface CustomSkeletonProps extends SkeletonProps { isLoading?: boolean;