Добавлены модели и функциональность для управления администраторами, включая авторизацию через JWT, запросы и мутации для получения информации об администраторах и управления пользователями. Обновлены стили и логика работы с токенами в Apollo Client. Улучшен интерфейс взаимодействия с пользователем.
This commit is contained in:
10
src/app/admin/dashboard/page.tsx
Normal file
10
src/app/admin/dashboard/page.tsx
Normal file
@ -0,0 +1,10 @@
|
||||
import { AdminGuard } from "@/components/admin/admin-guard"
|
||||
import { AdminDashboard } from "@/components/admin/admin-dashboard"
|
||||
|
||||
export default function AdminDashboardPage() {
|
||||
return (
|
||||
<AdminGuard>
|
||||
<AdminDashboard />
|
||||
</AdminGuard>
|
||||
)
|
||||
}
|
14
src/app/admin/page.tsx
Normal file
14
src/app/admin/page.tsx
Normal file
@ -0,0 +1,14 @@
|
||||
"use client"
|
||||
|
||||
import { AdminLogin } from "@/components/admin/admin-login"
|
||||
import { AdminGuard } from "@/components/admin/admin-guard"
|
||||
import { redirect } from "next/navigation"
|
||||
|
||||
export default function AdminPage() {
|
||||
return (
|
||||
<AdminGuard fallback={<AdminLogin />}>
|
||||
{/* Если администратор авторизован, перенаправляем в админ-дашборд */}
|
||||
{redirect('/admin/dashboard')}
|
||||
</AdminGuard>
|
||||
)
|
||||
}
|
@ -11,6 +11,10 @@ interface Context {
|
||||
id: string
|
||||
phone: string
|
||||
}
|
||||
admin?: {
|
||||
id: string
|
||||
username: string
|
||||
}
|
||||
}
|
||||
|
||||
// Создаем Apollo Server
|
||||
@ -31,27 +35,42 @@ const handler = startServerAndCreateNextHandler<NextRequest>(server, {
|
||||
|
||||
if (!token) {
|
||||
console.log('GraphQL Context - No token provided')
|
||||
return { user: undefined }
|
||||
return { user: undefined, admin: undefined }
|
||||
}
|
||||
|
||||
try {
|
||||
// Верифицируем JWT токен
|
||||
const decoded = jwt.verify(token, process.env.JWT_SECRET!) as {
|
||||
userId: string
|
||||
phone: string
|
||||
userId?: string
|
||||
phone?: string
|
||||
adminId?: string
|
||||
username?: string
|
||||
type?: string
|
||||
}
|
||||
|
||||
console.log('GraphQL Context - Decoded user:', { id: decoded.userId, phone: decoded.phone })
|
||||
|
||||
return {
|
||||
user: {
|
||||
id: decoded.userId,
|
||||
phone: decoded.phone
|
||||
// Проверяем тип токена
|
||||
if (decoded.type === 'admin' && decoded.adminId && decoded.username) {
|
||||
console.log('GraphQL Context - Decoded admin:', { id: decoded.adminId, username: decoded.username })
|
||||
return {
|
||||
admin: {
|
||||
id: decoded.adminId,
|
||||
username: decoded.username
|
||||
}
|
||||
}
|
||||
} else if (decoded.userId && decoded.phone) {
|
||||
console.log('GraphQL Context - Decoded user:', { id: decoded.userId, phone: decoded.phone })
|
||||
return {
|
||||
user: {
|
||||
id: decoded.userId,
|
||||
phone: decoded.phone
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return { user: undefined, admin: undefined }
|
||||
} catch (error) {
|
||||
console.error('GraphQL Context - Invalid token:', error)
|
||||
return { user: undefined }
|
||||
return { user: undefined, admin: undefined }
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -270,6 +270,15 @@
|
||||
box-shadow: 0 8px 24px rgba(139, 69, 199, 0.15);
|
||||
}
|
||||
|
||||
.glass-sidebar {
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
backdrop-filter: blur(20px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.12);
|
||||
box-shadow:
|
||||
0 8px 32px rgba(168, 85, 247, 0.15),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
/* Обеспечиваем курсор pointer для всех кликабельных элементов */
|
||||
button, [role="button"], [data-state] {
|
||||
cursor: pointer;
|
||||
|
Reference in New Issue
Block a user