diff --git a/src/api.ts b/src/api.ts index e7dc46e..bd1925b 100644 --- a/src/api.ts +++ b/src/api.ts @@ -1,15 +1,12 @@ import axios from 'axios'; const BASE_URL = 'https://api.themoviedb.org/3'; - -if (typeof window === 'undefined' && !process.env.NEXT_PUBLIC_TMDB_ACCESS_TOKEN) { - throw new Error('TMDB_ACCESS_TOKEN is not defined in environment variables'); -} +const AUTH_TOKEN = 'Bearer process.env.TMDB_API_KEY'; export const api = axios.create({ baseURL: BASE_URL, headers: { - 'Authorization': `Bearer ${process.env.NEXT_PUBLIC_TMDB_ACCESS_TOKEN}`, + 'Authorization': AUTH_TOKEN, 'Content-Type': 'application/json' } }); @@ -150,4 +147,4 @@ export const moviesAPI = { return []; } } -}; \ No newline at end of file +}; diff --git a/src/app/admin/login/AdminLoginClient.tsx b/src/app/admin/login/AdminLoginClient.tsx deleted file mode 100644 index 5660e2d..0000000 --- a/src/app/admin/login/AdminLoginClient.tsx +++ /dev/null @@ -1,147 +0,0 @@ -'use client'; - -import { useState } from 'react'; -import { signIn } from 'next-auth/react'; -import { useRouter } from 'next/navigation'; -import styled from 'styled-components'; - -const Container = styled.div` - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - min-height: 100vh; - padding: 2rem; - background: #1a1a1a; -`; - -const Form = styled.form` - width: 100%; - max-width: 400px; - padding: 2rem; - background: rgba(255, 255, 255, 0.1); - border-radius: 8px; - box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); -`; - -const Title = styled.h1` - color: white; - text-align: center; - margin-bottom: 2rem; - font-size: 1.5rem; -`; - -const Input = styled.input` - width: 100%; - padding: 0.75rem; - margin-bottom: 1rem; - border: 1px solid rgba(255, 255, 255, 0.2); - border-radius: 4px; - background: rgba(255, 255, 255, 0.05); - color: white; - font-size: 1rem; - - &:focus { - outline: none; - border-color: #3b82f6; - } - - &::placeholder { - color: rgba(255, 255, 255, 0.5); - } -`; - -const Button = styled.button` - width: 100%; - padding: 0.75rem; - background: #3b82f6; - color: white; - border: none; - border-radius: 4px; - font-size: 1rem; - cursor: pointer; - transition: background-color 0.2s; - - &:hover { - background: #2563eb; - } - - &:disabled { - background: #64748b; - cursor: not-allowed; - } -`; - -const ErrorMessage = styled.div` - color: #ef4444; - margin-bottom: 1rem; - text-align: center; -`; - -export default function AdminLoginClient() { - const [email, setEmail] = useState(''); - const [password, setPassword] = useState(''); - const [error, setError] = useState(''); - const [isLoading, setIsLoading] = useState(false); - const router = useRouter(); - - const handleSubmit = async (e: React.FormEvent) => { - e.preventDefault(); - setError(''); - setIsLoading(true); - - try { - const result = await signIn('credentials', { - email, - password, - isAdminLogin: 'true', - redirect: false, - }); - - if (result?.error) { - switch (result.error) { - case 'NOT_AN_ADMIN': - setError('У вас нет прав администратора'); - break; - case 'EMAIL_NOT_VERIFIED': - setError('Пожалуйста, подтвердите свой email'); - break; - default: - setError('Неверный email или пароль'); - } - } else { - router.push('/admin'); - } - } catch (error) { - setError('Произошла ошибка при входе'); - } finally { - setIsLoading(false); - } - }; - - return ( - -
- Вход в админ-панель - {error && {error}} - setEmail(e.target.value)} - required - /> - setPassword(e.target.value)} - required - /> - -
-
- ); -} diff --git a/src/app/admin/login/page.tsx b/src/app/admin/login/page.tsx deleted file mode 100644 index da44a9d..0000000 --- a/src/app/admin/login/page.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import AdminLoginClient from './AdminLoginClient'; - -export default function AdminLoginPage() { - return ; -} diff --git a/src/app/api/auth/[...nextauth]/route.ts b/src/app/api/auth/[...nextauth]/route.ts index 3b5f4a7..219a708 100644 --- a/src/app/api/auth/[...nextauth]/route.ts +++ b/src/app/api/auth/[...nextauth]/route.ts @@ -12,7 +12,6 @@ declare module 'next-auth' { email: string; verified: boolean; isAdmin: boolean; - adminVerified?: boolean; } & DefaultSession['user'] } } @@ -24,7 +23,7 @@ const handler = NextAuth({ credentials: { email: { label: 'Email', type: 'email' }, password: { label: 'Password', type: 'password' }, - isAdminLogin: { label: 'isAdminLogin', type: 'boolean' } + isAdminVerified: { label: 'isAdminVerified', type: 'checkbox' } }, async authorize(credentials) { if (!credentials?.email || !credentials?.password) { @@ -49,12 +48,9 @@ const handler = NextAuth({ throw new Error('EMAIL_NOT_VERIFIED'); } - // Если это попытка входа в админ-панель - if (credentials.isAdminLogin === 'true') { - // Проверяем, является ли пользователь админом - if (!user.isAdmin) { - throw new Error('NOT_AN_ADMIN'); - } + // Проверяем права администратора и флаг верификации для админ-панели + if (user.isAdmin && !credentials.isAdminVerified) { + throw new Error('ADMIN_NOT_VERIFIED'); } return { @@ -62,8 +58,7 @@ const handler = NextAuth({ email: user.email, name: user.name, verified: user.verified, - isAdmin: user.isAdmin, - adminVerified: credentials.isAdminLogin === 'true' + isAdmin: user.isAdmin }; } }) @@ -78,7 +73,6 @@ const handler = NextAuth({ token.id = user.id; token.verified = user.verified; token.isAdmin = user.isAdmin; - token.adminVerified = user.adminVerified; } return token; }, @@ -87,7 +81,6 @@ const handler = NextAuth({ session.user.id = token.id as string; session.user.verified = token.verified as boolean; session.user.isAdmin = token.isAdmin as boolean; - session.user.adminVerified = token.adminVerified as boolean; } return session; } diff --git a/src/components/MovieCard.tsx b/src/components/MovieCard.tsx index fb5629c..4700e77 100644 --- a/src/components/MovieCard.tsx +++ b/src/components/MovieCard.tsx @@ -87,7 +87,7 @@ const Rating = styled.div` right: 8px; padding: 4px 8px; border-radius: 6px; - font-size: 17px; + font-size: 12px; font-weight: 600; color: white; `; diff --git a/src/components/MoviePlayer.tsx b/src/components/MoviePlayer.tsx index 13b916c..e74400a 100644 --- a/src/components/MoviePlayer.tsx +++ b/src/components/MoviePlayer.tsx @@ -210,7 +210,7 @@ export default function MoviePlayer({ id, title, poster, imdbId }: MoviePlayerPr {settings.defaultPlayer === 'lumex' && imdbId ? ( diff --git a/src/lib/api.ts b/src/lib/api.ts index 8ae72bd..31ede32 100644 --- a/src/lib/api.ts +++ b/src/lib/api.ts @@ -1,17 +1,13 @@ import axios from 'axios'; const BASE_URL = 'https://api.themoviedb.org/3'; - -if (typeof window === 'undefined' && !process.env.NEXT_PUBLIC_TMDB_ACCESS_TOKEN) { - throw new Error('TMDB_ACCESS_TOKEN is not defined in environment variables'); -} +const API_KEY = 'process.env.TMDB_API_KEY'; export const api = axios.create({ baseURL: BASE_URL, - headers: { - 'Authorization': `Bearer ${process.env.NEXT_PUBLIC_TMDB_ACCESS_TOKEN}`, - 'Content-Type': 'application/json' - } + params: { + api_key: API_KEY, + }, }); export interface Genre { diff --git a/src/lib/auth.ts b/src/lib/auth.ts index b546ef2..1799081 100644 --- a/src/lib/auth.ts +++ b/src/lib/auth.ts @@ -64,6 +64,7 @@ export const authOptions: AuthOptions = { }, session: { strategy: 'jwt', + maxAge: 30 * 24 * 60 * 60, // 30 дней }, }; @@ -87,3 +88,4 @@ declare module 'next-auth/jwt' { isAdmin: boolean; } } +