Commit Graph

1318 Commits

Author SHA1 Message Date
Fringg
d0be127d30 feat: add sub-options UI for landing payment methods + extract components
Add interactive sub-option toggles (Card/SBP/Crypto) to the landing editor
payment method configuration. Extract SortableFeatureItem and
SortableSelectedMethodCard into dedicated component files to reduce
AdminLandingEditor from ~1160 to ~860 lines.
2026-03-06 23:30:53 +03:00
Fringg
b9f1f59e3c fix: show total purchase count instead of paid on admin landings 2026-03-06 22:16:41 +03:00
Fringg
d228d997d8 feat: guest purchase cabinet credentials UI
- CabinetCredentialsState with copyable email/password fields
- Auto-login via JWT token with checkAdminStatus
- /auto-login route with ErrorBoundary and no-referrer meta
- Narrowed contact_type to 'email' | 'telegram' | null
- Disabled button styling for PendingActivation go-to-cabinet
- i18n: added landing.copy key to all 4 locales
2026-03-06 21:59:59 +03:00
Fringg
b852e1e4cd feat: guest purchase activation UI & landing editor improvements
- Add PendingActivationState component with activate button
- Add double-click ref guard on activation handler
- Add activatePurchase API function
- Update PurchaseStatus type with new fields
- Show gift message and recipient contact in success state
- Add pending activation i18n translations (ru, en, zh, fa)
- Improve AdminLandingEditor with allowed_periods support
2026-03-06 19:56:38 +03:00
Fringg
9bd58cb914 fix: handle Pydantic validation errors in notify + nullify empty optional fields
- getApiErrorMessage now formats Pydantic [{loc, msg}] arrays as readable strings
- LandingPaymentMethod description/icon_url nullable
- Send null instead of empty string for optional payment method fields
2026-03-06 18:03:27 +03:00
Fringg
6755c1dc45 fix: landing list crash — title is now LocaleDict, not string
- Update LandingListItem.title type to LocaleDict
- Add resolveLocaleDisplay() helper for extracting display string
- Use resolveLocaleDisplay() in landing list and delete confirm
2026-03-06 17:00:05 +03:00
Fringg
6a92814ce2 fix: admin landing editor — tariff period mapping and cleanup
- Use data.id instead of positional index for tariffPeriodsMap
- Clean up allowedPeriods when tariff is unchecked
- Filter out empty period arrays and orphaned tariff keys on submit
2026-03-06 16:55:13 +03:00
Fringg
ab13616b0f feat: мультиязычные лендинги + переключатель языка + исправления по ревью
Мультиязычность:
- LanguageSwitcher на публичной странице покупки
- Вкладки локалей в админ-редакторе (ru/en/zh/fa)
- LocaleTabs и LocalizedInput компоненты
- Типы: LocaleDict, AdminLandingFeature, toLocaleDict хелпер
- ?lang= параметр при запросе конфига лендинга

Исправления по ревью:
- contentIndicators включает все локализуемые поля
- LocaleTabs вынесен над секциями аккордеона
- text-left → text-start для RTL
- nonEmptyDict: защита от undefined
- featureIds/methodIds обёрнуты в useMemo
- toggleSection/updateFeature* обёрнуты в useCallback
- formatPrice вынесен в shared utils/format.ts
- RTL через LOCALE_META.rtl вместо хардкода
- Переводы zh/fa для валидации и landing
- Variable shadowing: t → tariff
2026-03-06 16:11:58 +03:00
firewookie
ea374d6805 - RioPay payment system integration 2026-03-06 11:44:22 +05:00
firewookie
fd84df0020 - Карточки "Бонус новому пользователю" и "Бонус пригласившему"
скрыты когда значение = 0
- Динамический grid-cols в зависимости от количества видимых карточек
- Добавлено поле max_commission_payments в тип ReferralTerms
- Уведомления бота: строки с бонусом нового пользователя и бонусом
    пригласившего скрываются если соответствующие настройки = 0
- Раздел "Как работают награды": карточки бонусов скрыты при значении 0
- Invite message: строка про бонус за первое пополнение скрыта при 0
- Текст комиссии: "с каждого пополнения" при без лимита,
    "с пополнений" при наличии REFERRAL_MAX_COMMISSION_PAYMENTS- API /terms: добавлено поле max_commission_payments
