"use client"; import { useState } from "react"; import { useMutation, useQuery } from "@tanstack/react-query"; import "@/components/trade-in/trade-in.css"; import { Topbar } from "@/components/trade-in/Topbar"; import { apiFetch } from "@/lib/api"; interface UploadResponse { ok?: boolean; userId?: number; cookieCount?: number; detail?: string; } interface TestAuthResponse { authenticated: boolean; userId?: number; reason?: string; } interface CookieEditorEntry { name: string; value: string | number | boolean; [key: string]: unknown; } function convertCookiesFormat(input: string): Record { const parsed: unknown = JSON.parse(input.trim()); if (Array.isArray(parsed)) { // Cookie-Editor array format: [{name, value, domain, ...}, ...] return (parsed as CookieEditorEntry[]).reduce>( (acc, c) => { if ( typeof c === "object" && c !== null && "name" in c && "value" in c ) { acc[String(c.name)] = String(c.value); } return acc; }, {}, ); } if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) { // Already a dict: {"name1": "val1", "name2": "val2"} return Object.fromEntries( Object.entries(parsed as Record).map(([k, v]) => [ k, String(v), ]), ); } throw new Error("Expected JSON array or plain object"); } function parsePreview(raw: string): { cookies: Record | null; error: string | null; } { if (!raw.trim()) return { cookies: null, error: null }; try { const cookies = convertCookiesFormat(raw); return { cookies, error: null }; } catch (e) { return { cookies: null, error: e instanceof Error ? e.message : String(e) }; } } export default function CianCookiesPage() { const [rawInput, setRawInput] = useState(""); const [showInstructions, setShowInstructions] = useState(false); const preview = parsePreview(rawInput); const previewKeys = preview.cookies ? Object.keys(preview.cookies) : []; const uploadMutation = useMutation({ mutationFn: () => { if (!preview.cookies) { throw new Error("Invalid JSON — fix the input first"); } return apiFetch( "/api/v1/admin/scrape/cian/upload-cookies", { method: "POST", body: JSON.stringify(preview.cookies), }, ); }, onSuccess: () => setRawInput(""), }); const testAuthQuery = useQuery({ queryKey: ["cian-test-auth"], queryFn: () => apiFetch("/api/v1/admin/scrape/cian/test-auth"), enabled: false, // only on explicit button click retry: false, }); const canUpload = !!preview.cookies && previewKeys.length > 0 && !uploadMutation.isPending; return ( <>

Cian — обновление cookies

Позволяет обновить сессию Cian для скрапера оценщика без перезапуска backend. Endpoints:{" "} POST /api/v1/admin/scrape/cian/upload-cookies ·{" "} GET /api/v1/admin/scrape/cian/test-auth

{/* Instructions collapsible */}
{showInstructions && (
  1. Открой{" "} cian.ru {" "} и войди под нужным аккаунтом.
  2. Установи расширение Cookie-Editor{" "} (Chrome/Firefox) или открой DevTools → Application → Cookies → www.cian.ru.
  3. Cookie-Editor: нажми Export → Export as JSON → скопируй массив{" "} [{"{"}name, value, ...{"}"}].
  4. DevTools (ручной способ): собери объект{" "} {"{"} {'"'}name1{'"'}: {'"'}val1{'"'}, ...{"}"} .
  5. Вставь JSON в поле ниже — формат определится автоматически.
  6. Убедись что preview показывает нужные ключи, затем нажми Upload.
)}
{/* Cookie input */}

Cookie JSON

Вставьте Cookie-Editor array или plain dict. Формат определяется автоматически.