mirror of
https://github.com/chillpadclub/bedolaga-cabinet.git
synced 2026-09-13 16:23:08 +00:00
feat(users): кнопка удаления подписки в карточке пользователя
В мультитарифном режиме у пользователя несколько подписок, и убрать лишнюю — например, отработавший триал — можно было только через экран «Массовые действия». Во вкладке «Подписка» карточки подписки видны и открываются, но удалить выбранную нечем. Кнопка живёт в детальном виде подписки и требует подтверждения тем же inline-механизмом, что и отмена автоплатежа; ключ подтверждения включает id подписки, чтобы взведённое согласие не пережило переключение на соседнюю. Активная платная подписка на сервере защищена от случайного удаления, поэтому для неё запрос идёт с явным force — намерение админ уже подтвердил.
This commit is contained in:
@@ -131,6 +131,7 @@ export interface SubscriptionTabProps {
|
||||
onRemoveTraffic: (purchaseId: number) => Promise<void>;
|
||||
onResetDevices: () => Promise<void>;
|
||||
onCancelSbpRecurring: () => Promise<void>;
|
||||
onDeleteSubscription: () => Promise<void>;
|
||||
onDeleteDevice: (hwid: string) => Promise<void>;
|
||||
onRenameDevice: (hwid: string) => Promise<void>;
|
||||
onLoadDevices: () => Promise<void>;
|
||||
@@ -195,6 +196,7 @@ export function SubscriptionTab(props: SubscriptionTabProps) {
|
||||
onRemoveTraffic,
|
||||
onResetDevices,
|
||||
onCancelSbpRecurring,
|
||||
onDeleteSubscription,
|
||||
onDeleteDevice,
|
||||
onRenameDevice,
|
||||
onLoadDevices,
|
||||
@@ -429,6 +431,41 @@ export function SubscriptionTab(props: SubscriptionTabProps) {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Delete this subscription — in multi-tariff mode spent trials
|
||||
pile up in the card, and removing one used to be possible
|
||||
only through the bulk-actions screen. */}
|
||||
{hasPermission('users:subscription') && (
|
||||
<div className="rounded-xl bg-dark-800/50 p-4">
|
||||
<div className="flex items-center justify-between gap-3">
|
||||
<div>
|
||||
<div className="text-sm font-medium text-dark-200">
|
||||
{t('admin.users.detail.subscription.deleteTitle')}
|
||||
</div>
|
||||
<div className="mt-0.5 text-xs text-dark-400">
|
||||
{t('admin.users.detail.subscription.deleteHint')}
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
// Per-subscription confirm key: an armed confirm must not
|
||||
// survive switching to another subscription in the picker.
|
||||
onClick={() =>
|
||||
onInlineConfirm(`deleteSubscription_${selectedSub.id}`, onDeleteSubscription)
|
||||
}
|
||||
disabled={actionLoading}
|
||||
className={`shrink-0 rounded-lg px-3 py-2 text-sm font-medium transition-all disabled:opacity-50 ${
|
||||
confirmingAction === `deleteSubscription_${selectedSub.id}`
|
||||
? 'bg-error-500 text-white'
|
||||
: 'bg-error-500/15 text-error-400 hover:bg-error-500/25'
|
||||
}`}
|
||||
>
|
||||
{confirmingAction === `deleteSubscription_${selectedSub.id}`
|
||||
? t('admin.users.detail.actions.areYouSure')
|
||||
: t('admin.users.detail.subscription.deleteButton')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Traffic Packages */}
|
||||
{selectedSub.traffic_purchases && selectedSub.traffic_purchases.length > 0 && (
|
||||
<div className="rounded-xl bg-dark-800/50 p-4">
|
||||
|
||||
Reference in New Issue
Block a user