173 lines
5.6 KiB
TypeScript
173 lines
5.6 KiB
TypeScript
import React from "react";
|
||
import { Link, useNavigate } from "react-router";
|
||
import { Button } from "~/components/ui/button";
|
||
|
||
interface UnauthorizedProps {
|
||
title?: string;
|
||
message?: string;
|
||
showBackButton?: boolean;
|
||
showLoginButton?: boolean;
|
||
}
|
||
|
||
export function Unauthorized({
|
||
title = "دسترسی غیرمجاز",
|
||
message = "شما دسترسی لازم برای مشاهده این صفحه را ندارید. لطفاً با مدیر سیستم تماس بگیرید.",
|
||
showBackButton = true,
|
||
showLoginButton = false,
|
||
}: UnauthorizedProps) {
|
||
const navigate = useNavigate();
|
||
|
||
const handleGoBack = () => {
|
||
navigate(-1);
|
||
};
|
||
|
||
const handleGoHome = () => {
|
||
navigate("/dashboard");
|
||
};
|
||
|
||
const handleGoLogin = () => {
|
||
navigate("/login");
|
||
};
|
||
|
||
return (
|
||
<div className="min-h-screen bg-gradient-to-br from-slate-50 to-slate-100 dark:from-slate-900 dark:to-slate-800 flex items-center justify-center" dir="rtl">
|
||
<div className="max-w-md w-full px-6 py-8 text-center">
|
||
{/* 403 Illustration */}
|
||
<div className="mb-8">
|
||
<div className="mx-auto w-64 h-64 bg-gradient-to-br from-red-100 to-orange-100 dark:from-red-900/20 dark:to-orange-900/20 rounded-full flex items-center justify-center">
|
||
<div className="text-center">
|
||
<div className="text-6xl font-bold text-red-500 mb-2">403</div>
|
||
<svg
|
||
className="w-16 h-16 text-gray-400 mx-auto"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
viewBox="0 0 24 24"
|
||
>
|
||
<path
|
||
strokeLinecap="round"
|
||
strokeLinejoin="round"
|
||
strokeWidth={1.5}
|
||
d="M12 15v2m0 0v2m0-2h2m-2 0H10m12-6V9a6 6 0 10-12 0v6h12z"
|
||
/>
|
||
</svg>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Error Message */}
|
||
<div className="mb-8">
|
||
<h1 className="text-2xl font-bold text-gray-900 dark:text-white mb-4 font-persian">
|
||
{title}
|
||
</h1>
|
||
<p className="text-gray-600 dark:text-gray-400 leading-relaxed font-persian">
|
||
{message}
|
||
</p>
|
||
</div>
|
||
|
||
{/* Action Buttons */}
|
||
<div className="space-y-4">
|
||
<Button
|
||
onClick={handleGoHome}
|
||
className="w-full font-persian bg-green-500 hover:bg-green-600"
|
||
>
|
||
<svg
|
||
className="w-4 h-4 ml-2"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
viewBox="0 0 24 24"
|
||
>
|
||
<path
|
||
strokeLinecap="round"
|
||
strokeLinejoin="round"
|
||
strokeWidth={2}
|
||
d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"
|
||
/>
|
||
</svg>
|
||
بازگشت به داشبورد
|
||
</Button>
|
||
|
||
{showBackButton && (
|
||
<Button
|
||
variant="outline"
|
||
onClick={handleGoBack}
|
||
className="w-full font-persian"
|
||
>
|
||
<svg
|
||
className="w-4 h-4 ml-2"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
viewBox="0 0 24 24"
|
||
>
|
||
<path
|
||
strokeLinecap="round"
|
||
strokeLinejoin="round"
|
||
strokeWidth={2}
|
||
d="M10 19l-7-7m0 0l7-7m-7 7h18"
|
||
/>
|
||
</svg>
|
||
بازگشت به صفحه قبل
|
||
</Button>
|
||
)}
|
||
|
||
{showLoginButton && (
|
||
<Button
|
||
variant="secondary"
|
||
onClick={handleGoLogin}
|
||
className="w-full font-persian"
|
||
>
|
||
<svg
|
||
className="w-4 h-4 ml-2"
|
||
fill="none"
|
||
stroke="currentColor"
|
||
viewBox="0 0 24 24"
|
||
>
|
||
<path
|
||
strokeLinecap="round"
|
||
strokeLinejoin="round"
|
||
strokeWidth={2}
|
||
d="M11 16l-4-4m0 0l4-4m-4 4h14m-5 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h7a3 3 0 013 3v1"
|
||
/>
|
||
</svg>
|
||
ورود مجدد
|
||
</Button>
|
||
)}
|
||
</div>
|
||
|
||
{/* Contact Support */}
|
||
<div className="mt-8 pt-6 border-t border-gray-200 dark:border-gray-700">
|
||
<p className="text-xs text-gray-500 dark:text-gray-400 mb-2 font-persian">
|
||
اگر معتقدید که این خطا اشتباه است:
|
||
</p>
|
||
<p className="text-sm text-gray-600 dark:text-gray-300 font-persian">
|
||
با پشتیبانی سیستم تماس بگیرید
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
// Specialized unauthorized component for token expiry
|
||
export function TokenExpiredUnauthorized() {
|
||
return (
|
||
<Unauthorized
|
||
title="جلسه کاری منقضی شده"
|
||
message="جلسه کاری شما منقضی شده است. برای ادامه استفاده از سیستم لطفاً دوباره وارد شوید."
|
||
showBackButton={false}
|
||
showLoginButton={true}
|
||
/>
|
||
);
|
||
}
|
||
|
||
// Specialized unauthorized component for insufficient permissions
|
||
export function InsufficientPermissionsUnauthorized() {
|
||
return (
|
||
<Unauthorized
|
||
title="دسترسی محدود"
|
||
message="شما دسترسی کافی برای مشاهده این بخش را ندارید. در صورت نیاز با مدیر سیستم تماس بگیرید."
|
||
showBackButton={true}
|
||
showLoginButton={false}
|
||
/>
|
||
);
|
||
}
|