From 4dfe71f3929989550e92bfdf125b1a195f0ad1ef Mon Sep 17 00:00:00 2001 From: 3252a8 <3252a8@proton.me> Date: Thu, 28 May 2026 15:21:55 +0300 Subject: [PATCH] fix: align demo state flows --- docs-site/public/demo/demo-shell.js | 23 ++-- docs-site/src/pages/demo.astro | 2 - docs/getting-started/demo.md | 2 +- frontend/src/App.svelte | 8 +- frontend/src/lib/webapp/previewMock.js | 140 ++++++++++++------------- 5 files changed, 94 insertions(+), 81 deletions(-) diff --git a/docs-site/public/demo/demo-shell.js b/docs-site/public/demo/demo-shell.js index 4ae20aa..f370876 100644 --- a/docs-site/public/demo/demo-shell.js +++ b/docs-site/public/demo/demo-shell.js @@ -7,8 +7,6 @@ const stateMocks = new Set([ "depleted", "no-subscription", "trial", - "expiring", - "traffic", "devices", ]); const routeMocks = new Set([...stateMocks, "guides", "install"]); @@ -74,8 +72,19 @@ const routeFromParams = () => { return "/home"; }; -const initialRoute = routeFromParams(); -params.set("mock", normalizeRouteMock(params.get("mock"))); +const initialMock = normalizeRouteMock(params.get("mock")); +let initialRoute = routeFromParams(); +if (initialMock === "trial" && initialRoute === "/trial") { + initialRoute = "/home"; + const normalizedUrl = new URL(window.location.href); + normalizedUrl.pathname = `${demoBase}/home`; + window.history.replaceState( + null, + "", + `${normalizedUrl.pathname}${normalizedUrl.search}${normalizedUrl.hash}` + ); +} +params.set("mock", initialMock); params.delete("path"); params.delete("screen"); params.delete("admin_section"); @@ -103,6 +112,7 @@ const materializedRouteFromRuntime = (route) => { }; const publicPathFromRoute = (route) => `${demoBase}${materializedRouteFromRuntime(route)}`; +const routeForStateMock = (mock) => (mock === "devices" ? "/devices" : "/home"); const runtimeSrc = (route, searchParams = new URLSearchParams()) => { const nextParams = new URLSearchParams(searchParams); nextParams.delete("screen"); @@ -161,7 +171,8 @@ stateSelect?.addEventListener("change", () => { else nextParams.set("mock", mock); const query = nextParams.toString(); - const publicUrl = `${demoBase}/home${query ? `?${query}` : ""}`; + const stateRoute = routeForStateMock(mock); + const publicUrl = `${demoBase}${stateRoute}${query ? `?${query}` : ""}`; window.history.replaceState(null, "", publicUrl); - frame.src = runtimeSrc("/home", nextParams); + frame.src = runtimeSrc(stateRoute, nextParams); }); diff --git a/docs-site/src/pages/demo.astro b/docs-site/src/pages/demo.astro index eb19f6a..0104e56 100644 --- a/docs-site/src/pages/demo.astro +++ b/docs-site/src/pages/demo.astro @@ -291,8 +291,6 @@ const docsHref = '/getting-started/demo/'; - - diff --git a/docs/getting-started/demo.md b/docs/getting-started/demo.md index a56e0e5..28c2a32 100644 --- a/docs/getting-started/demo.md +++ b/docs/getting-started/demo.md @@ -10,7 +10,7 @@ - [Инструкции подключения](/demo/install?mock=guides) - [Админка: пользователи](/demo/admin/users) - [Админка: бэкапы](/demo/admin/backups) -- [Пробный период](/demo/trial?mock=trial) +- [Пробный период](/demo/home?mock=trial) - [Устройства](/demo/devices?mock=devices) ## Как собирается diff --git a/frontend/src/App.svelte b/frontend/src/App.svelte index 82e7153..311d68e 100644 --- a/frontend/src/App.svelte +++ b/frontend/src/App.svelte @@ -613,7 +613,13 @@ } activationHandoff.acknowledge(subscriptionKey, context, payload, state); stopPendingActivationWatch(); - navigateToActivationTarget({ replace: true }); + activationSuccessUseInstallGuides = canUseInstallGuides(); + billingStore.closePaymentModal(); + activeTab = "home"; + if (!activationSuccessUseInstallGuides) { + screen = "home"; + syncAppSectionPath("home", true); + } activationSuccessDialogOpen = true; return true; } diff --git a/frontend/src/lib/webapp/previewMock.js b/frontend/src/lib/webapp/previewMock.js index a825eb2..d59eabf 100644 --- a/frontend/src/lib/webapp/previewMock.js +++ b/frontend/src/lib/webapp/previewMock.js @@ -551,57 +551,7 @@ export function applyPreviewMock(kind) { return; } - if (mode === "traffic") { - DEV_MOCK.data.settings.traffic_mode = true; - DEV_MOCK.data.settings.trial_available = false; - DEV_MOCK.data.subscription = { - ...DEV_MOCK.data.subscription, - active: true, - status: "ACTIVE", - remaining_text: "Навсегда", - end_date_text: "01.01.2099 00:00", - days_left: 26000, - traffic_used: "18.4 GB", - traffic_limit: "100 GB", - traffic_used_bytes: 19756849561, - traffic_limit_bytes: 107374182400, - traffic_limit_strategy: "NO_RESET", - }; - DEV_MOCK.data.plans = [ - { - months: 10, - traffic_gb: 10, - price: 199, - currency: "RUB", - title: "10 GB", - sale_mode: "traffic", - }, - { - months: 50, - traffic_gb: 50, - price: 799, - currency: "RUB", - title: "50 GB", - sale_mode: "traffic", - }, - { - months: 100, - traffic_gb: 100, - price: 1390, - currency: "RUB", - title: "100 GB", - sale_mode: "traffic", - }, - { - months: 300, - traffic_gb: 300, - price: 3490, - currency: "RUB", - title: "300 GB", - sale_mode: "traffic", - }, - ]; - } else if (mode === "tariffs") { + if (mode === "tariffs") { DEV_MOCK.data.settings.traffic_mode = false; if (DEMO_DATASET.plans?.length) { applyDemoTariffScenario(); @@ -782,32 +732,80 @@ export function applyPreviewMock(kind) { return; } else if (mode === "no-subscription" || mode === "inactive") { applyInactiveSubscriptionScenario(); - } else if (mode === "expiring" || mode === "ending-soon") { - DEV_MOCK.data.settings.traffic_mode = false; - DEV_MOCK.data.settings.trial_available = false; - if (DEMO_DATASET.plans?.length) { - applyDemoTariffScenario({ - remaining_text: "2 д.", - end_date_text: "30.05.2026", - days_left: 2, - }); - return; - } - DEV_MOCK.data.subscription = { - ...DEV_MOCK.data.subscription, - active: true, - remaining_text: "2 д.", - end_date_text: "30.05.2026", - days_left: 2, - }; } else if (mode === "devices") { + const baseDevices = DEV_MOCK.data.devices || {}; + const baseList = Array.isArray(baseDevices.devices) ? baseDevices.devices : []; + const devices = [ + ...baseList, + { + display_name: "iPad Pro", + platform_label: "iPadOS 18.4", + user_agent: "Streisand/1.6 CFNetwork", + created_at_text: "18.05.2026 12:30", + hwid_short: "D3MOIPAD...7712AA", + token: "demo-device-ipad", + can_disconnect: true, + }, + { + display_name: "Windows Laptop", + platform_label: "Windows 11", + user_agent: "Hiddify/2.5.7", + created_at_text: "21.05.2026 19:45", + hwid_short: "D3MOWIN...50CC91", + token: "demo-device-windows", + can_disconnect: true, + }, + ] + .slice(0, 5) + .map((device, index) => ({ ...device, index: index + 1 })); DEV_MOCK.data.settings.my_devices_enabled = true; + DEV_MOCK.data.devices = { + ...baseDevices, + ok: true, + enabled: true, + current_devices: 5, + max_devices: 5, + max_devices_label: "5", + devices, + }; DEV_MOCK.data.subscription = { ...DEV_MOCK.data.subscription, active: true, max_devices: 5, - extra_hwid_devices: 2, - extra_hwid_devices_valid_until_text: "01.06.2026 12:00", + can_topup_devices: true, + extra_hwid_devices: 0, + extra_hwid_devices_valid_until_text: "", + }; + DEV_MOCK.data.device_topup_options = { + ok: true, + current_devices: 5, + max_devices: 5, + available_extra_devices: 3, + extra_hwid_devices: 0, + plans: [ + { + id: "standard:hwid:1", + tariff_key: "standard", + tariff_name: "Стандарт", + sale_mode: "hwid_device", + purchased_hwid_devices: 1, + price: 120, + currency: "RUB", + title: "+1 устройство", + device_count: 1, + }, + { + id: "standard:hwid:3", + tariff_key: "standard", + tariff_name: "Стандарт", + sale_mode: "hwid_device", + purchased_hwid_devices: 3, + price: 290, + currency: "RUB", + title: "+3 устройства", + device_count: 3, + }, + ], }; } else if (mode === "trial") { applyInactiveSubscriptionScenario({ trialAvailable: true });