- Update technology stack with implemented backend - Mark completed phases - Add src/server/ and data/ to file structure - Add validation.ts to structure
16 KiB
TenerifeProp - Архитектура агентства недвижимости на Тенерифе
📋 Обзор проекта
TenerifeProp — веб-приложение для агентства недвижимости на острове Тенерифе (Канарские острова, Испания). Позволяет просматривать, фильтровать и подбирать земельные участки, дома и квартиры. Включает публичную часть (Landing, каталог, страница объекта) и административную панель.
🏗️ Сущности данных
Основные сущности
| Сущность | Описание | Файл |
|---|---|---|
| Property | Недвижимость (участки, дома, квартиры) | src/types/property.ts |
| Lead | Потенциальный клиент (заявка) | src/types/user.ts |
| User | Пользователь системы (админ, агент) | src/types/user.ts |
| Testimonial | Отзыв клиента | src/types/content.ts |
| Service | Услуга агентства | src/types/content.ts |
| FAQ | Вопрос-ответ | src/types/content.ts |
| Settings | Настройки сайта | src/types/content.ts |
Типы недвижимости
type PropertyType =
| 'agricultural' // Сельскохозяйственный участок
| 'urban' // Городской участок
| 'house' // Дом/вилла
| 'apartment' // Квартира
| 'ruins' // Руины (под восстановление)
Статусы недвижимости
type PropertyStatus =
| 'active' // Активен (в продаже)
| 'reserved' // Зарезервирован
| 'sold' // Продан
| 'inactive' // Неактивен
Статусы лидов
type LeadStatus =
| 'new' // Новая заявка
| 'contacted' // Связались
| 'qualified' // Квалифицирован
| 'negotiating' // Переговоры
| 'closed' // Сделка закрыта
| 'lost' // Потерян
📁 Структура файлов
TenerifeProp/
├── public/ # Публичные файлы
│ ├── index.html # Главная страница (Landing)
│ ├── property.html # Страница объекта
│ ├── admin.html # Админ-панель
│ ├── css/
│ │ ├── variables.css # CSS переменные (цвета, шрифты)
│ │ ├── main.css # Основные стили
│ │ ├── property.css # Стили страницы объекта
│ │ └── admin.css # Стили админки
│ ├── js/
│ │ ├── app.js # Главная логика приложения
│ │ ├── property.js # Логика страницы объекта
│ │ ├── admin.js # Логика админки
│ │ ├── api.js # API клиент
│ │ ├── i18n.js # Система переводов
│ │ ├── map.js # Инициализация карты (Leaflet)
│ │ ├── charts.js # Графики (Chart.js)
│ │ └── utils.js # Утилиты
│ └── images/
│ ├── properties/ # Фото объектов
│ ├── agents/ # Фото агентов
│ └── icons/ # Иконки
├── src/
│ ├── server/ # Backend сервер
│ │ ├── index.ts # API сервер (Bun + Hono)
│ │ └── validation.ts # Zod схемы валидации
│ ├── types/ # TypeScript типы
│ │ ├── property.ts # Типы недвижимости
│ │ ├── user.ts # Типы пользователей и лидов
│ │ ├── content.ts # Типы контента
│ │ └── index.ts # Экспорт
│ ├── data/ # JSON база данных (deprecated - now using SQLite)
│ │ ├── properties.json # Объекты недвижимости
│ │ ├── leads.json # Заявки
│ │ ├── testimonials.json # Отзывы
│ │ ├── faq.json # FAQ
│ │ └── services.json # Услуги
│ ├── i18n/ # Переводы
│ │ ├── es.json # Испанский (основной)
│ │ ├── ru.json # Русский
│ │ └── en.json # Английский
│ └── utils/
│ ├── format.ts # Форматирование данных
│ ├── validation.ts # Валидация форм
│ └── api.ts # API клиент
├── data/ # SQLite база данных
│ └── tenerifeprop.db # Файл базы данных
├── docs/ # Документация
│ ├── ARCHITECTURE.md # Этот файл
│ ├── API.md # Документация API
│ └── DEPLOYMENT.md # Инструкции по деплою
├── .gitignore # Игнорируемые файлы
├── package.json # Зависимости проекта
├── tsconfig.json # Конфигурация TypeScript
└── README.md # Описание проекта
🔗 API Endpoints
Недвижимость (Properties)
| Метод | Endpoint | Описание |
|---|---|---|
GET |
/api/properties |
Список объектов с фильтрами |
GET |
/api/properties/:id |
Детали объекта |
GET |
/api/properties/:slug |
Детали по slug |
POST |
/api/properties |
Создать объект |
PUT |
/api/properties/:id |
Обновить объект |
DELETE |
/api/properties/:id |
Удалить объект |
GET |
/api/properties/featured |
Избранные объекты |
GET |
/api/properties/search |
Поиск с фильтрами |
Заявки (Leads)
| Метод | Endpoint | Описание |
|---|---|---|
GET |
/api/leads |
Список заявок |
GET |
/api/leads/:id |
Детали заявки |
POST |
/api/leads |
Создать заявку (форма) |
PUT |
/api/leads/:id |
Обновить заявку |
PUT |
/api/leads/:id/status |
Изменить статус |
POST |
/api/leads/:id/interaction |
Добавить взаимодействие |
Пользователи (Users)
| Метод | Endpoint | Описание |
|---|---|---|
POST |
/api/auth/login |
Авторизация |
POST |
/api/auth/logout |
Выход |
GET |
/api/users/me |
Текущий пользователь |
PUT |
/api/users/me |
Обновить профиль |
Аналитика (Analytics)
| Метод | Endpoint | Описание |
|---|---|---|
GET |
/api/analytics/stats |
Статистика (Dashboard) |
GET |
/api/analytics/events |
События |
POST |
/api/analytics/event |
Записать событие |
Контент (Content)
| Метод | Endpoint | Описание |
|---|---|---|
GET |
/api/testimonials |
Отзывы |
GET |
/api/faq |
FAQ |
GET |
/api/services |
Услуги |
GET |
/api/pages/:slug |
Страница по slug |
GET |
/api/settings |
Настройки сайта |
🎨 Компоненты UI
Публичная часть (Landing)
- Header/Navbar - Навигация, переключатель языка
- Hero - Главный баннер с CTA
- Advantages - Преимущества агентства
- Catalog - Каталог с фильтрами
- PropertyCard - Карточка объекта
- Map - Интерактивная карта (Leaflet)
- Statistics - Статистика в цифрах
- Services - Услуги агентства
- Testimonials - Отзывы клиентов
- FAQ - Вопросы-ответы
- Contact - Форма контакта
- Footer - Подвал с контактами
Страница объекта (Property)
- Gallery - Галерея изображений
- PropertyHeader - Заголовок, цена, характеристики
- Utilities - Коммуникации (вода, свет, etc.)
- Documents - Документы
- Map - Карта с местоположением
- Calculator - Калькулятор ипотеки/налогов
- ContactForm - Форма запроса
- SimilarProperties - Похожие объекты
Админ-панель
- Sidebar - Навигация по разделам
- Topbar - Поиск, уведомления, профиль
- Dashboard - Статистика, графики
- PropertyTable - Таблица объектов (DataTables)
- PropertyForm - Форма создания/редактирования
- LeadTable - Таблица заявок
- LeadDetail - Детали заявки
- ContentEditor - Редактор контента
🛠️ Технологии
Frontend
| Технология | Версия | Назначение |
|---|---|---|
| HTML5 | - | Семантическая разметка |
| CSS3 | - | Стили, анимации |
| Bootstrap | 5.3.2 | UI Framework |
| Bootstrap Icons | 1.11.1 | Иконки |
| Leaflet | 1.9.4 | Интерактивные карты |
| Chart.js | 4.4.1 | Графики |
| DataTables | 1.13.8 | Таблицы с пагинацией |
| AOS | 2.3.4 | Анимации при скролле |
| Lightbox2 | 2.11.4 | Галерея изображений |
Backend (Implemented)
| Технология | Назначение |
|---|---|
| Bun | Runtime |
| Hono | Web framework |
| SQLite | База данных |
| Zod | Валидация данных |
| Bun.password | Хеширование паролей |
Implemented API
The API is implemented in src/server/index.ts with:
- Session-based authentication with HTTP-only cookies
- Full CRUD for properties, leads, testimonials, FAQ, services
- Admin endpoints protected by authentication middleware
- Input validation using Zod schemas
- Global error handling
See docs/API.md for complete API documentation.
🔄 Рефакторинг из HTML артефактов
Переименование файлов
| Артефакт | Новый файл |
|---|---|
artifact-...-6.html |
public/index.html |
artifact-...-7.html |
public/property.html |
artifact-...-8.html |
public/admin.html |
Извлечение CSS
CSS встроен в <style> внутри HTML. Нужно:
-
Создать
public/css/variables.cssс CSS-переменными:--primary: #1a5f4a--secondary: #d4a853--accent: #e85d04- и т.д.
-
Создать
public/css/main.cssс общими стилями для Landing -
Создать
public/css/property.cssсо стилями страницы объекта -
Создать
public/css/admin.cssсо стилями админки
Извлечение JavaScript
JavaScript встроен в <script> внутри HTML. Нужно:
-
Создать
public/js/i18n.jsдля системы переводов:- Загрузка JSON файла языка
- Функция
t(key)для перевода - Переключение языка
-
Создать
public/js/app.js:- Инициализация компонентов
- Фильтрация каталога
- Карта Leaflet
- Обработка форм
-
Создать
public/js/admin.js:- Инициализация DataTables
- CRUD операции
- Графики Chart.js
🌍 Система переводов (i18n)
Структура JSON перевода
// src/i18n/es.json
{
"nav": {
"home": "Inicio",
"catalog": "Catálogo",
...
},
"hero": {
"title1": "Terrenos y Propiedades",
...
}
}
HTML атрибуты
<h1 data-i18n="hero.title1">Terrenos y Propiedades</h1>
<p data-i18n="hero.subtitle">Encuentra tu terreno perfecto...</p>
JavaScript
// public/js/i18n.js
class I18n {
constructor() {
this.lang = 'es';
this.translations = {};
}
async setLanguage(lang) {
this.lang = lang;
this.translations = await fetch(`/src/i18n/${lang}.json`).then(r => r.json());
this.updateElements();
}
updateElements() {
document.querySelectorAll('[data-i18n]').forEach(el => {
const key = el.getAttribute('data-i18n');
el.textContent = this.t(key);
});
}
t(key) {
const keys = key.split('.');
let value = this.translations;
keys.forEach(k => value = value?.[k]);
return value || key;
}
}
📊 Пример данных
Недвижимость
{
"id": "prop-001",
"slug": "terreno-urbano-adeje",
"type": "urban",
"status": "active",
"title": {
"es": "Terreno Urbano en Adeje",
"ru": "Городской участок в Адехе"
},
"area": 2500,
"price": 385000,
"pricePerM2": 154,
"location": {
"city": "Adeje",
"zone": "Costa Adeje",
"coordinates": { "lat": 28.1227, "lng": -16.6942 }
},
"utilities": {
"water": "available",
"electricity": "available",
"road": "asphalt"
}
}
🚀 План реализации
Фаза 1: Подготовка ✅ (Завершено)
- Создать структуру директорий
- Переименовать артефакты
- Создать TypeScript типы
- Создать JSON данные
- Создать i18n файлы (es, ru, en)
Фаза 2: Рефакторинг (В процессе)
- Вынести CSS в отдельные файлы
- Вынести JS в модули (app.js, property.js, admin.js, api.js, i18n.js)
- Настроить систему i18n
- Рефакторинг HTML компонентов
Фаза 3: Backend ✅ (Завершено)
- Настроить API сервер (Bun + Hono)
- Реализовать CRUD для Property
- Реализовать CRUD для Lead
- Реализовать CRUD для Testimonials, FAQ, Services
- Добавить авторизацию (сессии, cookies)
- Добавить валидацию (Zod)
- Docker конфигурация
Фаза 4: Frontend (В процессе)
- Подключить API к Frontend
- Реализовать базовые фильтры
- Настроить карты (Leaflet)
- Оптимизация
Фаза 5: Деплой (Ожидание)
- Сборка проекта
- Деплой на продакшн
- Тестирование
- Мониторинг
📝 Лицензия
MIT License - проект создан для UniqueSoft.