Extract admin dashboard from ghabilee-frontend2 into a dedicated Next.js app for backoffice.ghabilee.ir (no SEO indexing / Clarity).
89 lines
4.2 KiB
TypeScript
89 lines
4.2 KiB
TypeScript
'use client'
|
||
|
||
import React from 'react'
|
||
import clsx from 'clsx'
|
||
|
||
import SidebarMobile from '@/components/layouts/SidebarMobile'
|
||
import { useMediaQuery } from '@/hooks/useMediaQuery'
|
||
|
||
interface PageNavbarProps {
|
||
description?: string
|
||
pageTitle?: string
|
||
startSlot?: React.ReactNode
|
||
centerSlot?: React.ReactNode
|
||
endSlot?: React.ReactNode
|
||
className?: string
|
||
}
|
||
|
||
const ADMIN_PAGE_DESCRIPTIONS: Record<string, string> = {
|
||
پیشخوان: 'نمای کلی وضعیت و فعالیتهای سامانه',
|
||
کاربران: 'مشاهده و مدیریت حسابهای کاربری',
|
||
رویدادها: 'بررسی، ایجاد و مدیریت رویدادها',
|
||
رزروها: 'پیگیری رزروها و وضعیت حضور مهمانان',
|
||
پرداختها: 'مشاهده تراکنشها و وضعیت پرداختها',
|
||
تسویهها: 'مدیریت تسویهحسابهای مالی',
|
||
'درخواستهای برداشت': 'بررسی و پردازش درخواستهای مالی',
|
||
'دستهبندیهای رویداد': 'مدیریت ساختار دستهبندی رویدادها',
|
||
'لیستهای مهمان': 'مشاهده و مدیریت فهرست مهمانان',
|
||
'مدیریت نظرات': 'بررسی و مدیریت بازخورد کاربران',
|
||
شهرها: 'مدیریت اطلاعات جغرافیایی شهرها',
|
||
'احراز هویت میزبان': 'بررسی مدارک و وضعیت احراز هویت میزبانان',
|
||
اعلانها: 'ارسال و پیگیری اعلان درونبرنامهای، پوش و پیامک',
|
||
پیامکها: 'پیگیری پیامکهای ارسالی سامانه',
|
||
'ارسال اعلان دستی': 'ارسال اعلان درونبرنامهای و پوش به کاربران منتخب',
|
||
'تحویل پوش': 'عیبیابی وضعیت ارسال، نمایش و بازشدن اعلانهای پوش',
|
||
'گزارشهای کاربران': 'بررسی گزارشها و تخلفهای ثبتشده',
|
||
'پیامهای تماس': 'مشاهده پیامهای فرم تماس عمومی',
|
||
'نظارت بر گفتگوها': 'مشاهده فقطخواندنی گفتگوهای گروهی و خصوصی',
|
||
}
|
||
|
||
const PageNavbar = ({ description, pageTitle, startSlot, centerSlot, endSlot, className }: PageNavbarProps) => {
|
||
const isMobile = useMediaQuery('(max-width: 768px)')
|
||
const pageDescription =
|
||
description ?? (pageTitle ? (ADMIN_PAGE_DESCRIPTIONS[pageTitle] ?? `مدیریت و مشاهده اطلاعات ${pageTitle}`) : undefined)
|
||
|
||
return (
|
||
<header
|
||
className={clsx(
|
||
'admin-page-header sticky top-0 z-30 grid min-h-16 items-center gap-2 border-b border-secondary-40/70 bg-white/90 px-3 py-2 backdrop-blur-xl md:min-h-[76px] md:grid-cols-3 md:gap-0 md:px-7',
|
||
isMobile && !endSlot ? 'grid-cols-1' : isMobile ? 'grid-cols-[minmax(0,1fr)_auto]' : 'grid-cols-2',
|
||
className
|
||
)}
|
||
>
|
||
<div className="flex min-w-0 items-center justify-start">
|
||
{isMobile && <SidebarMobile />}
|
||
{pageTitle ? (
|
||
<div className="flex min-w-0 items-center gap-3 text-right">
|
||
<span
|
||
aria-hidden
|
||
className="hidden h-9 w-1 rounded-full bg-primary-600 sm:block"
|
||
/>
|
||
<div className="min-w-0">
|
||
<h1 className="truncate text-base font-bold tracking-normal text-secondary-10 md:text-xl">{pageTitle}</h1>
|
||
{pageDescription ? <p className="mt-1 hidden text-smt-neutral-30 lg:block">{pageDescription}</p> : null}
|
||
</div>
|
||
</div>
|
||
) : (
|
||
startSlot
|
||
)}
|
||
</div>
|
||
|
||
{isMobile ? (
|
||
<>
|
||
{endSlot && <div className="flex max-w-[52vw] items-center justify-end overflow-x-auto pb-1">{endSlot}</div>}
|
||
|
||
{centerSlot && <div className="flex items-center justify-center col-span-2">{centerSlot}</div>}
|
||
</>
|
||
) : (
|
||
<>
|
||
{centerSlot ? <div className="flex items-center justify-center">{centerSlot}</div> : <div />}
|
||
|
||
{endSlot && <div className="flex items-center justify-end">{endSlot}</div>}
|
||
</>
|
||
)}
|
||
</header>
|
||
)
|
||
}
|
||
|
||
export default PageNavbar
|