diff --git a/src/App.tsx b/src/App.tsx index aee47a1..b18c1ff 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -2,6 +2,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 { AmenitiesProvider } from './contexts/AmenitiesContext' import { AppLayout } from './layouts/AppLayout' import { LoginPage } from './pages/LoginPage' import { CalendarPage } from './pages/CalendarPage' @@ -38,6 +39,7 @@ export default function App() { + {/* Public */} @@ -86,6 +88,7 @@ export default function App() { } /> + diff --git a/src/components/rooms/RoomModal.tsx b/src/components/rooms/RoomModal.tsx index cf1ec21..e37fa5d 100644 --- a/src/components/rooms/RoomModal.tsx +++ b/src/components/rooms/RoomModal.tsx @@ -3,11 +3,7 @@ import { Modal } from '../ui/Modal' import { cn } from '../../lib/utils' import type { Room, RoomStatus, HousekeepingStatus, BedType } from '../../types' import { ImagePlus, X as XIcon, ChevronLeft, ChevronRight } from 'lucide-react' - -const AMENITY_LIST = [ - 'Wi-Fi', 'TV', 'AC', 'Mini-bar', 'Bathrobe', 'Jacuzzi', - 'Panoramic view', 'Kitchen', 'Washing machine', 'Butler', 'Terrace', -] +import { useAmenities } from '../../contexts/AmenitiesContext' const ROOM_TYPES = ['Стандарт', 'Делюкс', 'Полулюкс', 'Люкс', 'Пентхаус', 'Апартаменты', 'Другой'] @@ -65,6 +61,7 @@ export function RoomModal({ open, room, categories = [], onClose, onSave }: Room description: room?.description ?? '', }) + const { amenities: allAmenities } = useAmenities() const [amenities, setAmenities] = useState(room?.amenities ?? ['Wi-Fi', 'TV', 'AC']) const [photos, setPhotos] = useState(room?.photos ?? []) const [photoIdx, setPhotoIdx] = useState(0) @@ -265,7 +262,7 @@ export function RoomModal({ open, room, categories = [], onClose, onSave }: Room
- {AMENITY_LIST.map(a => { + {allAmenities.map(a => { const selected = amenities.includes(a) return (
- +
+ + Справочник удобств — на странице «Номера» +
- {AMENITY_LIST.map(a => { + {allAmenities.map(a => { const sel = amenities.includes(a) return ( - - ))} -
- {/* Add custom amenity */} -
- setCustomInput(e.target.value)} - onKeyDown={e => e.key === 'Enter' && (e.preventDefault(), addCustom())} - /> -
+ {amenities.length > 0 && ( +

Выбрано: {amenities.length}

+ )}
)} diff --git a/src/pages/RoomsPage.tsx b/src/pages/RoomsPage.tsx index 7d846a3..49fe96f 100644 --- a/src/pages/RoomsPage.tsx +++ b/src/pages/RoomsPage.tsx @@ -1,5 +1,6 @@ import { useState } from 'react' -import { BedDouble, Users, Wifi, Plus, Search, Pencil } from 'lucide-react' +import { BedDouble, Users, Wifi, Plus, Search, Pencil, ChevronDown, ChevronUp, Check, Trash2, X as XIcon } from 'lucide-react' +import { useAmenities } from '../contexts/AmenitiesContext' import { MOCK_ROOMS } from '../data/mockData' import { MOCK_CATEGORIES } from './RoomCategoriesPage' import type { Room } from '../types' @@ -14,6 +15,12 @@ export function RoomsPage() { const [modalOpen, setModalOpen] = useState(false) const [editingRoom, setEditingRoom] = useState(undefined) + const { amenities, addAmenity, removeAmenity, renameAmenity } = useAmenities() + const [showAmenities, setShowAmenities] = useState(false) + const [newAmenity, setNewAmenity] = useState('') + const [editingAmenity, setEditingAmenity] = useState(null) + const [editAmenityValue, setEditAmenityValue] = useState('') + const floors = [...new Set(rooms.map(r => r.floor))].sort() const filtered = rooms.filter(r => { @@ -130,6 +137,96 @@ export function RoomsPage() { ))}
+ {/* Справочник удобств */} +
+ + + {showAmenities && ( +
+ {/* Add new */} +
+ setNewAmenity(e.target.value)} + onKeyDown={e => { + if (e.key === 'Enter') { e.preventDefault(); if (newAmenity.trim()) { addAmenity(newAmenity.trim()); setNewAmenity('') } } + }} + /> + +
+ + {/* List */} +
+ {amenities.map(a => ( +
+ {editingAmenity === a ? ( + <> + setEditAmenityValue(e.target.value)} + onKeyDown={e => { + if (e.key === 'Enter') { renameAmenity(a, editAmenityValue); setEditingAmenity(null) } + if (e.key === 'Escape') setEditingAmenity(null) + }} + /> + + + + ) : ( + <> + {a} +
+ + +
+ + )} +
+ ))} +
+
+ )} +
+ {/* Modal */}