(room?.photos ?? [])
const [photoIdx, setPhotoIdx] = useState(0)
@@ -423,14 +415,14 @@ export function RoomModal({ open, room, existingNumbers = [], categories = [], o
{beds.map((bed, i) => (
- {BED_ITEM_TYPES.find(b => b.value === bed.type)?.icon ?? '🛏'}
+ {bedTypes.find(b => b.value === bed.type)?.icon ?? '🛏'}
diff --git a/src/contexts/BedTypesContext.tsx b/src/contexts/BedTypesContext.tsx
new file mode 100644
index 0000000..566de3f
--- /dev/null
+++ b/src/contexts/BedTypesContext.tsx
@@ -0,0 +1,53 @@
+import { createContext, useContext, useState } from 'react'
+import type { ReactNode } from 'react'
+
+export interface BedTypeItem {
+ value: string // unique key stored in DB (e.g. 'double', 'sofa')
+ label: string // display name
+ icon: string // emoji
+}
+
+const DEFAULT_BED_TYPES: BedTypeItem[] = [
+ { value: 'single', label: 'Кровать 1-сп.', icon: '🛏' },
+ { value: 'double', label: 'Кровать 2-сп.', icon: '🛏' },
+ { value: 'queen', label: 'Queen-кровать', icon: '🛏' },
+ { value: 'king', label: 'King-кровать', icon: '🛏' },
+ { value: 'twin', label: 'Две кровати', icon: '🛏' },
+ { value: 'sofa', label: 'Диван', icon: '🛋' },
+ { value: 'bunk', label: 'Двухъярусная', icon: '🛏' },
+ { value: 'cot', label: 'Раскладушка', icon: '🪑' },
+]
+
+interface BedTypesContextValue {
+ bedTypes: BedTypeItem[]
+ addBedType: (item: BedTypeItem) => void
+ removeBedType: (value: string) => void
+ updateBedType: (value: string, patch: Partial>) => void
+}
+
+const BedTypesContext = createContext(null)
+
+export function BedTypesProvider({ children }: { children: ReactNode }) {
+ const [bedTypes, setBedTypes] = useState(DEFAULT_BED_TYPES)
+
+ const addBedType = (item: BedTypeItem) =>
+ setBedTypes(prev => prev.find(b => b.value === item.value) ? prev : [...prev, item])
+
+ const removeBedType = (value: string) =>
+ setBedTypes(prev => prev.filter(b => b.value !== value))
+
+ const updateBedType = (value: string, patch: Partial>) =>
+ setBedTypes(prev => prev.map(b => b.value === value ? { ...b, ...patch } : b))
+
+ return (
+
+ {children}
+
+ )
+}
+
+export function useBedTypes() {
+ const ctx = useContext(BedTypesContext)
+ if (!ctx) throw new Error('useBedTypes must be used within BedTypesProvider')
+ return ctx
+}
diff --git a/src/pages/RoomCategoriesPage.tsx b/src/pages/RoomCategoriesPage.tsx
index da6cca5..5dc16e0 100644
--- a/src/pages/RoomCategoriesPage.tsx
+++ b/src/pages/RoomCategoriesPage.tsx
@@ -3,6 +3,7 @@ import { Plus, Pencil, Trash2, ImagePlus, X as XIcon, Tag, ChevronRight, Chevron
import { cn } from '../lib/utils'
import type { RoomCategory } from '../types'
import { useAmenities } from '../contexts/AmenitiesContext'
+import { useBedTypes } from '../contexts/BedTypesContext'
import { useAuth } from '../contexts/AuthContext'
import { api } from '../lib/api'
import type { CategoryApi } from '../lib/api'
@@ -362,6 +363,15 @@ export function RoomCategoriesPage() {
const [editingAmenity, setEditingAmenity] = useState(null)
const [editAmenityValue, setEditAmenityValue] = useState('')
+ // Bed types directory state
+ const { bedTypes, addBedType, removeBedType, updateBedType } = useBedTypes()
+ const [showBedTypes, setShowBedTypes] = useState(false)
+ const [newBedLabel, setNewBedLabel] = useState('')
+ const [newBedIcon, setNewBedIcon] = useState('🛏')
+ const [editingBed, setEditingBed] = useState(null)
+ const [editBedLabel, setEditBedLabel] = useState('')
+ const [editBedIcon, setEditBedIcon] = useState('')
+
useEffect(() => {
if (!slug) return
api.categories.list(slug)
@@ -599,6 +609,139 @@ export function RoomCategoriesPage() {
)}
+ {/* Справочник спальных мест */}
+
+
+
+ {showBedTypes && (
+
+ {/* Add new */}
+
+
+
setNewBedLabel(e.target.value)}
+ onKeyDown={e => {
+ if (e.key === 'Enter') {
+ e.preventDefault()
+ const label = newBedLabel.trim()
+ if (!label) return
+ const value = label.toLowerCase().replace(/\s+/g, '_').replace(/[^a-z0-9_а-яё]/gi, '')
+ + '_' + Date.now().toString(36)
+ addBedType({ value, label, icon: newBedIcon })
+ setNewBedLabel('')
+ setNewBedIcon('🛏')
+ }
+ }}
+ />
+
+
+
+
+ {bedTypes.map(b => (
+
+ {editingBed === b.value ? (
+ <>
+
+
setEditBedLabel(e.target.value)}
+ onKeyDown={e => {
+ if (e.key === 'Enter') {
+ updateBedType(b.value, { label: editBedLabel, icon: editBedIcon })
+ setEditingBed(null)
+ }
+ if (e.key === 'Escape') setEditingBed(null)
+ }}
+ />
+
+
+ >
+ ) : (
+ <>
+
{b.icon}
+
{b.label}
+
+
+
+
+ >
+ )}
+
+ ))}
+
+
+ )}
+
+
{formOpen && (