Commit Graph

29 Commits

Author SHA1 Message Date
c0mrade
f75b243f03 polish: clear 33/34 detector findings (bg-black, animate-bounce, spinner, transition-width, color)
After re-audit/critique cycle the deterministic detector (npx impeccable)
flagged 34 design-spec violations. Knock out 33 of them.

  • 25 × pure-black-white: sed-sweep bg-black/X → bg-dark-950/X across
    18+ files (modal scrims, photo viewer backdrop, code blocks). The
    base resolves to rgba(10,15,26,X) — visually identical to true
    black, satisfies the 'no #000' impeccable rule.
  • 3 × bounce-easing: SuccessNotificationModal celebration icon and
    SyncTab loading arrows used animate-bounce; replaced with
    animate-pulse. Bounce easing reads dated; pulse conveys 'in
    progress' without the cartoon feel.
  • 3 × border-accent-on-rounded: TelegramCallback + VerifyEmail
    spinners used 'border-b-2 border-accent-500' on rounded-full —
    detector reads it as a side-stripe even though it's a ring loader.
    Switch to canonical 'border-2 border-accent-500 border-t-transparent'
    (3/4 ring colored). Same visual, no spec violation.
  • 1 × ai-color-palette: AdminLandingStats had text-purple-400 on a
    gift-stats heading; purple is not in the brand palette. Swap to
    text-accent-400.
  • 1 × layout-transition: TrafficProgressBar.tsx fill bar still used
    transition: width 1.2s (slipped past the earlier optimize pass).
    Convert to transform: scaleX with origin-left. Same gradient, same
    duration, runs on the compositor.

Remaining: 1 finding in third-party Aceternity background-beams-collision
component (indigo-500 gradient on decorative WebGL background) — left
as-is, it's lifted decorative third-party code.

Detector: 34 → 1.
2026-05-26 21:52:56 +03:00
c0mrade
bef984d72a fix(scope-selector): drop role=dialog from non-modal popover (a11y)
The scope add-popover wrapped its tabs/search/list in role=dialog with
no aria-modal and no focus trap. That promises modality to AT but
delivers a non-modal popover users can click past — confusing.

Remove the wrapper role. The trigger button already exposes the popup
via aria-haspopup=listbox + aria-expanded, and the inner div carries
role=listbox aria-multiselectable. Nothing for AT to misinterpret now.
2026-05-26 13:50:22 +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
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
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
Fringg
6f58a0ce5d fix: defer Sigma init with requestAnimationFrame to prevent no-height crash
Container has no computed height when useEffect fires immediately
after data arrives. Defer to next animation frame so browser layout
completes. Also add allowInvalidContainer as safety net.
2026-03-19 08:56:31 +03:00
Fringg
3434073d7c fix: resolve Sigma container height error on page load
Use absolute positioning for graph container instead of flex-1
to ensure explicit dimensions when Sigma initializes.
2026-03-19 08:51:45 +03:00
Fringg
4ebd85b65d fix: fullscreen layout and filter dropdown positioning
- Page now uses fixed inset-0 overlay to fill entire viewport
- Simplified top bar to single row (back + title + search + filter)
- Filter dropdown uses absolute positioning on desktop (no layout shift)
- Filter button always visible, toggles dropdown on click
2026-03-19 08:43:39 +03:00
Fringg
ea143fdbc9 fix: redesign top bar and filter panel for mobile
- Split top bar into two rows on mobile: title + filter icon, then
  full-width search below
- Desktop keeps single-row layout with search and filter inline
- Filter button: icon-only on mobile with active indicator dot
- Filter panel: full-screen overlay with backdrop on mobile,
  inline dropdown on desktop
- Outside-click closes filter panel
- Removed subtitle (only on desktop, saves space)
2026-03-19 08:30:32 +03:00
Fringg
818557f57d fix: improve graph spacing, mobile layout, and Telegram viewport
- Increase FA2 scalingRatio to 10 and decrease gravity to 0.5 for
  better node spacing (less cluttered graph)
- Use 100dvh instead of 100vh for Telegram Mini App viewport compat
- Hide legend on mobile to prevent overlay collision
- Move controls to bottom-right on mobile, bottom-center on desktop
- Make stats single-column on mobile for compact layout
2026-03-19 08:20:38 +03:00
Fringg
0f756d633d fix: remove dead store code and add search input maxLength
- Remove unused networkData, searchQuery, searchResults from zustand store
- Remove setNetworkData write in NetworkGraph
- Add maxLength={200} to search input
2026-03-19 08:08:18 +03:00
Fringg
235eaec85f feat: add referral network graph visualization page
Interactive Sigma.js + graphology graph with ForceAtlas2 web worker
layout, campaign/user node coloring, filters via nodeReducer pattern,
search highlighting, user/campaign detail side panels, and 4-locale
translations. Dependencies: sigma v3, graphology, graphology-layout-forceatlas2.
2026-03-19 07:56:01 +03:00