"use client"; import { useEffect, useMemo, useState, useRef } from 'react'; import { Helmet } from '@/lib/helmet'; import { useSearchParams, Link } from '@/lib/router'; import QRCode from 'react-qr-code'; import jsPDF from 'jspdf'; import html2canvas from 'html2canvas'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { api } from '@/lib/api'; import { formatNumberPersian, formatToman, toPersianDigits } from '@/lib/utils'; import Markdown from '@/components/Markdown'; import { siteUrl } from '@/lib/site'; type SavedPayment = { event_id: number; slug?: string; title?: string; thumb?: string | null; base_amount?: number; discount_amount?: number; amount?: number; started_at?: string; success_markdown?: string | null; }; export default function PaymentResult() { const [params] = useSearchParams(); const status = params.get('status'); // success | failed const refId = params.get('ref_id') || ''; const eventId = Number(params.get('event_id') || '0'); const humanEventId = eventId ? formatNumberPersian(eventId) : '—'; const refIdDisplay = refId ? toPersianDigits(refId) : ''; const [fallback, setFallback] = useState(null); // 2) اگر saved نبود و refId هست، از بک‌اند اطلاعات را می‌گیریم (اندپوینت اختیاری by-ref) useEffect(() => { (async () => { if (!refId) return; try { const p = await api.getPaymentByRef(refId); setFallback({ event_id: p.event.id, slug: p.event.slug, title: p.event.title, thumb: p.event.image_url || null, base_amount: p.base_amount, discount_amount: p.discount_amount, amount: p.amount, started_at: p.verified_at || undefined, success_markdown: p.event?.success_markdown }); } catch { // بی‌صدا؛ حداقل status/ref_id نمایش داده می‌شود } })(); }, [refId]); const data = fallback; const ok = status === 'success'; const money = (n?: number) => (typeof n === 'number' && Number.isFinite(n) ? formatToman(n) : '—'); const receiptRef = useRef(null); const successMarkdown = data?.success_markdown ?? ''; const siteName = 'East Guilan CE'; const canonicalUrl = `${siteUrl}/payments/result`; const toAbsoluteUrl = (url?: string | null) => { if (!url) return undefined; if (url.startsWith('http')) return url; const normalizedSite = siteUrl.endsWith('/') ? siteUrl.slice(0, -1) : siteUrl; const normalizedPath = url.startsWith('/') ? url.slice(1) : url; return `${normalizedSite}/${normalizedPath}`; }; const eventTitle = data?.title || (eventId ? `Event #${humanEventId}` : 'Event payment'); const referenceFragment = refId ? ` Reference: ${refIdDisplay}.` : ''; const pageState = status === 'success' ? 'Payment successful' : status === 'failed' ? 'Payment failed' : 'Payment status'; const pageTitle = `${pageState} | ${siteName}`; const pageDescription = `${ok ? 'Payment confirmed' : 'Review your payment status'} for ${eventTitle}.${referenceFragment}`; const ogImage = toAbsoluteUrl(data?.thumb) ?? `${siteUrl}/favicon.ico`; const helmet = ( {pageTitle} ); const renderWithHelmet = (node: JSX.Element) => ( <> {helmet} {node} ); const qrValue = useMemo(() => { // لینک قابل بررسی/اشتراک‌گذاری const base = typeof window !== 'undefined' ? window.location.origin : siteUrl; const url = new URL(`${base}/payments/result`); if (refId) url.searchParams.set('ref_id', refId); if (eventId) url.searchParams.set('event_id', String(eventId)); url.searchParams.set('status', ok ? 'success' : 'failed'); return url.toString(); }, [eventId, ok, refId]); const handleDownloadPdf = async () => { const el = receiptRef.current; if (!el) return; // Force a light snapshot for the PDF const prevBg = el.style.backgroundColor; const prevColor = el.style.color; el.style.backgroundColor = '#ffffff'; el.style.color = '#000000'; try { const canvas = await html2canvas(el, { scale: 2, useCORS: true, backgroundColor: '#ffffff', }); const imgData = canvas.toDataURL('image/png'); const pdf = new jsPDF({ orientation: 'p', unit: 'pt', format: 'a4' }); const pageWidth = pdf.internal.pageSize.getWidth(); const pageHeight = pdf.internal.pageSize.getHeight(); const ratio = Math.min(pageWidth / canvas.width, pageHeight / canvas.height); const imgWidth = canvas.width * ratio; const imgHeight = canvas.height * ratio; const x = (pageWidth - imgWidth) / 2; const y = 24; // (Optional) paint white page background pdf.setFillColor(255, 255, 255); pdf.rect(0, 0, pageWidth, pageHeight, 'F'); pdf.addImage(imgData, 'PNG', x, y, imgWidth, imgHeight); pdf.save(`receipt-${refId || eventId}.pdf`); } finally { // restore colors for on-screen el.style.backgroundColor = prevBg; el.style.color = prevColor; } }; return renderWithHelmet(
نتیجهٔ پرداخت وضعیت تراکنش شما {/* RECEIPT AREA */}
{/* Header (status + ref) */}
{ok ? "پرداخت با موفقیت انجام شد." : "پرداخت ناموفق بود."}
{/* Event + QR */}
{/* Thumb */}
{data?.thumb ? ( {data?.title ) : (
بدون تصویر
)}
{/* Info */}
رویداد
{data?.title || `#${humanEventId}`}
{refId && ( <>
کد پیگیری
{refIdDisplay}
)}
{/* QR */}
{qrValue}
{/* Invoice */}
جزئیات پرداخت
  • مبلغ پایه {money(data?.base_amount)}
  • تخفیف {money(data?.discount_amount)}
  • مبلغ نهایی {money(data?.amount)}
{/* Actions */}
{data?.slug ? ( ) : ( )}
); }