Compare commits
8 Commits
fix/admin/
...
nico/1-des
| Author | SHA1 | Date | |
|---|---|---|---|
| 134ddc6154 | |||
| b2066caa13 | |||
| 9bf3ec72cf | |||
| 1c1e8fb190 | |||
| 54f83da3b8 | |||
| f8985c550f | |||
| e3d909e760 | |||
| 16a8df50c1 |
25
src/app/admin/(dashboard)/user&role/_com/getMenuIdByRole.ts
Normal file
25
src/app/admin/(dashboard)/user&role/_com/getMenuIdByRole.ts
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
// src/app/admin/_com/getMenuIdsByRoleId.ts
|
||||||
|
import { navBar, role1, role2, role3 } from '@/app/admin/_com/list_PageAdmin';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mengembalikan daftar ID menu (string[]) berdasarkan roleId
|
||||||
|
*/
|
||||||
|
export function getMenuIdsByRoleId(roleId: string | number): string[] {
|
||||||
|
const id = typeof roleId === 'string' ? parseInt(roleId, 10) : roleId;
|
||||||
|
|
||||||
|
switch (id) {
|
||||||
|
case 0:
|
||||||
|
// Asumsikan devBar ada dan punya struktur sama
|
||||||
|
return []; // atau sesuaikan jika ada devBar
|
||||||
|
case 1:
|
||||||
|
return navBar.map(section => section.id);
|
||||||
|
case 2:
|
||||||
|
return role1.map(section => section.id);
|
||||||
|
case 3:
|
||||||
|
return role2.map(section => section.id);
|
||||||
|
case 4:
|
||||||
|
return role3.map(section => section.id);
|
||||||
|
default:
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
import { getMenuIdsByRoleId } from "@/app/admin/(dashboard)/user&role/_com/getMenuIdByRole";
|
||||||
import prisma from "@/lib/prisma";
|
import prisma from "@/lib/prisma";
|
||||||
import { Context } from "elysia";
|
import { Context } from "elysia";
|
||||||
|
|
||||||
@@ -34,11 +35,25 @@ export default async function userUpdate(context: Context) {
|
|||||||
const isActiveChanged =
|
const isActiveChanged =
|
||||||
isActive !== undefined && currentUser.isActive !== isActive;
|
isActive !== undefined && currentUser.isActive !== isActive;
|
||||||
|
|
||||||
// ✅ Jika role berubah, hapus semua akses menu yang ada
|
// ✅ Jika role berubah, reset dan set ulang akses menu
|
||||||
if (isRoleChanged) {
|
if (isRoleChanged && roleId) {
|
||||||
|
// Hapus akses lama
|
||||||
await prisma.userMenuAccess.deleteMany({
|
await prisma.userMenuAccess.deleteMany({
|
||||||
where: { userId: id }
|
where: { userId: id }
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Ambil menu default untuk role baru
|
||||||
|
const menuIds = getMenuIdsByRoleId(roleId);
|
||||||
|
|
||||||
|
if (menuIds.length > 0) {
|
||||||
|
// Buat akses baru
|
||||||
|
await prisma.userMenuAccess.createMany({
|
||||||
|
data: menuIds.map(menuId => ({
|
||||||
|
userId: id,
|
||||||
|
menuId
|
||||||
|
}))
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update user
|
// Update user
|
||||||
|
|||||||
@@ -1,31 +1,105 @@
|
|||||||
/* styles/globals.css */
|
/* styles/globals.css */
|
||||||
|
|
||||||
|
/* ===================================
|
||||||
|
1. IMPORT CSS LIBRARIES
|
||||||
|
=================================== */
|
||||||
|
@import "@mantine/carousel/styles.css";
|
||||||
|
@import "@mantine/dropzone/styles.css";
|
||||||
|
@import "@mantine/charts/styles.css";
|
||||||
|
@import "@mantine/dates/styles.css";
|
||||||
|
@import "@mantine/tiptap/styles.css";
|
||||||
|
@import "animate.css";
|
||||||
|
@import "react-simple-toasts/dist/style.css";
|
||||||
|
@import "react-simple-toasts/dist/theme/dark.css";
|
||||||
|
@import "primereact/resources/themes/lara-light-blue/theme.css";
|
||||||
|
@import "primereact/resources/primereact.min.css";
|
||||||
|
@import "primeicons/primeicons.css";
|
||||||
|
|
||||||
|
/* ===================================
|
||||||
|
2. FONT FACE - OPTIMIZED
|
||||||
|
=================================== */
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'San Francisco';
|
font-family: 'San Francisco';
|
||||||
src: url('/assets/fonts/font.otf') format('opentype');
|
src: url('/assets/fonts/font.otf') format('opentype');
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
|
font-display: swap; /* ✅ TAMBAHKAN INI - Penting untuk PageSpeed! */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ===================================
|
||||||
|
3. RESET & BASE STYLES
|
||||||
|
=================================== */
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
-webkit-text-size-adjust: 100%; /* Prevent font scaling in landscape */
|
||||||
|
-moz-text-size-adjust: 100%;
|
||||||
|
text-size-adjust: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
font-family: 'San Francisco', -apple-system, BlinkMacSystemFont, 'Segoe UI',
|
||||||
|
Roboto, Helvetica, Arial, sans-serif;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===================================
|
||||||
|
4. GLASS EFFECTS - OPTIMIZED
|
||||||
|
=================================== */
|
||||||
.glass {
|
.glass {
|
||||||
background: rgba(255, 255, 255, 0.2);
|
background: rgba(255, 255, 255, 0.2);
|
||||||
-webkit-backdrop-filter: blur(40px);
|
|
||||||
backdrop-filter: blur(40px);
|
backdrop-filter: blur(40px);
|
||||||
|
-webkit-backdrop-filter: blur(40px);
|
||||||
position: fixed;
|
position: fixed;
|
||||||
z-index: 50;
|
z-index: 50;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
|
will-change: transform; /* ✅ Hardware acceleration */
|
||||||
}
|
}
|
||||||
|
|
||||||
.glass2 {
|
.glass2 {
|
||||||
background: rgba(255, 255, 255, 0.3);
|
background: rgba(255, 255, 255, 0.3);
|
||||||
-webkit-backdrop-filter: blur(40px);
|
|
||||||
backdrop-filter: blur(40px);
|
backdrop-filter: blur(40px);
|
||||||
|
-webkit-backdrop-filter: blur(40px);
|
||||||
position: fixed;
|
position: fixed;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
|
will-change: transform; /* ✅ Hardware acceleration */
|
||||||
}
|
}
|
||||||
|
|
||||||
.glass3 {
|
.glass3 {
|
||||||
background: rgba(255, 255, 255, 0.3);
|
background: rgba(255, 255, 255, 0.3);
|
||||||
-webkit-backdrop-filter: blur(40px);
|
|
||||||
backdrop-filter: blur(40px);
|
backdrop-filter: blur(40px);
|
||||||
|
-webkit-backdrop-filter: blur(40px);
|
||||||
|
will-change: transform; /* ✅ Hardware acceleration */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ===================================
|
||||||
|
5. PERFORMANCE OPTIMIZATION
|
||||||
|
=================================== */
|
||||||
|
img,
|
||||||
|
picture,
|
||||||
|
video,
|
||||||
|
canvas,
|
||||||
|
svg {
|
||||||
|
display: block;
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reduce motion for accessibility */
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
*,
|
||||||
|
*::before,
|
||||||
|
*::after {
|
||||||
|
animation-duration: 0.01ms !important;
|
||||||
|
animation-iteration-count: 1 !important;
|
||||||
|
transition-duration: 0.01ms !important;
|
||||||
|
scroll-behavior: auto !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,41 +1,89 @@
|
|||||||
// Import styles of packages that you've installed.
|
|
||||||
// All packages except `@mantine/hooks` require styles imports
|
|
||||||
import "@mantine/carousel/styles.css";
|
|
||||||
import "@mantine/core/styles.css";
|
import "@mantine/core/styles.css";
|
||||||
import '@mantine/dropzone/styles.css';
|
import "./globals.css"; // Sisanya import di globals.css
|
||||||
import "animate.css";
|
|
||||||
import 'react-simple-toasts/dist/style.css';
|
|
||||||
import 'react-simple-toasts/dist/theme/dark.css';
|
|
||||||
import "./globals.css";
|
|
||||||
import '@mantine/charts/styles.css';
|
|
||||||
import '@mantine/dates/styles.css';
|
|
||||||
import '@mantine/tiptap/styles.css';
|
|
||||||
import "primereact/resources/themes/lara-light-blue/theme.css";
|
|
||||||
import "primereact/resources/primereact.min.css";
|
|
||||||
import "primeicons/primeicons.css";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import LoadDataFirstClient from "@/app/darmasaba/_com/LoadDataFirstClient";
|
import LoadDataFirstClient from "@/app/darmasaba/_com/LoadDataFirstClient";
|
||||||
import {
|
import {
|
||||||
ColorSchemeScript,
|
ColorSchemeScript,
|
||||||
MantineProvider,
|
MantineProvider,
|
||||||
createTheme,
|
createTheme,
|
||||||
mantineHtmlProps,
|
// mantineHtmlProps,
|
||||||
} from "@mantine/core";
|
} from "@mantine/core";
|
||||||
import { ViewTransitions } from "next-view-transitions";
|
// import { Metadata } from "next";
|
||||||
|
// import { ViewTransitions } from "next-view-transitions";
|
||||||
import { ToastContainer } from "react-toastify";
|
import { ToastContainer } from "react-toastify";
|
||||||
|
|
||||||
export const metadata = {
|
// export const metadata: Metadata = {
|
||||||
title: "Desa Darmasaba",
|
// title: {
|
||||||
description: "Desa Darmasaba Kabupaten Badung",
|
// default: "Desa Darmasaba",
|
||||||
};
|
// template: "%s | Desa Darmasaba",
|
||||||
|
// },
|
||||||
|
// description: "Website resmi Desa Darmasaba, Kabupaten Badung, Bali. Informasi layanan publik, berita, dan profil desa.",
|
||||||
|
// keywords: [
|
||||||
|
// "desa darmasaba",
|
||||||
|
// "darmasaba",
|
||||||
|
// "badung",
|
||||||
|
// "bali",
|
||||||
|
// "desa",
|
||||||
|
// "pemerintah desa",
|
||||||
|
// "layanan publik",
|
||||||
|
// "abang batan desa",
|
||||||
|
// ],
|
||||||
|
// authors: [{ name: "Pemerintah Desa Darmasaba" }],
|
||||||
|
// creator: "Desa Darmasaba",
|
||||||
|
// publisher: "Desa Darmasaba",
|
||||||
|
// robots: {
|
||||||
|
// index: true,
|
||||||
|
// follow: true,
|
||||||
|
// googleBot: {
|
||||||
|
// index: true,
|
||||||
|
// follow: true,
|
||||||
|
// "max-video-preview": -1,
|
||||||
|
// "max-image-preview": "large",
|
||||||
|
// "max-snippet": -1,
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// icons: {
|
||||||
|
// icon: "/assets/images/darmasaba-icon.png",
|
||||||
|
// apple: "/assets/images/darmasaba-icon.png",
|
||||||
|
// },
|
||||||
|
// manifest: "/manifest.json",
|
||||||
|
// openGraph: {
|
||||||
|
// type: "website",
|
||||||
|
// locale: "id_ID",
|
||||||
|
// url: "https://cld-dkr-staging-desa-darmasaba.wibudev.com",
|
||||||
|
// siteName: "Desa Darmasaba",
|
||||||
|
// title: "Desa Darmasaba - Kabupaten Badung, Bali",
|
||||||
|
// description: "Website resmi Desa Darmasaba, Kabupaten Badung, Bali. Informasi layanan publik, berita, dan profil desa.",
|
||||||
|
// images: [
|
||||||
|
// {
|
||||||
|
// url: "/assets/images/darmasaba-icon.png",
|
||||||
|
// width: 1200,
|
||||||
|
// height: 630,
|
||||||
|
// alt: "Desa Darmasaba",
|
||||||
|
// },
|
||||||
|
// ],
|
||||||
|
// },
|
||||||
|
// twitter: {
|
||||||
|
// card: "summary_large_image",
|
||||||
|
// title: "Desa Darmasaba - Kabupaten Badung, Bali",
|
||||||
|
// description: "Website resmi Desa Darmasaba, Kabupaten Badung, Bali",
|
||||||
|
// images: ["/assets/images/darmasaba-icon.png"],
|
||||||
|
// },
|
||||||
|
// verification: {
|
||||||
|
// // google: "your-google-verification-code", // Tambahkan jika sudah punya
|
||||||
|
// // yandex: "your-yandex-verification-code",
|
||||||
|
// // yahoo: "your-yahoo-verification-code",
|
||||||
|
// },
|
||||||
|
// category: "government",
|
||||||
|
// other: {
|
||||||
|
// "msapplication-TileColor": "#ffffff",
|
||||||
|
// "theme-color": "#ffffff",
|
||||||
|
// },
|
||||||
|
// };
|
||||||
|
|
||||||
const theme = createTheme({
|
const theme = createTheme({
|
||||||
fontFamily:
|
fontFamily: "San Francisco, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, sans-serif",
|
||||||
"San Francisco, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial, sans-serif",
|
fontFamilyMonospace: "SFMono-Regular, Menlo, Monaco, Consolas, monospace",
|
||||||
fontFamilyMonospace:
|
|
||||||
"SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace",
|
|
||||||
headings: { fontFamily: "San Francisco, sans-serif" },
|
headings: { fontFamily: "San Francisco, sans-serif" },
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -45,27 +93,22 @@ export default function RootLayout({
|
|||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<ViewTransitions>
|
<html lang="id" data-mantine-color-scheme="light">
|
||||||
<html lang="en" {...mantineHtmlProps}>
|
<head>
|
||||||
<head>
|
<meta charSet="utf-8" />
|
||||||
<ColorSchemeScript />
|
<ColorSchemeScript />
|
||||||
<link
|
</head>
|
||||||
rel="icon"
|
<body>
|
||||||
href="/assets/images/darmasaba-icon.png"
|
<MantineProvider theme={theme}>
|
||||||
sizes="any"
|
{children}
|
||||||
/>
|
<LoadDataFirstClient />
|
||||||
</head>
|
</MantineProvider>
|
||||||
<body>
|
<ToastContainer
|
||||||
<MantineProvider theme={theme}>
|
position="bottom-center"
|
||||||
{children}
|
hideProgressBar
|
||||||
|
style={{ zIndex: 9999 }}
|
||||||
</MantineProvider>
|
/>
|
||||||
<ToastContainer position="bottom-center" hideProgressBar style={{
|
</body>
|
||||||
zIndex: 9999
|
</html>
|
||||||
}} />
|
|
||||||
</body>
|
|
||||||
<LoadDataFirstClient />
|
|
||||||
</html>
|
|
||||||
</ViewTransitions>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user