feat: show optional serivce description before payment
This commit is contained in:
@@ -279,6 +279,9 @@
|
||||
$: plans = data?.plans?.length ? data.plans : DEV_MOCK.data.plans;
|
||||
$: methods = data?.payment_methods?.length ? data.payment_methods : [];
|
||||
$: appSettings = data?.settings || DEV_MOCK.data.settings;
|
||||
$: subscriptionPurchaseDescription = String(
|
||||
appSettings?.subscription_purchase_description || ""
|
||||
).trim();
|
||||
$: trafficMode = Boolean(appSettings?.traffic_mode);
|
||||
$: tariffMode = plans.some((plan) => plan?.tariff_key);
|
||||
$: tariffCatalog = buildTariffCatalog(plans);
|
||||
@@ -1321,6 +1324,7 @@
|
||||
{selectedTariffPlans}
|
||||
{singleTariffMode}
|
||||
{subscription}
|
||||
{subscriptionPurchaseDescription}
|
||||
{tariffCatalog}
|
||||
{tariffMode}
|
||||
closeDeviceDisconnectDialog={devicesStore.closeDeviceDisconnectDialog}
|
||||
|
||||
@@ -269,6 +269,14 @@
|
||||
value={valueFor(field) ?? ""}
|
||||
oninput={(e) => settingsStore.markDirty(field.key, e.currentTarget.value)}
|
||||
/>
|
||||
{:else if field.type === "text"}
|
||||
<textarea
|
||||
class="admin-setting-textarea"
|
||||
rows="4"
|
||||
placeholder={field.placeholder}
|
||||
value={valueFor(field) ?? ""}
|
||||
oninput={(e) => settingsStore.markDirty(field.key, e.currentTarget.value)}
|
||||
></textarea>
|
||||
{:else if field.secret}
|
||||
<input
|
||||
class="input"
|
||||
|
||||
@@ -669,6 +669,10 @@ export async function mockApi(path, options = {}, context = {}) {
|
||||
}
|
||||
const language = normalizeLangCode(payload?.language || currentLang);
|
||||
DEV_MOCK.data.user.language_code = language;
|
||||
DEV_MOCK.data.settings.subscription_purchase_description =
|
||||
language === "en"
|
||||
? "By buying or renewing a subscription, you get access to a VPN/proxy service that helps protect your connection and keep your access stable."
|
||||
: "Покупая или продлевая подписку, вы получаете доступ к VPN/прокси-сервису, который помогает защищать ваше соединение и поддерживать стабильный доступ к сети.";
|
||||
return { ok: true, language };
|
||||
}
|
||||
if (path === "/account/email/request" && String(options.method || "").toUpperCase() === "POST") {
|
||||
|
||||
@@ -222,6 +222,8 @@ export const DEV_MOCK = {
|
||||
trial_duration_days: 5,
|
||||
trial_traffic_limit_gb: 10,
|
||||
trial_traffic_strategy: "NO_RESET",
|
||||
subscription_purchase_description:
|
||||
"Покупая или продлевая подписку, вы получаете доступ к VPN/прокси-сервису, который помогает защищать ваше соединение и поддерживать стабильный доступ к сети.",
|
||||
email_auth_enabled: true,
|
||||
},
|
||||
},
|
||||
|
||||
@@ -206,6 +206,7 @@
|
||||
|
||||
.admin-setting-control .input,
|
||||
.admin-setting-control .admin-setting-select,
|
||||
.admin-setting-control .admin-setting-textarea,
|
||||
.admin-setting-control input[type="text"],
|
||||
.admin-setting-control input[type="number"] {
|
||||
flex: 1 1 160px;
|
||||
@@ -213,6 +214,25 @@
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.admin-setting-control .admin-setting-textarea {
|
||||
min-height: 86px;
|
||||
resize: vertical;
|
||||
border-radius: 8px;
|
||||
border: 1px solid var(--admin-border-strong);
|
||||
background: color-mix(in srgb, var(--admin-bg) 82%, var(--admin-surface-2));
|
||||
color: var(--admin-text);
|
||||
padding: 10px 12px;
|
||||
font-size: 13px;
|
||||
line-height: 1.45;
|
||||
outline: none;
|
||||
transition: border-color 0.12s ease, box-shadow 0.12s ease;
|
||||
}
|
||||
|
||||
.admin-setting-control .admin-setting-textarea:focus {
|
||||
border-color: var(--admin-ring);
|
||||
box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 20%, transparent);
|
||||
}
|
||||
|
||||
.admin-btn.admin-btn-icon {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
|
||||
@@ -795,6 +795,24 @@ a {
|
||||
line-height: 1.35;
|
||||
}
|
||||
|
||||
.subscription-purchase-description {
|
||||
display: grid;
|
||||
gap: 6px;
|
||||
padding: 11px 12px;
|
||||
border: 1px solid color-mix(in srgb, var(--accent) 34%, var(--border));
|
||||
border-radius: var(--radius);
|
||||
background: color-mix(in srgb, var(--accent) 8%, var(--surface-muted));
|
||||
box-shadow: inset 0 1px 0 var(--inset-highlight);
|
||||
}
|
||||
|
||||
.subscription-purchase-description p {
|
||||
margin: 0;
|
||||
color: var(--text);
|
||||
font-size: 12px;
|
||||
line-height: 1.45;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.skeleton-row,
|
||||
.skeleton-method,
|
||||
.skeleton-pay-button {
|
||||
|
||||
@@ -64,6 +64,7 @@
|
||||
export let setPasswordValue = "";
|
||||
export let singleTariffMode = false;
|
||||
export let subscription = {};
|
||||
export let subscriptionPurchaseDescription = "";
|
||||
export let tariffCatalog = [];
|
||||
export let tariffMode = false;
|
||||
export let trafficMode = false;
|
||||
@@ -111,6 +112,13 @@
|
||||
return trafficMode ? t("wa_traffic_packages_choose") : t("wa_subscription_choose_period");
|
||||
}
|
||||
|
||||
function showSubscriptionPurchaseDescription() {
|
||||
if (!subscriptionPurchaseDescription || trafficMode) return false;
|
||||
if (!tariffMode) return true;
|
||||
if (paymentStep === "tariff") return false;
|
||||
return String(selectedTariff?.billing_model || "period").toLowerCase() !== "traffic";
|
||||
}
|
||||
|
||||
export let closeDeviceDisconnectDialog = () => {};
|
||||
export let closeLinkEmailDialog = () => {};
|
||||
export let closePaymentModal = () => {};
|
||||
@@ -184,6 +192,11 @@
|
||||
</p>
|
||||
{/if}
|
||||
{#if selectedTariffPlans.length}
|
||||
{#if showSubscriptionPurchaseDescription()}
|
||||
<div class="subscription-purchase-description">
|
||||
<p>{subscriptionPurchaseDescription}</p>
|
||||
</div>
|
||||
{/if}
|
||||
<div class="period-grid period-grid-two-columns">
|
||||
{#each selectedTariffPlans as plan}
|
||||
<button
|
||||
@@ -233,6 +246,11 @@
|
||||
branch above, so users on legacy mode saw the period grid, payment
|
||||
method grid and pay button duplicated.
|
||||
-->
|
||||
{#if showSubscriptionPurchaseDescription()}
|
||||
<div class="subscription-purchase-description">
|
||||
<p>{subscriptionPurchaseDescription}</p>
|
||||
</div>
|
||||
{/if}
|
||||
<div class="period-grid period-grid-two-columns">
|
||||
{#each plans as plan}
|
||||
<button
|
||||
|
||||
Reference in New Issue
Block a user