fix(dashboard): счётчик устройств в плитке на главной

Дополнения к PR #544 при мерже.

Плитка на главной берёт число подключённых устройств из запроса ['devices'],
а он выключен ровно там, где плитка живёт: `enabled: !!subscription &&
!isMultiTariff`, тогда как блок с плиткой рендерится в мультитарифной ветке,
где `subscription` всегда null (свой запрос отключён по !isMultiTariff).
То есть счётчик показывал бы «0 из N» всегда, лимит устройств не срабатывал бы
никогда, а точки-индикаторы стояли бы пустыми — при том, что счётчик и есть
смысл плитки.

Добавлен запрос по конкретной подписке: getDevices принимает subscription_id,
ключ ['devices', id] — тот же, что на странице подписки, поэтому кэш общий и
лишнего похода в сеть при переходе туда не будет. Заодно вынес выбор
единственной подписки в переменную, чтобы условие показа и данные плитки не
разъезжались.

Отдельно поправлен потерянный пробел в className: `duration-300${...}` склеивал
класс в `duration-300cursor-not-allowed`, из-за чего оформление заблокированной
плитки не применялось. Баг приехал вместе с переносом из SubscriptionCardActive
(там он с самого начала), но раз компонент всё равно выделяется — чиню здесь.
This commit is contained in:
Fringg
2026-08-07 15:27:17 +03:00
parent 9532819fc6
commit 39b9b8e1d2
2 changed files with 24 additions and 8 deletions

View File

@@ -53,7 +53,7 @@ export default function ConnectDeviceTile({
} }
navigate(`/connection?sub=${subscription.id}`); navigate(`/connection?sub=${subscription.id}`);
}} }}
className={`mb-2.5 flex w-full items-center gap-3.5 rounded-[14px] p-3.5 text-left transition-shadow duration-300${isAtDeviceLimit ? 'cursor-not-allowed opacity-50' : ''}`} className={`mb-2.5 flex w-full items-center gap-3.5 rounded-[14px] p-3.5 text-left transition-shadow duration-300 ${isAtDeviceLimit ? 'cursor-not-allowed opacity-50' : ''}`}
data-onboarding="connect-devices" data-onboarding="connect-devices"
style={{ fontFamily: 'inherit' }} style={{ fontFamily: 'inherit' }}
> >

View File

@@ -80,6 +80,24 @@ export default function Dashboard() {
staleTime: API.BALANCE_STALE_TIME_MS, staleTime: API.BALANCE_STALE_TIME_MS,
}); });
// Плитка «Подключить устройство» на главной живёт в МУЛЬТИТАРИФНОЙ ветке, а
// запрос выше там выключен: он привязан к одиночной подписке (`subscription`
// в мультитарифе всегда null). Без отдельного запроса счётчик плитки всегда
// показывал бы «0 из N», а лимит устройств не срабатывал бы никогда — то
// есть ровно то, ради чего плитку и добавили, не работало бы.
// Ключ ['devices', id] — тот же, что на странице подписки, так что кэш общий.
const homeSingleSub =
isMultiTariff && multiSubData?.subscriptions?.length === 1
? multiSubData.subscriptions[0]
: null;
const { data: homeSingleSubDevices } = useQuery({
queryKey: ['devices', homeSingleSub?.id],
queryFn: () => subscriptionApi.getDevices(homeSingleSub?.id),
enabled: !!homeSingleSub,
staleTime: API.BALANCE_STALE_TIME_MS,
});
const { data: referralInfo, isLoading: refLoading } = useQuery({ const { data: referralInfo, isLoading: refLoading } = useQuery({
queryKey: ['referral-info'], queryKey: ['referral-info'],
queryFn: referralApi.getReferralInfo, queryFn: referralApi.getReferralInfo,
@@ -306,18 +324,16 @@ export default function Dashboard() {
и человек попадает на главную с готовым доступом. Пока подписка и человек попадает на главную с готовым доступом. Пока подписка
одна, показываем здесь же, как подключить устройство: иначе за одна, показываем здесь же, как подключить устройство: иначе за
этим нужно уходить на отдельную страницу, о чём он не догадается. */} этим нужно уходить на отдельную страницу, о чём он не догадается. */}
{multiSubData.subscriptions.length === 1 && ( {homeSingleSub && (
<ConnectDeviceTile <ConnectDeviceTile
subscription={multiSubData.subscriptions[0]} subscription={homeSingleSub}
connectedDevices={devicesData?.total ?? 0} connectedDevices={homeSingleSubDevices?.total ?? 0}
usedPercent={ usedPercent={
multiSubData.subscriptions[0].traffic_limit_gb > 0 homeSingleSub.traffic_limit_gb > 0
? Math.min( ? Math.min(
100, 100,
Math.round( Math.round(
(multiSubData.subscriptions[0].traffic_used_gb / (homeSingleSub.traffic_used_gb / homeSingleSub.traffic_limit_gb) * 100,
multiSubData.subscriptions[0].traffic_limit_gb) *
100,
), ),
) )
: 0 : 0