Merge pull request #263 from bipproduction/bagas/31-jan-25

fix event admin
This commit is contained in:
Bagasbanuna02
2025-02-03 14:08:14 +08:00
committed by GitHub
13 changed files with 331 additions and 160 deletions

BIN
bun.lockb

Binary file not shown.

View File

@@ -28,7 +28,7 @@
"@mantine/next": "^6.0.17", "@mantine/next": "^6.0.17",
"@mantine/notifications": "^6.0.17", "@mantine/notifications": "^6.0.17",
"@mantine/tiptap": "^7.5.3", "@mantine/tiptap": "^7.5.3",
"@prisma/client": "^5.0.0", "@prisma/client": "^6.3.0",
"@react-pdf/renderer": "^3.4.4", "@react-pdf/renderer": "^3.4.4",
"@tabler/icons-react": "^2.38.0", "@tabler/icons-react": "^2.38.0",
"@tiptap/extension-highlight": "^2.2.3", "@tiptap/extension-highlight": "^2.2.3",
@@ -72,7 +72,7 @@
"p-limit": "^6.2.0", "p-limit": "^6.2.0",
"pdfjs-dist": "^4.6.82", "pdfjs-dist": "^4.6.82",
"postcss": "8.4.27", "postcss": "8.4.27",
"prisma": "^5.19.1", "prisma": "^6.3.0",
"react": "18.2.0", "react": "18.2.0",
"react-countdown": "^2.3.5", "react-countdown": "^2.3.5",
"react-dom": "18.2.0", "react-dom": "18.2.0",
@@ -90,6 +90,7 @@
"react-toastify": "^9.1.3", "react-toastify": "^9.1.3",
"sharp": "^0.33.5", "sharp": "^0.33.5",
"socket.io-client": "^4.7.2", "socket.io-client": "^4.7.2",
"swr": "^2.3.0",
"tailwindcss": "3.3.3", "tailwindcss": "3.3.3",
"ts-node": "^10.9.2", "ts-node": "^10.9.2",
"typescript": "5.1.6", "typescript": "5.1.6",

View File

@@ -4,6 +4,7 @@
generator client { generator client {
provider = "prisma-client-js" provider = "prisma-client-js"
engineType = "binary" engineType = "binary"
binaryTargets = ["native"]
} }
datasource db { datasource db {

View File

@@ -85,7 +85,6 @@ export async function GET(
}, },
}); });
await prisma.$disconnect();
return NextResponse.json({ return NextResponse.json({
success: true, success: true,
message: "Success create sponsor", message: "Success create sponsor",
@@ -93,7 +92,6 @@ export async function GET(
}); });
} catch (error) { } catch (error) {
backendLogger.error("Error get sponsor event", error); backendLogger.error("Error get sponsor event", error);
await prisma.$disconnect();
return NextResponse.json( return NextResponse.json(
{ {
success: false, success: false,
@@ -102,5 +100,7 @@ export async function GET(
}, },
{ status: 500 } { status: 500 }
); );
} finally {
await prisma.$disconnect();
} }
} }

View File

@@ -0,0 +1,39 @@
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.eventMaster_TipeAcara.findMany({
orderBy: {
id: "asc",
},
});
return NextResponse.json({
success: true,
message: "Success get tipe acara",
data: data,
});
} catch (error) {
backendLogger.error("Error get tipe acara", error);
return NextResponse.json(
{
success: false,
message: "Failed get tipe acara ",
reason: (error as Error).message,
},
{ status: 500 }
);
} finally {
await prisma.$disconnect();
}
}

View File

@@ -1,33 +1,55 @@
import { decrypt } from "@/app/auth/_lib/decrypt"; import { decrypt } from "@/app/auth/_lib/decrypt";
import { prisma } from "@/app/lib"; import { prisma } from "@/app/lib";
import { cookies } from 'next/headers' import { cookies } from "next/headers";
import { NextRequest, NextResponse } from "next/server"; import { NextRequest, NextResponse } from "next/server";
export const dynamic = "force-dynamic"; export const dynamic = "force-dynamic";
export async function GET(req: NextRequest) { export async function GET(req: NextRequest) {
const token = req.headers.get('Authorization')?.split(' ')[1]; try {
const token = req.headers.get("Authorization")?.split(" ")[1];
const decripted = await decrypt({ const decripted = await decrypt({
token: token!, token: token!,
encodedKey: process.env.NEXT_PUBLIC_BASE_TOKEN_KEY! encodedKey: process.env.NEXT_PUBLIC_BASE_TOKEN_KEY!,
}) });
if (!decripted) { if (!decripted) {
return NextResponse.json({ await prisma.$disconnect();
return NextResponse.json(
{
success: false, success: false,
message: "Unauthorized" message: "Unauthorized",
}, { status: 401 }) },
{ status: 401 }
);
} }
const user = await prisma.user.findUnique({ const user = await prisma.user.findUnique({
where: { where: {
id: decripted.id id: decripted.id,
} },
}) });
// Disconnect after successful query
await prisma.$disconnect();
return NextResponse.json({ return NextResponse.json({
success: true, success: true,
message: "Berhasil mendapatkan data", message: "Berhasil mendapatkan data",
data: user data: user,
}) });
} catch (error) {
// Ensure connection is closed even if error occurs
await prisma.$disconnect();
console.error("Error in user validation:", error);
return NextResponse.json(
{
success: false,
message: "Terjadi kesalahan pada server",
},
{ status: 500 }
);
}
} }

