# CampFire Critics CampFire Critics — это веб-приложение, созданное с использованием React, Vite и Tailwind CSS, предназначенное для каталогизации медиаконтента (фильмов, сериалов, игр, аниме) и управления пользовательскими отзывами. Приложение включает в себя систему аутентификации, подробные страницы медиа, профили пользователей, систему достижений, систему поддержки и административную панель для модерации контента и управления данными. В качестве бэкенда используется PocketBase. ## Функции * **Аутентификация пользователей**: Полная система регистрации, входа, выхода и сброса пароля с использованием PocketBase Auth. * **Профили пользователей**: Просмотр профилей пользователей, отображение их статистики (количество рецензий, средний рейтинг, XP, уровень), списка достижений и витрины избранных рецензий. Возможность редактирования собственного профиля (описание, аватар, баннер, витрина). * **Каталог медиа**: Просмотр списка медиа с фильтрацией по типу (фильмы, сериалы, игры, аниме) и поиском. * **Страницы обзора медиа**: Подробные страницы для каждого медиа, включающие информацию о нем, список сезонов (для сериалов/аниме), а также раздел с пользовательскими рецензиями и рейтингами. * **Система рецензий**: Пользователи могут оставлять рецензии на медиа или отдельные сезоны, выставлять оценки по нескольким характеристикам, указывать прогресс просмотра/прохождения и отмечать спойлеры. Рецензии отображаются на страницах медиа/сезонов и в профилях пользователей. * **Система лайков рецензий**: Пользователи могут ставить лайки рецензиям других пользователей. * **Система XP и уровней**: Пользователи получают XP за создание рецензий и получение достижений, что повышает их уровень. Уровень и XP отображаются в профиле. * **Система достижений**: Пользователи могут получать достижения за различные действия. Список достижений отображается в профиле. * **Система поддержки**: Пользователи могут создавать тикеты поддержки с выбором категории и описанием проблемы. * **Административная панель**: Раздел для администраторов с возможностью управления медиа, пользователями, сезонами, достижениями и тикетами поддержки. Включает дашборд с общей статистикой. * **Адаптивный дизайн**: Приложение адаптировано для корректного отображения на различных устройствах с использованием Tailwind CSS. ## Технологии * **Фронтенд**: * React: Библиотека для построения пользовательских интерфейсов. * Vite: Быстрый сборщик фронтенда. * Tailwind CSS: Утилитарный CSS-фреймворк для быстрой стилизации. * React Router DOM: Для маршрутизации в приложении. * `react-icons`: Набор популярных иконок. * `chart.js` и `react-chartjs-2`: Для построения графиков рейтингов. * `react-datepicker`: Для выбора дат. * `react-fast-marquee`: Для бегущей строки (если используется). * `react-quill`: WYSIWYG редактор для контента рецензий/описаний. * `react-select`: Кастомизируемый компонент выбора. * `react-toastify`: Для уведомлений (тостов). * `dompurify`: Для очистки HTML контента. * `uuid`: Для генерации уникальных ID. * **Бэкенд**: * PocketBase: Опенсорсный бэкенд в одном файле (Go) с базой данных SQLite, системой аутентификации, файловым хранилищем, realtime подписками и хуками. * **Внешние API**: * TMDB (The Movie Database): Используется для получения информации о фильмах, сериалах и, возможно, другом медиаконтенте (подразумевается, исходя из предыдущего README). ## Настройка проекта 1. **Клонирование репозитория** (стандартный шаг, не применимо в WebContainer): ```bash git clone https://github.com/your-username/campfire-critics.git cd campfire-critics ``` 2. **Установка зависимостей**: ```bash npm install ``` 3. **Настройка PocketBase**: * Скачайте и запустите PocketBase с [официального сайта](https://pocketbase.io/docs/getting-started/). * Перейдите в Admin UI (обычно `http://127.0.0.1:8090/_/`). * Создайте следующие коллекции (убедитесь, что включены необходимые поля и связи): * `users` (тип `auth`): Стандартная коллекция пользователей PocketBase. Добавьте поля: `role` (select, options: `user`, `admin`), `is_critic` (bool), `description` (text), `profile_picture` (file), `banner_picture` (file), `review_count` (number, default 0), `average_rating` (number, default 0), `xp` (number, default 0), `level` (number, default 1), `showcase` (relation to `reviews`, multiple). * `media`: Поля: `title` (text), `type` (select, options: `movie`, `tv`, `game`, `anime`), `path` (text, unique), `overview` (text), `release_date` (date), `poster` (file), `backdrop` (file), `trailer_url` (url), `characteristics` (json), `average_rating` (number, default 0), `review_count` (number, default 0), `is_published` (bool, default false), `is_popular` (bool, default false), `progress_type` (select, options: `percentage`, `episodes`, `chapters`, `none`), `created_by` (relation to `users`), `created` (datetime), `updated` (datetime). * `seasons`: Поля: `media_id` (relation to `media`, required), `season_number` (number, required), `title` (text), `overview` (text), `release_date` (date), `poster` (file), `average_rating` (number, default 0), `review_count` (number, default 0), `is_published` (bool, default false), `created_by` (relation to `users`), `created` (datetime), `updated` (datetime). * `reviews`: Поля: `user_id` (relation to `users`, required), `media_id` (relation to `media`, required), `season_id` (relation to `seasons`, optional), `content` (text), `ratings` (json), `overall_rating` (number, default 0), `has_spoilers` (bool, default false), `progress` (number), `created` (datetime), `updated` (datetime). * `achievements`: Поля: `name` (text), `description` (text), `icon` (file), `xp_reward` (number, default 0), `created` (datetime), `updated` (datetime). * `user_achievements`: Поля: `user_id` (relation to `users`, required), `achievement_id` (relation to `achievements`, required), `awarded_at` (datetime), `awarded_by` (relation to `users`, optional), `created` (datetime), `updated` (datetime). * `review_likes`: Поля: `review_id` (relation to `reviews`, required), `user_id` (relation to `users`, required), `created` (datetime). * `support_tickets`: Поля: `user_id` (relation to `users`, required), `category` (select, options: `bug`, `feature_request`, `question`, `other`), `subject` (text), `message` (text), `status` (select, options: `open`, `in_progress`, `closed`, default `open`), `admin_notes` (text), `created` (datetime), `updated` (datetime). * **Настройте RLS (Row Level Security)** для каждой коллекции, чтобы определить, кто может просматривать, создавать, обновлять и удалять записи. * **Настройте Hooks/Triggers** в PocketBase для автоматического обновления полей `average_rating` и `review_count` в коллекциях `media`, `seasons` и `users` при создании, обновлении или удалении записей в коллекциях `reviews` и `review_likes`. Также настройте хуки для обновления `xp` и `level` пользователя при создании рецензии или получении достижения. *Это критически важный шаг для корректной работы статистики.* 4. **Настройте переменные окружения**: * Создайте файл `.env` в корне проекта, если его нет. * Добавьте URL вашего PocketBase инстанса: ``` VITE_POCKETBASE_URL=http://127.0.0.1:8090 ``` Замените URL на адрес вашего запущенного PocketBase. 5. **Запустите сервер разработки**: ```bash npm run dev ``` Приложение будет доступно по адресу, указанному Vite (обычно `http://localhost:5173`). ## Структура проекта и описание модулей Проект организован следующим образом: ``` src/ ├── App.jsx # Основной компонент приложения, определяет маршруты. ├── main.jsx # Точка входа в приложение, инициализирует React и оборачивает App в контекст-провайдеры и роутер. ├── index.css # Основной файл стилей, импортирует Tailwind CSS. ├── pages/ # Компоненты, представляющие целые страницы приложения. │ ├── HomePage.jsx # Главная страница с обзорами и статистикой. │ ├── CatalogPage.jsx # Страница каталога медиа. │ ├── MediaOverviewPage.jsx# Страница с подробным обзором конкретного медиа. │ ├── ProfilePage.jsx # Страница профиля пользователя. │ ├── RatingPage.jsx # Страница с рейтингами пользователей (по рецензиям, по уровню). │ ├── SupportPage.jsx # Страница для создания тикетов поддержки. │ ├── NotFoundPage.jsx # Страница 404. │ ├── LoginPage.jsx # Страница входа. │ ├── RegisterPage.jsx # Страница регистрации. │ ├── ForgotPasswordPage.jsx# Страница сброса пароля. │ └── admin/ # Страницы административной панели. │ ├── AdminDashboard.jsx │ ├── AdminMediaPage.jsx │ ├── AdminUsersPage.jsx │ ├── AdminSeasonsPage.jsx │ ├── AdminAchievementsPage.jsx │ ├── AdminTicketsPage.jsx │ └── AdminTicketDetailPage.jsx ├── components/ # Переиспользуемые UI-компоненты. │ ├── auth/ # Компоненты и логика, связанные с аутентификацией (AuthRoute, GuestRoute). │ ├── layout/ # Компоненты макета (Header, Footer, Layout). │ ├── admin/ # Компоненты для административной панели (AdminLayout). │ ├── MediaCard.jsx # Карточка медиа для каталога/списков. │ ├── ReviewCard.jsx # Карточка рецензии. │ ├── RatingChart.jsx # Компонент графика рейтинга. │ ├── SearchBar.jsx # Компонент поиска. │ ├── UserRankCard.jsx # Карточка пользователя для рейтингов. │ ├── AchievementCard.jsx # Карточка достижения. │ ├── SupportTicketCard.jsx# Карточка тикета поддержки. │ └── ... другие компоненты ├── contexts/ # React Context провайдеры для глобального состояния. │ ├── AuthContext.jsx # Управляет состоянием аутентификации пользователя. │ └── ProfileActionsContext.jsx # Управляет действиями, связанными с профилем (например, витрина). ├── services/ # Утилиты и сервисы для взаимодействия с API/бэкендом. │ └── pocketbaseService.js # **Основной модуль для взаимодействия с PocketBase API.** ├── assets/ # Статические файлы (изображения, шрифты и т.д.). └── ... другие файлы конфигурации (tailwind.config.js, postcss.config.js, vite.config.js) ``` ### Описание ключевых модулей: * **`src/services/pocketbaseService.js`**: Этот файл является центральным слоем для всех операций взаимодействия с бэкендом PocketBase. Он инициализирует PocketBase SDK и экспортирует функции для: * **Аутентификации**: `signUp`, `signIn`, `signOut`, `getCurrentUser`, `requestPasswordReset`. * **Пользователей**: `getUserProfile`, `getUserProfileByUsername`, `updateUserProfile`, `updateUserShowcase`, `listUsersRankedByReviews`, `listUsersRankedByLevel`. * **Медиа**: `createMedia`, `getMediaByPath`, `getMediaById`, `listMedia`, `listPopularMedia`, `updateMedia`, `deleteMedia`, `searchMedia`. * **Рецензий**: `getLatestReviews`, `getReviewsByMediaId`, `getReviewsByUserId`, `getUserReviewForMedia`, `createReview`, `updateReview`, `deleteReview`. * **Сезонов**: `getSeasonsByMediaId`, `getSeasonById`, `createSeason`, `updateSeason`, `deleteSeason`. * **Достижений**: `getAllAchievements`, `getUserAchievements`, `awardAchievement`. * **Лайков рецензий**: `likeReview`, `unlikeReview`, `getReviewLikeCount`, `hasUserLikedReview`. * **Тикетов поддержки**: `createSupportTicket`, `getUserTickets`, `getAllTickets`, `getTicketById`, `updateSupportTicket`. * **Файлового хранилища**: `uploadFile`, `deleteFile`, `getFileUrl`. * **Утилит**: `calculateLevel`, `getXpForNextLevel`, `getXpForCurrentLevel`, `validateMediaData`, `formatMediaData`, `updateRatingStats` (функция для пересчета средних рейтингов и количества рецензий, часто вызывается после операций с рецензиями). Этот модуль абстрагирует логику работы с API, делая компоненты более чистыми. * **`src/contexts/AuthContext.jsx`**: Предоставляет глобальный доступ к состоянию аутентификации текущего пользователя. Использует `pocketbaseService` для выполнения операций входа/выхода/регистрации и хранит информацию о пользователе в состоянии React Context. Компоненты могут использовать хук `useAuth` для доступа к данным пользователя и функциям аутентификации. * **`src/contexts/ProfileActionsContext.jsx`**: Предоставляет контекст для управления действиями, специфичными для страницы профиля, такими как обновление витрины рецензий. * **`src/App.jsx`**: Определяет структуру маршрутизации приложения с использованием `react-router-dom`. Здесь настраиваются публичные маршруты, маршруты только для гостей (`GuestRoute`) и защищенные маршруты (`AuthRoute`), включая маршруты административной панели. * **`src/components/auth/AuthRoute.jsx` и `src/components/auth/GuestRoute.jsx`**: Вспомогательные компоненты маршрутизации, которые используют `AuthContext` для проверки статуса аутентификации пользователя и его роли, перенаправляя пользователя на другие страницы при необходимости (например, перенаправление неаутентифицированных пользователей с защищенных маршрутов или аутентифицированных пользователей со страниц входа/регистрации). * **`src/pages/` и `src/components/`**: Эти директории содержат компоненты пользовательского интерфейса. `pages` содержат компоненты верхнего уровня, представляющие целые страницы, а `components` содержат более мелкие, переиспользуемые блоки UI. Стилизация в основном выполняется с помощью классов Tailwind CSS. * **Административная панель (`src/pages/admin/`, `src/components/admin/AdminLayout.jsx`)**: Набор страниц и компонентов, доступных только пользователям с ролью 'admin'. `AdminLayout` предоставляет общую структуру макета для всех страниц админки (навигация, заголовок). Страницы внутри `pages/admin/` используют функции из `pocketbaseService` для управления данными (создание, чтение, обновление, удаление) медиа, пользователей, сезонов, достижений и тикетов поддержки. ## Вклад в проект 1. Откройте issue для обсуждения новой функции или исправления. 2. Сделайте fork репозитория. 3. Создайте новую ветку (`git checkout -b feature-name`). 4. Зафиксируйте изменения. 5. Запушьте ветку (`git push origin feature-name`). 6. Создайте Pull Request. ## Требования * Node.js 18+ * npm 8+ * Запущенный инстанс PocketBase с настроенными коллекциями, RLS и хуками. ## Лицензия MIT License. Подробнее см. [LICENSE](LICENSE).