diff --git a/src/components/dashboard/ConnectDeviceTile.tsx b/src/components/dashboard/ConnectDeviceTile.tsx new file mode 100644 index 0000000..49929f3 --- /dev/null +++ b/src/components/dashboard/ConnectDeviceTile.tsx @@ -0,0 +1,143 @@ +import { useTranslation } from 'react-i18next'; +import { useNavigate } from 'react-router'; +import { useHaptic } from '../../platform'; +import { useTheme } from '../../hooks/useTheme'; +import { useTrafficZone } from '../../hooks/useTrafficZone'; +import { getGlassColors } from '../../utils/glassTheme'; +import { HoverBorderGradient } from '../ui/hover-border-gradient'; + +interface ConnectDeviceTileProps { + subscription: { + id: number; + device_limit: number; + subscription_url?: string | null; + }; + connectedDevices: number; + /** Процент израсходованного трафика — от него зависит акцентный цвет плитки. */ + usedPercent?: number; +} + +/** + * Плитка «Подключить устройство». + * + * Живёт и в карточке активной подписки, и на главной: пользователь, + * которому подписку выдал бонус рекламной кампании, попадает на главную + * с готовым доступом — и без этой плитки не понимает, что делать дальше. + */ +export default function ConnectDeviceTile({ + subscription, + connectedDevices, + usedPercent = 0, +}: ConnectDeviceTileProps) { + const { t } = useTranslation(); + const navigate = useNavigate(); + const haptic = useHaptic(); + const { isDark } = useTheme(); + const g = getGlassColors(isDark); + const zone = useTrafficZone(usedPercent); + + const isAtDeviceLimit = + subscription.device_limit > 0 && connectedDevices >= subscription.device_limit; + + if (!subscription.subscription_url) return null; + + return ( + { + if (isAtDeviceLimit) { + haptic.notification('error'); + return; + } + 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' : ''}`} + data-onboarding="connect-devices" + style={{ fontFamily: 'inherit' }} + > + {/* Monitor icon */} +
+ +
+ + {/* Text */} +
+
+ {t('dashboard.connectDevice')} +
+
+ {subscription.device_limit === 0 + ? t('dashboard.devicesConnectedUnlimited', { used: connectedDevices }) + : t('dashboard.devicesOfMax', { + used: connectedDevices, + max: subscription.device_limit, + })} +
+ {isAtDeviceLimit && ( +
+ {t('dashboard.deviceLimitReached')} +
+ )} +
+ + {/* Device indicator */} + {subscription.device_limit === 0 ? ( + + ) : subscription.device_limit <= 10 ? ( +