From 2fc66d1e849770a8a86747148d412a20942a51a1 Mon Sep 17 00:00:00 2001 From: HotelSync Date: Tue, 17 Mar 2026 00:27:43 +0300 Subject: [PATCH] Fix mobile responsiveness across all pages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - PosPage: rooms list becomes horizontal scroll row on mobile instead of w-56 sidebar - AvailabilityPage: edit panel stacks below grid on mobile (was fixed w-80 side panel) - UsersPage roles tab: sidebar stacks above permissions on mobile - All page containers: p-6 → p-4 md:p-6 (TariffsPage, DiscountsPage, MaintenancePage, ReportsPage, DynamicPricingPage, GuestsPage, LoyaltyPage) - Stats grids: lg:grid-cols-4 → md:grid-cols-4 (GuestsPage, TariffsPage, DiscountsPage, MaintenancePage, ReportsPage, LoyaltyPage) - Modal form grids: grid-cols-3 → grid-cols-1 sm:grid-cols-3, grid-cols-5 → grid-cols-3 sm:grid-cols-5, grid-cols-4 → grid-cols-2 sm:grid-cols-4 - PosPage modals: fixed w-80/w-96 → responsive w-[calc(100vw-2rem)] sm:w-80/96 Co-Authored-By: Claude Sonnet 4.6 --- src/pages/AvailabilityPage.tsx | 4 +-- src/pages/DiscountsPage.tsx | 8 +++--- src/pages/DynamicPricingPage.tsx | 2 +- src/pages/GuestsPage.tsx | 6 ++--- src/pages/LoyaltyPage.tsx | 6 ++--- src/pages/MaintenancePage.tsx | 6 ++--- src/pages/PosPage.tsx | 43 ++++++++++++++++++++++++++------ src/pages/ReportsPage.tsx | 4 +-- src/pages/TariffsPage.tsx | 14 +++++------ src/pages/UsersPage.tsx | 4 +-- 10 files changed, 62 insertions(+), 35 deletions(-) diff --git a/src/pages/AvailabilityPage.tsx b/src/pages/AvailabilityPage.tsx index 630d01f..d4b794c 100644 --- a/src/pages/AvailabilityPage.tsx +++ b/src/pages/AvailabilityPage.tsx @@ -265,7 +265,7 @@ function EditPanel({ }, [startDate, endDate]) return ( -
+
{/* Header */}
@@ -922,7 +922,7 @@ export function AvailabilityPage() {
{/* ── Content ── */} -
+
{/* Grid tab */} {tab === 'grid' && ( diff --git a/src/pages/DiscountsPage.tsx b/src/pages/DiscountsPage.tsx index b85500a..13e8040 100644 --- a/src/pages/DiscountsPage.tsx +++ b/src/pages/DiscountsPage.tsx @@ -140,8 +140,8 @@ function DiscountModal({ } >
-
-
+
+
set('name', e.target.value)} /> @@ -285,7 +285,7 @@ export function DiscountsPage() { setDiscounts(prev => prev.map(d => d.id === id ? { ...d, isActive: !d.isActive } : d)) return ( -
+
{/* Header */}
@@ -301,7 +301,7 @@ export function DiscountsPage() {
{/* Stats */} -
+
{[ { label: 'Всего скидок', value: discounts.length }, { label: 'Активных', value: discounts.filter(d => d.isActive).length }, diff --git a/src/pages/DynamicPricingPage.tsx b/src/pages/DynamicPricingPage.tsx index b991444..8d75605 100644 --- a/src/pages/DynamicPricingPage.tsx +++ b/src/pages/DynamicPricingPage.tsx @@ -772,7 +772,7 @@ export function DynamicPricingPage() { setRules(prev => prev.map(r => r.id === id ? { ...r, isActive: !r.isActive } : r)) return ( -
+
{/* Header */}
diff --git a/src/pages/GuestsPage.tsx b/src/pages/GuestsPage.tsx index c71eec1..6e98009 100644 --- a/src/pages/GuestsPage.tsx +++ b/src/pages/GuestsPage.tsx @@ -287,7 +287,7 @@ function GuestModal({ guest, onClose }: { guest: Guest; onClose: () => void }) {
{/* Body */} -
+
{tab === 'overview' && (
{/* Tags */} @@ -556,7 +556,7 @@ export function GuestsPage() { const avgRating = (MOCK_GUESTS.reduce((s, g) => s + g.rating, 0) / MOCK_GUESTS.length).toFixed(1) return ( -
+
{/* Header */}

Гости

@@ -588,7 +588,7 @@ export function GuestsPage() { {pageTab === 'list' && <> {/* Stats */} -
+
{[ { icon: Users, label: 'Всего гостей', value: MOCK_GUESTS.length, color: 'text-brand-600 dark:text-brand-400', bg: 'bg-brand-50 dark:bg-brand-900/20' }, { icon: Award, label: 'VIP гостей', value: vipCount, color: 'text-amber-600 dark:text-amber-400', bg: 'bg-amber-50 dark:bg-amber-900/20' }, diff --git a/src/pages/LoyaltyPage.tsx b/src/pages/LoyaltyPage.tsx index 5fb04cf..feca94e 100644 --- a/src/pages/LoyaltyPage.tsx +++ b/src/pages/LoyaltyPage.tsx @@ -815,7 +815,7 @@ export function LoyaltyPage() { const totalPoints = MOCK_GUESTS.reduce((s, g) => s + g.points, 0) return ( -
+
{/* Header */}
@@ -837,7 +837,7 @@ export function LoyaltyPage() {
{/* Stats */} -
+
{[ { label: 'Участников программы', value: activeGuests, icon: User, color: 'text-brand-600 dark:text-brand-400', bg: 'bg-brand-50 dark:bg-brand-900/20' }, { label: 'Всего баллов в обороте', value: totalPoints.toLocaleString('ru-RU'), icon: TrendingUp, color: 'text-amber-600 dark:text-amber-400', bg: 'bg-amber-50 dark:bg-amber-900/20' }, @@ -885,7 +885,7 @@ export function LoyaltyPage() { {editSettings ? <> Сохранить : <> Изменить}
-
+
{[ { label: 'Начисление', desc: `${settings.pointsPerRuble} балл за 1 ₽`, field: 'pointsPerRuble' as const, unit: 'балл/₽' }, { label: 'Ценность', desc: `1 балл = ${settings.pointValue} ₽`, field: 'pointValue' as const, unit: '₽' }, diff --git a/src/pages/MaintenancePage.tsx b/src/pages/MaintenancePage.tsx index 43315b2..edfc824 100644 --- a/src/pages/MaintenancePage.tsx +++ b/src/pages/MaintenancePage.tsx @@ -231,7 +231,7 @@ function MaintenanceModal({ {/* Type selector */}
-
+
{([ { id: 'room' as const, label: 'Номер', icon: BedDouble }, { id: 'service' as const, label: 'Услуга', icon: Wrench }, @@ -362,7 +362,7 @@ export function MaintenancePage() { const active = records.filter(r => r.status !== 'done' && r.status !== 'cancelled') return ( -
+
{/* Header */}
@@ -378,7 +378,7 @@ export function MaintenancePage() {
{/* Stats */} -
+
{[ { label: 'Всего записей', value: records.length, cls: '' }, { label: 'Активных', value: active.length, cls: 'text-amber-600 dark:text-amber-400' }, diff --git a/src/pages/PosPage.tsx b/src/pages/PosPage.tsx index 320cd55..338bc51 100644 --- a/src/pages/PosPage.tsx +++ b/src/pages/PosPage.tsx @@ -270,14 +270,41 @@ export function PosPage() { <> {/* ══════════════════════ TAB: main ══════════════════════ */} {activeTab === 'main' && ( -
+
- {/* ── Left sidebar: Заезды (w-56) ── */} -
-
+ {/* ── Заезды: horizontal scroll on mobile, sidebar on desktop ── */} +
+

Заезды

-
+ {/* Mobile: horizontal scroll row */} +
+ {MOCK_BALANCES.map(rb => { + const debt = Math.max(0, rb.totalAmount - rb.paidAmount) + const paid = debt === 0 + const sel = selectedRoom?.roomId === rb.roomId + return ( + + ) + })} +
+ {/* Desktop: vertical list */} +
{MOCK_BALANCES.map(rb => { const debt = Math.max(0, rb.totalAmount - rb.paidAmount) const paid = debt === 0 @@ -313,7 +340,7 @@ export function PosPage() {
{/* ── Center: payment form ── */} -
+
{selectedRoom ? ( <> {/* Guest info */} @@ -781,7 +808,7 @@ export function PosPage() { {/* ── Receipt success overlay ── */} {lastReceipt && (
-
+

Оплата принята

@@ -815,7 +842,7 @@ export function PosPage() { {/* ── Close shift confirmation modal ── */} {closeConfirm && (
-
+
diff --git a/src/pages/ReportsPage.tsx b/src/pages/ReportsPage.tsx index 32f012f..36f888c 100644 --- a/src/pages/ReportsPage.tsx +++ b/src/pages/ReportsPage.tsx @@ -21,7 +21,7 @@ const maxOcc = Math.max(...OCC) export function ReportsPage() { return ( -
+
@@ -33,7 +33,7 @@ export function ReportsPage() {
{/* KPI cards */} -
+
{KPI.map(k => (

{k.label}

diff --git a/src/pages/TariffsPage.tsx b/src/pages/TariffsPage.tsx index ced2f09..fb00878 100644 --- a/src/pages/TariffsPage.tsx +++ b/src/pages/TariffsPage.tsx @@ -200,8 +200,8 @@ function TariffModal({ >
{/* Name + Code */} -
-
+
+
@@ -223,7 +223,7 @@ function TariffModal({ -
+
{mealPlans.map(mp => (