Release 2.4

This commit is contained in:
2025-08-08 18:39:58 +00:00
parent e1685487f0
commit 3b0f0dd4e1
4 changed files with 108 additions and 51 deletions

View File

@@ -1,47 +1,64 @@
# NeoMovies Web 🎬 # 🎬 Neo Movies
> Современный веб-интерфейс для поиска и просмотра фильмов и сериалов <div align="center">
<img src="public/logo.png" alt="Neo Movies Logo" width="200"/>
<p><strong>Современный онлайн-сервис с удобным интерфейсом</strong></p>
</div>
## 🚀 Особенности ## 📋 О проекте
- 🎭 **TMDB интеграция** - полная информация о фильмах и сериалах Neo Movies - это современная веб-платформа построенная с использованием передовых технологий. Проект предлагает удобный интерфейс, быструю навигацию и множество функций для комфортного просмотра информации об фильмах и сералах а также стороние плееры предоставляемые видео-балансерами.
- 🔍 **Умный поиск** - поиск по названию, актерам, жанрам
- 🎬 **Встроенные плееры** - просмотр через Alloha и Lumex ### ✨ Основные возможности
- 🧲 **Торрент интеграция** - поиск раздач по IMDB ID
- **Система избранного** - сохраняйте любимые фильмы - 🎥 Два встроенных видеоплеера на выбор (Alloha, Lumex)
- 🎨 **Современный UI** - адаптивный дизайн с темной темой - 🔍 Умный поиск по фильмам
- 📱 **Мобильная версия** - оптимизировано для всех устройств - 📱 Адаптивный дизайн для всех устройств
- 🔐 **JWT аутентификация** - безопасная авторизация - 🌙 Темная тема
- 📧 **Email верификация** - подтверждение аккаунта - 👤 Система авторизации и профили пользователей
- ❤️ Возможность добавлять фильмы в избранное
- ⚡ Быстрая загрузка и оптимизированная производительность
## 🛠 Технологии ## 🛠 Технологии
- **Frontend**: Next.js 15, React 19, TypeScript - **Frontend:**
- **Styling**: Tailwind CSS, Radix UI - Next.js 13+ (App Router)
- **State Management**: Redux Toolkit - React 18
- **API**: Go API (neomovies-api) - TypeScript
- **Database**: MongoDB - Styled Components
- **Authentication**: JWT - JWT-based authentication (custom)
- **Deployment**: Vercel
## 📦 Установка - **Backend:**
- Node.js + Express (neomovies-api)
- MongoDB (native driver)
1. **Клонируйте репозиторий:** - **Дополнительно:**
- ESLint
- Prettier
- Git
- npm
## Начало работы
1. Клонируйте репозиторий:
```bash ```bash
git clone https://github.com/Ernous/neomovies-web.git git clone https://gitlab.com/foxixus/neomovies.git
cd neomovies-web cd neomovies
``` ```
2. **Установите зависимости:** 2. Установите зависимости:
```bash ```bash
npm install npm install
``` ```
3. Создайте файл `.env` и добавьте следующие переменные: 3. Создайте файл `.env` и добавьте следующие переменные:
```env ```env
NEXT_PUBLIC_API_URL=https://api.neomovies.ru NEXT_PUBLIC_API_URL=https://neomovies-api.vercel.app
NEXT_PUBLIC_TMDB_API_KEY=your_tmdb_api_key
NEXT_PUBLIC_TMDB_ACCESS_TOKEN=your_tmdb_access_token
``` ```
4. **Запустите проект:** 4. **Запустите проект:**
```bash ```bash
# Режим разработки # Режим разработки
@@ -55,37 +72,33 @@ npm start
## API (neomovies-api) ## API (neomovies-api)
Приложение использует отдельный Go API сервер. API предоставляет следующие возможности: Приложение использует отдельный API сервер. API предоставляет следующие возможности:
- Поиск фильмов и сериалов через TMDB - Поиск фильмов и сериалов
- Получение детальной информации о фильме/сериале - Получение детальной информации о фильме/сериале
- Поиск торрентов по IMDB ID с парсингом сезонов из названий
- Система избранного и реакций
- JWT аутентификация с email верификацией
- Оптимизированная загрузка изображений - Оптимизированная загрузка изображений
- Кэширование запросов - Кэширование запросов
### Особенности торрент-поиска ### Gmail App Password
1. Включите двухфакторную аутентификацию в аккаунте Google
2. Перейдите в настройки безопасности
3. Создайте пароль приложения
4. Используйте этот пароль в GMAIL_APP_PASSWORD
Новый API автоматически парсит сезоны из названий торрентов, что позволяет: Backend `.env` пример смотрите в репозитории [neomovies-api](https://gitlab.com/foxixus/neomovies-api).
- Получать реальные доступные сезоны, а не только из TMDB
- Находить раздачи даже если нумерация сезонов отличается от официальной
- Группировать торренты по сезонам для удобного выбора
Backend `.env` пример смотрите в репозитории [neomovies-api](https://github.com/Ernous/neomovies-api).
--- ---
## Структура проекта ## Структура проекта
``` ```
neomovies-web/ neomovies/
├── src/ ├── src/
│ ├── app/ # App Router pages │ ├── app/ # App Router pages
│ ├── components/ # React компоненты │ ├── components/ # React компоненты
│ ├── hooks/ # React хуки │ ├── hooks/ # React хуки
│ ├── lib/ # Утилиты и API │ ├── lib/ # Утилиты и API
│ ├── types/ # TypeScript типы │ ├── models/ # MongoDB модели
│ └── styles/ # Глобальные стили │ └── styles/ # Глобальные стили
├── public/ # Статические файлы ├── public/ # Статические файлы
└── package.json └── package.json
@@ -95,7 +108,6 @@ neomovies-web/
## 👥 Авторы ## 👥 Авторы
- **Frontend Developer** - [Foxix](https://gitlab.com/foxixus) - **Frontend Developer** - [Foxix](https://gitlab.com/foxixus)
- **Backend Developer** - [Ernous](https://github.com/Ernous)
## 📄 Лицензия ## 📄 Лицензия
@@ -114,7 +126,7 @@ neomovies-web/
## Благодарности ## Благодарности
- [TMDB](https://www.themoviedb.org/) за предоставление API - [TMDB](https://www.themoviedb.org/) за предоставление API
- [Vercel](https://vercel.com/) за хостинг - [Vercel](https://vercel.com/) за хостинг API
## 📞 Контакты ## 📞 Контакты

View File

@@ -1,13 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:mobile="http://www.google.com/schemas/sitemap-mobile/1.0" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns:video="http://www.google.com/schemas/sitemap-video/1.1"> <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:mobile="http://www.google.com/schemas/sitemap-mobile/1.0" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns:video="http://www.google.com/schemas/sitemap-video/1.1">
<url><loc>https://neomovies.ru/admin/login</loc><lastmod>2025-08-07T09:55:31.360Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url> <url><loc>https://neomovies.ru/auth/callback</loc><lastmod>2025-08-08T16:29:17.862Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>
<url><loc>https://neomovies.ru/categories</loc><lastmod>2025-08-07T09:55:31.360Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url> <url><loc>https://neomovies.ru/admin/login</loc><lastmod>2025-08-08T16:29:17.862Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>
<url><loc>https://neomovies.ru/favorites</loc><lastmod>2025-08-07T09:55:31.360Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url> <url><loc>https://neomovies.ru/categories</loc><lastmod>2025-08-08T16:29:17.862Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>
<url><loc>https://neomovies.ru/login</loc><lastmod>2025-08-07T09:55:31.360Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url> <url><loc>https://neomovies.ru/login</loc><lastmod>2025-08-08T16:29:17.862Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>
<url><loc>https://neomovies.ru</loc><lastmod>2025-08-07T09:55:31.360Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url> <url><loc>https://neomovies.ru/favorites</loc><lastmod>2025-08-08T16:29:17.862Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>
<url><loc>https://neomovies.ru/profile</loc><lastmod>2025-08-07T09:55:31.360Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url> <url><loc>https://neomovies.ru</loc><lastmod>2025-08-08T16:29:17.862Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>
<url><loc>https://neomovies.ru/search</loc><lastmod>2025-08-07T09:55:31.360Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url> <url><loc>https://neomovies.ru/profile</loc><lastmod>2025-08-08T16:29:17.862Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>
<url><loc>https://neomovies.ru/settings</loc><lastmod>2025-08-07T09:55:31.360Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url> <url><loc>https://neomovies.ru/search</loc><lastmod>2025-08-08T16:29:17.862Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>
<url><loc>https://neomovies.ru/terms</loc><lastmod>2025-08-07T09:55:31.360Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url> <url><loc>https://neomovies.ru/settings</loc><lastmod>2025-08-08T16:29:17.862Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>
<url><loc>https://neomovies.ru/verify</loc><lastmod>2025-08-07T09:55:31.360Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url> <url><loc>https://neomovies.ru/verify</loc><lastmod>2025-08-08T16:29:17.862Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>
<url><loc>https://neomovies.ru/terms</loc><lastmod>2025-08-08T16:29:17.862Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>
</urlset> </urlset>

View File

@@ -0,0 +1,38 @@
'use client';
import { useEffect } from 'react';
import { useRouter } from 'next/navigation';
import { neoApi } from '@/lib/neoApi';
export default function OAuthCallbackPage() {
const router = useRouter();
useEffect(() => {
const run = async () => {
const url = new URL(window.location.href);
const token = url.searchParams.get('token');
if (!token) {
router.replace('/login');
return;
}
try {
localStorage.setItem('token', token);
neoApi.defaults.headers.common['Authorization'] = `Bearer ${token}`;
const resp = await neoApi.get('/api/v1/auth/profile');
const user = resp.data;
if (user?.name) localStorage.setItem('userName', user.name);
if (user?.email) localStorage.setItem('userEmail', user.email);
} catch {
// ignore, proceed to home
} finally {
window.dispatchEvent(new Event('auth-changed'));
router.replace('/');
}
};
run();
}, [router]);
return null;
}

View File

@@ -40,6 +40,11 @@ export default function LoginClient() {
} }
}; };
const handleGoogle = () => {
const base = process.env.NEXT_PUBLIC_API_URL || 'https://api.neomovies.ru';
window.location.href = `${base}/api/v1/auth/google/login`;
};
return ( return (
<div className="min-h-screen flex items-center justify-center p-4 bg-background"> <div className="min-h-screen flex items-center justify-center p-4 bg-background">
<div className="w-full max-w-md bg-warm-50 dark:bg-warm-900 rounded-lg shadow-lg p-8"> <div className="w-full max-w-md bg-warm-50 dark:bg-warm-900 rounded-lg shadow-lg p-8">
@@ -99,6 +104,7 @@ export default function LoginClient() {
<button <button
type="button" type="button"
onClick={handleGoogle}
className="w-full flex items-center justify-center gap-3 px-4 py-3 border border-warm-200 dark:border-warm-700 rounded-lg bg-white dark:bg-warm-800 hover:bg-warm-100 dark:hover:bg-warm-700 text-warm-900 dark:text-warm-50 transition-colors" className="w-full flex items-center justify-center gap-3 px-4 py-3 border border-warm-200 dark:border-warm-700 rounded-lg bg-white dark:bg-warm-800 hover:bg-warm-100 dark:hover:bg-warm-700 text-warm-900 dark:text-warm-50 transition-colors"
> >
<Image src="/google.svg" alt="Google" width={20} height={20} /> <Image src="/google.svg" alt="Google" width={20} height={20} />