Commit Graph

1434 Commits

Author SHA1 Message Date
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
Fringg
2235b3cb77 feat: add daily traffic & device purchase chart to addons stats
Add DualAreaChart to addons tab showing daily traffic purchases vs
device purchases with date-union merge. Add daily_devices field to
AddonsStats type and i18n keys for all 4 locales.
2026-03-02 21:57:18 +03:00
Fringg
4622b4b200 feat: enhance sales stats with device stats, per-tariff charts, and dual-series trials
- Add DualAreaChart component for two-series visualization (registrations vs trials)
- Add MultiSeriesAreaChart component for N-series tariff breakdown with dynamic pivoting
- AddonsTab: add device purchases and device revenue stat cards
- SalesTab: add per-tariff daily sales chart using MultiSeriesAreaChart
- TrialsTab: replace single-series area chart with dual-series registrations + trials chart
- Update TypeScript interfaces to match backend schema changes
- Add i18n keys for all new UI elements across en, ru, zh, fa locales
2026-03-02 21:42:25 +03:00
Fringg
14e5f436ce fix: bar chart white hover cursor on dark theme
Recharts BarChart default tooltip cursor renders a white Rectangle
on hover which washes out the dark theme. Set cursor fill to grid
color with low opacity for a subtle theme-appropriate highlight.
Fixes addons "By package" and deposits "By payment method" charts.
2026-03-02 21:09:36 +03:00
Fringg
a47c222310 feat: add admin sales statistics dashboard with 5 analytics tabs
- Add sales stats API client with typed interfaces for all endpoints
- Implement AdminSalesStats page with summary cards and period selector
- Add TrialsTab with provider breakdown donut chart and daily area chart
- Add SalesTab with tariff/period breakdown and daily revenue chart
- Add RenewalsTab with period comparison and trend indicators
- Add AddonsTab with package breakdown bar chart
- Add DepositsTab with payment method breakdown bar chart
- Add SimpleBarChart, SimpleAreaChart, DonutChart components
- Add PeriodSelector with preset periods and custom date range
- Full responsive design (mobile/tablet/desktop/TG Mini App)
- ARIA accessibility (tablist, tab, tabpanel, aria-selected)
- Error handling with isError on all queries
- Empty data guards on all chart components
- i18n support across all 4 locales (en, ru, zh, fa)
2026-03-02 20:34:39 +03:00
Fringg
673de08dd4 fix: improve campaign stats, shared chart components, and i18n coverage
- Extract shared chart constants to constants/charts.ts
- Add TREND_STYLES to stats/constants.ts for reuse
- Fix useChartColors with MutationObserver for theme changes
- Fix DailyChart date parsing to prevent timezone shift
- Add truncate to StatCard value for overflow safety
- Fix CampaignCard copy feedback inside try block
- Add NaN validation and staleTime to AdminCampaignStats
- Replace hardcoded strings with i18n keys in Referral page
- Add missing i18n keys across all 4 locales (en, ru, zh, fa)
- Add sales stats route to AdminPanel and App router
2026-03-02 20:34:24 +03:00
Fringg
c7d05c4809 feat: add recharts analytics to admin campaign stats page
- Move shared chart components (DailyChart, PeriodComparison, StatCard) to src/components/stats/ with configurable label props
- Create shared types for chart data decoupled from partner API
- Add campaign chart data API client with deposits/spending split
- Enhance AdminCampaignStats with daily trends chart, period comparison, top registrations, and deposit/spending stat cards
- Add useChartColors hook with SSR guard and theme-aware CSS variable parsing
- Add cross-platform clipboard utility with execCommand fallback for Telegram WebView
- Add i18n keys for chart analytics across all 4 locales (en, ru, zh, fa)
- Responsive fixes: truncation for long names/values, responsive text sizing, touch-friendly copy buttons
2026-03-02 06:10:20 +03:00
Fringg
60f16e64e8 fix: support VK ID OAuth 2.1 device_id in frontend
- Extract device_id from VK callback URL query params
- Pass device_id through store → API → backend
- Add useRef guard to prevent useEffect double-fire
- Fix URL validation catch-block anti-pattern in Login
- Improve error extraction in OAuthCallback (show Error.message)
2026-03-02 04:10:05 +03:00
Fringg
3f050396b8 fix: align RecentPaymentItem types with backend schema
- telegram_id: number → number | null (email-only users)
- Add email field
- Fix username, payment_method, description nullability
2026-03-02 02:42:14 +03:00
Fringg
11343f4f12 fix: align TypeScript types with backend referral schemas
- Add campaign_name field to ReferralEarning interface
- Fix telegram_id to number | null in TopReferrerItem (email-only users)
- Add email field to TopReferrerItem
2026-03-02 02:35:00 +03:00
Fringg
75a6149e2d feat: display per-campaign stats on partner detail page
- Add registrations_count, referrals_count, earnings_kopeks to campaign type
- Show per-campaign stats grid (registrations, referrals, earnings) under each campaign card
- Use conditional coloring for zero earnings (neutral instead of green)
2026-03-02 01:09:55 +03:00
Fringg
a933f661e4 perf: optimize animated backgrounds for mobile — reduce GPU load and memory pressure
- Add useAnimationLoop hook with FPS throttling (30fps mobile/60fps desktop),
  Page Visibility API pause, and Telegram WebApp activated/deactivated events
