823 lines
26 KiB
JavaScript
823 lines
26 KiB
JavaScript
import { DEMO_DATASET } from "./demoDataset.js";
|
|
import { withDemoAvatar } from "./demoAvatars.js";
|
|
|
|
const DEMO_LANGUAGE_STORAGE_KEY = "rw_minishop_demo_language";
|
|
|
|
function readStoredDemoLanguage() {
|
|
if (typeof window === "undefined") return "";
|
|
try {
|
|
return window.localStorage?.getItem(DEMO_LANGUAGE_STORAGE_KEY) || "";
|
|
} catch {
|
|
return "";
|
|
}
|
|
}
|
|
|
|
const WINDOWS_95_THEME = {
|
|
key: "windows95",
|
|
names: { ru: "Windows 95", en: "Windows 95" },
|
|
enabled: true,
|
|
default: false,
|
|
css_file: "style.css",
|
|
assets_version: 9,
|
|
tokens: {
|
|
color_scheme: "light",
|
|
style_preset: "win95",
|
|
},
|
|
};
|
|
|
|
const ASCII_THEME = {
|
|
key: "ascii",
|
|
names: { ru: "ASCII", en: "ASCII" },
|
|
enabled: true,
|
|
default: false,
|
|
css_file: "style.css",
|
|
tokens: {
|
|
color_scheme: "dark",
|
|
style_preset: "ascii",
|
|
},
|
|
};
|
|
|
|
const INSTALL_GUIDES_CONFIG = {
|
|
version: "1",
|
|
locales: ["ru", "en"],
|
|
brandingSettings: {
|
|
title: "/minishop",
|
|
logoUrl: "https://example.com/logo.svg",
|
|
supportUrl: "https://t.me/support",
|
|
},
|
|
uiConfig: {
|
|
subscriptionInfoBlockType: "collapsed",
|
|
installationGuidesBlockType: "cards",
|
|
},
|
|
baseSettings: {
|
|
metaTitle: "Subscription",
|
|
metaDescription: "Subscription",
|
|
showConnectionKeys: false,
|
|
hideGetLinkButton: false,
|
|
},
|
|
baseTranslations: Object.fromEntries(
|
|
[
|
|
"active",
|
|
"bandwidth",
|
|
"connectionKeysHeader",
|
|
"copyLink",
|
|
"expired",
|
|
"expires",
|
|
"expiresIn",
|
|
"getLink",
|
|
"inactive",
|
|
"indefinitely",
|
|
"installationGuideHeader",
|
|
"linkCopied",
|
|
"linkCopiedToClipboard",
|
|
"name",
|
|
"scanQrCode",
|
|
"scanQrCodeDescription",
|
|
"scanToImport",
|
|
"status",
|
|
"unknown",
|
|
].map((key) => [
|
|
key,
|
|
{
|
|
ru: key === "installationGuideHeader" ? "Установка и настройка" : key,
|
|
en: key === "installationGuideHeader" ? "Install and configure" : key,
|
|
},
|
|
])
|
|
),
|
|
svgLibrary: {
|
|
App: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><rect x="5" y="3" width="14" height="18" rx="3"/><path d="M9 7h6M9 17h6"/></svg>',
|
|
Copy: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><rect x="8" y="8" width="10" height="10" rx="2"/><path d="M6 16H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>',
|
|
Desktop:
|
|
'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><rect x="3" y="4" width="18" height="12" rx="2"/><path d="M8 20h8M12 16v4"/></svg>',
|
|
Download:
|
|
'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M12 3v12"/><path d="m7 10 5 5 5-5"/><path d="M5 21h14"/></svg>',
|
|
Phone:
|
|
'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><rect x="7" y="2" width="10" height="20" rx="2"/><path d="M11 18h2"/></svg>',
|
|
},
|
|
platforms: {
|
|
ios: {
|
|
displayName: "iOS",
|
|
svgIconKey: "Phone",
|
|
apps: [
|
|
{
|
|
name: "Streisand",
|
|
svgIconKey: "App",
|
|
featured: true,
|
|
blocks: [
|
|
{
|
|
svgIconKey: "Download",
|
|
svgIconColor: "green",
|
|
title: { ru: "Установите приложение", en: "Install the app" },
|
|
description: {
|
|
ru: "Откройте App Store и установите клиент.",
|
|
en: "Open the App Store and install the client.",
|
|
},
|
|
buttons: [
|
|
{
|
|
type: "external",
|
|
link: "https://apps.apple.com/app/streisand/id6450534064",
|
|
text: { ru: "Открыть App Store", en: "Open App Store" },
|
|
svgIconKey: "Download",
|
|
},
|
|
{
|
|
type: "subscriptionLink",
|
|
link: "streisand://import/{{SUBSCRIPTION_LINK}}",
|
|
text: { ru: "Импортировать", en: "Import" },
|
|
svgIconKey: "App",
|
|
},
|
|
{
|
|
type: "copyButton",
|
|
link: "{{SUBSCRIPTION_LINK}}",
|
|
text: { ru: "Скопировать ссылку", en: "Copy link" },
|
|
svgIconKey: "Copy",
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
android: {
|
|
displayName: "Android",
|
|
svgIconKey: "Phone",
|
|
apps: [
|
|
{
|
|
name: "Happ",
|
|
svgIconKey: "App",
|
|
featured: true,
|
|
blocks: [
|
|
{
|
|
svgIconKey: "Download",
|
|
svgIconColor: "emerald",
|
|
title: { ru: "Установите Happ", en: "Install Happ" },
|
|
description: {
|
|
ru: "Загрузите приложение и добавьте подписку по ссылке.",
|
|
en: "Install the app and add the subscription link.",
|
|
},
|
|
buttons: [
|
|
{
|
|
type: "external",
|
|
link: "https://play.google.com/store/apps/details?id=com.happproxy",
|
|
text: { ru: "Открыть Google Play", en: "Open Google Play" },
|
|
svgIconKey: "Download",
|
|
},
|
|
{
|
|
type: "copyButton",
|
|
link: "{{SUBSCRIPTION_LINK}}",
|
|
text: { ru: "Скопировать ссылку", en: "Copy link" },
|
|
svgIconKey: "Copy",
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
windows: {
|
|
displayName: "Windows",
|
|
svgIconKey: "Desktop",
|
|
apps: [
|
|
{
|
|
name: "Hiddify",
|
|
svgIconKey: "Desktop",
|
|
featured: true,
|
|
blocks: [
|
|
{
|
|
svgIconKey: "Download",
|
|
svgIconColor: "sky",
|
|
title: { ru: "Установите клиент", en: "Install the client" },
|
|
description: {
|
|
ru: "Скачайте приложение и импортируйте ссылку подписки.",
|
|
en: "Download the client and import the subscription link.",
|
|
},
|
|
buttons: [
|
|
{
|
|
type: "external",
|
|
link: "https://github.com/hiddify/hiddify-app/releases",
|
|
text: { ru: "Открыть релизы", en: "Open releases" },
|
|
svgIconKey: "Download",
|
|
},
|
|
{
|
|
type: "copyButton",
|
|
link: "{{SUBSCRIPTION_LINK}}",
|
|
text: { ru: "Скопировать ссылку", en: "Copy link" },
|
|
svgIconKey: "Copy",
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
},
|
|
};
|
|
|
|
export const DEV_MOCK = {
|
|
config: {
|
|
title: "/minishop",
|
|
primaryColor: "#00fe7a",
|
|
logoUrl: "/webapp-default-logo.webp",
|
|
logoUseEmoji: false,
|
|
logoEmoji: "🫥",
|
|
logoEmojiFont: "system",
|
|
faviconUrl: "/webapp-favicon/19b2a242e5b7bc2d/icon-180.png",
|
|
faviconUseCustom: false,
|
|
trialEnabled: true,
|
|
trialDurationDays: 3,
|
|
trialTrafficLimitGb: 5,
|
|
trialTrafficStrategy: "NO_RESET",
|
|
trialSquadUuids: "2f2f6e0a-1f2d-4e80-a33b-0ebf3a409012",
|
|
apiBase: "/api",
|
|
adminJsAsset: "subscription_webapp_admin.js",
|
|
adminCssAsset: "subscription_webapp_admin.css",
|
|
supportUrl: "https://t.me/support",
|
|
privacyPolicyUrl: "https://example.com/privacy",
|
|
userAgreementUrl: "https://example.com/agreement",
|
|
currency: "RUB",
|
|
language: "ru",
|
|
languages: [
|
|
{ code: "ru", label: "Русский", flag: "🇷🇺", base: true },
|
|
{ code: "en", label: "English", flag: "🇬🇧", base: true },
|
|
],
|
|
emailAuthEnabled: true,
|
|
telegramLoginBotUsername: "preview_bot",
|
|
telegramLoginBotId: 1234567890,
|
|
telegramOAuthClientId: 1234567890,
|
|
telegramOAuthRequestAccess: ["write"],
|
|
appVersion: "dev+local",
|
|
appRepositoryUrl: "https://github.com/3252a8/remnawave-minishop",
|
|
themesCatalog: {
|
|
default_theme: "dark",
|
|
themes: [
|
|
{
|
|
key: "dark",
|
|
names: { ru: "Тёмная", en: "Dark" },
|
|
enabled: true,
|
|
default: true,
|
|
tokens: {
|
|
color_scheme: "dark",
|
|
accent: "#00fe7a",
|
|
bg: "#03070b",
|
|
panel: "#111820",
|
|
text: "#f2f7f4",
|
|
muted: "#a9b4b0",
|
|
},
|
|
},
|
|
{
|
|
key: "light",
|
|
names: { ru: "Светлая", en: "Light" },
|
|
enabled: true,
|
|
default: false,
|
|
css_file: "style.css",
|
|
tokens: {
|
|
color_scheme: "light",
|
|
},
|
|
},
|
|
WINDOWS_95_THEME,
|
|
ASCII_THEME,
|
|
],
|
|
},
|
|
},
|
|
data: {
|
|
ok: true,
|
|
user: {
|
|
id: 100200300,
|
|
username: "username",
|
|
email: "user@example.com",
|
|
email_verified: true,
|
|
password_auth_enabled: false,
|
|
telegram_id: 100200300,
|
|
telegram_linked: true,
|
|
telegram_photo_url: "",
|
|
first_name: "Preview",
|
|
language_code: "ru",
|
|
is_admin: true,
|
|
},
|
|
subscription: {
|
|
active: true,
|
|
status: "ACTIVE",
|
|
remaining_text: "25 д. 8 ч.",
|
|
end_date_text: "24.05.2026",
|
|
days_left: 25,
|
|
config_link: "https://sub.example.com/sub/preview-token",
|
|
connect_url: "https://sub.example.com/connect/preview-token",
|
|
panel_short_uuid: "preview-token",
|
|
install_share_token: "8f559061460e8fede78ef18dce887236",
|
|
install_share_url: "https://app.example.com/s/8f559061460e8fede78ef18dce887236",
|
|
traffic_used: "18.4 GB",
|
|
traffic_limit: "100 GB",
|
|
traffic_used_bytes: 19756849561,
|
|
traffic_limit_bytes: 107374182400,
|
|
premium_used: "32.0 GB",
|
|
premium_limit: "50.0 GB",
|
|
premium_used_bytes: 34359738368,
|
|
premium_limit_bytes: 53687091200,
|
|
premium_baseline_bytes: 53687091200,
|
|
premium_topup_balance_bytes: 0,
|
|
premium_is_limited: false,
|
|
premium_title: "Premium-серверы",
|
|
premium_node_labels: ["Premium NL-1", "Premium DE-1"],
|
|
can_topup_regular_traffic: true,
|
|
can_topup_premium_traffic: true,
|
|
max_devices: 5,
|
|
},
|
|
subscription_guides: {
|
|
ok: true,
|
|
enabled: true,
|
|
config: INSTALL_GUIDES_CONFIG,
|
|
source: "mock",
|
|
},
|
|
devices: {
|
|
ok: true,
|
|
enabled: true,
|
|
current_devices: 3,
|
|
max_devices: 5,
|
|
max_devices_label: "5",
|
|
devices: [
|
|
{
|
|
index: 1,
|
|
display_name: "iPhone 15 Pro",
|
|
platform_label: "iOS 18.4",
|
|
user_agent: "Streisand/1.6 CFNetwork",
|
|
created_at_text: "28.04.2026 16:12",
|
|
hwid_short: "A1B2C3D4...98FA01",
|
|
token: "preview-device-1",
|
|
can_disconnect: true,
|
|
},
|
|
{
|
|
index: 2,
|
|
display_name: "MacBook Air",
|
|
platform_label: "macOS 15.4",
|
|
user_agent: "Happ/3.1.0",
|
|
created_at_text: "29.04.2026 09:40",
|
|
hwid_short: "F0E1D2C3...44AB22",
|
|
token: "preview-device-2",
|
|
can_disconnect: true,
|
|
},
|
|
{
|
|
index: 3,
|
|
display_name: "Android Phone",
|
|
platform_label: "Android 15",
|
|
user_agent: "v2rayNG/1.9.35",
|
|
created_at_text: "30.04.2026 07:55",
|
|
hwid_short: "778899AA...BCDD10",
|
|
token: "preview-device-3",
|
|
can_disconnect: true,
|
|
},
|
|
],
|
|
},
|
|
plans: [
|
|
{ months: 1, price: 290, currency: "RUB", title: "1 месяц" },
|
|
{ months: 3, price: 790, currency: "RUB", title: "3 месяца" },
|
|
{ months: 6, price: 1490, currency: "RUB", title: "6 месяцев" },
|
|
{ months: 12, price: 2690, currency: "RUB", title: "12 месяцев" },
|
|
],
|
|
payment_methods: [
|
|
{ id: "yookassa", name: "Карта", icon: "CreditCard" },
|
|
{ id: "platega_sbp", name: "Telegram Pay", icon: "CreditCard" },
|
|
{ id: "cryptopay", name: "Криптовалюта", icon: "Bitcoin" },
|
|
{ id: "freekassa", name: "Другие способы", icon: "Smartphone" },
|
|
],
|
|
referral: {
|
|
code: "ABCD1234",
|
|
bot_link: "https://t.me/preview_bot?start=ref_uABCD1234",
|
|
webapp_link: "https://minishop.app/ref/ABCD1234",
|
|
invited_count: 4,
|
|
purchased_count: 2,
|
|
welcome_bonus_days: 3,
|
|
one_bonus_per_referee: false,
|
|
bonus_details: [
|
|
{ months: 1, title: "1 месяц", inviter_days: 14, friend_days: 7 },
|
|
{ months: 3, title: "3 месяца", inviter_days: 21, friend_days: 14 },
|
|
{ months: 6, title: "6 месяцев", inviter_days: 31, friend_days: 21 },
|
|
{ months: 12, title: "12 месяцев", inviter_days: 62, friend_days: 31 },
|
|
],
|
|
},
|
|
themes_catalog: {
|
|
default_theme: "dark",
|
|
themes: [
|
|
{
|
|
key: "dark",
|
|
names: { ru: "Тёмная", en: "Dark" },
|
|
enabled: true,
|
|
tokens: {
|
|
color_scheme: "dark",
|
|
accent: "#00fe7a",
|
|
bg: "#03070b",
|
|
panel: "#111820",
|
|
text: "#f2f7f4",
|
|
muted: "#a9b4b0",
|
|
},
|
|
},
|
|
{
|
|
key: "light",
|
|
names: { ru: "Светлая", en: "Light" },
|
|
enabled: true,
|
|
css_file: "style.css",
|
|
tokens: {
|
|
color_scheme: "light",
|
|
},
|
|
},
|
|
WINDOWS_95_THEME,
|
|
ASCII_THEME,
|
|
],
|
|
},
|
|
settings: {
|
|
support_url: "https://t.me/support",
|
|
traffic_mode: false,
|
|
my_devices_enabled: false,
|
|
user_hwid_device_limit: 5,
|
|
trial_enabled: true,
|
|
trial_available: true,
|
|
trial_duration_days: 5,
|
|
trial_traffic_limit_gb: 10,
|
|
trial_traffic_strategy: "NO_RESET",
|
|
subscription_purchase_description:
|
|
"Покупая или продлевая подписку, вы получаете доступ к VPN/прокси-сервису, который помогает защищать ваше соединение и поддерживать стабильный доступ к сети.",
|
|
subscription_guides_enabled: true,
|
|
email_auth_enabled: true,
|
|
},
|
|
},
|
|
};
|
|
|
|
function applyDemoDataset() {
|
|
const storedLanguage = readStoredDemoLanguage();
|
|
const demoUser = withDemoAvatar(
|
|
{
|
|
...(DEMO_DATASET.currentUser || {}),
|
|
id: DEMO_DATASET.currentUser?.id ?? DEMO_DATASET.currentUser?.user_id,
|
|
language_code: storedLanguage || DEMO_DATASET.currentUser?.language_code || "ru",
|
|
},
|
|
160
|
|
);
|
|
|
|
Object.assign(DEV_MOCK.config, DEMO_DATASET.config || {});
|
|
DEV_MOCK.config.language = demoUser.language_code || "ru";
|
|
Object.assign(DEV_MOCK.data, {
|
|
user: demoUser,
|
|
subscription: DEMO_DATASET.currentSubscription || DEV_MOCK.data.subscription,
|
|
devices: DEMO_DATASET.devices || DEV_MOCK.data.devices,
|
|
plans: DEMO_DATASET.plans || DEV_MOCK.data.plans,
|
|
payment_methods: DEMO_DATASET.paymentMethods || DEV_MOCK.data.payment_methods,
|
|
referral: DEMO_DATASET.referral || DEV_MOCK.data.referral,
|
|
tariff_change_options:
|
|
DEMO_DATASET.tariff_change_options || DEV_MOCK.data.tariff_change_options,
|
|
topup_options: DEMO_DATASET.topup_options || DEV_MOCK.data.topup_options,
|
|
device_topup_options: DEMO_DATASET.device_topup_options || DEV_MOCK.data.device_topup_options,
|
|
settings: {
|
|
...DEV_MOCK.data.settings,
|
|
...(DEMO_DATASET.webappSettings || {}),
|
|
},
|
|
});
|
|
}
|
|
|
|
applyDemoDataset();
|
|
|
|
function applyDemoTariffScenario(subscriptionPatch = {}) {
|
|
DEV_MOCK.data.subscription = {
|
|
...DEV_MOCK.data.subscription,
|
|
...(DEMO_DATASET.currentSubscription || {}),
|
|
...subscriptionPatch,
|
|
traffic_limit_strategy:
|
|
subscriptionPatch.traffic_limit_strategy ||
|
|
DEMO_DATASET.currentSubscription?.traffic_limit_strategy ||
|
|
DEV_MOCK.data.subscription.traffic_limit_strategy ||
|
|
"MONTH",
|
|
};
|
|
DEV_MOCK.data.plans = DEMO_DATASET.plans;
|
|
DEV_MOCK.data.tariff_change_options =
|
|
DEMO_DATASET.tariff_change_options || DEV_MOCK.data.tariff_change_options;
|
|
DEV_MOCK.data.topup_options = DEMO_DATASET.topup_options || DEV_MOCK.data.topup_options;
|
|
DEV_MOCK.data.device_topup_options =
|
|
DEMO_DATASET.device_topup_options || DEV_MOCK.data.device_topup_options;
|
|
}
|
|
|
|
function applyInactiveSubscriptionScenario({ trialAvailable = false } = {}) {
|
|
DEV_MOCK.data.settings.traffic_mode = false;
|
|
DEV_MOCK.data.settings.trial_enabled = true;
|
|
DEV_MOCK.data.settings.trial_available = Boolean(trialAvailable);
|
|
DEV_MOCK.data.settings.trial_duration_days = 5;
|
|
DEV_MOCK.data.settings.trial_traffic_limit_gb = 10;
|
|
DEV_MOCK.data.subscription = {
|
|
...DEV_MOCK.data.subscription,
|
|
active: false,
|
|
status: "INACTIVE",
|
|
remaining_text: "Подписка не активна",
|
|
end_date_text: "",
|
|
days_left: 0,
|
|
config_link: null,
|
|
connect_url: null,
|
|
panel_short_uuid: "",
|
|
install_share_token: "",
|
|
install_share_url: "",
|
|
traffic_used: "0 B",
|
|
traffic_limit: "0 GB",
|
|
traffic_used_bytes: 0,
|
|
traffic_limit_bytes: 0,
|
|
premium_used_bytes: 0,
|
|
premium_limit_bytes: 0,
|
|
premium_is_limited: false,
|
|
};
|
|
DEV_MOCK.data.plans = DEMO_DATASET.plans || DEV_MOCK.data.plans;
|
|
DEV_MOCK.data.tariff_change_options =
|
|
DEMO_DATASET.tariff_change_options || DEV_MOCK.data.tariff_change_options;
|
|
}
|
|
|
|
export function applyPreviewMock(kind) {
|
|
const mode = String(kind || "")
|
|
.trim()
|
|
.toLowerCase();
|
|
|
|
const themeKeys = new Set((DEV_MOCK.config.themesCatalog.themes || []).map((theme) => theme.key));
|
|
if (themeKeys.has(mode)) {
|
|
DEV_MOCK.config.themesCatalog.default_theme = mode;
|
|
DEV_MOCK.data.themes_catalog.default_theme = mode;
|
|
for (const theme of DEV_MOCK.config.themesCatalog.themes || []) {
|
|
theme.default = theme.key === mode;
|
|
}
|
|
for (const theme of DEV_MOCK.data.themes_catalog.themes || []) {
|
|
theme.default = theme.key === mode;
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (mode === "guides" || mode === "install") {
|
|
DEV_MOCK.data.settings.subscription_guides_enabled = true;
|
|
DEV_MOCK.data.subscription_guides = {
|
|
...DEV_MOCK.data.subscription_guides,
|
|
enabled: true,
|
|
config: INSTALL_GUIDES_CONFIG,
|
|
};
|
|
return;
|
|
}
|
|
|
|
if (mode === "tariffs") {
|
|
DEV_MOCK.data.settings.traffic_mode = false;
|
|
if (DEMO_DATASET.plans?.length) {
|
|
applyDemoTariffScenario();
|
|
return;
|
|
}
|
|
DEV_MOCK.data.subscription = {
|
|
...DEV_MOCK.data.subscription,
|
|
tariff_key: "standard",
|
|
tariff_name: "Стандарт",
|
|
tariff_description: "100 GB каждый месяц",
|
|
billing_model: "period",
|
|
traffic_limit_strategy: "MONTH",
|
|
};
|
|
DEV_MOCK.data.plans = [
|
|
{
|
|
id: "standard:period:1",
|
|
tariff_key: "standard",
|
|
tariff_name: "Стандарт",
|
|
tariff_description: "100 GB каждый месяц",
|
|
billing_model: "period",
|
|
months: 1,
|
|
price: 150,
|
|
currency: "RUB",
|
|
title: "Стандарт",
|
|
subtitle: "1 месяц",
|
|
sale_mode: "subscription",
|
|
},
|
|
{
|
|
id: "standard:period:3",
|
|
tariff_key: "standard",
|
|
tariff_name: "Стандарт",
|
|
tariff_description: "100 GB каждый месяц",
|
|
billing_model: "period",
|
|
months: 3,
|
|
price: 400,
|
|
currency: "RUB",
|
|
title: "Стандарт",
|
|
subtitle: "3 месяца",
|
|
sale_mode: "subscription",
|
|
},
|
|
{
|
|
id: "business:period:1",
|
|
tariff_key: "business",
|
|
tariff_name: "Business",
|
|
tariff_description: "500 GB и premium-серверы",
|
|
billing_model: "period",
|
|
months: 1,
|
|
price: 690,
|
|
currency: "RUB",
|
|
title: "Business",
|
|
subtitle: "1 месяц",
|
|
sale_mode: "subscription",
|
|
},
|
|
];
|
|
DEV_MOCK.data.tariff_change_options = {
|
|
ok: true,
|
|
current: {
|
|
tariff_key: "standard",
|
|
title: "Стандарт",
|
|
description: "100 GB каждый месяц",
|
|
billing_model: "period",
|
|
monthly_gb: 100,
|
|
expires_at: "31.05.2026",
|
|
},
|
|
targets: [
|
|
{
|
|
tariff_key: "business",
|
|
title: "Business",
|
|
description: "500 GB и premium-серверы",
|
|
billing_model: "period",
|
|
monthly_gb: 500,
|
|
price: 690,
|
|
currency: "RUB",
|
|
actions: [
|
|
{
|
|
mode: "recalc_days",
|
|
kind: "free",
|
|
title: "Пересчитать дни",
|
|
days_after: 12,
|
|
remaining_days: 28,
|
|
},
|
|
{
|
|
mode: "paid_diff",
|
|
kind: "payment",
|
|
title: "Доплатить разницу",
|
|
price: 240,
|
|
currency: "RUB",
|
|
},
|
|
],
|
|
},
|
|
],
|
|
};
|
|
DEV_MOCK.data.topup_options = {
|
|
ok: true,
|
|
topup_kind: "regular",
|
|
traffic_mode: false,
|
|
tariff_key: "standard",
|
|
regular: {
|
|
can_topup: true,
|
|
monthly_limit_gb: 100,
|
|
used_gb: 86,
|
|
available_gb: 14,
|
|
packages: [
|
|
{ gb: 10, price: 99, currency: "RUB" },
|
|
{ gb: 50, price: 399, currency: "RUB" },
|
|
],
|
|
},
|
|
premium: {
|
|
can_topup: true,
|
|
monthly_limit_gb: 25,
|
|
used_gb: 24,
|
|
available_gb: 1,
|
|
packages: [
|
|
{ gb: 10, price: 190, currency: "RUB" },
|
|
{ gb: 25, price: 390, currency: "RUB" },
|
|
],
|
|
},
|
|
plans: [
|
|
{
|
|
id: "standard:topup:10",
|
|
tariff_key: "standard",
|
|
tariff_name: "Стандарт",
|
|
sale_mode: "topup",
|
|
traffic_gb: 10,
|
|
months: 10,
|
|
price: 99,
|
|
currency: "RUB",
|
|
title: "10 GB",
|
|
subtitle: "Стандарт",
|
|
},
|
|
{
|
|
id: "standard:premium_topup:10",
|
|
tariff_key: "standard",
|
|
tariff_name: "Стандарт",
|
|
sale_mode: "premium_topup",
|
|
traffic_gb: 10,
|
|
months: 10,
|
|
price: 190,
|
|
currency: "RUB",
|
|
title: "Premium 10 GB",
|
|
subtitle: "Стандарт",
|
|
},
|
|
],
|
|
};
|
|
DEV_MOCK.data.device_topup_options = {
|
|
ok: true,
|
|
current_devices: 1,
|
|
max_devices: 2,
|
|
available_extra_devices: 3,
|
|
packages: [
|
|
{ count: 1, price: 120, currency: "RUB" },
|
|
{ count: 3, price: 290, currency: "RUB" },
|
|
],
|
|
plans: [
|
|
{
|
|
id: "standard:hwid:1",
|
|
tariff_key: "standard",
|
|
tariff_name: "Стандарт",
|
|
sale_mode: "hwid_device",
|
|
purchased_hwid_devices: 1,
|
|
price: 120,
|
|
currency: "RUB",
|
|
title: "+1 устройство",
|
|
},
|
|
],
|
|
};
|
|
} else if (mode === "depleted") {
|
|
DEV_MOCK.data.settings.traffic_mode = false;
|
|
DEV_MOCK.data.settings.trial_available = false;
|
|
if (DEMO_DATASET.plans?.length) {
|
|
const limitBytes = Number(DEMO_DATASET.currentSubscription?.traffic_limit_bytes || 0);
|
|
applyDemoTariffScenario({
|
|
traffic_used: DEMO_DATASET.currentSubscription?.traffic_limit || "150 GB",
|
|
traffic_used_bytes: limitBytes,
|
|
});
|
|
return;
|
|
}
|
|
return;
|
|
} else if (mode === "no-subscription" || mode === "inactive") {
|
|
applyInactiveSubscriptionScenario();
|
|
} 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,
|
|
can_topup_devices: true,
|
|
extra_hwid_devices: 0,
|
|
extra_hwid_devices_valid_until_text: "",
|
|
};
|
|
DEV_MOCK.data.device_topup_options = {
|
|
ok: true,
|
|
enabled: true,
|
|
tariff_key: "standard",
|
|
tariff_name: "Стандарт",
|
|
current_limit: 5,
|
|
current_devices: 5,
|
|
max_devices: 5,
|
|
available_extra_devices: 3,
|
|
extra_hwid_devices: 0,
|
|
extra_hwid_devices_valid_until_text: "",
|
|
renewal_available: false,
|
|
renewal_recommended_count: 0,
|
|
plans: [
|
|
{
|
|
id: "standard:hwid:1",
|
|
tariff_key: "standard",
|
|
tariff_name: "Стандарт",
|
|
sale_mode: "hwid_devices",
|
|
purchased_hwid_devices: 1,
|
|
price: 120,
|
|
currency: "RUB",
|
|
title: "+1 устройство",
|
|
subtitle: "Стандарт",
|
|
device_count: 1,
|
|
},
|
|
{
|
|
id: "standard:hwid:3",
|
|
tariff_key: "standard",
|
|
tariff_name: "Стандарт",
|
|
sale_mode: "hwid_devices",
|
|
purchased_hwid_devices: 3,
|
|
price: 290,
|
|
currency: "RUB",
|
|
title: "+3 устройства",
|
|
subtitle: "Стандарт",
|
|
device_count: 3,
|
|
},
|
|
],
|
|
};
|
|
} else if (mode === "trial") {
|
|
applyInactiveSubscriptionScenario({ trialAvailable: true });
|
|
}
|
|
}
|