BookingModal: move guest fields to right column; Theme: auto mode follows system prefers-color-scheme

This commit is contained in:
2026-03-21 00:04:24 +03:00
parent d3581f27f2
commit fd804926e4
2 changed files with 43 additions and 44 deletions

View File

@@ -450,7 +450,12 @@ export function BookingModal({ open, draft, rooms, bookings = [], onClose, onSav
)} )}
</div> </div>
{/* 3. ФИО гостя */} </div>
{/* ── RIGHT COLUMN ── */}
<div className="flex-1 space-y-4 min-w-0">
{/* Гость */}
<div> <div>
<label className="block text-sm font-semibold text-slate-700 dark:text-slate-300 mb-2"> <label className="block text-sm font-semibold text-slate-700 dark:text-slate-300 mb-2">
Гость Гость
@@ -499,45 +504,38 @@ export function BookingModal({ open, draft, rooms, bookings = [], onClose, onSav
/> />
</div> </div>
</div> </div>
</div> <div className="grid grid-cols-3 gap-2 mt-2">
<div>
{/* 4. Взрослые / Дети / Статус */} <label className="block text-xs text-slate-500 dark:text-slate-400 mb-1">Взрослых</label>
<div className="grid grid-cols-3 gap-2"> <input
<div> type="number" min={1} max={room?.maxGuests ?? 6} className="input"
<label className="block text-xs text-slate-500 dark:text-slate-400 mb-1">Взрослых</label> value={form.adults}
<input onChange={e => set('adults', parseInt(e.target.value) || 1)}
type="number" min={1} max={room?.maxGuests ?? 6} className="input" />
value={form.adults} </div>
onChange={e => set('adults', parseInt(e.target.value) || 1)} <div>
/> <label className="block text-xs text-slate-500 dark:text-slate-400 mb-1">Детей</label>
</div> <input
<div> type="number" min={0} max={4} className="input"
<label className="block text-xs text-slate-500 dark:text-slate-400 mb-1">Детей</label> value={form.children}
<input onChange={e => set('children', parseInt(e.target.value) || 0)}
type="number" min={0} max={4} className="input" />
value={form.children} </div>
onChange={e => set('children', parseInt(e.target.value) || 0)} <div>
/> <label className="block text-xs text-slate-500 dark:text-slate-400 mb-1">Статус</label>
</div> <select
<div> className="input"
<label className="block text-xs text-slate-500 dark:text-slate-400 mb-1">Статус</label> value={form.status}
<select onChange={e => set('status', e.target.value as BookingStatus)}
className="input" >
value={form.status} {(Object.entries(BOOKING_STATUS_LABELS) as [BookingStatus, string][]).map(([k, v]) => (
onChange={e => set('status', e.target.value as BookingStatus)} <option key={k} value={k}>{v}</option>
> ))}
{(Object.entries(BOOKING_STATUS_LABELS) as [BookingStatus, string][]).map(([k, v]) => ( </select>
<option key={k} value={k}>{v}</option> </div>
))}
</select>
</div> </div>
</div> </div>
</div>
{/* ── RIGHT COLUMN ── */}
<div className="w-56 shrink-0 space-y-4">
{/* Доп. места */} {/* Доп. места */}
<div className="flex items-center justify-between px-3 py-2.5 rounded-xl bg-slate-50 dark:bg-slate-700/40 border border-slate-200 dark:border-slate-600"> <div className="flex items-center justify-between px-3 py-2.5 rounded-xl bg-slate-50 dark:bg-slate-700/40 border border-slate-200 dark:border-slate-600">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">

View File

@@ -12,9 +12,8 @@ interface ThemeContextValue {
const ThemeContext = createContext<ThemeContextValue | null>(null) const ThemeContext = createContext<ThemeContextValue | null>(null)
function getAutoTheme(): Theme { function getSystemTheme(): Theme {
const h = new Date().getHours() return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
return h >= 7 && h < 22 ? 'light' : 'dark'
} }
export function ThemeProvider({ children }: { children: React.ReactNode }) { export function ThemeProvider({ children }: { children: React.ReactNode }) {
@@ -26,14 +25,16 @@ export function ThemeProvider({ children }: { children: React.ReactNode }) {
const stored = localStorage.getItem('hotelsync-theme') as ThemeMode | null const stored = localStorage.getItem('hotelsync-theme') as ThemeMode | null
if (!stored || stored === 'light') return 'light' if (!stored || stored === 'light') return 'light'
if (stored === 'dark') return 'dark' if (stored === 'dark') return 'dark'
return getAutoTheme() return getSystemTheme()
}) })
useEffect(() => { useEffect(() => {
if (mode === 'auto') { if (mode === 'auto') {
setTheme(getAutoTheme()) setTheme(getSystemTheme())
const interval = setInterval(() => setTheme(getAutoTheme()), 60_000) const mq = window.matchMedia('(prefers-color-scheme: dark)')
return () => clearInterval(interval) const handler = (e: MediaQueryListEvent) => setTheme(e.matches ? 'dark' : 'light')
mq.addEventListener('change', handler)
return () => mq.removeEventListener('change', handler)
} else { } else {
setTheme(mode) setTheme(mode)
} }