- Add useAnimationPause hook for CSS/Framer Motion components
- Validate animation config with type allowlist, numeric clamping, JSON size guard
- Move ctx.setTransform from per-frame to init/resize across all canvas backgrounds
- Move ctx.lineCap to init/resize in vortex, replace Float32Array.set with direct writes
- Pre-compute shooting star delay instead of per-frame Math.random
- Cap DPR to 1.5 on mobile, reduce particle counts, cap blur to 4px
- Disable aurora CSS animation on mobile, remove blur on mobile spotlight
- Remove mix-blend-hard-light on mobile gradient-animation
- Add NaN/Infinity guard to clampNumber, remove dead CSS variables
- Add conditional unmount for Framer Motion backgrounds when paused
- Add animationPlayState pause for CSS-animated backgrounds
2026-03-01 22:36:57 +03:00
Fringg
430b703bbe fix: improve light theme visibility for inner panels on subscription page
Replace hardcoded dark-800/50 backgrounds and dark-700/50 borders with
isDark-conditional classes using champagne palette for light mode:
- Collapsed accordion buttons (4x)
- Expanded panels (4x)
- Traffic/server selector unselected state (2x)
- Info/warning boxes (2x)
- Section divider (1x)
2026-03-01 19:29:27 +03:00
Fringg
4cdff9730b fix: improve light theme visibility for dashboard and subscription cards
- Increase card opacity and shadow contrast in glassTheme for light mode
- Add accent-tinted borders and shadows to subscription cards (active, expired, trial)
- Fix grid patterns to use dark lines instead of white in light mode
- Fix trial CTA button: solid green with dark text instead of invisible transparent
- Fix trial icon background: light accent gradient instead of hardcoded dark
- Add + prefix to referral earnings in StatsGrid
2026-02-28 06:37:40 +03:00
Fringg
4a68347ae8 revert: remove user-facing reset traffic toggle
Reset traffic on tariff switch is an admin-only setting.
Backend handles it via admin settings system (data-driven, no frontend code needed).
Reverted all user-facing toggle UI, API params, types, and translations.
2026-02-27 09:50:13 +03:00
Fringg
49fff8e855 feat: add reset traffic toggle on tariff switch
- Add reset_traffic parameter to previewTariffSwitch and switchTariff API calls
- Add reset_traffic_available/reset_traffic_default fields to TariffSwitchPreview type
- Add toggle switch in tariff switch preview modal (shown when backend enables it)
- Initialize toggle from server default (reset_traffic_default)
- Pass reset_traffic flag on switch execution
- Add translations for all 4 locales (ru, en, zh, fa)
2026-02-27 09:48:28 +03:00
Fringg
d2f02d605c fix: clean up expired trial card - remove redundant badge and subtitle
- Remove red "Пробный период" badge from expired trial card
- Remove "Пробный период завершен" subtitle text
- Simplify header layout (no justify-between needed without badge)
- Change "Тарифы" button link to /subscription/purchase
2026-02-27 09:38:33 +03:00
Fringg
396f814cbd fix: remove devices stat block, stretch countdown to full width
Remove the separate devices count card from the stats row since device
info is already shown in the connect-device card above. Stretch the
countdown timer to full width with timer on the left and expiry date
on the right. Revert squeezed font sizes now that space is available.
2026-02-27 09:31:22 +03:00
Fringg
d567817e05 fix: show progress bar instead of dots when device_limit > 10
Match the Dashboard behavior: show individual dots for <= 10 devices,
switch to a compact progress bar for higher limits (e.g. 18 devices).
Prevents dot overflow breaking the connect-device card layout on mobile.
2026-02-27 09:27:36 +03:00
Fringg
96bcc76d69 fix: prevent countdown timer overflow on narrow mobile screens
Add min-w-0 + overflow-hidden to the countdown card to prevent it from
blowing out the grid column. Reduce number font from 20px to 18px on
mobile (20px on sm+), tighten gaps and colon sizes to fit within the
50% grid column on 375px screens.
2026-02-27 08:51:56 +03:00
Fringg
d89c534c0b fix: rewrite BackgroundBoxes from 225 DOM divs to single canvas element
Root cause: 225 individually animated DOM elements forced Chrome's
compositor to create separate paint regions per element. Any hover
state change on page content triggered re-compositing of all 225
regions, causing visible flickering on all pages.

