Компактные hero секции и улучшенная инициализация БД

🎨 UI улучшения:
- Уменьшена высота синих панелей с 100vh до 70vh на главной
- Добавлен класс .compact (25vh) для всех остальных страниц
- Улучшена адаптивность для мобильных устройств
- Обновлены все шаблоны с hero секциями

🚀 Инфраструктура:
- Автоматическая инициализация базы данных при деплое
- Улучшены мокапные данные (больше отзывов, бронирований, сообщений)
- Добавлены настройки сайта в базу данных
- Создан скрипт автоматического деплоя deploy.sh

📦 Система сборки:
- Обновлен .gitignore с полным покрытием файлов
- Добавлена папка для загрузок с .gitkeep
- Улучшен README с инструкциями по запуску
- ES модули для инициализации базы данных

🐛 Исправления:
- Совместимость с ES модулями в Node.js
- Правильная обработка ошибок инициализации БД
- Корректные SQL запросы для PostgreSQL
This commit is contained in:
2025-11-29 18:47:42 +09:00
parent 409e6c146b
commit a461fea9d9
24 changed files with 1442 additions and 84 deletions

View File

@@ -0,0 +1,73 @@
-- Система лайков/дизлайков для туров, гидов и статей
CREATE TABLE ratings (
id SERIAL PRIMARY KEY,
user_ip VARCHAR(45) NOT NULL, -- IP адрес для анонимных пользователей
target_id INTEGER NOT NULL,
target_type VARCHAR(20) NOT NULL CHECK (target_type IN ('route', 'guide', 'article')),
rating INTEGER NOT NULL CHECK (rating IN (1, -1)), -- 1 = лайк, -1 = дизлайк
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE(user_ip, target_id, target_type) -- Один пользователь - один голос за объект
);
-- График работы гидов
CREATE TABLE guide_schedules (
id SERIAL PRIMARY KEY,
guide_id INTEGER NOT NULL REFERENCES guides(id) ON DELETE CASCADE,
monday BOOLEAN DEFAULT true,
tuesday BOOLEAN DEFAULT true,
wednesday BOOLEAN DEFAULT true,
thursday BOOLEAN DEFAULT true,
friday BOOLEAN DEFAULT true,
saturday BOOLEAN DEFAULT false,
sunday BOOLEAN DEFAULT false,
start_time TIME DEFAULT '09:00',
end_time TIME DEFAULT '18:00',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE(guide_id)
);
-- Выходные дни (общие и индивидуальные)
CREATE TABLE holidays (
id SERIAL PRIMARY KEY,
date DATE NOT NULL,
title VARCHAR(255) NOT NULL,
type VARCHAR(20) NOT NULL CHECK (type IN ('public', 'guide_personal')), -- публичный или персональный
guide_id INTEGER REFERENCES guides(id) ON DELETE CASCADE, -- NULL для публичных выходных
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE(date, guide_id) -- Один выходной день для одного гида
);
-- Обновляем таблицу бронирований для связи с гидом
ALTER TABLE bookings ADD COLUMN guide_id INTEGER REFERENCES guides(id);
ALTER TABLE bookings ADD COLUMN route_id INTEGER REFERENCES routes(id);
-- Добавляем индексы для производительности
CREATE INDEX idx_ratings_target ON ratings(target_type, target_id);
CREATE INDEX idx_ratings_user_ip ON ratings(user_ip);
CREATE INDEX idx_bookings_date ON bookings(preferred_date);
CREATE INDEX idx_bookings_guide ON bookings(guide_id);
CREATE INDEX idx_holidays_date ON holidays(date);
-- Функция для подсчета рейтинга
CREATE OR REPLACE FUNCTION calculate_rating(target_type_param VARCHAR, target_id_param INTEGER)
RETURNS TABLE(
likes_count BIGINT,
dislikes_count BIGINT,
total_votes BIGINT,
rating_percentage NUMERIC(5,2)
) AS $$
BEGIN
RETURN QUERY
SELECT
COUNT(CASE WHEN rating = 1 THEN 1 END) as likes_count,
COUNT(CASE WHEN rating = -1 THEN 1 END) as dislikes_count,
COUNT(*) as total_votes,
CASE
WHEN COUNT(*) = 0 THEN 0
ELSE ROUND((COUNT(CASE WHEN rating = 1 THEN 1 END)::NUMERIC / COUNT(*)::NUMERIC) * 100, 2)
END as rating_percentage
FROM ratings
WHERE target_type = target_type_param AND target_id = target_id_param;
END;
$$ LANGUAGE plpgsql;