Activate documents module, reorganize sidebar, add cleaning plans to housekeeping

Sidebar restructure:
- Основное: Шахматка, Бронирования, Номера, Категории номеров, Доступность
- Модули: Уборка + all active addon modules (including Documents)
- Управление: План этажей, Каналы, Модули, Настройки
- Разработчикам: API

ModulesContext: documents module now active by default (version bump to 3)

HousekeepingPage: added «Планы уборки» tab with:
- Уборка при выезде: auto task creation, priority (high/normal), inspection toggle
- Ежедневная уборка: interval (every 1/2/3/7 days), start from day N of stay
- Уборка по запросу: guest-initiated via QR, priority selection
- Генеральная уборка: deep clean every N days toggle
- Проверка после уборки: inspection task after any cleaning
- Автоназначение горничной: assign based on shift schedule

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-11 22:38:00 +03:00
parent de5b56c577
commit 401825c01e
3 changed files with 333 additions and 76 deletions

View File

@@ -44,9 +44,9 @@ export function Sidebar({ open, onClose }: SidebarProps) {
const isModuleActive = (id: string) => statuses[id] === 'active' || statuses[id] === 'trial'
// Core modules with dedicated nav positions (not shown in generic module list)
const CORE_MODULE_IDS = ['housekeeping', 'channel-manager']
const CORE_MODULE_IDS = ['channel-manager']
// Extra module items for the "Модули" sidebar section (excluding core ones)
// Module items for the "Модули" sidebar section
const activeModuleItems = MODULES_DATA.filter(
m => m.sidebarItem &&
!m.sidebarItem.showForHousekeeper &&
@@ -112,14 +112,26 @@ export function Sidebar({ open, onClose }: SidebarProps) {
</>
) : (
<>
{/* ── Основное ── */}
<p className="px-3 pt-2 pb-1 text-xs font-semibold text-slate-400 uppercase tracking-wider">
Основное
</p>
<NavItem to="/calendar" icon={CalendarDays} label="Шахматка" onClick={onClose} />
{!isHousekeeper && (
<NavItem to="/bookings" icon={BookOpen} label="Бронирования" onClick={onClose} />
<>
<NavItem to="/bookings" icon={BookOpen} label="Бронирования" onClick={onClose} />
<NavItem to="/rooms" icon={BedDouble} label="Номера" onClick={onClose} />
<NavItem to="/room-categories" icon={LayoutGrid} label="Категории номеров" onClick={onClose} />
<NavItem to="/availability" icon={CalendarRange} label="Доступность" onClick={onClose} />
</>
)}
{/* ── Модули ── */}
{(isModuleActive('housekeeping') || (!isHousekeeper && activeModuleItems.length > 0)) && (
<p className="px-3 pt-3 pb-1 text-xs font-semibold text-slate-400 uppercase tracking-wider">
Модули
</p>
)}
{/* Housekeeping — controlled by module status, visible to all roles */}
{isModuleActive('housekeeping') && (
<NavItem
to="/housekeeping"
@@ -128,16 +140,23 @@ export function Sidebar({ open, onClose }: SidebarProps) {
onClick={onClose}
/>
)}
{!isHousekeeper && activeModuleItems.map(m => (
<NavItem
key={m.id}
to={m.sidebarItem!.path}
icon={m.sidebarItem!.icon}
label={m.sidebarItem!.label}
onClick={onClose}
/>
))}
{/* ── Управление ── */}
{!isHousekeeper && (
<>
<p className="px-3 pt-3 pb-1 text-xs font-semibold text-slate-400 uppercase tracking-wider">
Управление
</p>
<NavItem to="/rooms" icon={BedDouble} label="Номера" onClick={onClose} />
<NavItem to="/room-categories" icon={LayoutGrid} label="Категории номеров" onClick={onClose} />
<NavItem to="/floor-map" icon={Map} label="План этажей" onClick={onClose} />
<NavItem to="/availability" icon={CalendarRange} label="Доступность" onClick={onClose} />
<NavItem to="/floor-map" icon={Map} label="План этажей" onClick={onClose} />
{isModuleActive('channel-manager') && (
<NavItem
to="/channels"
@@ -149,24 +168,6 @@ export function Sidebar({ open, onClose }: SidebarProps) {
<NavItem to="/modules" icon={Puzzle} label="Модули" onClick={onClose} />
<NavItem to="/settings" icon={Settings} label="Настройки" onClick={onClose} />
{/* Active addon modules */}
{activeModuleItems.length > 0 && (
<>
<p className="px-3 pt-3 pb-1 text-xs font-semibold text-slate-400 uppercase tracking-wider">
Модули
</p>
{activeModuleItems.map(m => (
<NavItem
key={m.id}
to={m.sidebarItem!.path}
icon={m.sidebarItem!.icon}
label={m.sidebarItem!.label}
onClick={onClose}
/>
))}
</>
)}
<p className="px-3 pt-3 pb-1 text-xs font-semibold text-slate-400 uppercase tracking-wider">
Разработчикам
</p>