View File

@@ -4,6 +4,7 @@ export {
apiGetAdminEventRiwayatCount as apiGetEventRiwayatCount, apiGetAdminEventRiwayatCount as apiGetEventRiwayatCount,
apiGetAdminEventByStatus as apiGetDataEventByStatus, apiGetAdminEventByStatus as apiGetDataEventByStatus,
apiGetAdminEventRiwayat, apiGetAdminEventRiwayat,
apiGetAdminEventTipeAcara,
}; };
const apiGetAdminEventStatusCountDashboard = async ({ const apiGetAdminEventStatusCountDashboard = async ({
@@ -114,3 +115,20 @@ const apiGetAdminEventRiwayat = async ({
return await response.json().catch(() => null); return await response.json().catch(() => null);
}; };
const apiGetAdminEventTipeAcara = 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/event/tipe-acara`, {
method: "GET",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
"Access-Control-Allow-Origin": "*",
Authorization: `Bearer ${token}`,
},
});
return await response.json().catch(() => null);
};

View File

@@ -1,8 +1,6 @@
import { AdminEvent_Riwayat } from "@/app_modules/admin/event"; import { AdminEvent_Riwayat } from "@/app_modules/admin/event";
import { adminEvent_funGetListAllRiwayat } from "@/app_modules/admin/event/fun/get/get_list_all_riwayat";
export default async function Page() { export default async function Page() {
// const listRiwayat = await adminEvent_funGetListAllRiwayat({ page: 1 });
return ( return (
<> <>

View File

@@ -2,11 +2,11 @@ import { AdminEvent_DetailTipeAcara } from "@/app_modules/admin/event";
import { AdminEvent_getListTipeAcara } from "@/app_modules/admin/event/fun/get/get_list_tipe_acara"; import { AdminEvent_getListTipeAcara } from "@/app_modules/admin/event/fun/get/get_list_tipe_acara";
export default async function Page() { export default async function Page() {
const listTipe = await AdminEvent_getListTipeAcara() // const listTipe = await AdminEvent_getListTipeAcara()
return ( return (
<> <>
<AdminEvent_DetailTipeAcara listTipe={listTipe}/> <AdminEvent_DetailTipeAcara />
</> </>
); );
} }

View File

@@ -0,0 +1,30 @@
"use client";
import { Stack } from "@mantine/core";
import useSwr from "swr";
const fether = (url: string) =>
fetch("https://jsonplaceholder.typicode.com" + url, {
cache: "force-cache",
next: {
revalidate: 60,
},
}).then((res) => res.json());
export default function LoadDataContoh() {
const { data, isLoading, error, mutate, isValidating } = useSwr(
"/posts/1",
fether,
{
revalidateOnFocus: false,
revalidateOnReconnect: false,
refreshInterval: 1000,
}
);
return (
<Stack>
{isLoading && <div>Loading...</div>}
LoadDataContoh
{JSON.stringify(data, null, 2)}
</Stack>
);
}

View File

@@ -0,0 +1,9 @@
async function getDataExample() {
const res = await fetch("https://jsonplaceholder.typicode.com/posts", {
next: {
revalidate: 60,
},
});
return res.json();
}

View File

@@ -1,14 +1,51 @@
"use client"; import { Suspense } from "react";
import { useHookstate } from "@hookstate/core"; import LoadDataContoh from "./LoadDataContoh";
import { Button, Stack } from "@mantine/core";
const listMenu = [
{
name: "Dashboard",
url: "/dashboard",
icon: "dashboard",
},
{
name: "Event",
url: "/event",
icon: "event",
},
{
name: "Donasi",
url: "/donasi",
icon: "donasi",
},
];
export default function Page() { const fether = async (url: string) =>
fetch("https://jsonplaceholder.typicode.com" + url, {
next: {
revalidate: 2,
},
}).then(async (res) => {
const data = await res.json();
// console.log(data);
return data;
});
export default async function Page() {
const data = await fether("/posts/1");
return ( return (
<Stack> <div>
{listMenu.map((item) => {
<Button onClick={() => {}}>tekan</Button> return (
</Stack> <div key={item.name}>
<a href={item.url}>{item.name}</a>
</div>
);
})}
{/* <LoadDataContoh /> */}
<Suspense fallback={<div>Loading...</div>}>
{JSON.stringify(data, null, 2)}
</Suspense>
</div>
); );
} }

View File

@@ -17,7 +17,7 @@ import {
TextInput, TextInput,
Title, Title,
} from "@mantine/core"; } from "@mantine/core";
import { useDisclosure } from "@mantine/hooks"; import { useDisclosure, useShallowEffect } from "@mantine/hooks";
import { IconCirclePlus, IconEditCircle, IconTrash } from "@tabler/icons-react"; import { IconCirclePlus, IconEditCircle, IconTrash } from "@tabler/icons-react";
import { useState } from "react"; import { useState } from "react";
import ComponentAdminGlobal_HeaderTamplate from "../../_admin_global/header_tamplate"; import ComponentAdminGlobal_HeaderTamplate from "../../_admin_global/header_tamplate";
@@ -25,29 +25,23 @@ import { AdminEvent_funCreateTipeAcara } from "../fun/create/fun_create_tipe_aca
import { AdminEvent_funEditActivationTipeAcaraById } from "../fun/edit/fun_edit_activation_tipe_acara"; import { AdminEvent_funEditActivationTipeAcaraById } from "../fun/edit/fun_edit_activation_tipe_acara";
import { AdminEvent_funEditTipeAcara } from "../fun/edit/fun_edit_tipe_acara"; import { AdminEvent_funEditTipeAcara } from "../fun/edit/fun_edit_tipe_acara";
import { AdminEvent_getListTipeAcara } from "../fun/get/get_list_tipe_acara"; import { AdminEvent_getListTipeAcara } from "../fun/get/get_list_tipe_acara";
import { apiGetAdminEventTipeAcara } from "@/app/dev/admin/event/_lib/api_fecth_admin_event";
import CustomSkeleton from "@/app_modules/components/CustomSkeleton";
import { clientLogger } from "@/util/clientLogger";
export default function AdminEvent_DetailTipeAcara({ export default function AdminEvent_DetailTipeAcara() {
listTipe,
}: {
listTipe: any;
}) {
return ( return (
<> <>
<Stack> <Stack>
<ComponentAdminGlobal_HeaderTamplate name="Event" /> <ComponentAdminGlobal_HeaderTamplate name="Event" />
<DetailTipeAcara />
<DetailTipeAcara listTipe={listTipe} />
</Stack> </Stack>
</> </>
); );
} }
function DetailTipeAcara({ function DetailTipeAcara() {
listTipe, const [tipe, setTipe] = useState<MODEL_DEFAULT_MASTER_OLD[] | null>(null);
}: {
listTipe: MODEL_DEFAULT_MASTER_OLD[];
}) {
const [tipe, setTipe] = useState(listTipe);
const [name, setName] = useState(""); const [name, setName] = useState("");
const [openEditor, setOpenEditor] = useState(false); const [openEditor, setOpenEditor] = useState(false);
const [edit, setEdit] = useState<MODEL_DEFAULT_MASTER_OLD | null>(null); const [edit, setEdit] = useState<MODEL_DEFAULT_MASTER_OLD | null>(null);
@@ -58,6 +52,21 @@ function DetailTipeAcara({
}); });
const [openCreate, setOpenCreate] = useState(false); const [openCreate, setOpenCreate] = useState(false);
useShallowEffect(() => {
onLoadData();
}, []);
async function onLoadData() {
try {
const respone = await apiGetAdminEventTipeAcara();
if (respone) {
setTipe(respone.data);
}
} catch (error) {
clientLogger.error("Error get tipe acara", error);
}
}
return ( return (
<> <>
<Modal opened={opened} onClose={close} centered withCloseButton={false}> <Modal opened={opened} onClose={close} centered withCloseButton={false}>
@@ -101,6 +110,9 @@ function DetailTipeAcara({
</Button> </Button>
</Group> </Group>
{!tipe ? (
<CustomSkeleton height={400} width={"60%"} />
) : (
<SimpleGrid <SimpleGrid
cols={2} cols={2}
spacing="lg" spacing="lg"
@@ -205,7 +217,10 @@ function DetailTipeAcara({
/> />
<Group position="right"> <Group position="right">
<Group position="apart"> <Group position="apart">
<Button radius={"xl"} onClick={() => setOpenEditor(false)}> <Button
radius={"xl"}
onClick={() => setOpenEditor(false)}
>
Batal Batal
</Button> </Button>
<Button <Button
@@ -230,6 +245,7 @@ function DetailTipeAcara({
)} )}
</div> </div>
</SimpleGrid> </SimpleGrid>
)}
</> </>
); );
} }