Fix Kondisi Verify Otp Registrasi dan Login
Next mau fix eror saat user sudah terdaftar tetapi di redirect ke login, seharusnya redirect sesuai roleIdnya
This commit is contained in:
@@ -118,7 +118,7 @@ const userState = proxy({
|
||||
console.error("Gagal delete user:", error);
|
||||
toast.error("Terjadi kesalahan saat menghapus user");
|
||||
} finally {
|
||||
userState.delete.loading = false;
|
||||
userState.deleteUser.loading = false;
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
//
|
||||
|
||||
'use client';
|
||||
|
||||
import { apiFetchOtpData, apiFetchVerifyOtp } from '@/app/api/auth/_lib/api_fetch_auth';
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Button, Center, Loader, Paper, PinInput, Stack, Text, Title } from '@mantine/core';
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Center,
|
||||
Loader,
|
||||
Paper,
|
||||
PinInput,
|
||||
Stack,
|
||||
Text,
|
||||
Title,
|
||||
} from '@mantine/core';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { toast } from 'react-toastify';
|
||||
@@ -17,8 +24,14 @@ export default function Validasi() {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [kodeId, setKodeId] = useState<string | null>(null);
|
||||
const [isRegistrationFlow, setIsRegistrationFlow] = useState(false); // Tambahkan flag
|
||||
|
||||
// Cek apakah ini alur registrasi
|
||||
useEffect(() => {
|
||||
const storedUsername = localStorage.getItem('auth_username');
|
||||
setIsRegistrationFlow(!!storedUsername);
|
||||
}, []);
|
||||
|
||||
// Inisialisasi data OTP
|
||||
useEffect(() => {
|
||||
const storedKodeId = localStorage.getItem('auth_kodeId');
|
||||
if (!storedKodeId) {
|
||||
@@ -28,11 +41,12 @@ export default function Validasi() {
|
||||
}
|
||||
|
||||
setKodeId(storedKodeId);
|
||||
|
||||
const loadOtpData = async () => {
|
||||
try {
|
||||
const result = await apiFetchOtpData({ kodeId: storedKodeId });
|
||||
if (result.success && result.data?.nomor) {
|
||||
const res = await fetch(`/api/auth/otp-data?kodeId=${encodeURIComponent(storedKodeId)}`);
|
||||
const result = await res.json();
|
||||
|
||||
if (res.ok && result.data?.nomor) {
|
||||
setNomor(result.data.nomor);
|
||||
} else {
|
||||
throw new Error('Data OTP tidak valid');
|
||||
@@ -45,82 +59,21 @@ export default function Validasi() {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
loadOtpData();
|
||||
}, [router]);
|
||||
|
||||
// Verifikasi OTP
|
||||
const handleVerify = async () => {
|
||||
if (!kodeId || !nomor || otp.length < 4) return;
|
||||
|
||||
setLoading(true);
|
||||
try {
|
||||
const verifyResult = await apiFetchVerifyOtp({ nomor, otp, kodeId });
|
||||
|
||||
if (!verifyResult.success) {
|
||||
// Registrasi baru?
|
||||
if (
|
||||
verifyResult.status === 404 &&
|
||||
verifyResult.message?.includes('Akun tidak ditemukan')
|
||||
) {
|
||||
await handleNewRegistration();
|
||||
return;
|
||||
}
|
||||
|
||||
// Error lain
|
||||
toast.error(verifyResult.message || 'Verifikasi gagal');
|
||||
return;
|
||||
if (isRegistrationFlow) {
|
||||
// 🔑 Alur REGISTRASI
|
||||
await handleRegistrationVerification();
|
||||
} else {
|
||||
// 🔑 Alur LOGIN
|
||||
await handleLoginVerification();
|
||||
}
|
||||
|
||||
// ✅ Verifikasi sukses → simpan user ke store
|
||||
const user = verifyResult.user;
|
||||
console.log('=== DEBUG USER ===');
|
||||
console.log('Full user object:', user);
|
||||
|
||||
if (!user || !user.id) {
|
||||
toast.error('Data pengguna tidak lengkap');
|
||||
return;
|
||||
}
|
||||
|
||||
const roleId = Number(user.roleId);
|
||||
authStore.setUser({
|
||||
id: user.id,
|
||||
name: user.name || user.username || 'User',
|
||||
roleId: roleId,
|
||||
});
|
||||
|
||||
cleanupStorage();
|
||||
|
||||
const isUserActive = user.isActive ?? user.is_active ?? true;
|
||||
|
||||
// Redirect berdasarkan status approval
|
||||
if (!isUserActive) {
|
||||
router.replace('/waiting-room');
|
||||
return;
|
||||
}
|
||||
|
||||
// ✅ Switch statement lebih clean
|
||||
let redirectPath: string;
|
||||
|
||||
switch (roleId) {
|
||||
case 0:
|
||||
case 1:
|
||||
redirectPath = '/admin/landing-page/profil/program-inovasi';
|
||||
break;
|
||||
case 2:
|
||||
redirectPath = '/admin/kesehatan/posyandu';
|
||||
break;
|
||||
case 3:
|
||||
redirectPath = '/admin/pendidikan/info-sekolah/jenjang-pendidikan';
|
||||
break;
|
||||
default:
|
||||
redirectPath = '/admin';
|
||||
console.warn('Unknown roleId:', roleId);
|
||||
}
|
||||
|
||||
console.log('Redirecting to:', redirectPath);
|
||||
router.replace(redirectPath);
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error saat verifikasi:', error);
|
||||
toast.error('Terjadi kesalahan sistem');
|
||||
@@ -129,38 +82,111 @@ export default function Validasi() {
|
||||
}
|
||||
};
|
||||
|
||||
// Registrasi baru
|
||||
const handleNewRegistration = async () => {
|
||||
// ✅ Verifikasi OTP untuk REGISTRASI
|
||||
const handleRegistrationVerification = async () => {
|
||||
const username = localStorage.getItem('auth_username');
|
||||
if (!username) {
|
||||
toast.error('Data registrasi tidak ditemukan');
|
||||
toast.error('Data registrasi tidak ditemukan. Silakan ulangi dari awal.');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const res = await fetch('/api/auth/finalize-registration', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ nomor, username, otp, kodeId }),
|
||||
});
|
||||
// ✅ Validasi format
|
||||
const cleanNomor = nomor?.replace(/\D/g, '') ?? '';
|
||||
if (cleanNomor.length < 10) {
|
||||
toast.error('Nomor tidak valid');
|
||||
return;
|
||||
}
|
||||
|
||||
const data = await res.json();
|
||||
if (username.trim().length < 5) {
|
||||
toast.error('Username minimal 5 karakter');
|
||||
return;
|
||||
}
|
||||
|
||||
if (data.success) {
|
||||
// Set user sementara (tanpa roleId, akan diisi saat approve)
|
||||
authStore.setUser({
|
||||
id: 'pending',
|
||||
name: username,
|
||||
roleId: 1,
|
||||
});
|
||||
cleanupStorage();
|
||||
router.replace('/waiting-room');
|
||||
} else {
|
||||
toast.error(data.message || 'Registrasi gagal');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error registrasi:', error);
|
||||
toast.error('Gagal menyelesaikan registrasi');
|
||||
// 1. Verifikasi OTP via endpoint register
|
||||
const verifyRes = await fetch('/api/auth/verify-otp-register', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ nomor: cleanNomor, otp, kodeId }),
|
||||
});
|
||||
|
||||
const verifyData = await verifyRes.json();
|
||||
|
||||
if (!verifyRes.ok) {
|
||||
toast.error(verifyData.message || 'Verifikasi OTP gagal');
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. Finalisasi registrasi
|
||||
const finalizeRes = await fetch('/api/auth/finalize-registration', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ nomor, username, kodeId }), // 🔴 Tidak perlu kirim `otp` ke sini
|
||||
});
|
||||
|
||||
const finalizeData = await finalizeRes.json();
|
||||
|
||||
if (!finalizeRes.ok) {
|
||||
toast.error(finalizeData.message || 'Registrasi gagal');
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. Set user & redirect
|
||||
authStore.setUser({
|
||||
id: finalizeData.user.id,
|
||||
name: finalizeData.user.name,
|
||||
roleId: Number(finalizeData.user.roleId),
|
||||
});
|
||||
|
||||
cleanupStorage();
|
||||
router.replace('/waiting-room');
|
||||
};
|
||||
|
||||
// ✅ Verifikasi OTP untuk LOGIN
|
||||
const handleLoginVerification = async () => {
|
||||
const loginRes = await fetch('/api/auth/verify-otp-login', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ nomor, otp, kodeId }),
|
||||
});
|
||||
|
||||
const loginData = await loginRes.json();
|
||||
|
||||
if (!loginRes.ok) {
|
||||
toast.error(loginData.message || 'Verifikasi gagal');
|
||||
return;
|
||||
}
|
||||
|
||||
const { id, name, roleId, isActive } = loginData.user;
|
||||
|
||||
authStore.setUser({
|
||||
id,
|
||||
name: name || 'User',
|
||||
roleId: Number(roleId),
|
||||
});
|
||||
|
||||
cleanupStorage();
|
||||
|
||||
if (!isActive) {
|
||||
router.replace('/waiting-room');
|
||||
return;
|
||||
}
|
||||
|
||||
const redirectPath = getRedirectPath(Number(roleId));
|
||||
router.replace(redirectPath);
|
||||
};
|
||||
|
||||
const getRedirectPath = (roleId: number): string => {
|
||||
switch (roleId) {
|
||||
case 0: // DEVELOPER
|
||||
case 1: // SUPERADMIN
|
||||
case 2: // ADMIN_DESA
|
||||
return '/admin/landing-page/profil/program-inovasi';
|
||||
case 3: // ADMIN_KESEHATAN
|
||||
return '/admin/kesehatan/posyandu';
|
||||
case 4: // ADMIN_PENDIDIKAN
|
||||
return '/admin/pendidikan/info-sekolah/jenjang-pendidikan';
|
||||
default:
|
||||
return '/admin';
|
||||
}
|
||||
};
|
||||
|
||||
@@ -173,7 +199,7 @@ export default function Validasi() {
|
||||
const handleResend = async () => {
|
||||
if (!nomor) return;
|
||||
try {
|
||||
const res = await fetch('/api/auth/resend-otp', {
|
||||
const res = await fetch('/api/auth/resend', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ nomor }),
|
||||
@@ -190,7 +216,6 @@ export default function Validasi() {
|
||||
}
|
||||
};
|
||||
|
||||
// Loading
|
||||
if (isLoading) {
|
||||
return (
|
||||
<Stack pos="relative" bg={colors.Bg} align="center" justify="center" h="100vh">
|
||||
@@ -209,7 +234,7 @@ export default function Validasi() {
|
||||
<Stack align="center" gap="lg">
|
||||
<Box>
|
||||
<Title ta="center" order={2} fw="bold" c={colors['blue-button']}>
|
||||
Kode Verifikasi
|
||||
{isRegistrationFlow ? 'Verifikasi Registrasi' : 'Verifikasi Login'}
|
||||
</Title>
|
||||
<Text ta="center" size="sm" c="dimmed" mt="xs">
|
||||
Kami telah mengirim kode ke nomor <strong>{nomor}</strong>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// src/app/admin/(dashboard)/user&role/_com/dynamicNavbar.ts
|
||||
import { navBar, role1, role2, role3 } from '@/app/admin/_com/list_PageAdmin';
|
||||
import { devBar, navBar, role1, role2, role3 } from '@/app/admin/_com/list_PageAdmin';
|
||||
|
||||
export function getNavbar({
|
||||
roleId,
|
||||
@@ -14,9 +14,10 @@ export function getNavbar({
|
||||
}
|
||||
|
||||
// Fallback ke role-based
|
||||
if (roleId === 0) return navBar;
|
||||
if (roleId === 1) return role1;
|
||||
if (roleId === 2) return role2;
|
||||
if (roleId === 3) return role3;
|
||||
if (roleId === 0) return devBar;
|
||||
if (roleId === 1) return navBar;
|
||||
if (roleId === 2) return role1;
|
||||
if (roleId === 3) return role2;
|
||||
if (roleId === 4) return role3;
|
||||
return [];
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import { Button, Checkbox, Group, Paper, Select, Stack, Text, Title } from '@man
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useProxy } from 'valtio/utils'
|
||||
import user from '../../_state/user/user-state'
|
||||
import { useShallowEffect } from '@mantine/hooks'
|
||||
|
||||
|
||||
// ✅ Helper: ekstrak semua menu ID dari struktur navBar
|
||||
@@ -23,6 +24,10 @@ function MenuAccessPage() {
|
||||
const [selectedUserId, setSelectedUserId] = useState<string | null>(null)
|
||||
const [userMenus, setUserMenus] = useState<string[]>([])
|
||||
|
||||
useShallowEffect(() => {
|
||||
stateUser.findMany.load()
|
||||
}, [])
|
||||
|
||||
// ✅ Gunakan helper untuk ekstrak menu
|
||||
const availableMenus = extractMenuIds(navBar);
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import { useProxy } from 'valtio/utils';
|
||||
import HeaderSearch from '../../_com/header';
|
||||
import { ModalKonfirmasiHapus } from '../../_com/modalKonfirmasiHapus';
|
||||
import user from '../../_state/user/user-state';
|
||||
import { authStore } from '@/store/authStore';
|
||||
|
||||
function User() {
|
||||
const [search, setSearch] = useState("");
|
||||
@@ -95,24 +96,17 @@ function ListUser({ search }: { search: string }) {
|
||||
});
|
||||
|
||||
if (success) {
|
||||
// Cek apakah role berubah
|
||||
const res = await fetch('/api/user/updt', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
id: userId,
|
||||
roleId: newRoleId,
|
||||
}),
|
||||
});
|
||||
const data = await res.json();
|
||||
|
||||
if (data.roleChanged) {
|
||||
// Tampilkan notifikasi
|
||||
alert(`User ${username} akan logout otomatis!`);
|
||||
// ✅ Logout user jika sedang mengedit diri sendiri
|
||||
const currentUserId = authStore.user?.id;
|
||||
if (currentUserId === userId) {
|
||||
authStore.setUser(null);
|
||||
document.cookie = `${process.env.BASE_SESSION_KEY}=; Max-Age=0; path=/;`;
|
||||
alert("Perubahan memerlukan login ulang");
|
||||
window.location.href = "/login";
|
||||
return;
|
||||
}
|
||||
|
||||
// Reload data
|
||||
stateUser.findMany.load(page, 10, search);
|
||||
}
|
||||
|
||||
@@ -127,6 +121,17 @@ function ListUser({ search }: { search: string }) {
|
||||
});
|
||||
|
||||
if (success) {
|
||||
// ✅ Logout user jika sedang mengedit diri sendiri
|
||||
const currentUserId = authStore.user?.id;
|
||||
if (currentUserId === userId) {
|
||||
authStore.setUser(null);
|
||||
document.cookie = `${process.env.BASE_SESSION_KEY}=; Max-Age=0; path=/;`;
|
||||
alert("Perubahan memerlukan login ulang");
|
||||
window.location.href = "/login";
|
||||
return;
|
||||
}
|
||||
|
||||
// Reload data
|
||||
stateUser.findMany.load(page, 10, search);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,3 +1,407 @@
|
||||
export const devBar = [
|
||||
{
|
||||
id: "Landing Page",
|
||||
name: "Landing Page",
|
||||
path: "",
|
||||
children: [
|
||||
{
|
||||
id: "Landing_Page_1",
|
||||
name: "Profil",
|
||||
path: "/admin/landing-page/profil/program-inovasi"
|
||||
},
|
||||
{
|
||||
id: "Landing_Page_2",
|
||||
name: "Desa Anti Korupsi",
|
||||
path: "/admin/landing-page/desa-anti-korupsi/list-desa-anti-korupsi"
|
||||
},
|
||||
{
|
||||
id: "Landing_Page_3",
|
||||
name: "Indeks Kepuasan Masyarakat",
|
||||
path: "/admin/landing-page/indeks-kepuasan-masyarakat/grafik-kepuasan-masyarakat"
|
||||
},
|
||||
{
|
||||
id: "Landing_Page_4",
|
||||
name: "SDGs",
|
||||
path: "/admin/landing-page/SDGs"
|
||||
},
|
||||
{
|
||||
id: "Landing_Page_5",
|
||||
name: "APBDes",
|
||||
path: "/admin/landing-page/apbdes"
|
||||
},
|
||||
{
|
||||
id: "Landing_Page_6",
|
||||
name: "Prestasi Desa",
|
||||
path: "/admin/landing-page/prestasi-desa/list-prestasi-desa"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "PPID",
|
||||
name: "PPID",
|
||||
path: "",
|
||||
children: [
|
||||
{
|
||||
id: "PPID_1",
|
||||
name: "Profil PPID",
|
||||
path: "/admin/ppid/profil-ppid"
|
||||
},
|
||||
{
|
||||
id: "PPID_2",
|
||||
name: "Struktur PPID",
|
||||
path: "/admin/ppid/struktur-ppid/pegawai"
|
||||
},
|
||||
{
|
||||
id: "PPID_3",
|
||||
name: "Visi Misi PPID",
|
||||
path: "/admin/ppid/visi-misi-ppid"
|
||||
},
|
||||
{
|
||||
id: "PPID_4",
|
||||
name: "Dasar Hukum",
|
||||
path: "/admin/ppid/dasar-hukum"
|
||||
},
|
||||
{
|
||||
id: "PPID_5",
|
||||
name: "Permohonan Informasi Publik",
|
||||
path: "/admin/ppid/permohonan-informasi-publik"
|
||||
},
|
||||
{
|
||||
id: "PPID_6",
|
||||
name: "Permohonan Keberatan Informasi Publik",
|
||||
path: "/admin/ppid/permohonan-keberatan-informasi-publik"
|
||||
},
|
||||
{
|
||||
id: "PPID_7",
|
||||
name: "Daftar Informasi Publik",
|
||||
path: "/admin/ppid/daftar-informasi-publik"
|
||||
},
|
||||
{
|
||||
id: "PPID_8",
|
||||
name: "Indeks Kepuasan Masyarakat",
|
||||
path: "/admin/ppid/indeks-kepuasan-masyarakat/grafik-kepuasan-masyarakat"
|
||||
},
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "Desa",
|
||||
name: "Desa",
|
||||
path: "",
|
||||
children: [
|
||||
{
|
||||
id: "Desa_1",
|
||||
name: "Profile",
|
||||
path: "/admin/desa/profile/profile-desa"
|
||||
},
|
||||
{
|
||||
id: "Desa_2",
|
||||
name: "Potensi",
|
||||
path: "/admin/desa/potensi/list-potensi"
|
||||
},
|
||||
{
|
||||
id: "Desa_3",
|
||||
name: "Berita",
|
||||
path: "/admin/desa/berita/list-berita"
|
||||
},
|
||||
{
|
||||
id: "Desa_4",
|
||||
name: "Pengumuman",
|
||||
path: "/admin/desa/pengumuman/list-pengumuman"
|
||||
},
|
||||
{
|
||||
id: "Desa_5",
|
||||
name: "Gallery",
|
||||
path: "/admin/desa/gallery/foto"
|
||||
},
|
||||
{
|
||||
id: "Desa_6",
|
||||
name: "Layanan",
|
||||
path: "/admin/desa/layanan/pelayanan_surat_keterangan"
|
||||
},
|
||||
{
|
||||
id: "Desa_7",
|
||||
name: "Penghargaan",
|
||||
path: "/admin/desa/penghargaan"
|
||||
}
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "Kesehatan",
|
||||
name: "Kesehatan",
|
||||
path: "",
|
||||
children: [
|
||||
{
|
||||
id: "Kesehatan_1",
|
||||
name: "Posyandu",
|
||||
path: "/admin/kesehatan/posyandu"
|
||||
},
|
||||
{
|
||||
id: "Kesehatan_2",
|
||||
name: "Data Kesehatan Warga",
|
||||
path: "/admin/kesehatan/data-kesehatan-warga/persentase_data_kelahiran_kematian"
|
||||
},
|
||||
{
|
||||
id: "Kesehatan_3",
|
||||
name: "Puskesmas",
|
||||
path: "/admin/kesehatan/puskesmas"
|
||||
},
|
||||
{
|
||||
id: "Kesehatan_4",
|
||||
name: "Program Kesehatan",
|
||||
path: "/admin/kesehatan/program-kesehatan"
|
||||
},
|
||||
{
|
||||
id: "Kesehatan_5",
|
||||
name: "Penanganan Darurat",
|
||||
path: "/admin/kesehatan/penanganan-darurat"
|
||||
},
|
||||
{
|
||||
id: "Kesehatan_6",
|
||||
name: "Kontak Darurat",
|
||||
path: "/admin/kesehatan/kontak-darurat"
|
||||
},
|
||||
{
|
||||
id: "Kesehatan_7",
|
||||
name: "Info Wabah/Penyakit",
|
||||
path: "/admin/kesehatan/info-wabah-penyakit"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "Keamanan",
|
||||
name: "Keamanan",
|
||||
path: "",
|
||||
children: [
|
||||
{
|
||||
id: "Keamanan_1",
|
||||
name: "Keamanan Lingkungan (Pecalang/Patwal)",
|
||||
path: "/admin/keamanan/keamanan-lingkungan-pecalang-patwal"
|
||||
},
|
||||
{
|
||||
id: "Keamanan_2",
|
||||
name: "Polsek Terdekat",
|
||||
path: "/admin/keamanan/polsek-terdekat"
|
||||
},
|
||||
{
|
||||
id: "Keamanan_3",
|
||||
name: "Kontak Darurat",
|
||||
path: "/admin/keamanan/kontak-darurat/kontak-darurat-keamanan"
|
||||
},
|
||||
{
|
||||
id: "Keamanan_4",
|
||||
name: "Pencegahan Kriminalitas",
|
||||
path: "/admin/keamanan/pencegahan-kriminalitas"
|
||||
},
|
||||
{
|
||||
id: "Keamanan_5",
|
||||
name: "Laporan Publik",
|
||||
path: "/admin/keamanan/laporan-publik"
|
||||
},
|
||||
{
|
||||
id: "Keamanan_6",
|
||||
name: "Tips Keamanan",
|
||||
path: "/admin/keamanan/tips-keamanan"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "Ekonomi",
|
||||
name: "Ekonomi",
|
||||
path: "",
|
||||
children: [
|
||||
{
|
||||
id: "Ekonomi_1",
|
||||
name: "Pasar Desa",
|
||||
path: "/admin/ekonomi/pasar-desa/produk-pasar-desa"
|
||||
},
|
||||
{
|
||||
id: "Ekonomi_2",
|
||||
name: "Lowongan Kerja Lokal",
|
||||
path: "/admin/ekonomi/lowongan-kerja-lokal"
|
||||
},
|
||||
{
|
||||
id: "Ekonomi_3",
|
||||
name: "Struktur Organisasi Dan Sk Pengurus Bumdesa",
|
||||
path: "/admin/ekonomi/struktur-organisasi-dan-sk-pengurus-bumdesa/pegawai"
|
||||
},
|
||||
{
|
||||
id: "Ekonomi_4",
|
||||
name: "PADesa (Pendapatan Asli Desa)",
|
||||
path: "/admin/ekonomi/PADesa-pendapatan-asli-desa/apbdesa"
|
||||
},
|
||||
{
|
||||
id: "Ekonomi_5",
|
||||
name: "Jumlah Pengangguran",
|
||||
path: "/admin/ekonomi/jumlah-pengangguran"
|
||||
},
|
||||
{
|
||||
id: "Ekonomi_6",
|
||||
name: "Jumlah penduduk usia kerja yang menganggur",
|
||||
path: "/admin/ekonomi/jumlah-penduduk-usia-kerja-yang-menganggur/pengangguran_berdasarkan_usia"
|
||||
},
|
||||
{
|
||||
id: "Ekonomi_7",
|
||||
name: "Jumlah Penduduk Miskin",
|
||||
path: "/admin/ekonomi/jumlah-penduduk-miskin"
|
||||
},
|
||||
{
|
||||
id: "Ekonomi_8",
|
||||
name: "Program Kemiskinan",
|
||||
path: "/admin/ekonomi/program-kemiskinan"
|
||||
},
|
||||
{
|
||||
id: "Ekonomi_9",
|
||||
name: "Sektor Unggulan Desa",
|
||||
path: "/admin/ekonomi/sektor-unggulan-desa"
|
||||
},
|
||||
{
|
||||
id: "Ekonomi_10",
|
||||
name: "Demografi Pekerjaan",
|
||||
path: "/admin/ekonomi/demografi-pekerjaan"
|
||||
}
|
||||
]
|
||||
}, {
|
||||
id: "Inovasi",
|
||||
name: "Inovasi",
|
||||
path: "",
|
||||
children: [
|
||||
{
|
||||
id: "Inovasi_1",
|
||||
name: "Desa Digital/Smart Village",
|
||||
path: "/admin/inovasi/desa-digital-smart-village"
|
||||
},
|
||||
{
|
||||
id: "Inovasi_2",
|
||||
name: "Layanan Online Desa",
|
||||
path: "/admin/inovasi/layanan-online-desa/administrasi-online"
|
||||
},
|
||||
{
|
||||
id: "Inovasi_3",
|
||||
name: "Program Kreatif Desa",
|
||||
path: "/admin/inovasi/program-kreatif-desa"
|
||||
},
|
||||
{
|
||||
id: "Inovasi_4",
|
||||
name: "Kolaborasi Inovasi",
|
||||
path: "/admin/inovasi/kolaborasi-inovasi/list-kolaborasi-inovasi"
|
||||
},
|
||||
{
|
||||
id: "Inovasi_5",
|
||||
name: "Info Teknologi Tepat Guna",
|
||||
path: "/admin/inovasi/info-teknologi-tepat-guna"
|
||||
},
|
||||
{
|
||||
id: "Inovasi_6",
|
||||
name: "Ajukan Ide Inovatif",
|
||||
path: "/admin/inovasi/ajukan-ide-inovatif"
|
||||
}
|
||||
|
||||
]
|
||||
}, {
|
||||
id: "Lingkungan",
|
||||
name: "Lingkungan",
|
||||
path: "",
|
||||
children: [
|
||||
{
|
||||
id: "Lingkungan_1",
|
||||
name: "Pengelolaan Sampah (Bank Sampah)",
|
||||
path: "/admin/lingkungan/pengelolaan-sampah-bank-sampah/list-pengelolaan-sampah-bank-sampah"
|
||||
},
|
||||
{
|
||||
id: "Lingkungan_2",
|
||||
name: "Program Penghijauan",
|
||||
path: "/admin/lingkungan/program-penghijauan"
|
||||
},
|
||||
{
|
||||
id: "Lingkungan_3",
|
||||
name: "Data Lingkungan Desa",
|
||||
path: "/admin/lingkungan/data-lingkungan-desa"
|
||||
},
|
||||
{
|
||||
id: "Lingkungan_4",
|
||||
name: "Gotong Royong",
|
||||
path: "/admin/lingkungan/gotong-royong/kegiatan-desa"
|
||||
},
|
||||
{
|
||||
id: "Lingkungan_5",
|
||||
name: "Edukasi Lingkungan",
|
||||
path: "/admin/lingkungan/edukasi-lingkungan/tujuan-edukasi-lingkungan"
|
||||
},
|
||||
{
|
||||
id: "Lingkungan_6",
|
||||
name: "Konservasi Adat Bali",
|
||||
path: "/admin/lingkungan/konservasi-adat-bali/filosofi-tri-hita-karana"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "Pendidikan",
|
||||
name: "Pendidikan",
|
||||
path: "",
|
||||
children: [
|
||||
{
|
||||
id: "Pendidikan_1",
|
||||
name: "Info Sekolah",
|
||||
path: "/admin/pendidikan/info-sekolah/jenjang-pendidikan"
|
||||
},
|
||||
{
|
||||
id: "Pendidikan_2",
|
||||
name: "Beasiswa Desa",
|
||||
path: "/admin/pendidikan/beasiswa-desa/beasiswa-pendaftar"
|
||||
},
|
||||
{
|
||||
id: "Pendidikan_3",
|
||||
name: "Program Pendidikan Anak",
|
||||
path: "/admin/pendidikan/program-pendidikan-anak/program-unggulan"
|
||||
},
|
||||
{
|
||||
id: "Pendidikan_4",
|
||||
name: "Bimbingan Belajar Desa",
|
||||
path: "/admin/pendidikan/bimbingan-belajar-desa/tujuan-program"
|
||||
},
|
||||
{
|
||||
id: "Pendidikan_5",
|
||||
name: "Pendidikan Non Formal",
|
||||
path: "/admin/pendidikan/pendidikan-non-formal/tujuan-program"
|
||||
},
|
||||
{
|
||||
id: "Pendidikan_6",
|
||||
name: "Perpustakaan Digital",
|
||||
path: "/admin/pendidikan/perpustakaan-digital/data-perpustakaan"
|
||||
},
|
||||
{
|
||||
id: "Pendidikan_7",
|
||||
name: "Data Pendidikan",
|
||||
path: "/admin/pendidikan/data-pendidikan"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "User & Role",
|
||||
name: "User & Role",
|
||||
path: "",
|
||||
children: [
|
||||
{
|
||||
id: "User",
|
||||
name: "User",
|
||||
path: "/admin/user&role/user"
|
||||
},
|
||||
{
|
||||
id: "Role",
|
||||
name: "Role",
|
||||
path: "/admin/user&role/role"
|
||||
},
|
||||
{
|
||||
id: "Menu Access",
|
||||
name: "Menu Access",
|
||||
path: "/admin/user&role/menu-access"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
export const navBar = [
|
||||
{
|
||||
id: "Landing Page",
|
||||
|
||||
Reference in New Issue
Block a user