* Make SBP default and first top-up option (#389)
* fix(connection): happ cryptolink flow + ui fixes (#385)
* fix(connection): respect happ_cryptolink mode
- read connect_mode from connection-link endpoint
- auto-redirect to happ cryptolink flow when mode is HAPP_CRYPTOLINK
- keep installation guide behavior for other modes
* docs(readme): fix source build step 2
- use compose service name for build/create commands
- copy static files from created compose container
- remove compose container via docker compose rm
* fix(connection): handle mode and ws path
- treat any non-guide connect mode as direct happ redirect
- wait for connection-link response before rendering installation guide
- build websocket URL from VITE_API_URL (supports /api and absolute URLs)
* docs(readme): fix docker cp static path
- copy /usr/share/nginx/html contents via html/.
- prevent nested /srv/cabinet/html deployment and 404 on root
* fix(connection): keep guide, use happ links
- restore guide page behavior for /connection (no auto redirect)
- use happ cryptolink URL in /connection/qr when happ crypt mode is active
- replace subscription page connection URL with happ cryptolink from connection-link API
* fix(connection): avoid wrong redirect flow
- force happ scheme deeplink in HAPP_CRYPTOLINK mode for guide connect buttons
- use cabinet redirect page only inside Telegram Mini App
- open deeplink directly in regular browsers
* fix(connection): enforce happ cryptolink
- prioritize backend crypt deeplink fields in HAPP_CRYPTOLINK mode
- fallback to local crypt4/crypt3 generation from subscription URL when backend returns plain happ://sub...
- apply same resolution for guide open action, qr page source and subscription page link display/copy
* fix(subscription): truncate long connect link
- render connection URL in a single line with ellipsis on /subscriptions
- preserve full URL in tooltip for easier manual copy
- keep copy button behavior unchanged
* fix(connection): build cryptolink from happ sub
- allow cryptolink fallback generation from happ://sub... URLs in addition to http(s)
- prevent plain happ://sub links from leaking into UI in HAPP_CRYPTOLINK mode
* fix: allow saving 0% period discount in promo groups
Changed condition from percent > 0 to percent >= 0 so that
admins can explicitly set 0% discount for a period. Previously
0% entries were silently dropped and not sent to the backend.
* fix: always send period_discounts in promo group updates
When all period discounts were removed, the frontend sent undefined
(field absent from JSON), so the backend never cleared them.
Now always sends the field - empty object {} to clear, or populated
object to update.
---------
Co-authored-by: zavul0nn <34007368+zavul0nn@users.noreply.github.com>
Co-authored-by: Dxnil <62987903+D4nilKO@users.noreply.github.com>
SubscriptionCardActive: passes ?sub= to /connection navigation.
Connection: QR state includes subscriptionId for back-navigation.
ConnectionQR: preserves subscription context on back button.
Dashboard + Subscription: localStorage traffic cache keyed per-subscription
to prevent cooldown bleed between different subscriptions.
- Add varsIgnorePattern to no-unused-vars for destructuring patterns
- Fix all react-hooks/exhaustive-deps by adding missing dependencies
- Refactor useAnimatedNumber to use ref instead of stale state closure
- Wrap handleLinkResult in useCallback for stable deps
- Extract OAuth utilities from OAuthCallback.tsx to utils/oauth.ts
- Extract background config utilities to utils/backgroundConfig.ts
- Remove unused catch parameter in GiftSubscription
- Fix stale initData comparison in clearStaleSessionIfNeeded that destroyed
valid refresh tokens on mobile WebView reopens
- Restrict X-Telegram-Init-Data header to auth endpoints only
- Close Mini App on auth retry to force fresh initData from Telegram
- Merge Connection page error/not-configured states for better UX
- Remove unnecessary comments across 40+ files (section dividers,
restating comments, noise catch block comments)
- Configure ESLint allowEmptyCatch to properly handle intentional
empty catch blocks (62 warnings resolved)
- Wrap /connection/qr route in ProtectedRoute with Layout
- Remove fullscreen overlay and custom close button
- Add AdminBackButton with replace prop to avoid history cycles
- Use replace navigation from Connection to QR page
- Add replace prop support to AdminBackButton component
- 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
Replace all bare useAuthStore(), useBlockingStore(), and
useSuccessNotification() calls with individual field selectors.
This prevents components from re-rendering when unrelated store
fields change.
- 21 useAuthStore usages across 20 files: individual selectors
for 1-2 fields, useShallow for 3+ fields
- 5 useBlockingStore usages: individual selectors
- 2 useSuccessNotification usages: individual selectors
Move the empty apps check before the subscription check so that
an empty or unconfigured appConfig shows "not configured" instead
of the misleading "no subscription" message.
Show different messages depending on user role:
- Regular users see a friendly "check back later" message
- Admins see a prompt with a link to /admin/apps settings
- Always route deep links through redirect.html instead of splitting
mobile/desktop paths, fixing Telegram Mini App WebView limitation
with custom URL schemes (happ://, clash://, etc.)
- Fallback to regular subscriptionUrl instead of crypto resolvedUrl
for subscriptionLink buttons
- Add svgIconKey to RemnawavePlatform and RemnawavePlatformData types
- Render platform OS icons from svgLibrary in AdminApps tabs and Connection page
- Replace platform dropdown with icon pill buttons on connection page
- Use .card class with colored left border for block cards
- Unify all back buttons with AdminBackButton pattern (border + bg)
- Fix app chips and platform tabs to not blend with background (btn-secondary style)
- Use accent outlined style for block action buttons matching original RemnaWave UI
- Use btn-secondary for tutorial button
SVG library entries from RemnaWave API are plain strings, not objects
with svgString property. Also map named colors (violet, cyan, teal, etc.)
to hex values for correct icon background rendering.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Redesign app selector from small pills to card buttons with name left
and large SVG icon right matching original RemnaWave subscription page
- Remove broken getAppIcon fallback (📦) for unknown apps
- Add svgIconKey field to app types for app-level logo from svgLibrary
- Use app.svgIconKey for admin apps page icons
- Increase subscription page tile opacity to 50% for readability
- Add temporary debug log to diagnose missing svgIconKey on apps
- Add svgIconKey field to RemnawaveAppClient and RemnawaveApp types
- Render app logos from svgLibrary via app.svgIconKey on connection page
chips with fallback to getAppIcon() by name
- Use app.svgIconKey for app icons on admin apps settings page
- Show featured indicator as amber dot matching original RemnaWave UI
- Increase inner tile background opacity from 30% to 50% on subscription
page for better text readability
- Wire baseTranslations from RemnaWave config to connection page UI
(copyLink, openApp, installApp, addSubscription, connectAndUse,
tutorial, close) with locale fallback: current lang → en → ru → first
- Add tutorial button when baseSettings.isShowTutorialButton is enabled
- Fix SVG icon rendering on admin apps settings page with proper scaling
- Add colored circle backgrounds for block and app icons in admin panel
- Add tutorial translation key to all locale files
- Add @kastov/cryptohapp + jsencrypt for encrypted Happ deep links
- Add templateEngine utility to resolve {{SUBSCRIPTION_LINK}},
{{HAPP_CRYPT3_LINK}}, {{HAPP_CRYPT4_LINK}}, {{USERNAME}} templates
- Convert ConnectionModal component into a standalone Connection page
- Add /connection route with ProtectedRoute and lazy loading
- Replace modal invocation in Dashboard and Subscription with
navigate('/connection')
- Add type and svgIconKey optional fields to RemnawaveButton
- Show button type badge and SVG icon in AdminApps BlockCard
- Refactor ThemeTab to use local draft state with Save/Cancel flow