import { useEffect } from 'react'; import { useTranslation } from 'react-i18next'; import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { subscriptionApi } from '../../../api/subscription'; import { getErrorMessage } from '../../../utils/subscriptionHelpers'; import { ChevronRightIcon } from '../../icons'; // ────────────────────────────────────────────────────────────────── // Reduce-devices sheet. Self-owns the reduction-info query + mutation; // parent passes shared state (target limit + setter + ids + open flag). // // Extracted from Subscription.tsx to keep one cohesive feature in // one file (~170 lines off the god page). // ────────────────────────────────────────────────────────────────── export interface DeviceReductionSheetProps { open: boolean; onOpen: () => void; onClose: () => void; subscriptionPresent: boolean; subscriptionId: number | undefined; targetDeviceLimit: number; onTargetDeviceLimitChange: (n: number) => void; isDark: boolean; } export function DeviceReductionSheet({ open, onOpen, onClose, subscriptionPresent, subscriptionId, targetDeviceLimit, onTargetDeviceLimitChange, isDark, }: DeviceReductionSheetProps) { const { t } = useTranslation(); const queryClient = useQueryClient(); const { data: deviceReductionInfo } = useQuery({ queryKey: ['device-reduction-info', subscriptionId], queryFn: () => subscriptionApi.getDeviceReductionInfo(subscriptionId), enabled: open && subscriptionPresent, }); // Seed the target limit once the info comes back. useEffect(() => { if (deviceReductionInfo && open) { onTargetDeviceLimitChange( Math.max( deviceReductionInfo.min_device_limit, deviceReductionInfo.current_device_limit - 1, ), ); } // onTargetDeviceLimitChange is a setter from the parent and stable // enough; intentionally narrow deps to avoid clobbering user input. // eslint-disable-next-line react-hooks/exhaustive-deps }, [deviceReductionInfo, open]); const reduceMutation = useMutation({ mutationFn: () => subscriptionApi.reduceDevices(targetDeviceLimit, subscriptionId), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['subscription', subscriptionId] }); queryClient.invalidateQueries({ queryKey: ['subscriptions-list'] }); queryClient.invalidateQueries({ queryKey: ['devices', subscriptionId] }); queryClient.invalidateQueries({ queryKey: ['device-reduction-info', subscriptionId] }); onClose(); }, }); if (!open) { return ( ); } return (

{t('subscription.additionalOptions.reduceDevicesTitle')}

{deviceReductionInfo?.available === false ? (
{deviceReductionInfo.reason || t('subscription.additionalOptions.reduceUnavailable')}
) : deviceReductionInfo ? (
{targetDeviceLimit}
{t('subscription.additionalOptions.devicesUnit')}
{t('subscription.additionalOptions.currentDeviceLimit', { count: deviceReductionInfo.current_device_limit, })}
{t('subscription.additionalOptions.minDeviceLimit', { count: deviceReductionInfo.min_device_limit, })}
{t('subscription.additionalOptions.connectedDevices', { count: deviceReductionInfo.connected_devices_count, })}
{deviceReductionInfo.connected_devices_count > deviceReductionInfo.min_device_limit && (
{t('subscription.additionalOptions.disconnectDevicesFirst', { count: deviceReductionInfo.connected_devices_count, })}
)}
{t('subscription.additionalOptions.newDeviceLimit', { count: targetDeviceLimit, })}
{reduceMutation.isError && (
{getErrorMessage(reduceMutation.error)}
)}
) : (
)}
); }