feat: rental drafts, room modal cleanup, tariff auto-code
- New hotels get 3 rental object templates (tennis/sauna/conference) as drafts (is_active=false) - RentalPage: draft templates shown separately with Activate/Delete buttons - Migration 047: adds is_active column to rental_objects - RoomModal: hide bed type/status/housekeeping in create mode; optional price (from category); restructured Places tab with extra beds constructor - TariffsPage: auto-generate tariff code from name initials if code field is empty - types: ExtraPlace.beds for extra place bed configuration Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
5
backend/migrations/047_rental_is_active.sql
Normal file
5
backend/migrations/047_rental_is_active.sql
Normal file
@@ -0,0 +1,5 @@
|
||||
-- Add is_active flag to rental_objects (false = template/draft, true = published)
|
||||
ALTER TABLE rental_objects ADD COLUMN IF NOT EXISTS is_active BOOLEAN NOT NULL DEFAULT true;
|
||||
|
||||
-- Mark all existing objects as active (they were already in use)
|
||||
UPDATE rental_objects SET is_active = true;
|
||||
@@ -171,6 +171,22 @@ const auth: FastifyPluginAsync = async (fastify) => {
|
||||
VALUES ($1, $2, $3, 'hotel_admin', $4, $5, false, $6, NOW())`,
|
||||
[contact, email.toLowerCase().trim(), passwordHash, hotel.id, phone ?? null, confirmToken],
|
||||
)
|
||||
// Template rental objects (inactive drafts — user activates as needed)
|
||||
const templates = [
|
||||
{ name: 'Теннисный корт', icon: '🎾', color: 'bg-green-500', text_color: 'text-green-700 dark:text-green-400', price_h: 1500, price_d: 8000, open: 8, close: 22, sort: 1 },
|
||||
{ name: 'Баня / сауна', icon: '🛁', color: 'bg-orange-500', text_color: 'text-orange-700 dark:text-orange-400', price_h: 2500, price_d: 12000, open: 10, close: 23, sort: 2 },
|
||||
{ name: 'Конференц-зал', icon: '🏛️', color: 'bg-blue-500', text_color: 'text-blue-700 dark:text-blue-400', price_h: 3000, price_d: 15000, open: 9, close: 20, sort: 3 },
|
||||
]
|
||||
for (const t of templates) {
|
||||
await client.query(
|
||||
`INSERT INTO rental_objects
|
||||
(hotel_id, name, icon, color, text_color, price_per_hour, price_per_day,
|
||||
open_hour, close_hour, sort_order, is_active)
|
||||
VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10, false)`,
|
||||
[hotel.id, t.name, t.icon, t.color, t.text_color, t.price_h, t.price_d, t.open, t.close, t.sort],
|
||||
)
|
||||
}
|
||||
|
||||
await client.query('COMMIT')
|
||||
} catch (err) {
|
||||
await client.query('ROLLBACK')
|
||||
|
||||
@@ -74,7 +74,7 @@ const rental: FastifyPluginAsync = async (fastify) => {
|
||||
if (!canAccess(request.user.hotelSlug, request.user.role, slug)) return reply.code(403).send({ error: 'Forbidden' })
|
||||
const b = request.body as Record<string, unknown>
|
||||
const allowed = ['name','icon','color','text_color','price_per_hour','price_per_day',
|
||||
'open_hour','close_hour','max_hours_per_slot','buffer_minutes','sort_order']
|
||||
'open_hour','close_hour','max_hours_per_slot','buffer_minutes','sort_order','is_active']
|
||||
const sets: string[] = []
|
||||
const vals: unknown[] = []
|
||||
for (const key of allowed) {
|
||||
|
||||
Reference in New Issue
Block a user