);
}
// همهی صفحات پشت ورود هستند — به جز پیشنویسهای ویزارد از ربات یا بدون نشست که به صفحهی ورود میروند.
function RequireAuth({ children }: { children: React.ReactNode }) {
const user = useAuthStore((s) => s.user);
const location = useLocation();
// در صورت داشتن شناسه پیشنویس (از ربات بله)، دسترسی مستقیم به ویزارد بدون لاگین مجاز است
const searchParams = new URLSearchParams(location.search);
const hasDraft = searchParams.has("draft") || searchParams.has("draft_id");
if (location.pathname === "/wizard" && hasDraft) {
return <>{children}>;
}
if (!user) {
const returnUrl = encodeURIComponent(location.pathname + location.search);
return ;
}
if (user.role === "supervisor") {
// اگر سرپرست پروژهای نداشته باشد، دسترسی مسدود میشود
if (!user.projects || user.projects.length === 0) {
return (
پروژه تخصیص داده نشده است
شما به عنوان سرپرست پروژه در سیستم ثبت شدهاید اما هنوز هیچ پروژهای به شما تخصیص داده نشده است.
تا زمان تخصیص پروژه توسط مدیر سیستم، اجازه ورود به سامانه را ندارید.
);
}
// سرپرست پروژه فقط به انبار و PM دسترسی دارد
if (!location.pathname.startsWith("/inventory") && location.pathname !== "/panel/pm") {
return ;
}
}
}
return <>{children}>;
}
// صفحهی اصلی بر اساس لایه پنلها (جایگزین نقشها):
// انبار → پنل انبار · تدارکات limited → خانه حداقلی استعلام · بقیه → دفتر تدارکات
// نقشهای میراث (سرپرست → PM، مدیر پروژه → انبار) برای دوره مهاجرت حفظ شدهاند.
function HomeRoute() {
const user = useAuthStore((s) => s.user);
const panels = user?.panels ?? {};
if (panels.inventory) return ;
if (panels.procurement === "limited") return ;
// فقط پنل PM: مستقیم به پنل مدیریت پروژه
if (panels.pm && !panels.inventory && !panels.procurement) {
return ;
}
if (user?.role === "supervisor") return ;
if (user?.role === "pm") return ;
return ;
}
// دسترسی ایجاد استعلام/پیشنهاد (ویزارد): ادمین، نقشهای میراث، تدارکات full
// و تدارکات limited (محدود به پروژههای عضویت — صفحه /requester)
function RequireProcurementWrite({ children }: { children: React.ReactNode }) {
const user = useAuthStore((s) => s.user);
const panels = user?.panels ?? {};
if (user?.role === "admin" || user?.role === "procurement_manager" || user?.role === "pm") {
return <>{children}>;
}
if (panels.procurement === "full") return <>{children}>;
if (panels.procurement === "limited") return ;
return ;
}
// پنل «مدیریت پروژه (PM)» — اپ PM روی همان دامنه زیر مسیر /pm سرو میشود
function PmPanelPage() {
return (
);
}
// دسترسی پنل PM: ادمین، پنل pm (full/limited) و نقشهای میراث pm/supervisor —
// مدیر تدارکات (یا هر کاربر بدون پنل pm) دسترسی ندارد
function RequirePmPanel({ children }: { children: React.ReactNode }) {
const user = useAuthStore((s) => s.user);
const panels = user?.panels ?? {};
const allowed =
user?.role === "admin" ||
Boolean(panels.pm) ||
user?.role === "pm" ||
user?.role === "supervisor";
if (!allowed) return ;
return <>{children}>;
}
// دسترسی پنل سازماندهی: فقط ادمین، مدیر تدارکات و مدیر پروژه
function RequireOrganization({ children }: { children: React.ReactNode }) {
const user = useAuthStore((s) => s.user);
const allowed = user?.role === "admin" || user?.role === "procurement_manager" || user?.role === "pm";
if (!allowed) return ;
return <>{children}>;
}
// دسترسی تغییر موجودی انبار: ادمین، سرپرست پروژه (میراث) و پنل انبار limited —
// پنل انبار full طبق طراحی به تغییر موجودی دسترسی ندارد
function RequireInventoryChange({ children }: { children: React.ReactNode }) {
const user = useAuthStore((s) => s.user);
const allowed =
user?.role === "admin" ||
user?.role === "supervisor" ||
user?.panels?.inventory === "limited";
if (!allowed) {
return ;
}
return <>{children}>;
}
// دسترسی مدیریت انبارها: مدیران، ادمین و سرپرست پروژه (سرپرست پروژه منحصراً انبارهای پروژه خودش را میبیند)
function RequireWarehouseManage({ children }: { children: React.ReactNode }) {
const user = useAuthStore((s) => s.user);
const allowed = user?.role === "admin" || user?.role === "procurement_manager" || user?.role === "pm" || user?.role === "supervisor";
if (!allowed) {
return ;
}
return <>{children}>;
}
export default function App() {
return (
}>
} />
} />
}
/>
}
/>
}
/>
{/* سلسلهمراتب دامنه: دسته → تأمینکننده. کارت دسته مستقیم به
فهرست تأمینکنندههای همان دسته میرود (بدون صفحهی واسط متریال). */}
}
/>
{/* مسیرهای قدیمی (درخت معکوس topic → material → supplier) — ریدایرکت */}
}
/>
}
/>
}
/>
}
/>
}
/>
}
/>
}
/>
}
/>
}
/>
}
/>
}
/>
}
/>
}
/>
{/* خانه حداقلی استعلام — تدارکات سطح limited */}
}
/>
{/* پنل مدیریت پروژه — فقط ادمین و مدیر پروژه */}
}
/>
} />
);
}