- Добавлен ключ локали REFERRAL_REWARD_COMMISSION_LIMITED (ru/en/ua/zh/fa)
2026-03-06 11:08:52 +05:00
firewookie
8063ec5014 фикс отправки письма на почту из авторизованного кабинета 2026-03-06 10:17:39 +05:00
firewookie
1b3e884a5d vite config fix 2026-03-06 09:50:10 +05:00
firewookie
00a013f02b - Интеграция рекурентов от Юкассы
- Багфикс личного кабинета
2026-03-06 09:47:58 +05:00
Fringg
e01c9f5143 fix: админ-редактор — системные методы оплаты, реальные периоды тарифов, фильтрация на публичной странице
- Способы оплаты: загрузка из системного API вместо ручного ввода, toggleable чекбоксы
- Периоды тарифов: загрузка из period_prices через useQueries вместо произвольного ввода
- Публичная страница: глобальный список периодов, скрытие тарифов без цены для выбранного периода
- Локализация: добавлены ключи для 4 языков (ru/en/zh/fa)
2026-03-06 07:33:19 +03:00
Fringg
3cea48235f fix: безопасность и UX лендингов — 16 исправлений
- CRITICAL: усиленная CSS-санитизация (escape-последовательности, at-rules)
- CRITICAL: очистка setTimeout при unmount
- HIGH: useMutation для создания покупки (вместо ручного fetch)
- HIGH: DOMPurify + rel="noopener noreferrer" на ссылках
- HIGH: ErrorBoundary для публичных страниц покупки
- MEDIUM: стабильные UUID для DnD элементов
- MEDIUM: race condition в delete timeout
- MEDIUM: клиентская валидация формы лендинга
- MEDIUM: staleTime для админ-запросов
- MEDIUM: общая утилита getApiErrorMessage
- MEDIUM: уведомление о таймауте поллинга
- LOW: ARIA роли для radio-карточек и форм
- LOW: дедупликация иконок в LandingIcons.tsx
- LOW: cn() вместо template literals
2026-03-06 07:23:11 +03:00
Fringg
8b5d777f0a feat: публичные лендинг-страницы для быстрой покупки VPN-подписок
- QuickPurchase: публичная страница покупки с выбором тарифа/периода/оплаты
- PurchaseSuccess: статус покупки с поллингом и копированием ссылки
- AdminLandings: управление лендингами (создание, сортировка, удаление)
- AdminLandingEditor: полнофункциональный редактор лендинга
- API-клиент landings.ts для всех эндпоинтов
- Роутинг /buy/:slug и /buy/success/:token
- Локализация ru/en/zh/fa для всех текстов лендинга
- Санитизация HTML/CSS, rate limit защита, DOMPurify
2026-03-06 07:02:21 +03:00
Egor
52248e7715 Merge pull request #250 from BEDOLAGA-DEV/release-please--branches--main--components--cabinet-frontend
chore(main): release 1.24.0
2026-03-05 11:35:39 +03:00
github-actions[bot]
6841738c29 chore(main): release 1.24.0 2026-03-05 08:32:54 +00:00
Egor
53db628052 Merge pull request #249 from BEDOLAGA-DEV/dev
Dev
2026-03-05 11:32:16 +03:00
Fringg
e278fec506 feat: кликабельные имена пользователей в последних платежах
Имена в блоке "Последние платежи" теперь ведут на профиль
пользователя /admin/users/:id (десктоп и мобильная версия).
2026-03-05 11:16:55 +03:00
Fringg
86f75f25a7 fix: заменить Tailwind green/emerald классы на success из темы
Замена green-*/emerald-* на success-* в 8 файлах:
AdminPolicyEdit, AdminBroadcastDetail, AdminAuditLog, ButtonsTab,
VerifyEmail, BackgroundEditor, AdminPolicies, AdminUpdates
2026-03-05 10:56:59 +03:00
Fringg
d526d095de fix: заменить хардкодный зелёный (#3EDBB0) на акцентный цвет из темы
Все вхождения #3EDBB0, #2BC49A и rgba(62,219,176,...) заменены на
CSS-переменные --color-accent-400/500 из системы тем.

Затронутые компоненты:
- TrialOfferCard: кнопка, бордер, свечение, иконка
- Subscription: лейблы, иконки, кнопки паузы/копирования
- SubscriptionCardActive: бордер карточки, бейдж статуса
- SubscriptionPurchase: градиент триал-блока
- PurchaseCTAButton: градиент кнопки, иконка
- TrafficProgressBar: цвета прогресс-бара
- StatsGrid: убрана зависимость от useTrafficZone, используется accent напрямую
- trafficZone.ts: добавлены mainVar/mainVarRaw для CSS-переменных
- tailwind.config.js: trialGlow keyframes на accent цвет
2026-03-05 10:56:45 +03:00
Fringg
262303d623 feat: add sales_stats RBAC permission section to frontend
- Update route guard and menu item to use sales_stats:read
- Add sales_stats:read to marketer preset
- Add i18n translations for sales_stats section (ru, en, fa, zh)
2026-03-05 05:46:07 +03:00
Fringg
2fc0759f89 feat: account merge flow — merge redirect, error handling, server-complete linking
- Добавлен merge_required + merge_token redirect в OAuthCallback и LinkTelegramCallback
- Server-complete OAuth linking для Mini App (внешний браузер)
- getErrorDetail: единый экстрактор ошибок из axios response
- LinkTelegramCallback: типизированный catch с getErrorDetail
- Удалён мёртвый экспорт getAndClearOAuthState
- CSRF валидация для Telegram и OAuth linking flows
- Типы ServerCompleteResponse, LinkCallbackResponse
2026-03-05 05:25:50 +03:00
Fringg
0d99ea0069 refactor: review round 2 — remove dead code, fix type safety, improve UX
- Remove LinkOAuthCallback.tsx (dead code) and its route from App.tsx
- Move LINK_OAUTH_* constants to OAuthCallback.tsx
- Replace local ServerLinkResult with LinkCallbackResponse from types
- Move merge navigate() from render body to useEffect
- Track errorMode to show correct CTA (Return to Telegram vs Back to Login)
- Remove non-null assertions with proper narrowing
- Extract getErrorDetail helper for error casting
- Add smart polling success detection (stop + toast when linked count increases)
2026-03-05 03:10:22 +03:00
Fringg
da1926f0e1 fix: review findings — polling fallback, sessionStorage cleanup, UX
- Add 5s polling for 90s after opening external browser link (Mini App)
- Show info toast "Continue in browser" when opening external OAuth
- Fix premature sessionStorage cleanup: peek-then-clear pattern
- Use useIsTelegram() hook instead of direct isInTelegramWebApp()
- Add continueInBrowser i18n key (ru, en, zh, fa)
2026-03-05 02:33:33 +03:00
Fringg
7c30a1eab6 feat: open OAuth linking in external browser from Telegram Mini App
- Rewrite OAuthCallback.tsx to handle 3 modes: login, link-browser,
  and link-server (external browser without JWT)
- Add linkServerComplete API method (no JWT, auth via state token)
- Update ConnectedAccounts to use platform.openLink() in Mini App
- Add server-complete endpoint to AUTH_ENDPOINTS (skip Bearer token)
- Enable refetchOnWindowFocus for linked-providers query
- Add returnToTelegram/openTelegram i18n keys (ru, en, zh, fa)
2026-03-05 02:24:28 +03:00
Fringg
9b4a8512c2 fix: remove unused linkTelegramWidget i18n key from all locales 2026-03-04 17:21:16 +03:00
Fringg
a6fabb1d9d feat: add Telegram account linking UI with CSRF protection
- TelegramLinkWidget component with Login Widget for browser users
- One-click initData linking for Mini App users
- LinkTelegramCallback page with CSRF state validation
- URL credential clearing via history.replaceState
- Merge flow support with replace navigation
- i18n keys for all 4 locales (ru, en, zh, fa)
2026-03-04 17:03:48 +03:00
Fringg
584f00297b fix: add Referrer-Policy to prevent merge token leakage via Referer header 2026-03-04 16:14:51 +03:00
Fringg
8ad0500cc8 fix: double-click guard on link, wall-clock timer, blur cleanup
- Add linkingProvider state to prevent double-click on Link button
- Use wall-clock based countdown timer to prevent drift
- Clean up onBlur setTimeout ref on unmount
2026-03-04 16:05:24 +03:00
Fringg
fba4481799 fix: move useState before useMutation for consistent hook ordering 2026-03-04 15:57:04 +03:00
Fringg
71198ab18a refactor: extract shared ProviderIcon, fix canUnlink hiding all buttons
- Extract TelegramIcon + EmailIcon to shared ProviderIcon component
- Remove duplicated icons from ConnectedAccounts and MergeAccounts
- Remove isPending from canUnlink (buttons already have disabled prop)
- Add onSettled to reset confirmingUnlink state after mutation
2026-03-04 15:46:53 +03:00
Fringg
3418ba9b8d fix: prevent onBlur race cancelling unlink confirmation
Add 150ms delay before resetting confirmation state so the click
event fires before blur resets it.
2026-03-04 15:35:45 +03:00
Fringg
d0c01a0e5c fix: replace window.confirm with inline confirmation for unlink
window.confirm() is silently suppressed in Telegram Mini Apps and iOS
WebView, making unlink completely non-functional on mobile. Replaced
with two-click inline confirmation: first click shows destructive
"Confirm disconnect?" button, second click executes unlink. Button
resets on blur.
2026-03-04 15:30:00 +03:00
Fringg
e447e993cb fix: accessibility, query cache clear, post-merge navigation
- Add aria-hidden="true" to all decorative SVGs (TelegramIcon, EmailIcon
  in MergeAccounts + ConnectedAccounts, all 4 OAuthProviderIcon SVGs)
- Add role="radiogroup" with aria-label to subscription choice container
- Clear react-query cache after merge to prevent stale data
- Wrap checkAdminStatus() in try-catch to prevent throw after token set
- Navigate to /profile/accounts after merge instead of /
- Import useQueryClient for cache management
2026-03-04 15:02:08 +03:00
Fringg
579f47e563 fix(merge): accessibility, token guard, state cleanup
- Add role="radio" + aria-checked to subscription radio buttons
- Add aria-hidden="true" to decorative SVG icons
- Treat success=true with null tokens as error (show error toast)
- Guard auto-select useEffect from overwriting user's manual choice
- Clear sessionStorage on OAuth state validation failure
2026-03-04 08:12:18 +03:00
Fringg
aa26059e00 fix: second round review fixes for merge UI
- Fix false success toast when response.success is false (CRITICAL)
- Remove mergeToken! non-null assertion in queryFn
- Add early return for missing mergeToken param
- Zero-pad minutes in formatCountdown (MM:SS format)
- Clamp negative seconds in formatCountdown
- Block all unlink buttons while any unlink mutation is pending
- Clear OAuth state only after validation succeeds (not before)
- Split getAndClearLinkOAuthState into read + clear functions
2026-03-04 07:56:19 +03:00
Fringg
58cf1e3b50 fix: harden merge UI and improve error handling
- MergeAccounts: guard mutationFn against null token/userId
- MergeAccounts: call checkAdminStatus after successful merge
- MergeAccounts: add fallback when success but tokens null
- MergeAccounts: fix ErrorState showing "expired" for all errors
- MergeAccounts: fix formatCountdown dead ternary and hardcoded English
- MergeAccounts: add staleTime/refetchOnWindowFocus to preview query
- MergeAccounts: remove manual useCallback (React Compiler handles it)
- LinkOAuthCallback: add toast feedback on all error/success paths
- ConnectedAccounts: use invalidateQueries instead of refetch
- ConnectedAccounts: add error state rendering
- ConnectedAccounts/LinkOAuthCallback: share sessionStorage key constants
- i18n: add missing profile.accounts.linking key to zh and fa locales
2026-03-04 07:47:36 +03:00
Fringg
93f97d45be feat: account linking and merge UI for cabinet
Add Connected Accounts page (link/unlink OAuth providers), Link OAuth
Callback handler, and Merge Accounts page with subscription comparison
and user choice. Includes API methods, TypeScript types, routes in
App.tsx, navigation from Profile, and i18n for all 4 locales (ru, en,
zh, fa). Merge page works without JWT auth (validated by merge token).
2026-03-04 07:25:45 +03:00
Egor
126443f194 Merge pull request #247 from BEDOLAGA-DEV/release-please--branches--main--components--cabinet-frontend
chore(main): release 1.23.1
2026-03-04 06:15:08 +03:00
github-actions[bot]
7e190543dd chore(main): release 1.23.1 2026-03-04 03:14:28 +00:00
Egor
4359202f76 Merge pull request #246 from BEDOLAGA-DEV/dev
Dev
2026-03-04 06:14:06 +03:00
Fringg
8157ca5f02 fix: ordered list numbering in Info page shows correct sequence
Each numbered rule (1, 2, 3...) was rendered as separate <ol> elements
all starting from 1. Added start attribute to preserve original numbering
and allowed it through DOMPurify sanitization.
2026-03-04 04:49:40 +03:00
Fringg
a3ddddfa8c fix: replace hardcoded green with theme-aware accent color
Normal traffic zone now uses configurable accent palette instead of
hardcoded success/green. Added useTrafficZone hook that resolves
mainHex dynamically from theme colors. Replaced emerald/teal classes
with success palette in SuccessNotificationModal. Fixed hardcoded
green hex values in Subscription and SubscriptionPurchase pages.
2026-03-04 02:50:28 +03:00
Egor
f74a67037b Merge pull request #244 from BEDOLAGA-DEV/release-please--branches--main--components--cabinet-frontend
chore(main): release 1.23.0
2026-03-02 22:27:47 +03:00
github-actions[bot]
c6dd2f5484 chore(main): release 1.23.0 2026-03-02 19:27:27 +00:00
Egor
a1dc5744f6 Merge pull request #243 from BEDOLAGA-DEV/dev
Dev
2026-03-02 22:26:41 +03:00
Fringg
f652936d78 fix: tile noise texture instead of stretching on large screens
Add background-size: 200px and background-repeat: repeat so the SVG
noise pattern tiles at its native resolution instead of stretching
across the entire viewport on high-res displays.
2026-03-02 22:22:00 +03:00
Fringg
f012710df0 feat: add daily deposits by payment method chart
Add MultiSeriesAreaChart showing daily deposit amounts per payment
method with human-readable labels and currency formatting. Memoize
all derived data before early returns for React Compiler compat.
2026-03-02 22:08:16 +03:00