diff --git a/.opencode/skills/common b/.opencode/skills/common new file mode 120000 index 0000000..daee0ca --- /dev/null +++ b/.opencode/skills/common @@ -0,0 +1 @@ +C:/Users/Serg/.config/opencode/skills \ No newline at end of file diff --git a/.opencode/skills/minivan/SKILL.md b/.opencode/skills/minivan/SKILL.md new file mode 100644 index 0000000..d99f392 --- /dev/null +++ b/.opencode/skills/minivan/SKILL.md @@ -0,0 +1,208 @@ +# minivan + +Проект: minivan-berlin.de — сервис аренды автомобилей (Minivan) в Берлине. + +Стек: Astro (SSR) + SolidJS + PocketBase + Tailwind CSS v4. + +## Коллекции PocketBase + +- `users` — пользователи +- `cars` — автомобили +- `bookings` — бронирования +- `reviews` — отзывы +- `posts` — статьи блога +- `faq_items` — FAQ вопросы +- `slider_cars` — автомобили для слайдера +- `site_settings` — настройки сайта +- `t_navbar` — пункты верхнего меню +- `b_navbar` — пункты нижнего меню (Footer) +- `t_top_header` — баннер в шапке +- `pages` — мета-данные страниц +- `preise_services` — услуги и цены +- `preise_cta` — CTA секции цен +- `comments` — комментарии блога + +## Структура проекта + +``` +frontend/ +├── src/ +│ ├── pages/ +│ │ ├── api/ +│ │ │ ├── auth/ # Авторизация +│ │ │ │ ├── login.ts +│ │ │ │ ├── register.ts +│ │ │ │ ├── logout.ts +│ │ │ │ ├── check-auth.ts +│ │ │ │ └── google/ +│ │ │ ├── contact.ts +│ │ │ ├── reviews/ +│ │ │ └── send-booking.ts +│ │ ├── index.astro # Главная +│ │ ├── kontakt.astro # Контакты +│ │ ├── preise.astro # Цены +│ │ ├── impressum.astro # Impressum +│ │ ├── datenschutz.astro # Privacy +│ │ ├── agb.astro # Terms +│ │ ├── stornierung.astro # Cancellation +│ │ ├── zahlungsarten.astro # Payment +│ │ ├── bewertungen.astro # Reviews +│ │ ├── partner.astro # Partner +│ │ ├── karriere.astro # Careers +│ │ ├── hilfe.astro # FAQ/Help +│ │ ├── premium-flotte.astro # Premium fleet +│ │ ├── vip-services.astro # VIP services +│ │ ├── ueber-uns.astro # About +│ │ ├── action.astro # Special offer +│ │ ├── blog/ +│ │ │ ├── [slug].astro +│ │ │ ├── [...page].astro +│ │ │ └── tags/ +│ │ │ └── [tag].astro +│ │ └── auth/ +│ │ ├── login.astro +│ │ ├── register.astro +│ │ ├── verify-email.astro +│ │ ├── forgot-password.astro +│ │ └── reset-password.astro +│ ├── components/ +│ │ ├── layouts/ +│ │ │ ├── header/ +│ │ │ │ ├── Header.astro +│ │ │ │ ├── TopHeader.astro +│ │ │ │ ├── SiteHeader.astro +│ │ │ │ ├── Logo.astro +│ │ │ │ └── UserAvatar.astro +│ │ │ └── footer/ +│ │ │ ├── Footer.astro +│ │ │ ├── FooterInfo.astro +│ │ │ └── FooterLinkColumn.astro +│ │ ├── base/ +│ │ │ ├── Button.astro +│ │ │ ├── Link.astro +│ │ │ ├── Modal.astro +│ │ │ └── Breadcrumbs.astro +│ │ ├── home/ +│ │ │ ├── hero/ +│ │ │ └── howIt/ +│ │ ├── blog/ +│ │ ├── reviews/ +│ │ ├── premium/ +│ │ ├── preise/ +│ │ ├── services/ +│ │ ├── partner/ +│ │ ├── career/ +│ │ └── contacts/ +│ ├── lib/ +│ │ ├── authService.ts +│ │ ├── emailService.ts +│ │ └── pocketbase.js +│ ├── types/ +│ │ ├── globalInterfaces.ts +│ │ └── types.ts +│ ├── constants/ +│ ├── layouts/ +│ │ └── Layout.astro +│ └── env.d.ts +├── public/ +│ ├── robots.txt +│ └── favicon.ico +├── astro.config.mjs +└── package.json +``` + +## Страницы + +| URL | Файл | Описание | +|-----|------|----------| +| `/` | `index.astro` | Главная | +| `/kontakt` | `kontakt.astro` | Контакты | +| `/preise` | `preise.astro` | Цены | +| `/bewertungen` | `bewertungen.astro` | Отзывы | +| `/partner` | `partner.astro` | Партнёры | +| `/karriere` | `karriere.astro` | Вакансии | +| `/hilfe` | `hilfe.astro` | FAQ | +| `/premium-flotte` | `premium-flotte.astro` | Премиум флот | +| `/vip-services` | `vip-services.astro` | VIP услуги | +| `/ueber-uns` | `ueber-uns.astro` | О нас | +| `/action` | `action.astro` | Акция | +| `/blog` | `blog/[...page].astro` | Блог | +| `/blog/[slug]` | `blog/[slug].astro` | Статья | +| `/auth/login` | `auth/login.astro` | Вход | +| `/auth/register` | `auth/register.astro` | Регистрация | +| `/impressum` | `impressum.astro` | Impressum | +| `/datenschutz` | `datenschutz.astro` | Privacy | +| `/agb` | `agb.astro` | Terms | +| `/stornierung` | `stornierung.astro` | Cancellation | +| `/zahlungsarten` | `zahlungsarten.astro` | Payment methods | + +## Компоненты + +### Layout +- `Header.astro` — основной header с навигацией +- `TopHeader.astro` — верхняя панель с контактами +- `SiteHeader.astro` — обёртка header +- `Footer.astro` — footer с ссылками +- `FooterLinkColumn.astro` — колонка ссылок +- `FooterInfo.astro` — информация о компании + +### Base +- `Button.astro` — кнопка с вариантами +- `Link.astro` — ссылка с prefetch +- `Modal.astro` — модальное окно +- `Breadcrumbs.astro` — хлебные крошки + +## Навигация + +- **Верхнее меню** (Header): `t_navbar` — первые 5 пунктов (order 1-5) +- **Нижнее меню** (Footer): `b_navbar` — группировка по order: 1-3, 4-6, 7-10, 11-13 + +## Типы + +Все типы в `frontend/src/types/globalInterfaces.ts`: +- User +- Car +- Booking +- Review +- Post +- SiteSettings + +## API-эндпоинты + +- `/api/auth/login` — вход +- `/api/auth/register` — регистрация +- `/api/auth/logout` — выход +- `/api/auth/check-auth` — проверка авторизации +- `/api/auth/google/*` — Google OAuth +- `/api/contact` — контактная форма +- `/api/reviews` — отзывы (GET/POST/DELETE) +- `/api/send-booking` — бронирование +- `/api/files-proxy/*` — прокси файлов + +## Переменные окружения + +``` +PB PocketBase URL=https://minivan-berlin.de +MAIL_* — почта +SMTP_* — SMTP +SENDER_* — отправитель +ADMIN_* — админ +``` + +## Правила + +1. SolidJS компоненты — `.tsx` расширение +2. Astro компоненты — `.astro` расширение +3. Запросы к PB — через authService +4. Типизация в types/globalInterfaces.ts +5. Не использовать any без крайней необходимости +6. Tailwind CSS v4 +7. Картинки — в astro:assets + +## Особенности + +- SSR mode с @astrojs/node +- Sitemap автоматически @astrojs/sitemap +- prefetching страниц +- Session via cookies +- Аутент��фикация через PocketBase \ No newline at end of file diff --git a/README.md b/README.md index 695c7e1..0aea3a2 100644 --- a/README.md +++ b/README.md @@ -1,46 +1,259 @@ -# Astro + PocketBase Monorepo +# Astro + PocketBase Monorepo — Minivan Berlin -Этот проект представляет собой монорепозиторий, содержащий Astro frontend и PocketBase backend. +Монорепозиторий для веб-сайта **Minivan Berlin** — сервиса аренды автомобилей в Берлине. Проект сочетает современный SSR-фронтенд на Astro с backend-ом на PocketBase в качестве headless CMS и системы аутентификации. -## Структура проекта +## 🚀 Технологический стек -- `frontend/` - Astro приложение -- `backend/` - PocketBase сервер +### Frontend +- **Astro 6** — SSR-фреймворк с поддержкой островной архитектуры +- **SolidJS** — реактивные компоненты для интерактивных элементов +- **Tailwind CSS 4** — утилитарные стили +- **TypeScript** — типизация всего проекта +- **PocketBase JS SDK** — клиент для взаимодействия с backend +- **astro-icon** — иконки в проекте +- **@astrojs/sitemap** — генерация sitemap для SEO +- **@astrojs/mdx** — поддержка MDX для контента -## Установка +### Backend +- **PocketBase** — легковесный backend с SQLite, аутентификацией и админ-панелью +- **Миграции** — управление схемой данных через JS-миграции + +### Инфраструктура +- **Bun** — пакетный менеджер и рантайм +- **Maildev** — локальный SMTP-сервер для тестирования email +- **Concurrently** — параллельный запуск нескольких серверов +- **Docker** — контейнеризация (Dockerfile в frontend и backend) + +## 📁 Структура проекта + +``` +astro_minivan/ +├── frontend/ # Astro-приложение +│ ├── src/ +│ │ ├── components/ # SolidJS и Astro компоненты +│ │ │ ├── auth/ # Компоненты аутентификации +│ │ │ ├── booking/ # Компоненты бронирования +│ │ │ ├── home/ # Компоненты главной страницы +│ │ │ ├── blog/ # Компоненты блога +│ │ │ └── ... # Другие секции сайта +│ │ ├── pages/ # Страницы Astro +│ │ │ ├── api/ # API endpoints +│ │ │ ├── auth/ # Страницы аутентификации +│ │ │ └── *.astro # Основные страницы сайта +│ │ ├── lib/ # Утилиты и сервисы +│ │ │ ├── authService.ts # Сервис аутентификации +│ │ │ ├── emailService.ts # Отправка email через Nodemailer +│ │ │ ├── pocketbase.js # Клиент PocketBase +│ │ │ └── ... +│ │ ├── layouts/ # Layouts Astro +│ │ ├── styles/ # Глобальные стили +│ │ ├── types/ # TypeScript типы +│ │ ├── constants/ # Константы приложения +│ │ ├── emails/ # Шаблоны email-писем +│ │ └── middleware.js # Middleware для аутентификации +│ ├── astro.config.mjs # Конфигурация Astro +│ ├── tsconfig.json # TypeScript конфигурация +│ └── Dockerfile +│ +├── backend/ # PocketBase backend +│ ├── pb_migrations/ # Миграции базы данных +│ ├── pb_data/ # Данные PocketBase (игнорируется в git) +│ ├── pocketbase.exe # Бинарник PocketBase +│ └── start.sh / start.bat # Скрипты запуска +│ +├── bunfig.toml # Конфигурация Bun (workspaces) +├── package.json # Корневой package.json +└── .gitignore +``` + +## ⚙️ Установка + +### Требования +- **Bun** (рекомендуемая версия указывается в `.nvmrc`) +- **Node.js** (совместимая версия) + +### Установка зависимостей ```bash bun install ``` -## Разработка +## 🛠️ Разработка -Для запуска обоих серверов одновременно: +### Запуск всех сервисов одновременно ```bash +# Фронтенд + бэкенд bun run dev + +# Фронтенд + бэкенд + почтовый сервер (для тестирования email) +bun run dev:all ``` -Это запустит: -- Astro на http://localhost:4321 -- PocketBase на http://localhost:8090 - -Для запуска только фронтенда: +### Запуск отдельных сервисов ```bash +# Только фронтенд (Astro на порту 4321) bun run frontend:dev -``` -Для запуска только бэкенда: - -```bash +# Только бэкенд (PocketBase на порту 8090) bun run backend:dev + +# Только почтовый сервер (Maildev) +bun run maildev ``` -## Сборка +### Доступные адреса -Для сборки фронтенда: +| Сервис | URL | Описание | +|--------|-----|----------| +| Frontend | http://localhost:4321 | Astro приложение (SSR) | +| Backend | http://localhost:8090 | PocketBase API и админ-панель | +| Maildev | http://localhost:1080 | Веб-интерфейс почтового сервера | +| Maildev SMTP | localhost:1025 | SMTP сервер для отправки писем | + +## 📦 Сборка и продакшен + +### Сборка проекта ```bash +# Сборка фронтенда bun run build -``` \ No newline at end of file + +# Или напрямую +cd frontend && bun run build +``` + +### Запуск продакшен-версии + +```bash +bun run start +``` + +## 🔐 Аутентификация + +Проект использует встроенную систему аутентификации PocketBase: + +- **OAuth2 провайдеры** — поддержка входа через Google, Apple и другие +- **Email/пароль** — классическая аутентификация +- **JWT токены** — хранятся в cookies +- **Middleware** — автоматическая проверка сессии на каждом запросе + +Файлы аутентификации: +- `frontend/src/lib/authService.ts` — сервис управления сессиями +- `frontend/src/middleware.js` — middleware для проверки авторизации +- `frontend/src/components/auth/` — UI компоненты входа/регистрации + +## 📧 Email-рассылка + +Для отправки уведомлений используется **Nodemailer**: + +- Подтверждение бронирования +- Уведомления администратору +- Верификация email + +### Локальное тестирование почты + +```bash +bun run maildev +``` + +Веб-интерфейс: http://localhost:1080 + +### API endpoints для отправки писем + +- `POST /api/send-email` — произвольное письмо +- `POST /api/send-booking-confirmation` — подтверждение бронирования +- `POST /api/send-admin-notification` — уведомление администратора + +## 🗄️ База данных и миграции + +PocketBase использует SQLite. Миграции хранятся в `backend/pb_migrations/`. + +### Применение миграций + +```bash +bun run backend:migrate +``` + +### Основные коллекции + +- `users` — пользователи +- `posts` — статьи блога +- `faq_items` — FAQ +- `slider_cars` — слайдер автомобилей +- `premium_fleet` — премиум автопарк +- `vip_services` — VIP услуги +- `reviews` — отзывы +- `pages` — статические страницы +- `site_settings` — настройки сайта + +## 🔧 Переменные окружения + +### Frontend (.env) + +```env +# PocketBase +POCKETBASE_URL=http://localhost:8090 + +# Почта (SMTP) +MAIL_HOST=localhost +MAIL_PORT=1025 +MAIL_FROM=no-reply@minv-berlin.de +ADMIN_EMAIL=admin@minivan-berlin.de +``` + +> ⚠️ **Важно:** В продакшене замените `localhost` на реальные адреса и используйте безопасные SMTP-настройки. + +## 🌐 Сайт + +Основной домен: **https://minivan-berlin.de** + +### Страницы сайта + +- Главная (`/`) +- О нас (`/ueber-uns`) +- Цены (`/preise`) +- Премиум флот (`/premium-flotte`) +- VIP услуги (`/vip-services`) +- Блог (`/blog`) +- Отзывы (`/bewertungen`) +- Партнёры (`/partner`) +- Карьера (`/karriere`) +- Контакты (`/kontakt`) +- Помощь (`/hilfe`) +- AGB, Datenschutz, Impressum + +## 📝 Скрипты npm + +| Команда | Описание | +|---------|----------| +| `bun run dev` | Запуск фронтенда и бэкенда | +| `bun run dev:all` | Запуск всех сервисов (включая maildev) | +| `bun run frontend:dev` | Только фронтенд | +| `bun run frontend:build` | Сборка фронтенда | +| `bun run frontend:start` | Preview собранного фронтенда | +| `bun run backend:dev` | Только бэкенд (PocketBase) | +| `bun run backend:migrate` | Применение миграций БД | +| `bun run maildev` | Запуск почтового сервера | +| `bun run build` | Сборка проекта | +| `bun run start` | Запуск продакшен-версии | + +## 🐳 Docker + +Проект включает Dockerfile для контейнеризации: + +- `frontend/Dockerfile` — образ для Astro приложения +- `backend/Dockerfile` — образ для PocketBase + +## 📚 Документация + +- [Astro](https://docs.astro.build/en/getting-started/) +- [SolidJS](https://docs.solidjs.com/solid-start/getting-started) +- [PocketBase](https://pocketbase.io/docs/) +- [Tailwind CSS](https://tailwindcss.com/docs) +- [astro-icon](https://www.astroicon.dev/getting-started/) + +## 📄 Лицензия + +ISC diff --git a/backend/pb_data/auxiliary.db b/backend/pb_data/auxiliary.db index 9d2e377..b1bd380 100644 Binary files a/backend/pb_data/auxiliary.db and b/backend/pb_data/auxiliary.db differ diff --git a/backend/pb_data/auxiliary.db-shm b/backend/pb_data/auxiliary.db-shm index ffa668f..bce2c62 100644 Binary files a/backend/pb_data/auxiliary.db-shm and b/backend/pb_data/auxiliary.db-shm differ diff --git a/backend/pb_data/auxiliary.db-wal b/backend/pb_data/auxiliary.db-wal index 5a709ff..a68727c 100644 Binary files a/backend/pb_data/auxiliary.db-wal and b/backend/pb_data/auxiliary.db-wal differ diff --git a/backend/pb_data/backups/@update_v0.34.2.zip b/backend/pb_data/backups/@update_v0.34.2.zip deleted file mode 100644 index 1ac4658..0000000 Binary files a/backend/pb_data/backups/@update_v0.34.2.zip and /dev/null differ diff --git a/backend/pb_data/backups/@update_v0.34.2.zip.attrs b/backend/pb_data/backups/@update_v0.34.2.zip.attrs deleted file mode 100644 index 2f5df86..0000000 --- a/backend/pb_data/backups/@update_v0.34.2.zip.attrs +++ /dev/null @@ -1 +0,0 @@ -{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"application/zip","user.metadata":{"original-filename":"@update_v0.34.2.zip"},"md5":"SZ4jsvp89dH7bADRXymb+Q=="} diff --git a/backend/pb_data/backups/minivan_berlin.zip b/backend/pb_data/backups/minivan_berlin_backup.zip similarity index 78% rename from backend/pb_data/backups/minivan_berlin.zip rename to backend/pb_data/backups/minivan_berlin_backup.zip index 391fab4..da11cba 100644 Binary files a/backend/pb_data/backups/minivan_berlin.zip and b/backend/pb_data/backups/minivan_berlin_backup.zip differ diff --git a/backend/pb_data/backups/minivan_berlin.zip.attrs b/backend/pb_data/backups/minivan_berlin_backup.zip.attrs similarity index 77% rename from backend/pb_data/backups/minivan_berlin.zip.attrs rename to backend/pb_data/backups/minivan_berlin_backup.zip.attrs index d34f467..4b88a46 100644 --- a/backend/pb_data/backups/minivan_berlin.zip.attrs +++ b/backend/pb_data/backups/minivan_berlin_backup.zip.attrs @@ -1 +1 @@ -{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"application/zip","user.metadata":{"original-filename":"minivan_berlin.zip"},"md5":"PYKtGG84Cgp75FbUL4+V6A=="} +{"user.cache_control":"","user.content_disposition":"","user.content_encoding":"","user.content_language":"","user.content_type":"application/zip","user.metadata":{"original-filename":"minivan_berlin_backup.zip"},"md5":"twrxG7BqJHh3X9Y7764oOg=="} diff --git a/frontend/public/robots.txt b/frontend/public/robots.txt index 02ff1ee..69dce68 100644 --- a/frontend/public/robots.txt +++ b/frontend/public/robots.txt @@ -8,4 +8,4 @@ Disallow: /email-verified Disallow: /profile Disallow: /auth/ -Sitemap: https://www.minivan-berlin.de/sitemap-index.xml \ No newline at end of file +Sitemap: https://minivan-berlin.de/sitemap-index.xml \ No newline at end of file diff --git a/frontend/src/components/blog/PopularPosts.astro b/frontend/src/components/blog/PopularPosts.astro index b985f87..a7ea515 100644 --- a/frontend/src/components/blog/PopularPosts.astro +++ b/frontend/src/components/blog/PopularPosts.astro @@ -1,6 +1,6 @@ --- interface Props { - posts: any[]; // Массив статей из PocketBase + posts: any[]; } const { posts } = Astro.props; diff --git a/frontend/src/components/blog/PostCard.astro b/frontend/src/components/blog/PostCard.astro index fa01752..d63ea99 100644 --- a/frontend/src/components/blog/PostCard.astro +++ b/frontend/src/components/blog/PostCard.astro @@ -2,8 +2,8 @@ import PostTags from '@components/blog/PostTags.astro'; interface Props { - post: any; // Объект статьи из PocketBase - compact?: boolean; // Опция для компактного вида (опционально) + post: any; + compact?: boolean; } const { post, compact = false } = Astro.props; diff --git a/frontend/src/components/layouts/header/Header.astro b/frontend/src/components/layouts/header/Header.astro index 915f7d8..c93aa8d 100644 --- a/frontend/src/components/layouts/header/Header.astro +++ b/frontend/src/components/layouts/header/Header.astro @@ -41,10 +41,13 @@ try { ]; } +// Фильтрация элементов верхнего меню (показываем только первые 5: Главная, Услуги, Маршруты, Цены, Контакты) +const topNavItems = navItems.filter(item => item.order <= 5); + // Фильтрация элемента "Startseite" на главной странице const filteredNavItems = currentPath === '/' - ? navItems.filter(item => item.label !== 'Startseite') - : navItems; + ? topNavItems.filter(item => item.label !== 'Startseite') + : topNavItems; const userName = session?.user?.name || session?.user?.email?.split('@')[0] || 'Gast'; diff --git a/frontend/src/pages/blog/[slug].astro b/frontend/src/pages/blog/[slug].astro index a95f0f3..42706fd 100644 --- a/frontend/src/pages/blog/[slug].astro +++ b/frontend/src/pages/blog/[slug].astro @@ -72,12 +72,12 @@ const dateOptions: Intl.DateTimeFormatOptions = { day: '2-digit', month: 'long', @@ -87,9 +87,12 @@ const dateOptions: Intl.DateTimeFormatOptions = { day: '2-digit', month: 'long',
+
+ year={year}, title={post.title}, adjusted={adjustedTitle} +

- {post.title} + {adjustedTitle}

@@ -98,7 +101,7 @@ const dateOptions: Intl.DateTimeFormatOptions = { day: '2-digit', month: 'long',