Canvas fix: single <canvas> element renders the entire grid effect
via requestAnimationFrame. Canvas content is pixel-based and cannot
be affected by DOM hover state changes on other elements.

Additional fixes:
- Fix z-index collision: portal z-index -1 → -2 (was same as body::before noise)
- Replace all transition-all with specific properties on .btn, .btn-icon,
  .input, .nav-item, .bottom-nav-item, checkbox
- Remove backdrop-blur-sm from desktop .bento-card and .card
  (forced Chrome to re-sample animated background pixels on every hover)
2026-02-27 08:46:22 +03:00
Fringg
fe32322c32 perf: remove permanent GPU layer promotion from cards to fix flickering
Remove translateZ(0) from base states of .bento-card, .card, .glass
and their light theme variants. Remove transform-gpu from Card.tsx.
Change bentoFadeIn animation to end with transform:none instead of
translateY(0). GPU promotion now only occurs during hover/active
interactions, preventing Chrome from creating excessive compositing
layers that cause flickering with animated backgrounds.
2026-02-27 08:27:07 +03:00
Fringg
7f17d95ed6 fix: replace framer-motion with CSS keyframes in boxes background
The boxes background was creating 225 motion.div elements, each running
independent opacity animations via framer-motion JS on the main thread.
This blocked hover transitions on cards, causing visible flickering.

CSS @keyframes run on the compositor thread and have zero main-thread
cost, eliminating the interference with user interactions.
2026-02-27 08:18:24 +03:00
Fringg
12c97a2c5e fix: render animated background via portal at z-index:-1 to stop implicit compositing
Previous isolation:isolate fix didn't work because:
- position:fixed elements still see through isolation boundary
- backdrop-filter samples all rendered content regardless of stacking context
- The real issue: animated background at z-index:0 with will-change:transform
  forces Chrome to implicitly composite EVERY overlapping element

Fix: render BackgroundRenderer via createPortal on document.body with
z-index:-1, placing it below the root stacking context. This eliminates
implicit compositing entirely.

Also:
- Remove backdrop-blur-xl from desktop header (was resampling bg 60fps)
- Remove will-change:opacity from card ::after pseudo-element
- Replace transition-all with transition-colors on header buttons
2026-02-27 08:14:20 +03:00
Fringg
04eacf6421 fix: isolate content layer from animated background to eliminate flickering
Root cause: backdrop-filter on header/nav resamples the animated
background 60fps, causing GPU compositing flicker (Chromium bug).

- Add isolation: isolate wrapper in AppShell to prevent backdrop-filter
  from seeing through to the animated background layer
- Add will-change: transform + translateZ(0) to BackgroundRenderer
  for stable GPU layer
- Replace contain: layout style with contain: content on main
- Replace transition-all with specific properties in Card component
2026-02-27 07:52:45 +03:00
Fringg
d8cf4301ca fix: resolve hover flickering caused by GPU layer destruction
- Preserve translateZ(0) on all hover/active transforms to prevent
  GPU compositing layer teardown/recreation cycle
