TorbatYar/frontend/modules/sports-center/constants/portals.ts
Mortezakoohjani 6f4a484051 Migrate Beauty, Healthcare, and Accounting frontend to modular src/modules architecture.
Move business logic out of App Router into module packages, add boundary validation scripts, and keep all routes as thin re-exports without changing URLs or API behavior.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-26 22:28:27 +03:30

363 lines
14 KiB
TypeScript

import type { LucideIcon } from "lucide-react";
import {
LayoutDashboard,
Users,
CreditCard,
Calendar,
Dumbbell,
Trophy,
Building2,
Shield,
ClipboardList,
QrCode,
BarChart3,
Settings,
Activity,
UserCircle,
Stethoscope,
Lock,
Plug,
Bell,
Sparkles,
Target,
MessageSquare,
Wallet,
ScanLine,
Heart,
} from "lucide-react";
export type SportsCenterPortalId =
| "owner"
| "reception"
| "coach"
| "athlete"
| "parent"
| "cashier"
| "support"
| "admin";
export type PortalNavItem = { href: string; label: string; feature?: string | null };
export type PortalNavGroup = {
id: string;
label: string;
icon: LucideIcon;
href?: string;
feature?: string | null;
items?: PortalNavItem[];
};
export const SPORTS_CENTER_PORTALS: {
id: SportsCenterPortalId;
label: string;
description: string;
basePath: string;
icon: LucideIcon;
}[] = [
{
id: "owner",
label: "مدیریت اجرایی",
description: "داشبورد، درآمد، آنالیتیکس",
basePath: "/sports-center/owner",
icon: LayoutDashboard,
},
{
id: "reception",
label: "پذیرش",
description: "چک‌این، جستجو، QR",
basePath: "/sports-center/reception",
icon: ClipboardList,
},
{
id: "coach",
label: "مربی",
description: "کلاس‌ها، تمرین، پیشرفت",
basePath: "/sports-center/coach",
icon: Dumbbell,
},
{
id: "athlete",
label: "ورزشکار",
description: "تمرین امروز، پیشرفت، عضویت",
basePath: "/sports-center/athlete",
icon: UserCircle,
},
{
id: "parent",
label: "والدین",
description: "خانواده، پرداخت‌ها",
basePath: "/sports-center/parent",
icon: Heart,
},
{
id: "cashier",
label: "صندوق",
description: "پرداخت‌ها و عضویت",
basePath: "/sports-center/cashier",
icon: Wallet,
},
{
id: "support",
label: "پشتیبانی",
description: "اعلان‌ها و پشتیبانی",
basePath: "/sports-center/support",
icon: MessageSquare,
},
{
id: "admin",
label: "مدیر سیستم",
description: "تنظیمات، نقش‌ها، دسترسی",
basePath: "/sports-center/admin",
icon: Shield,
},
];
export const OWNER_NAV: PortalNavGroup[] = [
{ id: "dash", label: "داشبورد", icon: LayoutDashboard, href: "/sports-center/owner" },
{
id: "members",
label: "اعضا",
icon: Users,
items: [
{ href: "/sports-center/members", label: "اعضا" },
{ href: "/sports-center/families", label: "خانواده‌ها" },
{ href: "/sports-center/medical-records", label: "سوابق پزشکی" },
{ href: "/sports-center/membership-cards", label: "کارت عضویت" },
{ href: "/sports-center/digital-membership", label: "عضویت دیجیتال" },
],
},
{
id: "membership",
label: "عضویت",
icon: CreditCard,
feature: "membership_catalog",
items: [
{ href: "/sports-center/memberships", label: "عضویت‌ها" },
{ href: "/sports-center/membership-types", label: "انواع عضویت" },
{ href: "/sports-center/catalog/packages", label: "پکیج‌ها" },
{ href: "/sports-center/catalog/plans", label: "طرح‌ها" },
{ href: "/sports-center/catalog/sport-categories", label: "دسته رشته" },
{ href: "/sports-center/catalog/age-groups", label: "گروه سنی" },
{ href: "/sports-center/catalog/pricing-models", label: "قیمت‌گذاری" },
{ href: "/sports-center/catalog/rules", label: "قوانین" },
{ href: "/sports-center/catalog/renewal-policies", label: "تمدید" },
{ href: "/sports-center/catalog/freezing-rules", label: "فریز" },
{ href: "/sports-center/catalog/expiration-policies", label: "انقضا" },
],
},
{
id: "staff",
label: "مربی و پرسنل",
icon: Target,
feature: "coach_staff_management",
items: [
{ href: "/sports-center/coaches", label: "مربیان" },
{ href: "/sports-center/staff/certificates", label: "گواهینامه" },
{ href: "/sports-center/staff/skills", label: "مهارت‌ها" },
{ href: "/sports-center/staff/working-hours", label: "ساعات کاری" },
{ href: "/sports-center/staff/availability", label: "دسترسی" },
{ href: "/sports-center/staff/assignments", label: "انتساب" },
],
},
{
id: "ops",
label: "عملیات",
icon: Calendar,
items: [
{ href: "/sports-center/sessions", label: "جلسات", feature: "booking_engine" },
{ href: "/sports-center/bookings", label: "رزروها", feature: "booking_engine" },
{ href: "/sports-center/attendance", label: "حضور", feature: "attendance_engine" },
{ href: "/sports-center/access-logs", label: "لاگ دسترسی", feature: "attendance_engine" },
{ href: "/sports-center/events", label: "رویدادها" },
],
},
{
id: "training",
label: "تمرین",
icon: Dumbbell,
feature: "training_management",
items: [
{ href: "/sports-center/training/programs", label: "برنامه‌ها" },
{ href: "/sports-center/training/exercises", label: "تمرینات" },
{ href: "/sports-center/training/workout-plans", label: "برنامه تمرین" },
{ href: "/sports-center/training/measurements", label: "اندازه‌گیری" },
{ href: "/sports-center/training/progress", label: "پیشرفت" },
{ href: "/sports-center/training/nutrition", label: "تغذیه" },
],
},
{
id: "competitions",
label: "مسابقات",
icon: Trophy,
feature: "competition_management",
items: [
{ href: "/sports-center/competitions", label: "مسابقات" },
{ href: "/sports-center/competitions/teams", label: "تیم‌ها" },
{ href: "/sports-center/competitions/results", label: "نتایج" },
],
},
{
id: "facilities",
label: "امکانات",
icon: Building2,
items: [
{ href: "/sports-center/sports-centers", label: "مراکز" },
{ href: "/sports-center/branches", label: "شعب" },
{ href: "/sports-center/sports", label: "رشته‌ها" },
{ href: "/sports-center/facilities", label: "امکانات" },
{ href: "/sports-center/courts", label: "زمین‌ها" },
{ href: "/sports-center/rooms", label: "اتاق‌ها" },
{ href: "/sports-center/lockers", label: "کمدها" },
{ href: "/sports-center/equipment", label: "تجهیزات", feature: "booking_engine" },
],
},
{
id: "analytics",
label: "گزارش‌ها",
icon: BarChart3,
items: [
{ href: "/sports-center/analytics", label: "آنالیتیکس" },
{ href: "/sports-center/reports", label: "گزارش‌ها" },
],
},
{
id: "integrations",
label: "یکپارچه‌سازی",
icon: Plug,
items: [
{ href: "/sports-center/integrations/crm", label: "CRM" },
{ href: "/sports-center/integrations/accounting", label: "حسابداری" },
{ href: "/sports-center/integrations/loyalty", label: "وفاداری" },
{ href: "/sports-center/integrations/communication", label: "ارتباطات" },
{ href: "/sports-center/integrations/ai", label: "هوش مصنوعی" },
],
},
];
export const RECEPTION_NAV: PortalNavGroup[] = [
{ id: "dash", label: "پذیرش", icon: ClipboardList, href: "/sports-center/reception" },
{ id: "checkin", label: "چک‌این سریع", icon: ScanLine, href: "/sports-center/reception/check-in" },
{ id: "search", label: "جستجوی عضو", icon: Users, href: "/sports-center/members" },
{ id: "qr", label: "QR", icon: QrCode, href: "/sports-center/reception/qr-scanner" },
{ id: "attendance", label: "حضور", icon: Activity, href: "/sports-center/attendance", feature: "attendance_engine" },
{ id: "bookings", label: "رزرو", icon: Calendar, href: "/sports-center/bookings", feature: "booking_engine" },
{ id: "schedule", label: "برنامه امروز", icon: Calendar, href: "/sports-center/sessions", feature: "booking_engine" },
];
export const COACH_NAV: PortalNavGroup[] = [
{ id: "dash", label: "داشبورد", icon: LayoutDashboard, href: "/sports-center/coach" },
{ id: "classes", label: "کلاس‌های امروز", icon: Calendar, href: "/sports-center/sessions", feature: "booking_engine" },
{ id: "attendance", label: "حضور", icon: ClipboardList, href: "/sports-center/attendance", feature: "attendance_engine" },
{
id: "training",
label: "تمرین",
icon: Dumbbell,
feature: "training_management",
items: [
{ href: "/sports-center/training/programs", label: "برنامه‌ها" },
{ href: "/sports-center/training/exercises", label: "کتابخانه تمرین" },
{ href: "/sports-center/training/workout-plans", label: "سازنده تمرین" },
{ href: "/sports-center/training/measurements", label: "اندازه‌گیری" },
{ href: "/sports-center/training/progress", label: "پیشرفت" },
{ href: "/sports-center/training/nutrition", label: "تغذیه" },
],
},
{ id: "messages", label: "پیام‌ها", icon: MessageSquare, href: "/sports-center/coach/messages" },
{ id: "schedule", label: "برنامه", icon: Calendar, href: "/sports-center/coach/schedule" },
];
export const ATHLETE_NAV: PortalNavGroup[] = [
{ id: "today", label: "تمرین امروز", icon: Dumbbell, href: "/sports-center/athlete" },
{ id: "workouts", label: "جزئیات تمرین", icon: Target, href: "/sports-center/athlete/workout" },
{ id: "progress", label: "پیشرفت", icon: BarChart3, href: "/sports-center/athlete/progress", feature: "training_management" },
{ id: "measurements", label: "اندازه‌گیری", icon: Activity, href: "/sports-center/athlete/measurements", feature: "training_management" },
{ id: "attendance", label: "حضور", icon: ClipboardList, href: "/sports-center/athlete/attendance", feature: "attendance_engine" },
{ id: "membership", label: "عضویت", icon: CreditCard, href: "/sports-center/athlete/membership" },
{ id: "qr", label: "QR عضویت", icon: QrCode, href: "/sports-center/athlete/qr" },
{ id: "nutrition", label: "تغذیه", icon: Heart, href: "/sports-center/athlete/nutrition", feature: "training_management" },
{ id: "bookings", label: "رزروها", icon: Calendar, href: "/sports-center/athlete/bookings", feature: "booking_engine" },
{ id: "achievements", label: "دستاوردها", icon: Trophy, href: "/sports-center/athlete/achievements", feature: "competition_management" },
{ id: "profile", label: "پروفایل", icon: UserCircle, href: "/sports-center/athlete/profile" },
];
export const ADMIN_NAV: PortalNavGroup[] = [
{ id: "settings", label: "تنظیمات", icon: Settings, href: "/sports-center/settings" },
{ id: "roles", label: "نقش‌ها", icon: Shield, href: "/sports-center/roles" },
{ id: "permissions", label: "مجوزها", icon: Lock, href: "/sports-center/permissions" },
{ id: "devices", label: "دستگاه‌ها", icon: ScanLine, href: "/sports-center/devices" },
{ id: "gateways", label: "گیت‌وی", icon: Plug, href: "/sports-center/attendance-gateways" },
{ id: "health", label: "سلامت سرویس", icon: Activity, href: "/sports-center/health" },
{ id: "capabilities", label: "قابلیت‌ها", icon: Sparkles, href: "/sports-center/capabilities" },
{ id: "notifications", label: "اعلان‌ها", icon: Bell, href: "/sports-center/notifications" },
];
export const PARENT_NAV: PortalNavGroup[] = [
{ id: "dash", label: "خانواده", icon: Heart, href: "/sports-center/parent" },
{ id: "family", label: "اعضای خانواده", icon: Users, href: "/sports-center/families" },
{ id: "membership", label: "عضویت", icon: CreditCard, href: "/sports-center/memberships" },
];
export const CASHIER_NAV: PortalNavGroup[] = [
{ id: "dash", label: "صندوق", icon: Wallet, href: "/sports-center/cashier" },
{ id: "membership", label: "عضویت", icon: CreditCard, href: "/sports-center/memberships" },
{ id: "members", label: "اعضا", icon: Users, href: "/sports-center/members" },
];
export const SUPPORT_NAV: PortalNavGroup[] = [
{ id: "dash", label: "پشتیبانی", icon: MessageSquare, href: "/sports-center/support" },
{ id: "notifications", label: "اعلان‌ها", icon: Bell, href: "/sports-center/notifications" },
];
export function navForPortal(portalId: SportsCenterPortalId): PortalNavGroup[] {
switch (portalId) {
case "owner":
return OWNER_NAV;
case "reception":
return RECEPTION_NAV;
case "coach":
return COACH_NAV;
case "athlete":
return ATHLETE_NAV;
case "parent":
return PARENT_NAV;
case "cashier":
return CASHIER_NAV;
case "support":
return SUPPORT_NAV;
case "admin":
return ADMIN_NAV;
default:
return OWNER_NAV;
}
}
export function detectPortal(pathname: string): SportsCenterPortalId {
if (pathname.startsWith("/sports-center/reception")) return "reception";
if (pathname.startsWith("/sports-center/coach")) return "coach";
if (pathname.startsWith("/sports-center/athlete")) return "athlete";
if (pathname.startsWith("/sports-center/parent")) return "parent";
if (pathname.startsWith("/sports-center/cashier")) return "cashier";
if (pathname.startsWith("/sports-center/support")) return "support";
if (pathname.startsWith("/sports-center/admin")) return "admin";
return "owner";
}
export function filterNavByCapabilities(
nav: PortalNavGroup[],
features?: Record<string, boolean>
): PortalNavGroup[] {
if (!features) return nav;
return nav
.map((group) => {
if (group.feature && features[group.feature] === false) return null;
if (!group.items) return group;
const items = group.items.filter((i) => !i.feature || features[i.feature] !== false);
if (items.length === 0 && !group.href) return null;
return { ...group, items };
})
.filter(Boolean) as PortalNavGroup[];
}
export function portalMeta(id: SportsCenterPortalId) {
return SPORTS_CENTER_PORTALS.find((p) => p.id === id)!;
}