tariffsStore.updateState({ tariffEditorOpen: false })} class="admin-dialog admin-tariff-dialog" > {at("tariff_tab_general", {}, "Основное")} {at("tariff_tab_pricing", {}, "Цены")} {at("tariff_tab_topup", {}, "Докупки")} {at("tariff_tab_premium", {}, "Premium")} {at("tariff_tab_hwid", {}, "Устройства")}
{at("tariff_label_key", {}, "Ключ тарифа")} {at( "tariff_hint_key", {}, "Латиницей, без пробелов. Используется в платежах и подписках, менять после публикации не рекомендуется" )}
{at("tariff_label_model", {}, "Модель тарификации")} {at("tariff_model_period_label", {}, "Период")} — {at( "tariff_model_period_desc", {}, "пользователь покупает фиксированный срок (1/3/12 мес. и т.д.)" )}. {at("tariff_model_traffic_label", {}, "Трафик")} — {at( "tariff_model_traffic_desc", {}, "пользователь покупает пакеты гигабайт по фиксированной цене за GB" )}
(tariffDraft.enabled = v)} class="admin-switch-root" > {tariffDraft.enabled ? at("tariff_visible", {}, "Тариф виден на витрине") : at("tariff_hidden", {}, "Тариф скрыт от пользователей")} {at( "tariff_enabled_hint", {}, "Выключенный тариф не показывается в боте/мини-аппе, но активные подписки на нём продолжают работать" )}
{at("tariff_label_name_ru", {}, "Название · RU")} {at("tariff_label_name_en", {}, "Название · EN")}
{at("tariff_label_desc_ru", {}, "Описание · RU")} {at("tariff_label_desc_en", {}, "Описание · EN")}
{at("tariff_label_squads", {}, "Базовые Internal Squads")} {panelSquadsLoading ? at("loading_squads", {}, "Загружаю список из панели…") : at( "tariff_hint_squads", {}, "Сквады Remnawave, к которым подключается пользователь по этому тарифу. Выберите один или несколько" )} { tariffsStore.addSquadToDraft("squadUuids", value); tariffsStore.update((s) => ({ ...s, selectedBaseSquad: "" })); }} />
{#each normalizeUuidList(tariffDraft.squadUuids) as uuid} {/each}
{at("tariff_label_hwid", {}, "Лимит устройств (HWID)")} {at( "tariff_hint_hwid", {}, "Сколько устройств может одновременно использовать подписку. Пусто — взять значение из .env, 0 — без ограничений" )} {#if tariffDraft.billing_model === "period"} {at("tariff_label_traffic_limit", {}, "Месячный лимит трафика, GB")} {at( "tariff_hint_traffic_limit", {}, "Сколько GB включено в тариф на каждый месяц. 0 — безлимитный трафика. Сверху можно докупать пакеты на вкладке «Докупки»" )} {:else} {conversionCurrencyLabel} {at( "tariff_hint_conversion", {}, "По этому курсу остаток подписки пересчитывается в гигабайты при переходе пользователя с тарифа «Период» на «Трафик»" )} {/if}
{at("tariff_premium_head", {}, "Premium-доступ и отдельный счётчик трафика")} {at( "tariff_premium_subhead", {}, "Premium-сквады дают пользователю доступ к более быстрым/премиальным нодам; их трафик считается отдельно от основного, чтобы можно было ограничить или продавать дополнительно" )}
{at("tariff_label_premium_name_ru", {}, "Название premium-раздела, RU")} {at( "tariff_hint_premium_name_ru", {}, "Эта строка заменит «Premium-серверы» в кабинете, докупках и карточках лимитов." )} {at("tariff_label_premium_name_en", {}, "Название premium-раздела, EN")} {at( "tariff_hint_premium_name_en", {}, "Опционально для английского интерфейса." )}
{at("tariff_label_premium_squads", {}, "Premium Internal Squads")} {at( "tariff_hint_premium_squads", {}, "Сквады из Remnawave, доступные только владельцам этого тарифа. Трафик считается по их accessible nodes" )} { tariffsStore.addSquadToDraft("premiumSquadUuids", value); tariffsStore.update((s) => ({ ...s, selectedPremiumSquad: "" })); }} />
{#each normalizeUuidList(tariffDraft.premiumSquadUuids) as uuid} {/each}
{at( "tariff_label_premium_traffic_limit", {}, "Месячный лимит premium-трафика, GB" )} {at( "tariff_hint_premium_traffic_limit", {}, "Сколько GB через premium-сквады включено в тариф каждый месяц. 0 или пусто — отдельного premium-лимита нет (premium-нодами можно пользоваться без ограничения)" )}
{at("tariff_premium_topup_title", {}, "Докупка premium-трафика")} {at( "tariff_premium_topup_subtitle", {}, "Пакеты для расширения месячного premium-лимита, когда пользователь его исчерпал" )}
tariffsStore.addDraftRow("premiumTopupRows", { gb: 10, price: "", stars: "" })} > {at("tariff_btn_package", {}, "Пакет")}
{#if tariffDraft.premiumTopupRows.length}
{at("tariff_col_volume_gb", {}, "Объём, GB")} {currencyPriceColumnLabel} {at("tariff_col_price_stars_full", {}, "Цена, ⭐ Stars")}
tariffsStore.moveDraftRow("premiumTopupRows", from, to)} let:item={row} let:index > tariffsStore.removeDraftRow("premiumTopupRows", index)} aria-label={at("btn_delete", {}, "Удалить")}>
{/if}
{#if tariffDraft.billing_model === "period"}
{at("tariff_pricing_period_title", {}, "Периоды подписки и цены")} {at( "tariff_pricing_period_subtitle", {}, "Каждая строка — отдельный вариант на витрине: за сколько месяцев пользователь платит и сколько это стоит" )}
tariffsStore.addDraftRow("periodRows", { months: 1, rub: "", stars: "", referral_inviter: "", referral_referee: "", })} > {at("tariff_btn_period", {}, "Период")}
{#if !tariffDraft.periodRows.length}

{at( "tariff_pricing_empty", {}, "Добавьте хотя бы один период — без него тариф не появится на витрине." )}

{:else}
{at("tariff_col_period_months", {}, "Срок, мес.")} {currencyPriceColumnLabel} {at("tariff_col_price_stars_full", {}, "Цена, ⭐ Stars")} {at("tariff_col_ref_inviter", {}, "Бонус приглашающему")} {at("tariff_col_ref_referee", {}, "Бонус приглашённому")}
tariffsStore.moveDraftRow("periodRows", from, to)} let:item={row} let:index > tariffsStore.removeDraftRow("periodRows", index)} aria-label={at("btn_delete", {}, "Удалить")} >
{/if}
{:else}
{at("tariff_pricing_traffic_title", {}, "Пакеты трафика")} {at( "tariff_pricing_traffic_subtitle", {}, "Базовая витрина для трафиковой модели. Каждая строка — пакет «N гигабайт за N единиц валюты»" )}
tariffsStore.addDraftRow("trafficRows", { gb: 10, price: "", stars: "" })} > {at("tariff_btn_package", {}, "Пакет")}
{#if tariffDraft.trafficRows.length}
{at("tariff_col_volume_gb", {}, "Объём, GB")} {currencyPriceColumnLabel} {at("tariff_col_price_stars_full", {}, "Цена, ⭐ Stars")}
tariffsStore.moveDraftRow("trafficRows", from, to)} let:item={row} let:index > tariffsStore.removeDraftRow("trafficRows", index)} aria-label={at("btn_delete", {}, "Удалить")}>
{/if}
{/if}
{#if tariffDraft.billing_model === "period"}
{at("tariff_topup_title", {}, "Докупка трафика поверх месячного лимита")} {at( "tariff_topup_subtitle", {}, "Когда у пользователя кончился месячный лимит, ему предложат купить дополнительный пакет, не меняя срок подписки" )}
tariffsStore.addDraftRow("topupRows", { gb: 10, price: "", stars: "" })} > {at("tariff_btn_package", {}, "Пакет")}
{#if tariffDraft.topupRows.length}
{at("tariff_col_volume_gb", {}, "Объём, GB")} {currencyPriceColumnLabel} {at("tariff_col_price_stars_full", {}, "Цена, ⭐ Stars")}
tariffsStore.moveDraftRow("topupRows", from, to)} let:item={row} let:index > tariffsStore.removeDraftRow("topupRows", index)} aria-label={at("btn_delete", {}, "Удалить")}>
{/if}
{:else}

