Add Availability Calendar, Modules system, and route refactoring

- Add AvailabilityPage with price grid (categories × dates), drag-select,
  channel prices, EditPanel, PeriodModal, and rate periods tab
- Add ModulesContext with localStorage persistence and dynamic sidebar items
- Add ModulesPage with WiFi Auth, Payments, TV Welcome, Smart Locks,
  OLAP Reports, Website Builder, Booking Widget modules
- Add ReportsPage (OLAP analytics with KPI cards, charts, tables)
- Add WebsitePage and BookingWidgetPage placeholders
- Remove hotel slug from URL routing; hotel context from JWT
- Add Доступность nav item in Sidebar under Управление
- Fix LoginPage redirects and HotelSync branding

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-11 14:43:18 +03:00
parent 63c9ae574f
commit b277e3e38d
14 changed files with 1869 additions and 78 deletions

View File

@@ -1,6 +1,7 @@
import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom'
import { ThemeProvider } from './contexts/ThemeContext'
import { AuthProvider } from './contexts/AuthContext'
import { ModulesProvider } from './contexts/ModulesContext'
import { AppLayout } from './layouts/AppLayout'
import { LoginPage } from './pages/LoginPage'
import { CalendarPage } from './pages/CalendarPage'
@@ -10,56 +11,52 @@ import { HousekeepingPage } from './pages/HousekeepingPage'
import { ChannelsPage } from './pages/ChannelsPage'
import { ApiDocsPage } from './pages/ApiDocsPage'
import { SettingsPage } from './pages/SettingsPage'
import { ModulesPage } from './pages/ModulesPage'
import { ReportsPage } from './pages/ReportsPage'
import { WebsitePage } from './pages/WebsitePage'
import { BookingWidgetPage } from './pages/BookingWidgetPage'
import { AvailabilityPage } from './pages/AvailabilityPage'
import { AdminDashboard } from './pages/AdminDashboard'
import { useAuth } from './contexts/AuthContext'
function RoleGuard({
children,
allow,
}: {
children: React.ReactNode
allow: string[]
}) {
const { user } = useAuth()
if (!user || !allow.includes(user.role)) {
return <Navigate to="/login" replace />
}
return <>{children}</>
}
export default function App() {
return (
<ThemeProvider>
<AuthProvider>
<BrowserRouter>
<Routes>
{/* Public */}
<Route path="/login" element={<LoginPage />} />
<ModulesProvider>
<BrowserRouter>
<Routes>
{/* Public */}
<Route path="/login" element={<LoginPage />} />
{/* Hotel routes */}
<Route path="/:hotelSlug" element={<AppLayout />}>
<Route index element={<Navigate to="calendar" replace />} />
<Route path="calendar" element={<CalendarPage />} />
<Route path="bookings" element={<BookingsPage />} />
<Route path="rooms" element={<RoomsPage />} />
<Route path="housekeeping" element={<HousekeepingPage />} />
<Route path="channels" element={<ChannelsPage />} />
<Route path="api-docs" element={<ApiDocsPage />} />
<Route path="settings" element={<SettingsPage />} />
</Route>
{/* App routes */}
<Route element={<AppLayout />}>
<Route path="/calendar" element={<CalendarPage />} />
<Route path="/bookings" element={<BookingsPage />} />
<Route path="/rooms" element={<RoomsPage />} />
<Route path="/housekeeping" element={<HousekeepingPage />} />
<Route path="/channels" element={<ChannelsPage />} />
<Route path="/api-docs" element={<ApiDocsPage />} />
<Route path="/modules" element={<ModulesPage />} />
<Route path="/settings" element={<SettingsPage />} />
{/* Module pages */}
<Route path="/reports" element={<ReportsPage />} />
<Route path="/website" element={<WebsitePage />} />
<Route path="/booking-widget" element={<BookingWidgetPage />} />
<Route path="/availability" element={<AvailabilityPage />} />
</Route>
{/* Admin routes */}
<Route path="/admin" element={<AppLayout />}>
<Route index element={<AdminDashboard />} />
<Route path="hotels" element={<AdminDashboard />} />
<Route path="users" element={<AdminDashboard />} />
</Route>
{/* Admin routes */}
<Route path="/admin" element={<AppLayout />}>
<Route index element={<AdminDashboard />} />
<Route path="hotels" element={<AdminDashboard />} />
<Route path="users" element={<AdminDashboard />} />
</Route>
{/* Default */}
<Route path="/" element={<Navigate to="/login" replace />} />
<Route path="*" element={<Navigate to="/login" replace />} />
</Routes>
</BrowserRouter>
<Route path="/" element={<Navigate to="/login" replace />} />
<Route path="*" element={<Navigate to="/login" replace />} />
</Routes>
</BrowserRouter>
</ModulesProvider>
</AuthProvider>
</ThemeProvider>
)