mirror of
https://github.com/chillpadclub/bedolaga-cabinet.git
synced 2026-07-28 09:33:46 +00:00
Dev (#394)
* 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>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { useState, useEffect, useRef, useCallback, memo } from 'react';
|
||||
import { useState, useEffect, useRef, useCallback, useMemo, memo } from 'react';
|
||||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Navigate, useNavigate, useParams } from 'react-router';
|
||||
@@ -18,6 +18,7 @@ import { useCloseOnSuccessNotification } from '../store/successNotification';
|
||||
import PurchaseCTAButton from '../components/subscription/PurchaseCTAButton';
|
||||
import { CopyIcon, CheckIcon } from '../components/icons';
|
||||
import { useHaptic } from '../platform';
|
||||
import { resolveConnectionUrlForUi } from '../utils/connectionLink';
|
||||
import {
|
||||
getErrorMessage,
|
||||
getInsufficientBalanceError,
|
||||
@@ -221,9 +222,41 @@ export default function Subscription() {
|
||||
staleTime: 0,
|
||||
refetchOnMount: 'always',
|
||||
});
|
||||
const { data: connectionLink, isLoading: isConnectionLinkLoading } = useQuery({
|
||||
queryKey: ['connection-link', subscriptionId],
|
||||
queryFn: () => subscriptionApi.getConnectionLink(subscriptionId),
|
||||
retry: false,
|
||||
staleTime: 0,
|
||||
});
|
||||
|
||||
// Extract subscription from response (null if no subscription)
|
||||
const subscription = subscriptionResponse?.subscription ?? null;
|
||||
const displayedConnectionUrl = useMemo(
|
||||
() =>
|
||||
resolveConnectionUrlForUi({
|
||||
mode: connectionLink?.connect_mode,
|
||||
happSchemeLink: connectionLink?.happ_scheme_link,
|
||||
displayLink: connectionLink?.display_link,
|
||||
subscriptionUrl: connectionLink?.subscription_url,
|
||||
happCryptLink: connectionLink?.happ_cryptolink,
|
||||
happCryptoLink: connectionLink?.happ_crypto_link,
|
||||
happLink: connectionLink?.happ_link,
|
||||
fallbackUrl: isConnectionLinkLoading ? null : (subscription?.subscription_url ?? null),
|
||||
}),
|
||||
[
|
||||
connectionLink?.connect_mode,
|
||||
connectionLink?.display_link,
|
||||
connectionLink?.happ_cryptolink,
|
||||
connectionLink?.happ_crypto_link,
|
||||
connectionLink?.happ_link,
|
||||
connectionLink?.happ_scheme_link,
|
||||
connectionLink?.subscription_url,
|
||||
isConnectionLinkLoading,
|
||||
subscription?.subscription_url,
|
||||
],
|
||||
);
|
||||
const shouldHideConnectionLink =
|
||||
subscription?.hide_subscription_link || connectionLink?.hide_link;
|
||||
|
||||
// Traffic zone (theme-aware) — called unconditionally at top level
|
||||
const usedPercent = trafficData?.traffic_used_percent ?? subscription?.traffic_used_percent ?? 0;
|
||||
@@ -453,8 +486,8 @@ export default function Subscription() {
|
||||
}, [subscription, refreshTrafficMutation, subscriptionId]);
|
||||
|
||||
const copyUrl = () => {
|
||||
if (subscription?.subscription_url) {
|
||||
navigator.clipboard.writeText(subscription.subscription_url);
|
||||
if (displayedConnectionUrl) {
|
||||
navigator.clipboard.writeText(displayedConnectionUrl);
|
||||
setCopied(true);
|
||||
setTimeout(() => setCopied(false), 2000);
|
||||
}
|
||||
@@ -890,16 +923,17 @@ export default function Subscription() {
|
||||
)}
|
||||
|
||||
{/* ─── Subscription URL ─── */}
|
||||
{subscription.subscription_url && !subscription.hide_subscription_link && (
|
||||
{displayedConnectionUrl && !shouldHideConnectionLink && (
|
||||
<div className="mb-5 flex gap-2">
|
||||
<code
|
||||
className="scrollbar-hide flex-1 overflow-x-auto break-all rounded-[10px] px-3 py-2 font-mono text-[11px] text-dark-50/30"
|
||||
className="block min-w-0 flex-1 truncate whitespace-nowrap rounded-[10px] px-3 py-2 font-mono text-[11px] text-dark-50/30"
|
||||
style={{
|
||||
background: g.codeBg,
|
||||
border: `1px solid ${g.codeBorder}`,
|
||||
}}
|
||||
title={displayedConnectionUrl}
|
||||
>
|
||||
{subscription.subscription_url}
|
||||
{displayedConnectionUrl}
|
||||
</code>
|
||||
<button
|
||||
onClick={copyUrl}
|
||||
|
||||
Reference in New Issue
Block a user