Implementasi Backend pada login, FAQ, Settings Intern, Projects Intern, Home Intern

This commit is contained in:
Kemas M. Aryadary Rasyad
2026-06-25 00:35:53 +07:00
parent 9e5a97ef10
commit f63efb0e12
29 changed files with 682 additions and 280 deletions
+6 -13
View File
@@ -1,13 +1,12 @@
import { Outlet, Navigate } from "react-router-dom";
interface PrivateRouteProps {
allowedRoles?: ("admin" | "intern" | "mentor")[];
allowedRoles?: ("intern" | "admin")[];
}
// Helper function untuk decode payload JWT tanpa library external
const decodeJWT = (token: string) => {
try {
const base64Url = token.split(".")[1]; // Ambil bagian payload (segmen kedua)
const base64Url = token.split(".")[1];
const base64 = base64Url.replace(/-/g, "+").replace(/_/g, "/");
const jsonPayload = decodeURIComponent(
window
@@ -23,31 +22,25 @@ const decodeJWT = (token: string) => {
};
const ProtectedRoutes = ({ allowedRoles }: PrivateRouteProps) => {
// 1. Ambil token dari cookie
const token = document.cookie
.split("; ")
.find((row) => row.startsWith("token="))
?.split("=")[1];
// Jika tidak punya token, tendang ke login admin awal
if (!token) {
return <Navigate to="/login-admin" replace />;
return <Navigate to="/login-internify" replace />;
}
// 2. Decode token untuk mendapatkan role asli dari Backend
const decoded = decodeJWT(token);
const userRole = decoded?.role as "admin" | "intern" | "mentor" | undefined;
const userRole = decoded?.role as"intern" | "admin" | undefined;
// Jika token corrupt atau tidak bisa di-decode, hanguskan dan tendang ke login
if (!userRole) {
return <Navigate to="/login-admin" replace />;
return <Navigate to="/login-internify" replace />;
}
// 3. Periksa hak akses role terhadap halaman yang dituju
if (allowedRoles && !allowedRoles.includes(userRole)) {
// Jika role tidak diizinkan, kembalikan ke base dashboard masing-masing role
if (userRole === "admin") return <Navigate to="/dashboard" replace />;
if (userRole === "mentor") return <Navigate to="/mentor" replace />;
if (userRole === "admin") return <Navigate to="/mentor" replace />;
if (userRole === "intern") return <Navigate to="/intern" replace />;
}
-20
View File
@@ -1,20 +0,0 @@
import axios from "axios";
const api = axios.create({
baseURL: import.meta.env.VITE_API_BASE_URL,
});
// Otomatis tempel Token Bearer di setiap request ke BE
api.interceptors.request.use((config) => {
const token = document.cookie
.split("; ")
.find((row) => row.startsWith("token="))
?.split("=")[1];
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
});
export default api;