feat: lock traffic topup when under 80% of traffic used
This commit is contained in:
@@ -35,6 +35,9 @@
|
|||||||
import { normalizedEmail, telegramName } from "./lib/webapp/formatters.js";
|
import { normalizedEmail, telegramName } from "./lib/webapp/formatters.js";
|
||||||
import { activeTariffName, buildTariffCatalog } from "./lib/webapp/tariffs.js";
|
import { activeTariffName, buildTariffCatalog } from "./lib/webapp/tariffs.js";
|
||||||
import { premiumTrafficPercent, trafficPercent } from "./lib/webapp/traffic.js";
|
import { premiumTrafficPercent, trafficPercent } from "./lib/webapp/traffic.js";
|
||||||
|
|
||||||
|
/** Used-traffic percent from which top-up modals and CTAs unlock in the web app home screen */
|
||||||
|
const TRAFFIC_TOPUP_UNLOCK_PERCENT = 80;
|
||||||
import { buildGravatarUrl } from "./lib/webapp/gravatar.js";
|
import { buildGravatarUrl } from "./lib/webapp/gravatar.js";
|
||||||
import { createBillingActions } from "./lib/webapp/billingActions.js";
|
import { createBillingActions } from "./lib/webapp/billingActions.js";
|
||||||
import { invalidateWebappTariffOptionCaches } from "./lib/webapp/billingOptionCache.js";
|
import { invalidateWebappTariffOptionCaches } from "./lib/webapp/billingOptionCache.js";
|
||||||
@@ -215,10 +218,26 @@
|
|||||||
(subscription?.can_topup_premium_traffic ?? subscription?.can_topup_traffic) &&
|
(subscription?.can_topup_premium_traffic ?? subscription?.can_topup_traffic) &&
|
||||||
Number(subscription?.premium_limit_bytes || 0) > 0,
|
Number(subscription?.premium_limit_bytes || 0) > 0,
|
||||||
);
|
);
|
||||||
$: canOpenTopupModal = Boolean(canOpenRegularTopupModal || canOpenPremiumTopupModal);
|
$: activeTariffCatalogEntry =
|
||||||
$: canShowTopupButton = Boolean(
|
tariffCatalog.find((entry) => entry.key === String(subscription?.tariff_key || "").trim()) || null;
|
||||||
canOpenTopupModal &&
|
$: subscriptionIsTrafficTariff = Boolean(
|
||||||
(trafficPercent(subscription) >= 85 || premiumTrafficPercent(subscription) >= 85),
|
String(subscription?.billing_model || activeTariffCatalogEntry?.billing_model || "")
|
||||||
|
.toLowerCase() === "traffic",
|
||||||
|
);
|
||||||
|
$: regularTrafficTopupUnlocked = Boolean(
|
||||||
|
canOpenRegularTopupModal && trafficPercent(subscription) >= TRAFFIC_TOPUP_UNLOCK_PERCENT,
|
||||||
|
);
|
||||||
|
$: premiumTrafficTopupUnlocked = Boolean(
|
||||||
|
canOpenPremiumTopupModal && premiumTrafficPercent(subscription) >= TRAFFIC_TOPUP_UNLOCK_PERCENT,
|
||||||
|
);
|
||||||
|
/** Progress-bar card opens top-up immediately on traffic-only tariffs; period tariffs still need 80% usage */
|
||||||
|
$: regularTrafficTopupBarClickable = Boolean(
|
||||||
|
canOpenRegularTopupModal &&
|
||||||
|
(subscriptionIsTrafficTariff || trafficPercent(subscription) >= TRAFFIC_TOPUP_UNLOCK_PERCENT),
|
||||||
|
);
|
||||||
|
$: premiumTrafficTopupBarClickable = Boolean(
|
||||||
|
canOpenPremiumTopupModal &&
|
||||||
|
(subscriptionIsTrafficTariff || premiumTrafficPercent(subscription) >= TRAFFIC_TOPUP_UNLOCK_PERCENT),
|
||||||
);
|
);
|
||||||
$: user = data?.user || {};
|
$: user = data?.user || {};
|
||||||
$: isAdmin = Boolean(user?.is_admin);
|
$: isAdmin = Boolean(user?.is_admin);
|
||||||
@@ -877,12 +896,13 @@
|
|||||||
{brandEmoji}
|
{brandEmoji}
|
||||||
{brandTitle}
|
{brandTitle}
|
||||||
{canChangeTariff}
|
{canChangeTariff}
|
||||||
{canOpenPremiumTopupModal}
|
|
||||||
{canOpenRegularTopupModal}
|
|
||||||
{canShowTopupButton}
|
|
||||||
{currentTariffName}
|
{currentTariffName}
|
||||||
{hasActiveTariffSubscription}
|
{hasActiveTariffSubscription}
|
||||||
{hasMultipleTariffs}
|
{hasMultipleTariffs}
|
||||||
|
{premiumTrafficTopupBarClickable}
|
||||||
|
{premiumTrafficTopupUnlocked}
|
||||||
|
{regularTrafficTopupBarClickable}
|
||||||
|
{regularTrafficTopupUnlocked}
|
||||||
{subscription}
|
{subscription}
|
||||||
{termUnitLabel}
|
{termUnitLabel}
|
||||||
{trafficMode}
|
{trafficMode}
|
||||||
|
|||||||
@@ -23,9 +23,10 @@
|
|||||||
export let brandEmoji = "";
|
export let brandEmoji = "";
|
||||||
export let brandTitle = "";
|
export let brandTitle = "";
|
||||||
export let canChangeTariff = false;
|
export let canChangeTariff = false;
|
||||||
export let canOpenPremiumTopupModal = false;
|
export let premiumTrafficTopupBarClickable = false;
|
||||||
export let canOpenRegularTopupModal = false;
|
export let premiumTrafficTopupUnlocked = false;
|
||||||
export let canShowTopupButton = false;
|
export let regularTrafficTopupBarClickable = false;
|
||||||
|
export let regularTrafficTopupUnlocked = false;
|
||||||
export let currentTariffName = "";
|
export let currentTariffName = "";
|
||||||
export let hasActiveTariffSubscription = false;
|
export let hasActiveTariffSubscription = false;
|
||||||
export let hasMultipleTariffs = false;
|
export let hasMultipleTariffs = false;
|
||||||
@@ -86,9 +87,9 @@
|
|||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
{#if subscription.active}
|
{#if subscription.active}
|
||||||
<Card class={canOpenRegularTopupModal ? "traffic-card-clickable" : ""}>
|
<Card class={regularTrafficTopupBarClickable ? "traffic-card-clickable" : ""}>
|
||||||
{#if canOpenRegularTopupModal}
|
{#if regularTrafficTopupBarClickable}
|
||||||
<button class="card-click-target" type="button" onclick={openRegularTopupModal} aria-label={t("wa_topup_traffic")}></button>
|
<button class="card-click-target" type="button" onclick={openRegularTopupModal} aria-label={t("wa_add_traffic")}></button>
|
||||||
{/if}
|
{/if}
|
||||||
<div class="traffic-top">
|
<div class="traffic-top">
|
||||||
<span>{t("wa_home_traffic_used")}</span>
|
<span>{t("wa_home_traffic_used")}</span>
|
||||||
@@ -128,9 +129,14 @@
|
|||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
{:else if Number(subscription?.premium_limit_bytes || 0) > 0}
|
{:else if Number(subscription?.premium_limit_bytes || 0) > 0}
|
||||||
<Card class={`${canOpenPremiumTopupModal ? "traffic-card-clickable " : ""}premium-traffic-card${subscription?.premium_is_limited ? " premium-traffic-card-limited" : ""}`}>
|
<Card class={`${premiumTrafficTopupBarClickable ? "traffic-card-clickable " : ""}premium-traffic-card${subscription?.premium_is_limited ? " premium-traffic-card-limited" : ""}`}>
|
||||||
{#if canOpenPremiumTopupModal}
|
{#if premiumTrafficTopupBarClickable}
|
||||||
<button class="card-click-target" type="button" onclick={openPremiumTopupModal} aria-label={premiumTitle(subscription)}></button>
|
<button
|
||||||
|
class="card-click-target"
|
||||||
|
type="button"
|
||||||
|
onclick={openPremiumTopupModal}
|
||||||
|
aria-label={t("wa_add_traffic_premium", { target: premiumTitle(subscription) })}
|
||||||
|
></button>
|
||||||
{/if}
|
{/if}
|
||||||
<div class="traffic-top">
|
<div class="traffic-top">
|
||||||
<span>{premiumTitle(subscription)}</span>
|
<span>{premiumTitle(subscription)}</span>
|
||||||
@@ -199,10 +205,16 @@
|
|||||||
{t("wa_change_tariff")}
|
{t("wa_change_tariff")}
|
||||||
</Button>
|
</Button>
|
||||||
{/if}
|
{/if}
|
||||||
{#if canShowTopupButton}
|
{#if regularTrafficTopupUnlocked}
|
||||||
<Button class="wide" variant="secondary" onclick={canOpenRegularTopupModal ? openRegularTopupModal : openPremiumTopupModal}>
|
<Button class="wide" variant="secondary" onclick={openRegularTopupModal}>
|
||||||
<Database size={18} />
|
<Database size={18} />
|
||||||
{t("wa_topup_traffic")}
|
{t("wa_add_traffic")}
|
||||||
|
</Button>
|
||||||
|
{/if}
|
||||||
|
{#if premiumTrafficTopupUnlocked}
|
||||||
|
<Button class="wide" variant="secondary" onclick={openPremiumTopupModal}>
|
||||||
|
<Database size={18} />
|
||||||
|
{t("wa_add_traffic_premium", { target: premiumTitle(subscription) })}
|
||||||
</Button>
|
</Button>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -701,6 +701,8 @@
|
|||||||
"wa_tariff_no_description": "Tariff description is not configured",
|
"wa_tariff_no_description": "Tariff description is not configured",
|
||||||
"wa_change_tariff": "Change tariff",
|
"wa_change_tariff": "Change tariff",
|
||||||
"wa_topup_traffic": "Buy traffic",
|
"wa_topup_traffic": "Buy traffic",
|
||||||
|
"wa_add_traffic": "Add traffic",
|
||||||
|
"wa_add_traffic_premium": "Add traffic on {target}",
|
||||||
"wa_current_tariff": "Current tariff: {tariff}",
|
"wa_current_tariff": "Current tariff: {tariff}",
|
||||||
"wa_tariff_options_loading": "Loading options",
|
"wa_tariff_options_loading": "Loading options",
|
||||||
"wa_tariff_options_failed": "Failed to load tariff options",
|
"wa_tariff_options_failed": "Failed to load tariff options",
|
||||||
|
|||||||
@@ -701,6 +701,8 @@
|
|||||||
"wa_tariff_no_description": "Описание тарифа не задано",
|
"wa_tariff_no_description": "Описание тарифа не задано",
|
||||||
"wa_change_tariff": "Сменить тариф",
|
"wa_change_tariff": "Сменить тариф",
|
||||||
"wa_topup_traffic": "Докупить трафик",
|
"wa_topup_traffic": "Докупить трафик",
|
||||||
|
"wa_add_traffic": "Добавить трафик",
|
||||||
|
"wa_add_traffic_premium": "Добавить трафик на {target}",
|
||||||
"wa_current_tariff": "Текущий тариф: {tariff}",
|
"wa_current_tariff": "Текущий тариф: {tariff}",
|
||||||
"wa_tariff_options_loading": "Загружаем варианты",
|
"wa_tariff_options_loading": "Загружаем варианты",
|
||||||
"wa_tariff_options_failed": "Не удалось загрузить варианты тарифов",
|
"wa_tariff_options_failed": "Не удалось загрузить варианты тарифов",
|
||||||
|
|||||||
Reference in New Issue
Block a user