- Lower body::before noise texture z-index to -1
- Add will-change: opacity to card spotlight pseudo-element
- Include backdrop-blur-linear in mobile performance override
- Replace transition-all with specific properties in BentoCard
2026-02-27 07:41:27 +03:00
Fringg
bdc201b5ea fix: eliminate hover flickering across all pages
- Extract CountdownTimer into React.memo component to isolate 1s
  interval re-renders from the full Subscription page
- Add box-shadow transition to .hover-border-gradient (was instant)
- Remove conflicting p-[1.5px] from PurchaseCTAButton (CSS border
  already handles 1.5px)
- Replace transition-all with specific properties on bento-card-hover,
  bento-card-glow, device dots, toggle switches, progress bars
- Reduce translateY hover from -4px to -2px to prevent cursor
  losing hover target during fast vertical mouse movement
2026-02-27 07:02:59 +03:00
Fringg
0bc817fa7f fix: move CTA button above additional options section 2026-02-27 06:52:31 +03:00
Fringg
126f9ab9b9 refactor: extract purchase/renewal flow to separate page
Move ~1900 lines of purchase/renewal logic from Subscription.tsx into
a new SubscriptionPurchase.tsx page at /subscription/purchase.

- Create SubscriptionPurchase.tsx with tariffs grid, classic mode wizard,
  switch preview modal, and promo handling
- Create PurchaseCTAButton.tsx with animated gradient border, state-aware
  colors and context-aware text
- Create subscriptionHelpers.ts with shared utilities
- Add CopyIcon to shared icons module
- Register /subscription/purchase route with lazy loading
- Update SubscriptionCardExpired and PromoOffersSection navigators
- Add CTA translation keys to ru.json and en.json
- Remove all scrollToExtend references
2026-02-27 06:47:30 +03:00
Fringg
f4d7a2cc8d fix: subscription UI improvements - expired card, duplicate badges, live countdown
- SubscriptionCardExpired: use trialTitle for expired trials, remove traffic/devices grid, show only expiry date
- Subscription page: remove duplicate trial badge from zone indicator, fix expired trial badge showing "Пробный период" instead of "Истекла"
- Subscription page: replace static days counter with live HH:MM:SS countdown timer, merge "Действует до" into countdown block
- Subscription page: remove duplicate traffic percentage block
- Handle expired state in countdown (show "Истекла" in red instead of 00:00:00)
- Use live countdown.days for urgency threshold instead of stale server value
2026-02-27 06:04:06 +03:00
Fringg
27f85a1db1 fix: add subscription tab to desktop nav, fix device dots overflow, show available referral balance
- Add Subscription tab to desktop header navigation (was only in mobile)
- Fix device dots overflow for large limits (>10) by using progress bar
- Show available referral balance on dashboard instead of total earnings
- Add available_balance and withdrawn fields to ReferralInfo type
2026-02-27 04:53:37 +03:00
Fringg
82987fd49a fix: review fixes - Math.round kopecks, fa locale, admin list commission
1. Add Math.round() to rubles→kopecks conversion (floating point safety)
2. Add missing {{currency}} template var in fa.json amountPlaceholder
3. Show desired_commission_percent in admin applications list
2026-02-27 04:08:15 +03:00
Fringg
e94d81fe5a 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).
2026-02-27 04:02:27 +03:00
Fringg
4d14e3e806 feat: add fullscreen QR code for subscription connection
- New ConnectionQR page with fullscreen QR display (no modal)
- QR button in InstallationGuide header next to platform selector
- Respects hideLink setting: shows URL below QR only when visible
- i18n translations for ru, en, zh, fa
2026-02-27 03:14:15 +03:00
Fringg
821e991f51 fix: block wheel spin without active subscription
- Add has_subscription to WheelConfig type
- Disable spin button when user has no subscription
- Add noSubscription guard in handleUnifiedSpin handler
- Show warning banner directing user to activate subscription
- Prevent banner stacking (noSubscription takes priority over daily limit)
- Add noSubscription i18n keys for ru, en, zh, fa
2026-02-27 00:53:50 +03:00