/* eslint-disable @typescript-eslint/no-explicit-any */ import { useState, useEffect } from "react"; import Head from "next/head"; import Image from "next/image"; import PocketBase from "pocketbase"; import { fluxgore, gothampro } from "@/utils/fonts"; const pb = new PocketBase("https://base.mossport.info"); interface FormData { lastName: string; firstName: string; middleName: string; birthDate: string; citizenship: string; phone: string; email: string; carBrand: string; carModel: string; engine: string; power: string; additionalInfo: string; } interface Application { id: string; data: FormData; images: string[]; type: string; status?: string; approved?: boolean; // Add this new field created: string; } function FightApplicationsPage() { const [applications, setApplications] = useState([]); const [selectedImage, setSelectedImage] = useState(null); const [loading, setLoading] = useState(true); const [processingId, setProcessingId] = useState(null); const [isAuthenticated, setIsAuthenticated] = useState(false); const [credentials, setCredentials] = useState({ email: "", password: "" }); const [authError, setAuthError] = useState(""); useEffect(() => { // Проверяем, авторизован ли пользователь if (pb.authStore.isValid) { setIsAuthenticated(true); fetchApplications(); } else { setLoading(false); } }, []); const handleLogin = async (e: React.FormEvent) => { e.preventDefault(); setAuthError(""); try { await pb.admins.authWithPassword(credentials.email, credentials.password); setIsAuthenticated(true); setLoading(true); await fetchApplications(); } catch (error) { console.error("Auth error:", error); setAuthError("Неверный email или пароль"); } }; const handleLogout = () => { pb.authStore.clear(); setIsAuthenticated(false); setApplications([]); }; const fetchApplications = async () => { try { const records = await pb.collection("forms").getFullList({ filter: 'type = "fight" && approved != true', // Updated filter to use boolean field sort: "-created", }); const formattedApplications = records.map((record: any) => ({ id: record.id, data: typeof record.data === "string" ? JSON.parse(record.data) : record.data, images: record.images || [], type: record.type, status: record.status || "pending", approved: record.approved || false, // Include the approved field created: record.created, })); setApplications(formattedApplications); } catch (error) { console.error("Error fetching applications:", error); // Detailed error logging if ( typeof error === "object" && error !== null && "response" in error && typeof (error as any).response === "object" ) { console.error("Response status:", (error as any).response.status); console.error("Response data:", (error as any).response.data); } if (typeof error === "object" && error !== null && "data" in error) { console.error("Error data:", (error as any).data); } // Add more detailed error logging if (typeof error === "object" && error !== null && "data" in error) { console.error("Error details:", (error as any).data); } if (error instanceof Error && error.message.includes("403")) { setAuthError("Недостаточно прав доступа"); handleLogout(); } } finally { setLoading(false); } }; const handleApprove = async (id: string) => { setProcessingId(id); try { await pb.collection("forms").update(id, { status: "approved", approved: true // Set the boolean field }); setApplications((prev) => prev.filter((app) => app.id !== id)); alert("Заявка одобрена!"); } catch (error) { console.error("Error approving application:", error); alert("Ошибка при одобрении заявки"); } finally { setProcessingId(null); } }; const handleReject = async (id: string) => { setProcessingId(id); try { await pb.collection("forms").update(id, { status: "rejected", approved: false // Explicitly set to false }); setApplications((prev) => prev.filter((app) => app.id !== id)); alert("Заявка отклонена!"); } catch (error) { console.error("Error rejecting application:", error); alert("Ошибка при отклонении заявки"); } finally { setProcessingId(null); } }; const getImageUrl = (record: Application, filename: string) => { // Manual URL construction with proper token handling const url = `${pb.baseUrl}/api/files/forms/${record.id}/${filename}`; // Add auth token if available if (pb.authStore.token) { const separator = url.includes("?") ? "&" : "?"; return `${url}${separator}token=${pb.authStore.token}`; } return url; }; // Форма авторизации if (!isAuthenticated) { return (

Панель администратора

Войдите для доступа к заявкам

setCredentials((prev) => ({ ...prev, email: e.target.value, })) } />
setCredentials((prev) => ({ ...prev, password: e.target.value, })) } />
{authError && (
{authError}
)}
); } if (loading) { return (
Загрузка...
); } return (
Заявки на Битву за Москву - Модерация {/* Header */}

Заявки на Битву за Москву

{/* Content */}
{applications.length === 0 ? (

Нет заявок

Пока нет заявок для модерации

) : (
{applications.map((application) => (
{/* Личная информация */}

Личная информация

ФИО: {application.data.lastName}{" "} {application.data.firstName}{" "} {application.data.middleName}
Дата рождения: {application.data.birthDate}
Гражданство: {application.data.citizenship}
Телефон: {application.data.phone}
Email: {application.data.email}
{/* Информация об автомобиле */}

Автомобиль

Марка: {application.data.carBrand}
Модель: {application.data.carModel}
Двигатель: {application.data.engine}
Мощность: {application.data.power}
{application.data.additionalInfo && (
Доп. информация: {application.data.additionalInfo}
)}
{/* Фотографии */} {application.images.length > 0 && (

Фотографии автомобиля ({application.images.length})

{application.images.map((image, index) => { const imageUrl = getImageUrl(application, image); return (
setSelectedImage(imageUrl)} > {`Фото
Увеличить
); })}
)} {/* Дата подачи заявки */}
Заявка подана:{" "} {new Date(application.created).toLocaleString("ru-RU")}
{/* Кнопки действий */}
))}
)}
{/* Улучшенное модальное окно для увеличенного изображения */} {selectedImage && (
setSelectedImage(null)} >
e.stopPropagation()} >
Увеличенное фото { console.error("Modal image failed to load:", selectedImage); setSelectedImage(null); }} />

Нажмите вне изображения или на × чтобы закрыть

)}
); } export default FightApplicationsPage;