'use client'; import { useEffect, useState } from 'react'; import Link from 'next/link'; import { useParams } from 'next/navigation'; import { ArrowLeft, ShieldCheck, Trophy, ExternalLink, Copy, Check, Calendar, RefreshCw, CheckCircle2, AlertTriangle } from 'lucide-react'; import { StoredGiveaway } from '@/lib/giveaway-store'; export default function GiveawayDetailPage() { const params = useParams(); const id = params?.id as string; const [giveaway, setGiveaway] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [copied, setCopied] = useState(false); const [verifying, setVerifying] = useState(false); const [verificationResult, setVerificationResult] = useState(null); useEffect(() => { if (!id) return; const fetchGw = async () => { try { setLoading(true); const res = await fetch(`/api/giveaways/${id}`); const data = await res.json(); if (!res.ok) throw new Error(data.error || 'Розыгрыш не найден'); setGiveaway(data.giveaway); } catch (err: any) { setError(err.message); } finally { setLoading(false); } }; fetchGw(); }, [id]); const handleVerify = async () => { if (!id) return; try { setVerifying(true); const res = await fetch(`/api/giveaways/${id}/verify`); const data = await res.json(); setVerificationResult(data); } catch (err: any) { alert(err.message); } finally { setVerifying(false); } }; if (loading) { return (
Загрузка данных розыгрыша...
); } if (error || !giveaway) { return (

{error || 'Розыгрыш не найден'}

← Вернуться на главную
); } const drawResult = giveaway.drawResult; return (
{/* Top Header */}
Назад к списку
VKontakte {giveaway.status}
{/* Main Details Card */}

{giveaway.title}

{giveaway.description}

{giveaway.postImageUrl && (
)} {/* Source link */}
Ссылка на запись: {giveaway.sourceUrl}
{/* Draw Result Presentation */} {drawResult && (
Официальные победители
{new Date(drawResult.drawnAt).toLocaleString('ru-RU')}
{drawResult.winners.map((winner) => (
{winner.participant.avatarUrl ? ( ) : ( {winner.participant.firstName[0]} )}
#{winner.position} место

{winner.participant.firstName} {winner.participant.lastName}

id{winner.participant.platformUserId}
))}
{/* Provably Fair Audit Trail */}
Публичный криптографический аудит (Provably Fair)
{/* Live Verification Banner if clicked */} {verificationResult && (
{verificationResult.verified ? ( <> Результат 100% подтвержден и математически доказуем! ) : ( <> Несоответствие верификации! )}
Победители совпали: {verificationResult.winnersMatch ? 'ДА ✓' : 'НЕТ ✗'}
Хеш слепка совпал: {verificationResult.snapshotHashMatch ? 'ДА ✓' : 'НЕТ ✗'}
Хеш условий совпал: {verificationResult.conditionsHashMatch ? 'ДА ✓' : 'НЕТ ✗'}
Proof Hash совпал: {verificationResult.deterministicProofHashMatch ? 'ДА ✓' : 'НЕТ ✗'}
)}
Snapshot ID:

{drawResult.snapshotId}

Алгоритм:

{drawResult.algorithmVersion}

Seed:

{drawResult.seedUsed}

Snapshot Hash:

{drawResult.participantsSnapshotHash}

deterministicProofHash (воспроизводимый):

{drawResult.deterministicProofHash}

auditEventHash (уникальный для события):

{drawResult.auditEventHash}

)}
); }