Commit Graph

1619 Commits

Author SHA1 Message Date
Fringg
38b0f4be9a fix: add news link to admin panel, prevent empty news section flash
- Add News item to marketing group in AdminPanel with NewspaperIcon
- Add news nav/panel translations for all 4 locales (ru, en, zh, fa)
- Don't render NewsSection until query confirms articles exist
- Remove skeleton that caused brief flash when news list is empty
2026-03-23 11:21:25 +03:00
Fringg
74e6d52fee fix: news feature security, accessibility, performance improvements
- DOMPurify strict allowlist with sandbox on iframes
- safeColor() CSS injection prevention for category_color
- URL validation (http/https) for images and links
- encodeURIComponent for slug in API calls
- Keyboard navigation on news cards (Enter/Space)
- aria-label, aria-pressed, type=button on all buttons
- 44px touch targets on remaining buttons
- memo() wrappers + stable callbacks (fewer re-renders)
- Canvas draw call batching (~75% reduction)
- TipTap extensions useMemo deps fix ([t] -> [])
- Featured image loading=eager fetchPriority=high (LCP)
- Unsafe Number(id) NaN guard
2026-03-23 11:09:52 +03:00
Fringg
99fc33625e feat: add news section with admin editor and public article view
- NewsSection with animated grid background, category filters, featured cards
- AdminNews list page with toggle publish/featured, pagination
- AdminNewsCreate with TipTap rich text editor, URL validation
- NewsArticle detail page with DOMPurify sanitization, Telegram back button
- Toggle component with WCAG 44px touch targets, role=switch
- Prose styles for highlight marks and responsive iframes
- i18n translations (en, ru, zh, fa)
2026-03-23 10:49:46 +03:00
Egor
eea3b6c269 Merge pull request #343 from BEDOLAGA-DEV/release-please--branches--main--components--cabinet-frontend
chore(main): release 1.41.0
2026-03-22 10:56:31 +03:00
github-actions[bot]
be9c28cd14 chore(main): release 1.41.0 2026-03-22 07:56:07 +00:00
Egor
39c0d11962 Merge pull request #342 from BEDOLAGA-DEV/dev
Dev
2026-03-22 10:55:40 +03:00
Fringg
5b12784ab8 feat: show subscription revenue and referral earnings in network stats
Add subscription revenue (total from subscription payments) to the
stats panel alongside referral earnings. Layout updated to 2-column
grid with subscription revenue highlighted in accent color.
2026-03-22 10:31:29 +03:00
Fringg
ebe2c3af7e fix: use dark label color on hover (white bg), light on normal (dark bg)
Switch labelColor to attribute-based mode so hovered/highlighted nodes
get dark text (#111827) readable on the white hover background, while
normal labels stay light (#e5e7eb) readable on the dark canvas.
2026-03-22 10:26:16 +03:00
Fringg
0cc1cd5871 fix: use light label color for graph nodes on dark background 2026-03-22 10:18:34 +03:00
Fringg
2229eeecb0 fix: remove campaignUser fill color — campaign membership shown via edges
Campaign users no longer get a separate amber fill color. Their campaign
association is already visible through the edge connecting them to the
campaign node. Users from campaigns now show their subscription status
color (or regular gray if no subscription), reducing visual noise.
2026-03-22 10:13:56 +03:00
Fringg
2436060b5a fix: use white campaign edges to avoid blending with trial expired nodes 2026-03-22 10:08:42 +03:00
Fringg
2a57442e04 fix: make trial, campaign, and no-subscription node colors distinct
- campaignUser: #4dd9c0 (teal) → #fbbf24 (amber) — no longer blends with trial blue
- regular: #6b7280 (gray) → #94a3b8 (slate) — visible on dark background
- Campaign edges updated to amber tint
- defaultNodeColor now references NODE_COLORS.regular instead of hardcoded value
- Legend gradient uses actual campaign palette colors
2026-03-22 10:02:17 +03:00
Fringg
cc64f7b8ea fix: rename "Regular user" to "No subscription" in legend
The gray color in the referral network legend represents users without
a subscription, not "regular/organic" users. Updated labels in all
4 locales (en, ru, fa, zh) to reflect this.
2026-03-22 09:51:43 +03:00
Fringg
5a92484912 fix: add fill border to node-border program config
The createNodeBorderProgram was missing the second border entry
with { size: { fill: true }, color: { attribute: 'color' } }
which renders the node's fill color. Without it, node bodies
were transparent and only edges were visible.
2026-03-22 09:39:19 +03:00
Fringg
61ca5cc53d fix: fallback to referral role fill color when subscription_status is null
When subscription_status is not available (backend not deployed or user
has no subscription), fill color now falls through to referral role
(partner/topReferrer/activeReferrer) before defaulting to campaign/regular.
Increases border size from 0.25 to 0.35 and merges legend sections.
2026-03-22 09:32:53 +03:00
Fringg
b18f3fb211 feat: add fill+border dual-color nodes, radial layout, and dark labels
Node fill color now encodes subscription status (paid/trial active/expired),
while border color indicates referral role (partner/top/active referrer).
Added BFS-based radial initial positioning to spread referral branches outward.
Updated legend with two sections and adjusted FA2 gravity for less clustering.
2026-03-22 09:25:23 +03:00
Fringg
b289ea9c23 feat: color-code referral network nodes by subscription status
Add subscription status colors: green (paid active), blue (trial active),
red (paid expired), orange (trial expired). Extract NODE_COLORS constant
as single source of truth. Add SubscriptionStatus union type. Show status
badge in user detail panel. Add i18n for all 4 locales.
2026-03-22 09:07:32 +03:00
Fringg
8e59af96c5 fix: superadmin assignments show ENV badge, block UI revoke
Superadmin role (level 999) is managed via env config only. Hide X
button for superadmin assignments and show ENV badge instead. Filter
superadmin from assignable roles dropdown. Add envManaged translation
to all 4 locales.
2026-03-22 08:41:41 +03:00
Egor
15f13d8682 Merge pull request #340 from BEDOLAGA-DEV/release-please--branches--main--components--cabinet-frontend
chore(main): release 1.40.0
2026-03-22 07:36:23 +03:00
github-actions[bot]
cb14f18d21 chore(main): release 1.40.0 2026-03-22 04:36:05 +00:00
Egor
b433149fb7 Merge pull request #339 from BEDOLAGA-DEV/dev
Dev
2026-03-22 07:35:31 +03:00
Fringg
3e27472c8a fix: clear all cached auth state on Telegram MiniApp retry
When users hit 'Try Again' after auth failure, clear ALL cached state
(tokens, SDK launch params, initData, zustand persist, tg_user_id)
to prevent stale token loops. Applies to both Login and TelegramRedirect
retry handlers.
2026-03-22 07:24:45 +03:00
Fringg
1538879f97 fix: clear expire timer on 410/error and reset pollInFlight on retry 2026-03-22 05:37:09 +03:00
Fringg
e57166745c fix: prevent polling race condition and add missing zh/fa translations 2026-03-22 05:21:01 +03:00
Fringg
76c9d6448a feat: add QR code and command to deeplink auth fallback, fix polling on tab return 2026-03-22 05:16:56 +03:00
Fringg
58b1f96852 feat: show short device identifier (HWID) in device list 2026-03-22 05:06:14 +03:00
Fringg
9d519fb5ec fix: show error state instead of blank page on purchase-options failure
When the purchase-options API call failed (e.g. for email-registered
users), the page rendered only the header with no content. Now shows
an error message with retry button. Also adds a fallback for when
the API returns no available tariffs or periods.
2026-03-22 04:45:19 +03:00
Fringg
ac1550ce10 fix: use live panel traffic data in admin subscription card
Subscription card showed stale traffic from local DB (0.0 GB) while
the live traffic section below showed correct data from panel (3.52 GB).
Now uses panelInfo.used_traffic_bytes when available, with DB fallback.
2026-03-22 04:17:21 +03:00
Fringg
86d997d01d feat: custom broadcast buttons UI and fix stale mediaType bug
- Add inline custom button editor (no popups): label, type
  (callback/URL), action value with byte-level validation
- Frontend validates callback_data in UTF-8 bytes via TextEncoder
- URLs restricted to https:// and tg:// matching backend
- Form wrapped in <form> for Enter key submit support
- Fix pre-existing stale mediaType bug in file upload handler
- Translations added for ru, en, zh, fa locales
2026-03-22 01:54:38 +03:00
Fringg
3c034d2e70 fix: referral system — stop cabinet redirect to Telegram, fix deep link code handling
- Remove redirect to Telegram bot when email auth disabled + referral code present
  (cabinet links should stay on cabinet, bot links should go to bot)
- Remove referral_code from deep link auth (existing users can't get referrals)
- Don't consume referralCode in deep link path — leave it in localStorage for
  OIDC/widget auth methods that actually send it to the backend
- Consume campaign slug once into ref to survive retries (codesConsumedRef pattern)
- Update loginWithDeepLink to only accept (token, campaignSlug) — no referralCode
- Update pollDeepLinkToken API to match backend schema change
2026-03-22 01:54:38 +03:00
Egor
d2c2329d8b Merge pull request #335 from BEDOLAGA-DEV/release-please--branches--main--components--cabinet-frontend
chore(main): release 1.39.1
2026-03-21 03:18:39 +03:00
github-actions[bot]
c0415082e2 chore(main): release 1.39.1 2026-03-21 00:18:12 +00:00
Egor
45bcc35b2d Merge pull request #334 from BEDOLAGA-DEV/dev
Dev
2026-03-21 03:17:47 +03:00
Egor
a87085e2b2 Merge pull request #333 from BEDOLAGA-DEV/main
w
2026-03-21 03:12:45 +03:00
Fringg
c34375e579 fix: infinite reload loop on login when Telegram widget unavailable
When the Telegram OIDC widget fails to load (ad blockers, DNS, CSP),
the deep link polling fallback caused an infinite page reload:

1. pollDeepLinkToken received 202 (pending) which axios treated as success
2. loginWithDeepLink stored undefined tokens with isAuthenticated=true
3. checkAdminStatus() fired with invalid token → 401
4. Response interceptor called safeRedirectToLogin() → page reload → loop

Fixes:
- pollDeepLinkToken: validateStatus rejects non-200 (202 now caught in poll loop)
- AUTH_ENDPOINTS: add /cabinet/auth/deeplink/ and /cabinet/auth/login/auto
- safeRedirectToLogin: guard against redirect when already on /login
- loginWithDeepLink: validate response tokens before storing
- setTokens: validate tokens in store method (protects AutoLogin, VerifyEmail, etc.)
2026-03-20 22:28:50 +03:00
Egor
9eebb76f8a Merge pull request #330 from BEDOLAGA-DEV/release-please--branches--main--components--cabinet-frontend
chore(main): release 1.39.0
2026-03-20 07:24:01 +03:00
github-actions[bot]
e561b6ea40 chore(main): release 1.39.0 2026-03-20 04:21:56 +00:00
Egor
795a8983c5 Merge pull request #329 from BEDOLAGA-DEV/dev
Dev
2026-03-20 07:21:21 +03:00
Egor
accde7b720 Merge pull request #328 from BEDOLAGA-DEV/main
w
2026-03-20 07:19:36 +03:00
Fringg
d34f5e8559 fix: hide trial banner when subscription expired banner is active 2026-03-20 07:18:11 +03:00
Fringg
94c8e73787 fix: bottom nav overlap and safe area handling in referral network
- Raise portal z-index to z-50 so it covers MobileBottomNav
- Use TG SDK bottom safe area (JS) via CSS variable instead of unreliable env()
- Fix TicketNotificationBell regression: conditional inline style for fullscreen only
- Add bottom safe area padding to detail panel scroll areas
2026-03-20 05:02:47 +03:00
Fringg
33486a09d0 fix: adapt referral network for Telegram MiniApp safe areas
- Extract useHeaderHeight() hook — single source of truth for header
  height across AppShell, ReferralNetwork, and TicketNotificationBell
- Portal top offset now computed dynamically from TG safe area insets
  instead of hardcoded top-16 (fixes overlap with TG header bar)
- Two-row mobile layout: title + selector on separate rows so dropdown
  gets full width on small screens
- Add MOBILE_HEADER_HEIGHT_PX and DESKTOP_HEADER_HEIGHT_PX to constants
- Fix TicketNotificationBell using hardcoded 45px for all platforms
2026-03-20 04:23:45 +03:00
Fringg
2780898d1c fix: scope selector UX, ARIA, and code quality improvements
- removeScope preserves graph state when items remain (only resets on empty)
- Extract shared CheckIcon, CloseIcon, Spinner, ScopeListItem components
- Unify three handleSelect* into single handleToggle
- Fix shared mutable Set in reset state (factory function)
- Add MAX_SCOPE_ITEMS UI feedback (disabled button, warning banner)
- Correct ARIA: dialog > tablist + listbox > option structure
- Event listeners only attached when dropdown is open
- isSelected uses Set lookup via useMemo instead of O(n) scan
- Clear user search only on add, not on deselect
2026-03-20 02:44:29 +03:00
Fringg
db76cd0c64 feat: multi-select scope for referral network graph
Replace single-select scope with multi-select supporting multiple
campaigns, partners, and users simultaneously. Chips UI with remove
buttons, clear-all, sorted query keys for cache stability.
2026-03-20 02:31:11 +03:00
Fringg
a6faf702ec feat: redesign referral network with scope selector
- Replace full graph with scoped view (campaign/partner/user)
- ScopeSelector component with tabs and searchable dropdown
- Store resets all state on scope change (selection, hover, filters)
- Remove dead NetworkSearch component and graphInstance globals
- i18n keys for scope selector in all 4 locales
2026-03-20 01:50:09 +03:00
Fringg
2adb0047dd feat: add partner → campaign edges with distinct color to referral network 2026-03-20 01:17:01 +03:00
c0mrade
2b43a30ccc fix: referral network rendering — portal fix and visual tuning
Portal to document.body escapes main's contain:content which broke
fixed positioning (container had height:0 and was clipped to main).

Visual fixes for 662+ node graphs:
- labels only on large nodes (threshold 6→14, density 0.5→0.12)
- leaf nodes 5px, referrers 10px, campaigns 16px
- edge opacity reduced to prevent white starburst
- default edge color opacity lowered
2026-03-19 11:12:05 +03:00
c0mrade
b787726d1b fix: referral network graph rendering and layout
- fix top offset breakpoint: sm:top-14 → lg:top-14 to match AppShell
  header visibility (mobile header is lg:hidden with h-16)
- add gravity to FA2 layout to prevent disconnected nodes from flying
  to extreme positions, making auto-rescale shrink everything to dots
- clamp outlier node positions after FA2 finishes (3σ threshold)
- add ResizeObserver to sync sigma canvas with container size changes
- call sigma.resize() before camera reset after FA2
- increase node sizes: user min 8→12, max 40→50, campaign 18→24
- reduce FA2 duration 5s→3s and slowDown 5→2 for tighter layout
2026-03-19 10:24:47 +03:00
Fringg
7c0b8e571a fix: graph layout, node visibility and FA2 settings
- Switch to CSS Grid layout for reliable content area height
- Use inferSettings() for ForceAtlas2 auto-tuning based on graph structure
- Enable linLogMode and adjustSizes for better node clustering
- Fit camera after layout settles with animatedReset
- Increase node sizes for better visibility (MIN 8, MAX 40)
- Center controls at bottom, fix overlay positions
2026-03-19 09:18:11 +03:00
Fringg
fd9a47ecda fix: position page below AppShell header, wait for container size
- Page uses top-16/sm:top-14 to start below AppShell header (z-50)
  instead of inset-0 which renders behind the header
- Sigma init polls with RAF until container has real dimensions
  instead of allowInvalidContainer which creates broken canvas
- Removed overflow-hidden from content area (not needed)
2026-03-19 09:04:55 +03:00