From e94d81fe5a25341172bb787146fd80d70067a140 Mon Sep 17 00:00:00 2001 From: Fringg Date: Fri, 27 Feb 2026 04:02:27 +0300 Subject: [PATCH] fix: partner system bugs - commission field, withdrawal UX, admin amount 1. Add desired commission percent field to partner application form and admin review page (Bug 1) 2. Add prominent "Requested Amount" row in admin withdrawal detail (Bug 2) 3. Switch withdrawal input from kopecks to rubles with auto-conversion on submit (Bug 3) Includes i18n updates for all 4 locales (ru, en, zh, fa). --- src/api/partners.ts | 3 +++ src/locales/en.json | 14 ++++++++----- src/locales/fa.json | 14 ++++++++----- src/locales/ru.json | 14 ++++++++----- src/locales/zh.json | 14 ++++++++----- src/pages/AdminApplicationReview.tsx | 8 +++++++ src/pages/AdminWithdrawalDetail.tsx | 8 +++++++ src/pages/ReferralPartnerApply.tsx | 23 ++++++++++++++++++++ src/pages/ReferralWithdrawalRequest.tsx | 28 ++++++++++++++----------- 9 files changed, 94 insertions(+), 32 deletions(-) diff --git a/src/api/partners.ts b/src/api/partners.ts index 007474f..9cfa82b 100644 --- a/src/api/partners.ts +++ b/src/api/partners.ts @@ -10,6 +10,7 @@ export interface PartnerApplicationInfo { telegram_channel: string | null; description: string | null; expected_monthly_referrals: number | null; + desired_commission_percent: number | null; admin_comment: string | null; approved_commission_percent: number | null; created_at: string; @@ -41,6 +42,7 @@ export interface PartnerApplicationRequest { telegram_channel?: string; description?: string; expected_monthly_referrals?: number; + desired_commission_percent?: number; } // ==================== Admin-facing types ==================== @@ -56,6 +58,7 @@ export interface AdminPartnerApplicationItem { telegram_channel: string | null; description: string | null; expected_monthly_referrals: number | null; + desired_commission_percent: number | null; status: string; admin_comment: string | null; approved_commission_percent: number | null; diff --git a/src/locales/en.json b/src/locales/en.json index 66840dd..105f662 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -755,7 +755,9 @@ "description": "Description", "descriptionPlaceholder": "Tell us about your audience and how you plan to promote...", "expectedReferrals": "Expected Monthly Referrals", - "expectedReferralsPlaceholder": "Estimated number per month" + "expectedReferralsPlaceholder": "Estimated number per month", + "desiredCommission": "Desired Commission (%)", + "desiredCommissionPlaceholder": "From 1 to 100%" } }, "withdrawal": { @@ -776,9 +778,9 @@ "submitRequest": "Submit Request", "requestError": "Failed to create withdrawal request. Please try again.", "fields": { - "amount": "Amount (kopeks)", - "amountPlaceholder": "Enter amount in kopeks", - "amountHint": "Enter the amount in kopeks (100 kopeks = 1 {{currency}})", + "amount": "Amount", + "amountPlaceholder": "Enter amount in {{currency}}", + "amountHint": "Minimum: {{min}} {{currency}}", "paymentDetails": "Payment Details", "paymentDetailsPlaceholder": "Card number, wallet address, or other payment info..." }, @@ -2046,6 +2048,7 @@ "balance": "Balance", "totalReferrals": "Total referrals", "totalEarnings": "Total earnings", + "requestedAmount": "Requested Amount", "createdAt": "Created", "paymentDetails": "Payment Details", "noPaymentDetails": "No payment details provided", @@ -2101,7 +2104,8 @@ "website": "Website", "channel": "Channel", "description": "Description", - "expectedReferrals": "Expected referrals/mo" + "expectedReferrals": "Expected referrals/mo", + "desiredCommission": "Desired commission" }, "approveDialog": { "title": "Approve Application", diff --git a/src/locales/fa.json b/src/locales/fa.json index ea719c6..25e5cf4 100644 --- a/src/locales/fa.json +++ b/src/locales/fa.json @@ -594,7 +594,9 @@ "description": "توضیحات", "descriptionPlaceholder": "درباره مخاطبان خود و نحوه تبلیغ بگویید...", "expectedReferrals": "تعداد معرفی ماهانه مورد انتظار", - "expectedReferralsPlaceholder": "تعداد تخمینی در ماه" + "expectedReferralsPlaceholder": "تعداد تخمینی در ماه", + "desiredCommission": "درصد کمیسیون مورد نظر", + "desiredCommissionPlaceholder": "از ۱ تا ۱۰۰٪" } }, "withdrawal": { @@ -615,9 +617,9 @@ "submitRequest": "ارسال درخواست", "requestError": "ایجاد درخواست برداشت ناموفق بود. لطفاً دوباره تلاش کنید.", "fields": { - "amount": "مبلغ (کوپک)", - "amountPlaceholder": "مبلغ را به کوپک وارد کنید", - "amountHint": "مبلغ را به کوپک وارد کنید (۱۰۰ کوپک = ۱ {{currency}})", + "amount": "مبلغ", + "amountPlaceholder": "مبلغ را وارد کنید", + "amountHint": "حداقل: {{min}} {{currency}}", "paymentDetails": "اطلاعات پرداخت", "paymentDetailsPlaceholder": "شماره کارت، آدرس کیف پول یا سایر اطلاعات پرداخت..." }, @@ -1729,6 +1731,7 @@ "balance": "موجودی", "totalReferrals": "مجموع معرفی‌ها", "totalEarnings": "مجموع درآمد", + "requestedAmount": "مبلغ درخواستی", "createdAt": "تاریخ ایجاد", "paymentDetails": "اطلاعات پرداخت", "noPaymentDetails": "اطلاعات پرداختی ارائه نشده", @@ -1784,7 +1787,8 @@ "website": "وب‌سایت", "channel": "کانال", "description": "توضیحات", - "expectedReferrals": "معرفی مورد انتظار/ماه" + "expectedReferrals": "معرفی مورد انتظار/ماه", + "desiredCommission": "کمیسیون مورد نظر" }, "approveDialog": { "title": "تأیید درخواست", diff --git a/src/locales/ru.json b/src/locales/ru.json index c5bae48..d6d06d0 100644 --- a/src/locales/ru.json +++ b/src/locales/ru.json @@ -783,7 +783,9 @@ "description": "Описание", "descriptionPlaceholder": "Расскажите о вашей аудитории и планах продвижения...", "expectedReferrals": "Ожидаемое количество рефералов в месяц", - "expectedReferralsPlaceholder": "Примерное количество в месяц" + "expectedReferralsPlaceholder": "Примерное количество в месяц", + "desiredCommission": "Желаемый процент комиссии", + "desiredCommissionPlaceholder": "От 1 до 100%" } }, "withdrawal": { @@ -804,9 +806,9 @@ "submitRequest": "Отправить запрос", "requestError": "Не удалось создать запрос на вывод. Попробуйте снова.", "fields": { - "amount": "Сумма (копейки)", - "amountPlaceholder": "Введите сумму в копейках", - "amountHint": "Введите сумму в копейках (100 копеек = 1 {{currency}})", + "amount": "Сумма", + "amountPlaceholder": "Введите сумму в {{currency}}", + "amountHint": "Минимум: {{min}} {{currency}}", "paymentDetails": "Реквизиты для оплаты", "paymentDetailsPlaceholder": "Номер карты, адрес кошелька или другие реквизиты..." }, @@ -2567,6 +2569,7 @@ "balance": "Баланс", "totalReferrals": "Всего рефералов", "totalEarnings": "Общий заработок", + "requestedAmount": "Запрошенная сумма", "createdAt": "Создано", "paymentDetails": "Реквизиты для оплаты", "noPaymentDetails": "Реквизиты не указаны", @@ -2622,7 +2625,8 @@ "website": "Сайт", "channel": "Канал", "description": "Описание", - "expectedReferrals": "Ожидаемых рефералов/мес" + "expectedReferrals": "Ожидаемых рефералов/мес", + "desiredCommission": "Желаемая комиссия" }, "approveDialog": { "title": "Одобрить заявку", diff --git a/src/locales/zh.json b/src/locales/zh.json index a3dab1f..122b6ae 100644 --- a/src/locales/zh.json +++ b/src/locales/zh.json @@ -594,7 +594,9 @@ "description": "描述", "descriptionPlaceholder": "请介绍您的受众以及推广计划...", "expectedReferrals": "预计每月推荐数", - "expectedReferralsPlaceholder": "每月预估数量" + "expectedReferralsPlaceholder": "每月预估数量", + "desiredCommission": "期望佣金比例 (%)", + "desiredCommissionPlaceholder": "1 到 100%" } }, "withdrawal": { @@ -615,9 +617,9 @@ "submitRequest": "提交请求", "requestError": "创建提现请求失败,请重试。", "fields": { - "amount": "金额(戈比)", - "amountPlaceholder": "输入金额(戈比)", - "amountHint": "请输入戈比金额(100戈比 = 1 {{currency}})", + "amount": "金额", + "amountPlaceholder": "输入金额({{currency}})", + "amountHint": "最低:{{min}} {{currency}}", "paymentDetails": "付款信息", "paymentDetailsPlaceholder": "银行卡号、钱包地址或其他付款信息..." }, @@ -1728,6 +1730,7 @@ "balance": "余额", "totalReferrals": "总推荐数", "totalEarnings": "总收益", + "requestedAmount": "请求金额", "createdAt": "创建时间", "paymentDetails": "付款信息", "noPaymentDetails": "未提供付款信息", @@ -1783,7 +1786,8 @@ "website": "网站", "channel": "频道", "description": "描述", - "expectedReferrals": "预计每月推荐数" + "expectedReferrals": "预计每月推荐数", + "desiredCommission": "期望佣金" }, "approveDialog": { "title": "批准申请", diff --git a/src/pages/AdminApplicationReview.tsx b/src/pages/AdminApplicationReview.tsx index 35f83e5..fdcc93b 100644 --- a/src/pages/AdminApplicationReview.tsx +++ b/src/pages/AdminApplicationReview.tsx @@ -136,6 +136,14 @@ export default function AdminApplicationReview() { {app.expected_monthly_referrals} )} + {app.desired_commission_percent != null && ( +
+ + {t('admin.partners.applicationFields.desiredCommission')}: + {' '} + {app.desired_commission_percent}% +
+ )} diff --git a/src/pages/AdminWithdrawalDetail.tsx b/src/pages/AdminWithdrawalDetail.tsx index d243bbb..6dbb260 100644 --- a/src/pages/AdminWithdrawalDetail.tsx +++ b/src/pages/AdminWithdrawalDetail.tsx @@ -126,6 +126,14 @@ export default function AdminWithdrawalDetail() {

{t('admin.withdrawals.detail.userInfo')}

+
+
+ {t('admin.withdrawals.detail.requestedAmount')} +
+
+ {formatWithCurrency(detail.amount_kopeks / 100, 0)} +
+
diff --git a/src/pages/ReferralPartnerApply.tsx b/src/pages/ReferralPartnerApply.tsx index 9638c04..766e063 100644 --- a/src/pages/ReferralPartnerApply.tsx +++ b/src/pages/ReferralPartnerApply.tsx @@ -15,6 +15,7 @@ export default function ReferralPartnerApply() { telegram_channel: '', description: '', expected_monthly_referrals: undefined, + desired_commission_percent: undefined, }); // Guard: redirect if already approved or pending @@ -50,6 +51,9 @@ export default function ReferralPartnerApply() { if (form.expected_monthly_referrals) { payload.expected_monthly_referrals = form.expected_monthly_referrals; } + if (form.desired_commission_percent) { + payload.desired_commission_percent = form.desired_commission_percent; + } applyMutation.mutate(payload); }; @@ -126,6 +130,25 @@ export default function ReferralPartnerApply() { placeholder={t('referral.partner.fields.expectedReferralsPlaceholder')} />
+
+ + + setForm({ + ...form, + desired_commission_percent: e.target.value ? Number(e.target.value) : undefined, + }) + } + placeholder={t('referral.partner.fields.desiredCommissionPlaceholder')} + /> +
{applyMutation.isError && ( diff --git a/src/pages/ReferralWithdrawalRequest.tsx b/src/pages/ReferralWithdrawalRequest.tsx index 5338812..ac9a75a 100644 --- a/src/pages/ReferralWithdrawalRequest.tsx +++ b/src/pages/ReferralWithdrawalRequest.tsx @@ -12,7 +12,7 @@ export default function ReferralWithdrawalRequest() { const { formatWithCurrency, currencySymbol } = useCurrency(); const [form, setForm] = useState({ - amount_kopeks: 0, + amount_rubles: 0, payment_details: '', }); @@ -40,9 +40,9 @@ export default function ReferralWithdrawalRequest() { const handleSubmit = (e: FormEvent) => { e.preventDefault(); if (form.payment_details.length < 5) return; - if (form.amount_kopeks <= 0) return; + if (form.amount_rubles <= 0) return; withdrawMutation.mutate({ - amount_kopeks: form.amount_kopeks, + amount_kopeks: form.amount_rubles * 100, payment_details: form.payment_details, }); }; @@ -64,21 +64,25 @@ export default function ReferralWithdrawalRequest() { setForm({ ...form, - amount_kopeks: e.target.value ? Number(e.target.value) : 0, + amount_rubles: e.target.value ? Number(e.target.value) : 0, }) } - placeholder={t('referral.withdrawal.fields.amountPlaceholder')} + placeholder={t('referral.withdrawal.fields.amountPlaceholder', { + currency: currencySymbol, + })} />

- {t('referral.withdrawal.fields.amountHint', { currency: currencySymbol })} + {t('referral.withdrawal.fields.amountHint', { + min: balance ? Math.ceil(balance.min_amount_kopeks / 100) : 0, + currency: currencySymbol, + })}

@@ -115,12 +119,12 @@ export default function ReferralWithdrawalRequest() { disabled={ withdrawMutation.isPending || form.payment_details.length < 5 || - form.amount_kopeks <= 0 + form.amount_rubles <= 0 } className={`btn-primary flex-1 px-5 ${ withdrawMutation.isPending || form.payment_details.length < 5 || - form.amount_kopeks <= 0 + form.amount_rubles <= 0 ? 'opacity-50' : '' }`}