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;