- Add glassTheme utility with theme-aware color tokens
- Replace hardcoded rgba(255,255,255,...) with dynamic values
- Replace text-white with text-dark-50 for auto theme remapping
- Restyle subscription page block to match dashboard glassmorphic design
- Light mode: white semi-opaque cards with subtle shadows
- Dark mode: unchanged visual appearance
Decompose monolithic Dashboard into SubscriptionCardActive,
SubscriptionCardExpired, TrialOfferCard, and StatsGrid sub-components.
Replace Subscription page progress bar with TrafficProgressBar compact.
Add i18n keys for traffic zones, stats labels, expired/trial states.
Redesign applyPromoDiscount to apply promo offer on top of promo group
prices instead of treating them as mutually exclusive. Calculate combined
discount percent from the deepest original price. Show promo banner in
confirm step regardless of existing server discounts.
servers_count already represents squad count on backend.
Renamed display labels to "locations" on tariff cards and
confirmation view. Server names still shown in subscription card.
- Fix falsy check: selectedTrafficPackage !== null instead of truthy
(gb=0 for unlimited was evaluated as false, hiding the buy button)
- Show "Buy Unlimited" instead of "Buy 0 GB" for unlimited packages
- Add buyUnlimited translation key to all 4 locales
- 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
- 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
- Add getAvailableServers helper to filter available servers
- Skip servers step in purchase wizard when only 1 server available
- Auto-select the single server on options load and period change
- Works for both new purchases and renewals in classic mode
- Add discount fields to TrafficPackage and TariffSwitchPreview types
- Show strikethrough original price and discount badge for device purchase
- Show discount badge and original price for traffic packages
- Show discount info and free label for tariff switch with 100% discount
- Add closeOthersSignal to success notification store
- Create useCloseOnSuccessNotification hook for modals to subscribe
- Update TopUpModal to auto-close on success events
- Update InsufficientBalancePrompt to auto-close on success events
- Update Subscription page to close all modals/forms on success events
This ensures that when a WebSocket event indicates successful payment
or subscription purchase, all related modals close automatically,
providing clear feedback to users.
Resolves conflict where subscription.servers existed as both a nested
object (for server management UI keys) and a pluralization base key.
Renamed the nested object to serverManagement in all 4 locales and
updated all t() references in Subscription.tsx.