{at( "tariff_topup_traffic_hint", {}, "Для трафиковой модели отдельные «докупки» не нужны — пакеты, которые вы настроили на вкладке «Цены», и являются докупками: пользователь покупает их повторно по мере исчерпания." )}

{/if}
{at( "tariff_hwid_packages_title", {}, "Пакеты дополнительных устройств (HWID)" )} {at( "tariff_hwid_packages_subtitle", {}, "Расширяет лимит, указанный во вкладке «Основное». Каждая строка — пакет «+N устройств за N единиц валюты»" )}
tariffsStore.addDraftRow("hwidRows", { count: 1, price: "", stars: "" })} > {at("tariff_btn_package", {}, "Пакет")}
{#if tariffDraft.hwidRows.length}
{at("tariff_col_hwid_count", {}, "+ устройств")} {currencyPriceColumnLabel} {at("tariff_col_price_stars_full", {}, "Цена, ⭐ Stars")}
tariffsStore.moveDraftRow("hwidRows", from, to)} let:item={row} let:index > tariffsStore.removeDraftRow("hwidRows", index)} aria-label={at("btn_delete", {}, "Удалить")}>
{/if}
tariffsStore.updateState({ tariffEditorOpen: false })} >{at("btn_cancel", {}, "Отмена")} {tariffsSaving ? at("btn_saving", {}, "Сохранение...") : at("btn_save_tariff", {}, "Сохранить тариф")}
tariffsStore.updateState({ tariffDeleteOpen: false })} class="admin-dialog" >
tariffsStore.updateState({ tariffDeleteOpen: false })} >{at("btn_cancel", {}, "Отмена")} {at("btn_confirm_delete", {}, "Подтвердить удаление")}