redesign: inline delete confirmation on web — expands in place instead of modal/sheet

This commit is contained in:
c0mrade
2026-03-24 19:11:48 +03:00
parent 93fa435ff7
commit 324aaa1f33

View File

@@ -4,14 +4,6 @@ import { useTranslation } from 'react-i18next';
import { useNavigate, useParams } from 'react-router'; import { useNavigate, useParams } from 'react-router';
import { subscriptionApi } from '../api/subscription'; import { subscriptionApi } from '../api/subscription';
import { WebBackButton } from '../components/WebBackButton'; import { WebBackButton } from '../components/WebBackButton';
import {
Sheet,
SheetContent,
SheetDescription,
SheetFooter,
SheetHeader,
SheetTitle,
} from '../components/primitives/Sheet';
import { useDestructiveConfirm } from '../platform/hooks/useNativeDialog'; import { useDestructiveConfirm } from '../platform/hooks/useNativeDialog';
import { usePlatform } from '../platform'; import { usePlatform } from '../platform';
import TrafficProgressBar from '../components/dashboard/TrafficProgressBar'; import TrafficProgressBar from '../components/dashboard/TrafficProgressBar';
@@ -1280,67 +1272,65 @@ export default function Subscription() {
{/* Delete expired subscription */} {/* Delete expired subscription */}
{isMultiTariff && subscription && !subscription.is_active && !subscription.is_trial && ( {isMultiTariff && subscription && !subscription.is_active && !subscription.is_trial && (
<> <div className="space-y-3">
<button {!showDeleteSheet ? (
onClick={async () => { <button
if (platform === 'telegram') { onClick={async () => {
// Telegram: native destructive popup if (platform === 'telegram') {
const confirmed = await destructiveConfirm( const confirmed = await destructiveConfirm(
t( t(
'subscription.deleteWarning', 'subscription.deleteWarning',
'Подписка будет удалена безвозвратно. Все данные, устройства и настройки будут потеряны.', 'Подписка будет удалена безвозвратно. Все данные, устройства и настройки будут потеряны.',
), ),
t('subscription.confirmDelete', 'Да, удалить'), t('subscription.confirmDelete', 'Да, удалить'),
t('subscription.deleteTitle', 'Удалить подписку?'), t('subscription.deleteTitle', 'Удалить подписку?'),
); );
if (!confirmed) return; if (!confirmed) return;
setDeleteLoading(true); setDeleteLoading(true);
try { try {
await subscriptionApi.deleteSubscription(subscription.id); await subscriptionApi.deleteSubscription(subscription.id);
queryClient.invalidateQueries({ queryKey: ['subscriptions-list'] }); queryClient.invalidateQueries({ queryKey: ['subscriptions-list'] });
navigate('/subscriptions', { replace: true }); navigate('/subscriptions', { replace: true });
} catch { } catch {
setDeleteLoading(false); setDeleteLoading(false);
}
} else {
setShowDeleteSheet(true);
} }
} else { }}
// Web: show Sheet disabled={deleteLoading}
setShowDeleteSheet(true); className="flex w-full items-center justify-center gap-2 rounded-2xl border border-red-400/20 bg-red-400/5 p-3.5 text-sm font-medium text-red-400 transition-colors hover:bg-red-400/10 disabled:opacity-50"
}
}}
disabled={deleteLoading}
className="flex w-full items-center justify-center gap-2 rounded-2xl border border-red-400/20 bg-red-400/5 p-3.5 text-sm font-medium text-red-400 transition-colors hover:bg-red-400/10 disabled:opacity-50"
>
<svg
className="h-4 w-4"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth={2}
> >
<path <svg
strokeLinecap="round" className="h-4 w-4"
strokeLinejoin="round" viewBox="0 0 24 24"
d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" fill="none"
/> stroke="currentColor"
</svg> strokeWidth={2}
{deleteLoading >
? t('common.processing', 'Удаление...') <path
: t('subscription.delete', 'Удалить подписку')} strokeLinecap="round"
</button> strokeLinejoin="round"
d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"
{/* Web: Sheet confirmation */} />
<Sheet open={showDeleteSheet} onOpenChange={setShowDeleteSheet}> </svg>
<SheetContent className="sm:inset-x-auto sm:left-1/2 sm:right-auto sm:mb-4 sm:max-w-md sm:-translate-x-1/2 sm:rounded-2xl"> {t('subscription.delete', 'Удалить подписку')}
<SheetHeader> </button>
<SheetTitle>{t('subscription.deleteTitle', 'Удалить подписку?')}</SheetTitle> ) : (
<SheetDescription> <div
{t( className="rounded-2xl border border-red-400/20 p-4"
'subscription.deleteWarning', style={{ background: 'rgba(255,59,92,0.04)' }}
'Подписка будет удалена безвозвратно. Все данные, устройства и настройки будут потеряны. Это действие нельзя отменить.', >
)} <div className="mb-3 text-sm font-semibold text-red-400">
</SheetDescription> {t('subscription.deleteTitle', 'Удалить подписку?')}
</SheetHeader> </div>
<SheetFooter> <div className="mb-4 text-xs" style={{ color: g.textSecondary }}>
{t(
'subscription.deleteWarning',
'Подписка будет удалена безвозвратно. Все данные, устройства и настройки будут потеряны. Это действие нельзя отменить.',
)}
</div>
<div className="flex gap-2">
<button <button
onClick={async () => { onClick={async () => {
setDeleteLoading(true); setDeleteLoading(true);
@@ -1354,7 +1344,7 @@ export default function Subscription() {
} }
}} }}
disabled={deleteLoading} disabled={deleteLoading}
className="w-full rounded-xl bg-red-500 py-3 text-sm font-semibold text-white transition-colors hover:bg-red-600 disabled:opacity-50" className="flex-1 rounded-xl bg-red-500 py-2.5 text-sm font-semibold text-white transition-colors hover:bg-red-600 disabled:opacity-50"
> >
{deleteLoading {deleteLoading
? t('common.processing', 'Удаление...') ? t('common.processing', 'Удаление...')
@@ -1362,14 +1352,15 @@ export default function Subscription() {
</button> </button>
<button <button
onClick={() => setShowDeleteSheet(false)} onClick={() => setShowDeleteSheet(false)}
className="w-full rounded-xl border border-dark-700 bg-dark-800 py-3 text-sm font-medium text-dark-300 transition-colors hover:bg-dark-700" className="flex-1 rounded-xl border border-dark-700 py-2.5 text-sm font-medium transition-colors hover:bg-dark-700"
style={{ color: g.textSecondary }}
> >
{t('common.cancel', 'Отмена')} {t('common.cancel', 'Отмена')}
</button> </button>
</SheetFooter> </div>
</SheetContent> </div>
</Sheet> )}
</> </div>
)} )}
{/* Additional Options (Buy Devices) */} {/* Additional Options (Buy Devices) */}