import React, { useEffect, useMemo, useState } from 'react'; import { Link, useLocation, useNavigate } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; import toast from 'react-hot-toast'; import { createSubDistributorOrder, getSubDistributorInfo } from '../api'; import { useAuth } from '../context/AuthContext'; import { useSite, useCurrency } from '../context/SiteContext'; function submitEpayForm(resData) { const params = resData.data; const url = resData.url; if (!params || !url) return false; const form = document.createElement('form'); form.action = url; form.method = 'POST'; const isSafari = navigator.userAgent.indexOf('Safari') > -1 && navigator.userAgent.indexOf('Chrome') < 1; if (!isSafari) { form.target = '_blank'; } Object.keys(params).forEach((key) => { const input = document.createElement('input'); input.type = 'hidden'; input.name = key; input.value = params[key]; form.appendChild(input); }); document.body.appendChild(form); form.submit(); document.body.removeChild(form); return true; } export default function SubDistributor() { const { t } = useTranslation(); const { user, refreshUser, loading: authLoading } = useAuth(); const { site } = useSite(); const { symbol, fmtCNY } = useCurrency(); const location = useLocation(); const navigate = useNavigate(); const [loading, setLoading] = useState(true); const [subInfo, setSubInfo] = useState(null); const [submitting, setSubmitting] = useState(false); const [cryptoOrder, setCryptoOrder] = useState(null); const [form, setForm] = useState({ name: '', slug: '', payment_method: '', chain: 'tron', token: 'usdt', }); useEffect(() => { getSubDistributorInfo() .then((res) => { if (res.data.success) { const info = res.data.data; setSubInfo(info); if (info.pay_methods?.length > 0) { setForm((prev) => ({ ...prev, payment_method: info.pay_methods[0].type })); } } }) .catch(() => {}) .finally(() => setLoading(false)); }, []); const paymentMethods = subInfo?.pay_methods || []; const currentPayMethod = useMemo( () => paymentMethods.find((item) => item.type === form.payment_method), [paymentMethods, form.payment_method] ); const paymentReturned = useMemo( () => new URLSearchParams(location.search).get('payment') === 'return', [location.search] ); useEffect(() => { if (!paymentReturned || authLoading) return; let cancelled = false; const toastId = 'sub-dist-payment-return'; const checkPaymentResult = async () => { if (!user) { toast(t('subDist.paymentPending'), { id: toastId }); navigate('/sub-site', { replace: true }); return; } toast.loading(t('subDist.confirmingPayment'), { id: toastId }); const refreshed = await refreshUser({ skipErrorHandler: true }); if (cancelled) return; if (refreshed?.has_distributor) { toast.success(t('subDist.openedSuccess'), { id: toastId }); } else { toast(t('subDist.paymentPending'), { id: toastId }); } navigate('/sub-site', { replace: true }); }; checkPaymentResult(); return () => { cancelled = true; }; }, [authLoading, navigate, paymentReturned, refreshUser, t, user]); const handleSubmit = async (e) => { e.preventDefault(); if (!user) { toast.error(t('subDist.loginRequired')); return; } if (!form.name.trim() || !form.slug.trim()) { toast.error(t('subDist.fillRequired')); return; } if (!form.payment_method) { toast.error(t('subDist.selectPayment')); return; } setSubmitting(true); setCryptoOrder(null); try { const payload = { name: form.name.trim(), slug: form.slug.trim().toLowerCase(), payment_method: form.payment_method, return_url: `${window.location.origin}/sub-site?payment=return`, }; if (form.payment_method === 'crypto') { payload.chain = form.chain; payload.token = form.token; } const res = await createSubDistributorOrder(payload); if (res.data.message === 'success') { if (res.data.payment_type === 'stripe' && res.data.data?.pay_link) { const opened = window.open(res.data.data.pay_link, '_blank'); if (opened) { toast.success(t('subDist.paymentPageOpened')); } else { toast.error(t('subDist.popupBlocked')); } } else if (res.data.payment_type === 'crypto') { setCryptoOrder(res.data.data); toast.success(t('subDist.cryptoOrderCreated')); } else { if (submitEpayForm(res.data)) { toast.success(t('subDist.paymentPageOpened')); } else { toast.error(t('subDist.paymentPageFailed')); } } } else if (res.data.data) { toast.error(typeof res.data.data === 'string' ? res.data.data : t('subDist.createFailed')); } else { toast.error(t('subDist.createFailed')); } } catch (e) { // handled by interceptor } setSubmitting(false); }; if (loading) { return (
); } return (

{t('subDist.badge')}

{t('subDist.title')}

{t('subDist.subtitle', { name: site?.name || t('subDist.defaultSiteName') })}

{!subInfo?.enabled ? (

{t('subDist.notAvailable')}

{subInfo?.disabled_reason || t('subDist.disabledFallback')}

) : !user ? (

{t('subDist.loginHint')}

{t('subDist.goLogin')} {t('subDist.goRegister')}
) : user?.has_distributor ? (

{t('subDist.alreadyOpenTitle')}

{t('subDist.alreadyOpenDesc', { name: user.distributor_name || user.distributor_slug || t('subDist.defaultSiteName'), })}

) : (
setForm({ ...form, name: e.target.value })} className="input" placeholder={t('subDist.siteNamePlaceholder')} required />
setForm({ ...form, slug: e.target.value.toLowerCase() })} className="input" placeholder="my-sub-site" required />

{t('subDist.siteSlugHelp')}

{paymentMethods.map((method) => ( ))}
{form.payment_method === 'crypto' && (
)}

{t('subDist.currentUserHint', { user: user.display_name || user.username || 'User', method: currentPayMethod?.name || form.payment_method })}

{t('subDist.postPayHint')}

)} {cryptoOrder && (

{t('subDist.cryptoTitle')}

{t('subDist.cryptoHint')}

{t('subDist.wallet')}: {cryptoOrder.wallet}
{t('subDist.amount')}: {cryptoOrder.amount} {cryptoOrder.token}
{t('subDist.tradeNo')}: {cryptoOrder.trade_no}
)}

{t('subDist.priceCardTitle')}

{t('subDist.openPrice')} {fmtCNY(subInfo?.price || 0)}

{t('subDist.priceSummary')}

{t('subDist.ruleTitle')}

{t('subDist.rule1')}

{t('subDist.rule2')}

{t('subDist.rule3')}

); }