fix(cabinet): sweep mobile flex-overflow across all pages + components

Full scan of every page/component for the Connected-Accounts overflow class
(long user data with no truncation pushing siblings off the card on mobile),
adversarially verified. Applied min-w-0 + truncate (break-all for copyable
values, break-words for titles) on text columns and shrink-0 on fixed
siblings across ~23 files: AppHeader, dashboard/SubscriptionCardActive,
subscription purchase/sheets (TariffPurchaseForm, ClassicPurchaseWizard,
SwitchTariffSheet), SuccessNotificationModal, PurchaseSuccess, Wheel sub
picker, ReferralNetwork UserDetailPanel, and the admin pages (AnalyticsTab,
BrandingTab, SubscriptionSubRow, user-detail Info/Referrals tabs,
ApplicationReview, PartnerCampaignAssign, Partners, PromocodeStats,
PromoOfferSend, RemnawaveSquadDetail, TariffCreate, Tickets, Withdrawals).
This commit is contained in:
c0mrade
2026-06-04 23:32:59 +03:00
parent 7383505a12
commit 800daf7506
23 changed files with 90 additions and 74 deletions

View File

@@ -256,9 +256,13 @@ export default function SuccessNotificationModal() {
{/* Tariff name */}
{data.tariffName && (
<div className="flex items-center justify-between rounded-xl bg-dark-800/50 px-4 py-3">
<span className="text-dark-400">{t('successNotification.tariff', 'Tariff')}</span>
<span className="font-semibold text-dark-100">{data.tariffName}</span>
<div className="flex items-center justify-between gap-3 rounded-xl bg-dark-800/50 px-4 py-3">
<span className="shrink-0 text-dark-400">
{t('successNotification.tariff', 'Tariff')}
</span>
<span className="min-w-0 truncate font-semibold text-dark-100">
{data.tariffName}
</span>
</div>
)}

View File

@@ -268,9 +268,9 @@ export function AnalyticsTab() {
</button>
</div>
) : (
<div className="flex items-center gap-2">
<div className="flex min-w-0 items-center gap-2">
<span
className={`text-base ${analytics?.google_ads_id ? 'font-mono text-dark-100' : 'text-dark-500'}`}
className={`min-w-0 truncate text-base ${analytics?.google_ads_id ? 'font-mono text-dark-100' : 'text-dark-500'}`}
>
{analytics?.google_ads_id || t('admin.settings.notConfigured')}
</span>
@@ -280,7 +280,7 @@ export function AnalyticsTab() {
setEditingGoogleId(true);
setError(null);
}}
className="rounded-lg p-1.5 text-dark-400 transition-colors hover:bg-dark-700 hover:text-dark-200"
className="shrink-0 rounded-lg p-1.5 text-dark-400 transition-colors hover:bg-dark-700 hover:text-dark-200"
>
<PencilIcon className="h-4 w-4" />
</button>
@@ -322,9 +322,9 @@ export function AnalyticsTab() {
</button>
</div>
) : (
<div className="flex items-center gap-2">
<div className="flex min-w-0 items-center gap-2">
<span
className={`text-base ${analytics?.google_ads_label ? 'font-mono text-dark-100' : 'text-dark-500'}`}
className={`min-w-0 truncate text-base ${analytics?.google_ads_label ? 'font-mono text-dark-100' : 'text-dark-500'}`}
>
{analytics?.google_ads_label || t('admin.settings.notConfigured')}
</span>
@@ -334,7 +334,7 @@ export function AnalyticsTab() {
setEditingGoogleLabel(true);
setError(null);
}}
className="rounded-lg p-1.5 text-dark-400 transition-colors hover:bg-dark-700 hover:text-dark-200"
className="shrink-0 rounded-lg p-1.5 text-dark-400 transition-colors hover:bg-dark-700 hover:text-dark-200"
>
<PencilIcon className="h-4 w-4" />
</button>

View File

@@ -180,8 +180,8 @@ export function BrandingTab({ accentColor = '#3b82f6' }: BrandingTabProps) {
</button>
</div>
) : (
<div className="flex items-center gap-2">
<span className="text-lg text-dark-100">
<div className="flex min-w-0 items-center gap-2">
<span className="min-w-0 truncate text-lg text-dark-100">
{branding?.name || t('admin.settings.notSpecified')}
</span>
<button
@@ -189,7 +189,7 @@ export function BrandingTab({ accentColor = '#3b82f6' }: BrandingTabProps) {
setNewName(branding?.name ?? '');
setEditingName(true);
}}
className="rounded-lg p-1.5 text-dark-400 transition-colors hover:bg-dark-700 hover:text-dark-200"
className="shrink-0 rounded-lg p-1.5 text-dark-400 transition-colors hover:bg-dark-700 hover:text-dark-200"
>
<PencilIcon />
</button>

View File

@@ -93,7 +93,7 @@ export function SubscriptionSubRow({
/>
</svg>
</span>
<span className="text-xs font-semibold text-dark-200">
<span className="min-w-0 flex-1 truncate text-xs font-semibold text-dark-200">
{subscription.tariff_name || '—'}
</span>
</div>

View File

@@ -421,16 +421,16 @@ export function InfoTab(props: InfoTabProps) {
onClick={() => navigate(`/admin/users/${ref.id}`)}
className="flex w-full items-center justify-between rounded-lg bg-dark-700/50 p-2 text-left transition-colors hover:bg-dark-700"
>
<div className="flex items-center gap-2">
<div className="flex h-7 w-7 items-center justify-center rounded-full bg-dark-600 text-xs font-bold text-dark-300">
<div className="flex min-w-0 items-center gap-2">
<div className="flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-dark-600 text-xs font-bold text-dark-300">
{ref.first_name?.[0] || ref.username?.[0] || '?'}
</div>
<div>
<div className="text-sm text-dark-100">{ref.full_name}</div>
<div className="min-w-0">
<div className="truncate text-sm text-dark-100">{ref.full_name}</div>
<div className="text-xs text-dark-500">{formatDate(ref.created_at)}</div>
</div>
</div>
<div className="text-xs text-dark-400">
<div className="shrink-0 text-xs text-dark-400">
{formatWithCurrency(ref.total_spent_kopeks / 100)}
</div>
</button>

View File

@@ -462,13 +462,13 @@ export function ReferralsTab({ user, userId, onUserRefresh }: ReferralsTabProps)
>
<button
onClick={() => navigate(`/admin/users/${ref.id}`)}
className="flex items-center gap-3 text-left"
className="flex min-w-0 items-center gap-3 text-left"
>
<div className="flex h-9 w-9 items-center justify-center rounded-full bg-dark-600/50 text-sm font-bold text-dark-300">
<div className="flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-dark-600/50 text-sm font-bold text-dark-300">
{(ref.full_name || ref.username || '?')[0].toUpperCase()}
</div>
<div>
<div className="text-sm font-medium text-dark-100">
<div className="min-w-0">
<div className="truncate text-sm font-medium text-dark-100">
{ref.full_name || ref.username || `ID: ${ref.id}`}
</div>
<div className="text-xs text-dark-500">
@@ -479,7 +479,7 @@ export function ReferralsTab({ user, userId, onUserRefresh }: ReferralsTabProps)
<button
onClick={() => handleRemoveReferral(ref.id)}
disabled={actionLoading}
className="rounded-lg p-2 text-dark-500 transition-colors hover:bg-error-500/10 hover:text-error-400 disabled:opacity-50"
className="shrink-0 rounded-lg p-2 text-dark-500 transition-colors hover:bg-error-500/10 hover:text-error-400 disabled:opacity-50"
title={t('admin.users.detail.referrals.removeReferral')}
>
<XIcon className="h-4 w-4" />

View File

@@ -283,7 +283,7 @@ export default function SubscriptionCardActive({
>
{t('dashboard.tariff')}
</div>
<div className="text-base font-bold leading-tight tracking-tight text-dark-50">
<div className="min-w-0 truncate text-base font-bold leading-tight tracking-tight text-dark-50">
{subscription.tariff_name || t('subscription.currentPlan')}
</div>
<div className="mt-0.5 font-mono text-[10px] text-dark-50/30">

View File

@@ -343,9 +343,11 @@ export function AppHeader({
>
<UserIcon className="h-5 w-5" />
</div>
<div>
<div className="text-sm font-medium text-dark-100">{displayName(user)}</div>
<div className="text-xs text-dark-500">
<div className="min-w-0">
<div className="truncate text-sm font-medium text-dark-100">
{displayName(user)}
</div>
<div className="truncate text-xs text-dark-500">
@{user?.username || `ID: ${user?.telegram_id}`}
</div>
</div>

View File

@@ -400,8 +400,8 @@ export function ClassicPurchaseWizard({
>
{selectedServers.includes(server.uuid) && <CheckIcon />}
</div>
<div>
<div className="font-medium text-dark-100">
<div className="min-w-0">
<div className="truncate font-medium text-dark-100">
<Twemoji options={{ className: 'twemoji', folder: 'svg', ext: '.svg' }}>
{server.name}
</Twemoji>

View File

@@ -105,9 +105,9 @@ export function TariffPurchaseForm({
return (
<div ref={ref} className="space-y-6">
<div className="flex items-center justify-between">
<h3 className="text-lg font-medium text-dark-100">{tariff.name}</h3>
<button onClick={onBack} className="text-dark-400 hover:text-dark-200">
<div className="flex items-center justify-between gap-2">
<h3 className="min-w-0 truncate text-lg font-medium text-dark-100">{tariff.name}</h3>
<button onClick={onBack} className="shrink-0 text-dark-400 hover:text-dark-200">
{t('common.back')}
</button>
</div>

View File

@@ -142,15 +142,15 @@ export function SwitchTariffSheet({
return (
<>
<div className="space-y-2 text-sm">
<div className="flex justify-between text-dark-300">
<span>{t('subscription.switchTariff.currentTariff')}</span>
<span className="font-medium text-dark-100">
<div className="flex justify-between gap-2 text-dark-300">
<span className="shrink-0">{t('subscription.switchTariff.currentTariff')}</span>
<span className="min-w-0 truncate font-medium text-dark-100">
{switchPreview.current_tariff_name || '-'}
</span>
</div>
<div className="flex justify-between text-dark-300">
<span>{t('subscription.switchTariff.newTariff')}</span>
<span className="font-medium text-accent-400">
<div className="flex justify-between gap-2 text-dark-300">
<span className="shrink-0">{t('subscription.switchTariff.newTariff')}</span>
<span className="min-w-0 truncate font-medium text-accent-400">
{switchPreview.new_tariff_name}
</span>
</div>