diff --git a/middleware.ts b/middleware.ts index c48b5ac..e636e47 100644 --- a/middleware.ts +++ b/middleware.ts @@ -2,53 +2,46 @@ import { NextResponse } from "next/server"; import type { NextRequest } from "next/server"; -// کلید کوکی که توکن در آن ذخیره می‌شود -const AUTH_COOKIE_KEY = "userToken"; // <<< این را با نام واقعی کوکی خودتان جایگزین کنید +const AUTH_COOKIE_KEY = "userToken"; + +// مسیرهای عمومی +const publicPaths = ["/"]; // فرض کردیم "/" صفحه لاگین است export function middleware(request: NextRequest) { const token = request.cookies.get(AUTH_COOKIE_KEY)?.value; const { pathname } = request.nextUrl; - // مسیرهای عمومی که نیاز به احراز هویت ندارند (مثلا برای لاگین و ثبت نام) - const publicPaths = ["/"]; + const isPublicPath = publicPaths.includes(pathname); - // اگر کاربر توکن دارد + // اگر کاربر لاگین کرده باشد if (token) { - // اگر در مسیر لاگین است، به داشبورد هدایت کن + // اگر رفت صفحه لاگین، بفرستش داخل پنل if (pathname === "/") { const url = request.nextUrl.clone(); url.pathname = "/tickets/create"; return NextResponse.redirect(url); } - // در غیر این صورت، اجازه دسترسی به مسیر فعلی را بده + + // بقیه مسیرها مجاز return NextResponse.next(); - } else { - // اگر کاربر توکن ندارد - // اگر در مسیرهای عمومی است، اجازه دسترسی بده - if (publicPaths.includes(pathname)) { + } + + // اگر کاربر توکن نداشته باشد + if (!token) { + // فقط مسیرهای عمومی مجازند + if (isPublicPath) { return NextResponse.next(); } - // اگر در مسیرهای خصوصی است (مثل داشبورد)، به صفحه لاگین هدایت کن - if (pathname.startsWith("/tickets/create")) { - const url = request.nextUrl.clone(); - url.pathname = "/"; - return NextResponse.redirect(url); - } - // برای سایر مسیرهای خصوصی ناشناس - return NextResponse.next(); // یا هدایت به صفحه لاگین + + // هر مسیر دیگری => ریدایرکت به لاگین + const url = request.nextUrl.clone(); + url.pathname = "/"; + return NextResponse.redirect(url); } + + return NextResponse.next(); } -// تنظیمات middleware: کدام مسیرها را پوشش دهد export const config = { - matcher: [ - /* - * Match all request paths except for the ones starting with: - * - api (API routes) - * - _next/static (static files) - * - _next/image (image optimization files) - * - favicon.ico (favicon file) - */ - "/((?!api|_next/static|_next/image|favicon.ico).*)", - ], + matcher: ["/((?!api|_next/static|_next/image|favicon.ico).*)"], }; diff --git a/services/api/auth.api.ts b/services/api/auth.api.ts index 6fe4431..439ad21 100644 --- a/services/api/auth.api.ts +++ b/services/api/auth.api.ts @@ -4,3 +4,7 @@ export async function loginUser(data: any) { return await callAPI.post("/auth/login", data).then((res) => res.data); } +export async function logoutUser() { + return await callAPI.post("/auth/logout").then((res) => res.data); +} + diff --git a/services/hooks/auth.hook.ts b/services/hooks/auth.hook.ts new file mode 100644 index 0000000..173ecc9 --- /dev/null +++ b/services/hooks/auth.hook.ts @@ -0,0 +1,4 @@ +import { useMutation } from "@tanstack/react-query"; +import { logoutUser } from "../api/auth.api"; + +export const useLogout = () => useMutation({ mutationFn: logoutUser }); diff --git a/ui/LogoutButton.tsx b/ui/LogoutButton.tsx new file mode 100644 index 0000000..2efbf50 --- /dev/null +++ b/ui/LogoutButton.tsx @@ -0,0 +1,35 @@ +"use client"; +import { handleAxiosError } from "@/core/utils"; +import { useLogout } from "@/services/hooks/auth.hook"; +import { Logout } from "@mui/icons-material"; +import { Button } from "@mui/material"; +import { useRouter } from "next/navigation"; +import { toast } from "react-toastify"; + +export default function LogoutButton() { + const { mutateAsync, isPending } = useLogout(); + const router = useRouter(); + const handleLogout = async () => { + try { + const { message } = await mutateAsync(); + toast.success(message); + router.push("/"); + } catch (error) { + toast.error(handleAxiosError(error)); + } + }; + return ( + <> + + + ); +} diff --git a/ui/layout/Sidebar.tsx b/ui/layout/Sidebar.tsx index 6b2e046..9784691 100644 --- a/ui/layout/Sidebar.tsx +++ b/ui/layout/Sidebar.tsx @@ -1,7 +1,12 @@ -import { Apartment, Dashboard, Logout, Notes, Person, PictureInPicture, ShowChart } from "@mui/icons-material"; +import { + Logout, + Notes, + PictureInPicture, + ShowChart, +} from "@mui/icons-material"; import { Button } from "@mui/material"; import Link from "next/link"; -import React from "react"; +import LogoutButton from "../LogoutButton"; export default function Sidebar() { return ( @@ -67,15 +72,7 @@ export default function Sidebar() { گزارش گيري - + );