diff --git a/src/app/(admin)/layout.tsx b/src/app/(admin)/layout.tsx index 362a432..26b844d 100644 --- a/src/app/(admin)/layout.tsx +++ b/src/app/(admin)/layout.tsx @@ -1,13 +1,17 @@ "use client"; import { useSidebar } from "@/context/SidebarContext"; +import { UserData } from "@/interface/user"; import AppHeader from "@/layout/AppHeader"; import AppSidebar from "@/layout/AppSidebar"; import Backdrop from "@/layout/Backdrop"; import { apiGetCurrentUser } from "@/service/auth"; import { setUserData } from "@/store/features/userSlice"; -import React, { useEffect } from "react"; -import { useDispatch } from "react-redux"; +import { RootState } from "@/store/store"; +import { useRouter } from "next/navigation"; +import React, { useEffect, useState } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { toast } from "sonner"; export default function AdminLayout({ children, @@ -15,20 +19,44 @@ export default function AdminLayout({ children: React.ReactNode; }) { const { isExpanded, isHovered, isMobileOpen } = useSidebar(); - const dispatch = useDispatch() + const dispatch = useDispatch(); + const router = useRouter(); + const userData = useSelector((state: RootState) => state.user.data); + const [isLoading, setIsLoading] = useState(!userData); useEffect(() => { + if (userData) { + setIsLoading(false); + return; + } + const fetchUser = async () => { try { - const userData = await apiGetCurrentUser(); - dispatch(setUserData(userData.data)); - } catch (err) { - console.error("Lỗi:", err); + setIsLoading(true); + const res = await apiGetCurrentUser(); + const userData: UserData = res; + + const allowedRoles = ["ADMIN", "MOD", "HISTORIAN"]; + + const isBanned = userData.roles.some((role) => role.name === "BANNED"); + + const hasPermission = userData.roles.some((role) => + allowedRoles.includes(role.name) + ); + + if (isBanned || !hasPermission) { + toast.error("Bạn không có quyền truy cập"); + router.replace("/auth/signin"); + } + dispatch(setUserData(res.data)); + } catch { + router.replace("/auth/signin"); + } finally { + setIsLoading(false); } }; fetchUser(); - }, []) - + }, [dispatch, userData, router]); // Dynamic class for main content margin based on sidebar state const mainContentMargin = isMobileOpen @@ -37,6 +65,29 @@ export default function AdminLayout({ ? "lg:ml-[290px]" : "lg:ml-[90px]"; + if (isLoading || !userData) { + return ( +
+ Đang tải dữ liệu +
++ Vui lòng chờ trong giây lát... +
+Don't have an account? {""} Sign Up diff --git a/src/components/auth/SignUpForm.tsx b/src/components/auth/SignUpForm.tsx index d440f70..a4949f9 100644 --- a/src/components/auth/SignUpForm.tsx +++ b/src/components/auth/SignUpForm.tsx @@ -72,7 +72,7 @@ export default function SignUpForm() { setLoading(true); await apiCreateOTP(formData.email); setStep(2); - } catch (error) { + } catch { setErrorMsg("Lỗi khi tạo OTP. Vui lòng thử lại."); toast.error("Tạo OTP thất bại. Vui lòng kiểm tra lại thông tin."); } finally { @@ -106,7 +106,7 @@ export default function SignUpForm() { token_id: tokenId, }; - const signupRes = await apiSignUp(signupPayload); + await apiSignUp(signupPayload); await Swal.fire({ title: "Tạo tài khoản thành công!. Quay về trang đăng nhập để tiếp tục", @@ -131,7 +131,7 @@ export default function SignUpForm() {
Already have an account?{" "} Sign In diff --git a/src/components/ecommerce/DailyNewChart.tsx b/src/components/ecommerce/DailyNewChart.tsx index f00d123..6b63b48 100644 --- a/src/components/ecommerce/DailyNewChart.tsx +++ b/src/components/ecommerce/DailyNewChart.tsx @@ -31,7 +31,6 @@ export default function MonthlyNewChart() { try { const response = await getStatistics({ start_date: start, end_date: end }); if (response?.data) { - // Tổng hợp theo tháng const monthsMap: { [key: string]: number } = {}; response.data.forEach(item => { @@ -56,8 +55,7 @@ export default function MonthlyNewChart() { setChartData(aggregated); } - } catch (error) { - console.error("Failed to fetch chart data", error); + } catch { } finally { setLoading(false); } diff --git a/src/config/config.ts b/src/config/config.ts index 43f6edc..61fff74 100644 --- a/src/config/config.ts +++ b/src/config/config.ts @@ -67,7 +67,7 @@ api.interceptors.response.use( isRefreshing = true; try { - await axios.post(`${baseURL}/auth/refresh`, {}, { withCredentials: true }); + await axios.post(`${baseURL}/auth/refresh`, undefined, { withCredentials: true }); processQueue(null);