mirror of
https://github.com/chillpadclub/bedolaga-cabinet.git
synced 2026-07-30 02:23:47 +00:00
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:
@@ -256,9 +256,13 @@ export default function SuccessNotificationModal() {
|
|||||||
|
|
||||||
{/* Tariff name */}
|
{/* Tariff name */}
|
||||||
{data.tariffName && (
|
{data.tariffName && (
|
||||||
<div className="flex items-center justify-between rounded-xl bg-dark-800/50 px-4 py-3">
|
<div className="flex items-center justify-between gap-3 rounded-xl bg-dark-800/50 px-4 py-3">
|
||||||
<span className="text-dark-400">{t('successNotification.tariff', 'Tariff')}</span>
|
<span className="shrink-0 text-dark-400">
|
||||||
<span className="font-semibold text-dark-100">{data.tariffName}</span>
|
{t('successNotification.tariff', 'Tariff')}
|
||||||
|
</span>
|
||||||
|
<span className="min-w-0 truncate font-semibold text-dark-100">
|
||||||
|
{data.tariffName}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|||||||
@@ -268,9 +268,9 @@ export function AnalyticsTab() {
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex min-w-0 items-center gap-2">
|
||||||
<span
|
<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')}
|
{analytics?.google_ads_id || t('admin.settings.notConfigured')}
|
||||||
</span>
|
</span>
|
||||||
@@ -280,7 +280,7 @@ export function AnalyticsTab() {
|
|||||||
setEditingGoogleId(true);
|
setEditingGoogleId(true);
|
||||||
setError(null);
|
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" />
|
<PencilIcon className="h-4 w-4" />
|
||||||
</button>
|
</button>
|
||||||
@@ -322,9 +322,9 @@ export function AnalyticsTab() {
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex min-w-0 items-center gap-2">
|
||||||
<span
|
<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')}
|
{analytics?.google_ads_label || t('admin.settings.notConfigured')}
|
||||||
</span>
|
</span>
|
||||||
@@ -334,7 +334,7 @@ export function AnalyticsTab() {
|
|||||||
setEditingGoogleLabel(true);
|
setEditingGoogleLabel(true);
|
||||||
setError(null);
|
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" />
|
<PencilIcon className="h-4 w-4" />
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -180,8 +180,8 @@ export function BrandingTab({ accentColor = '#3b82f6' }: BrandingTabProps) {
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex min-w-0 items-center gap-2">
|
||||||
<span className="text-lg text-dark-100">
|
<span className="min-w-0 truncate text-lg text-dark-100">
|
||||||
{branding?.name || t('admin.settings.notSpecified')}
|
{branding?.name || t('admin.settings.notSpecified')}
|
||||||
</span>
|
</span>
|
||||||
<button
|
<button
|
||||||
@@ -189,7 +189,7 @@ export function BrandingTab({ accentColor = '#3b82f6' }: BrandingTabProps) {
|
|||||||
setNewName(branding?.name ?? '');
|
setNewName(branding?.name ?? '');
|
||||||
setEditingName(true);
|
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 />
|
<PencilIcon />
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ export function SubscriptionSubRow({
|
|||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</span>
|
</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 || '—'}
|
{subscription.tariff_name || '—'}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -421,16 +421,16 @@ export function InfoTab(props: InfoTabProps) {
|
|||||||
onClick={() => navigate(`/admin/users/${ref.id}`)}
|
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"
|
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 min-w-0 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 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] || '?'}
|
{ref.first_name?.[0] || ref.username?.[0] || '?'}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div className="min-w-0">
|
||||||
<div className="text-sm text-dark-100">{ref.full_name}</div>
|
<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 className="text-xs text-dark-500">{formatDate(ref.created_at)}</div>
|
||||||
</div>
|
</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)}
|
{formatWithCurrency(ref.total_spent_kopeks / 100)}
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -462,13 +462,13 @@ export function ReferralsTab({ user, userId, onUserRefresh }: ReferralsTabProps)
|
|||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
onClick={() => navigate(`/admin/users/${ref.id}`)}
|
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()}
|
{(ref.full_name || ref.username || '?')[0].toUpperCase()}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div className="min-w-0">
|
||||||
<div className="text-sm font-medium text-dark-100">
|
<div className="truncate text-sm font-medium text-dark-100">
|
||||||
{ref.full_name || ref.username || `ID: ${ref.id}`}
|
{ref.full_name || ref.username || `ID: ${ref.id}`}
|
||||||
</div>
|
</div>
|
||||||
<div className="text-xs text-dark-500">
|
<div className="text-xs text-dark-500">
|
||||||
@@ -479,7 +479,7 @@ export function ReferralsTab({ user, userId, onUserRefresh }: ReferralsTabProps)
|
|||||||
<button
|
<button
|
||||||
onClick={() => handleRemoveReferral(ref.id)}
|
onClick={() => handleRemoveReferral(ref.id)}
|
||||||
disabled={actionLoading}
|
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')}
|
title={t('admin.users.detail.referrals.removeReferral')}
|
||||||
>
|
>
|
||||||
<XIcon className="h-4 w-4" />
|
<XIcon className="h-4 w-4" />
|
||||||
|
|||||||
@@ -283,7 +283,7 @@ export default function SubscriptionCardActive({
|
|||||||
>
|
>
|
||||||
{t('dashboard.tariff')}
|
{t('dashboard.tariff')}
|
||||||
</div>
|
</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')}
|
{subscription.tariff_name || t('subscription.currentPlan')}
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-0.5 font-mono text-[10px] text-dark-50/30">
|
<div className="mt-0.5 font-mono text-[10px] text-dark-50/30">
|
||||||
|
|||||||
@@ -343,9 +343,11 @@ export function AppHeader({
|
|||||||
>
|
>
|
||||||
<UserIcon className="h-5 w-5" />
|
<UserIcon className="h-5 w-5" />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div className="min-w-0">
|
||||||
<div className="text-sm font-medium text-dark-100">{displayName(user)}</div>
|
<div className="truncate text-sm font-medium text-dark-100">
|
||||||
<div className="text-xs text-dark-500">
|
{displayName(user)}
|
||||||
|
</div>
|
||||||
|
<div className="truncate text-xs text-dark-500">
|
||||||
@{user?.username || `ID: ${user?.telegram_id}`}
|
@{user?.username || `ID: ${user?.telegram_id}`}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -400,8 +400,8 @@ export function ClassicPurchaseWizard({
|
|||||||
>
|
>
|
||||||
{selectedServers.includes(server.uuid) && <CheckIcon />}
|
{selectedServers.includes(server.uuid) && <CheckIcon />}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div className="min-w-0">
|
||||||
<div className="font-medium text-dark-100">
|
<div className="truncate font-medium text-dark-100">
|
||||||
<Twemoji options={{ className: 'twemoji', folder: 'svg', ext: '.svg' }}>
|
<Twemoji options={{ className: 'twemoji', folder: 'svg', ext: '.svg' }}>
|
||||||
{server.name}
|
{server.name}
|
||||||
</Twemoji>
|
</Twemoji>
|
||||||
|
|||||||
@@ -105,9 +105,9 @@ export function TariffPurchaseForm({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div ref={ref} className="space-y-6">
|
<div ref={ref} className="space-y-6">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between gap-2">
|
||||||
<h3 className="text-lg font-medium text-dark-100">{tariff.name}</h3>
|
<h3 className="min-w-0 truncate text-lg font-medium text-dark-100">{tariff.name}</h3>
|
||||||
<button onClick={onBack} className="text-dark-400 hover:text-dark-200">
|
<button onClick={onBack} className="shrink-0 text-dark-400 hover:text-dark-200">
|
||||||
← {t('common.back')}
|
← {t('common.back')}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -142,15 +142,15 @@ export function SwitchTariffSheet({
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="space-y-2 text-sm">
|
<div className="space-y-2 text-sm">
|
||||||
<div className="flex justify-between text-dark-300">
|
<div className="flex justify-between gap-2 text-dark-300">
|
||||||
<span>{t('subscription.switchTariff.currentTariff')}</span>
|
<span className="shrink-0">{t('subscription.switchTariff.currentTariff')}</span>
|
||||||
<span className="font-medium text-dark-100">
|
<span className="min-w-0 truncate font-medium text-dark-100">
|
||||||
{switchPreview.current_tariff_name || '-'}
|
{switchPreview.current_tariff_name || '-'}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex justify-between text-dark-300">
|
<div className="flex justify-between gap-2 text-dark-300">
|
||||||
<span>{t('subscription.switchTariff.newTariff')}</span>
|
<span className="shrink-0">{t('subscription.switchTariff.newTariff')}</span>
|
||||||
<span className="font-medium text-accent-400">
|
<span className="min-w-0 truncate font-medium text-accent-400">
|
||||||
{switchPreview.new_tariff_name}
|
{switchPreview.new_tariff_name}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -88,9 +88,11 @@ export default function AdminApplicationReview() {
|
|||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
<div className="flex items-start justify-between gap-4">
|
<div className="flex items-start justify-between gap-4">
|
||||||
<div className="min-w-0 flex-1">
|
<div className="min-w-0 flex-1">
|
||||||
<div className="mb-1 flex items-center gap-2">
|
<div className="mb-1 flex min-w-0 items-center gap-2">
|
||||||
<span className="font-medium text-dark-100">{displayName}</span>
|
<span className="truncate font-medium text-dark-100">{displayName}</span>
|
||||||
{app.username && <span className="text-sm text-dark-500">@{app.username}</span>}
|
{app.username && (
|
||||||
|
<span className="shrink-0 text-sm text-dark-500">@{app.username}</span>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -87,9 +87,11 @@ export default function AdminPartnerCampaignAssign() {
|
|||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-1 flex items-center gap-3 text-xs text-dark-500">
|
<div className="mt-1 flex min-w-0 items-center gap-3 text-xs text-dark-500">
|
||||||
<span className="font-mono">?start={campaign.start_parameter}</span>
|
<span className="min-w-0 truncate font-mono">
|
||||||
<span>
|
?start={campaign.start_parameter}
|
||||||
|
</span>
|
||||||
|
<span className="shrink-0">
|
||||||
{campaign.registrations_count}{' '}
|
{campaign.registrations_count}{' '}
|
||||||
{t('admin.campaigns.overview.registrations').toLowerCase()}
|
{t('admin.campaigns.overview.registrations').toLowerCase()}
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -129,12 +129,14 @@ export default function AdminPartners() {
|
|||||||
>
|
>
|
||||||
<div className="flex items-start justify-between gap-4">
|
<div className="flex items-start justify-between gap-4">
|
||||||
<div className="min-w-0 flex-1">
|
<div className="min-w-0 flex-1">
|
||||||
<div className="mb-1 flex items-center gap-2">
|
<div className="mb-1 flex min-w-0 items-center gap-2">
|
||||||
<h3 className="truncate font-medium text-dark-100">
|
<h3 className="truncate font-medium text-dark-100">
|
||||||
{partner.first_name || partner.username || `#${partner.user_id}`}
|
{partner.first_name || partner.username || `#${partner.user_id}`}
|
||||||
</h3>
|
</h3>
|
||||||
{partner.username && (
|
{partner.username && (
|
||||||
<span className="text-sm text-dark-500">@{partner.username}</span>
|
<span className="shrink-0 text-sm text-dark-500">
|
||||||
|
@{partner.username}
|
||||||
|
</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-wrap gap-x-4 gap-y-1 text-sm text-dark-400">
|
<div className="flex flex-wrap gap-x-4 gap-y-1 text-sm text-dark-400">
|
||||||
@@ -177,12 +179,12 @@ export default function AdminPartners() {
|
|||||||
<div key={app.id} className="rounded-xl border border-dark-700 bg-dark-800 p-4">
|
<div key={app.id} className="rounded-xl border border-dark-700 bg-dark-800 p-4">
|
||||||
<div className="mb-3 flex items-start justify-between gap-4">
|
<div className="mb-3 flex items-start justify-between gap-4">
|
||||||
<div className="min-w-0 flex-1">
|
<div className="min-w-0 flex-1">
|
||||||
<div className="mb-1 flex items-center gap-2">
|
<div className="mb-1 flex min-w-0 items-center gap-2">
|
||||||
<h3 className="truncate font-medium text-dark-100">
|
<h3 className="truncate font-medium text-dark-100">
|
||||||
{app.first_name || app.username || `#${app.user_id}`}
|
{app.first_name || app.username || `#${app.user_id}`}
|
||||||
</h3>
|
</h3>
|
||||||
{app.username && (
|
{app.username && (
|
||||||
<span className="text-sm text-dark-500">@{app.username}</span>
|
<span className="shrink-0 text-sm text-dark-500">@{app.username}</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{app.company_name && (
|
{app.company_name && (
|
||||||
|
|||||||
@@ -339,18 +339,18 @@ export default function AdminPromoOfferSend() {
|
|||||||
<div ref={searchRef} className="relative">
|
<div ref={searchRef} className="relative">
|
||||||
{selectedUser ? (
|
{selectedUser ? (
|
||||||
// Selected user display
|
// Selected user display
|
||||||
<div className="flex items-center justify-between rounded-lg border border-accent-500 bg-accent-500/10 px-3 py-2.5">
|
<div className="flex items-center justify-between gap-2 rounded-lg border border-accent-500 bg-accent-500/10 px-3 py-2.5">
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex min-w-0 items-center gap-3">
|
||||||
<div className="flex h-8 w-8 items-center justify-center rounded-full bg-dark-600">
|
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-dark-600">
|
||||||
<UserIcon />
|
<UserIcon />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div className="min-w-0">
|
||||||
<div className="text-sm font-medium text-dark-100">
|
<div className="truncate text-sm font-medium text-dark-100">
|
||||||
{selectedUser.full_name ||
|
{selectedUser.full_name ||
|
||||||
selectedUser.username ||
|
selectedUser.username ||
|
||||||
`ID: ${selectedUser.telegram_id}`}
|
`ID: ${selectedUser.telegram_id}`}
|
||||||
</div>
|
</div>
|
||||||
<div className="text-xs text-dark-400">
|
<div className="truncate text-xs text-dark-400">
|
||||||
{selectedUser.username && `@${selectedUser.username} · `}
|
{selectedUser.username && `@${selectedUser.username} · `}
|
||||||
Telegram: {selectedUser.telegram_id}
|
Telegram: {selectedUser.telegram_id}
|
||||||
</div>
|
</div>
|
||||||
@@ -358,7 +358,7 @@ export default function AdminPromoOfferSend() {
|
|||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
onClick={handleClearUser}
|
onClick={handleClearUser}
|
||||||
className="rounded-lg p-1.5 text-dark-400 transition-colors hover:bg-dark-600 hover:text-dark-100"
|
className="shrink-0 rounded-lg p-1.5 text-dark-400 transition-colors hover:bg-dark-600 hover:text-dark-100"
|
||||||
>
|
>
|
||||||
<CloseIcon className="h-4 w-4" />
|
<CloseIcon className="h-4 w-4" />
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ export default function AdminPromocodeStats() {
|
|||||||
<AdminBackButton to="/admin/promocodes" />
|
<AdminBackButton to="/admin/promocodes" />
|
||||||
<div className="flex flex-wrap items-center gap-2">
|
<div className="flex flex-wrap items-center gap-2">
|
||||||
<div
|
<div
|
||||||
className={`rounded-lg px-3 py-1.5 font-mono text-lg font-bold ${getTypeColor(promocode.type)}`}
|
className={`min-w-0 break-all rounded-lg px-3 py-1.5 font-mono text-lg font-bold ${getTypeColor(promocode.type)}`}
|
||||||
>
|
>
|
||||||
{promocode.code}
|
{promocode.code}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -229,11 +229,11 @@ export default function AdminRemnawaveSquadDetail() {
|
|||||||
key={idx}
|
key={idx}
|
||||||
className="flex items-center justify-between rounded-lg bg-dark-700/50 px-4 py-3"
|
className="flex items-center justify-between rounded-lg bg-dark-700/50 px-4 py-3"
|
||||||
>
|
>
|
||||||
<span className="text-sm text-dark-200">
|
<span className="min-w-0 flex-1 truncate text-sm text-dark-200">
|
||||||
{String(inbound.tag || inbound.uuid || `Inbound ${idx + 1}`)}
|
{String(inbound.tag || inbound.uuid || `Inbound ${idx + 1}`)}
|
||||||
</span>
|
</span>
|
||||||
{typeof inbound.type === 'string' && (
|
{typeof inbound.type === 'string' && (
|
||||||
<span className="rounded bg-dark-600 px-2 py-1 text-xs text-dark-400">
|
<span className="ml-2 shrink-0 rounded bg-dark-600 px-2 py-1 text-xs text-dark-400">
|
||||||
{inbound.type}
|
{inbound.type}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -697,8 +697,10 @@ export default function AdminTariffCreate() {
|
|||||||
>
|
>
|
||||||
{isSelected && <CheckIcon />}
|
{isSelected && <CheckIcon />}
|
||||||
</div>
|
</div>
|
||||||
<span className="flex-1 text-sm font-medium">{squad.name}</span>
|
<span className="min-w-0 flex-1 truncate text-sm font-medium">
|
||||||
<span className="text-xs text-dark-500">
|
{squad.name}
|
||||||
|
</span>
|
||||||
|
<span className="shrink-0 text-xs text-dark-500">
|
||||||
{squad.members_count} {t('admin.tariffs.externalSquadUsers')}
|
{squad.members_count} {t('admin.tariffs.externalSquadUsers')}
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
@@ -1059,7 +1061,9 @@ export default function AdminTariffCreate() {
|
|||||||
>
|
>
|
||||||
{isSelected && <CheckIcon />}
|
{isSelected && <CheckIcon />}
|
||||||
</div>
|
</div>
|
||||||
<span className="flex-1 text-sm font-medium">{group.name}</span>
|
<span className="min-w-0 flex-1 truncate text-sm font-medium">
|
||||||
|
{group.name}
|
||||||
|
</span>
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|||||||
@@ -443,7 +443,7 @@ export default function AdminTickets() {
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="mb-4 flex items-center gap-2 text-sm text-dark-500">
|
<div className="mb-4 flex flex-wrap items-center gap-2 text-sm text-dark-500">
|
||||||
<span>
|
<span>
|
||||||
{t('admin.tickets.from')}: {formatUser(selectedTicket)}
|
{t('admin.tickets.from')}: {formatUser(selectedTicket)}
|
||||||
{selectedTicket.user?.telegram_id && (
|
{selectedTicket.user?.telegram_id && (
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ export default function AdminWithdrawals() {
|
|||||||
<div className="min-w-0 flex-1">
|
<div className="min-w-0 flex-1">
|
||||||
{/* User and amount */}
|
{/* User and amount */}
|
||||||
<div className="mb-2 flex items-center gap-2">
|
<div className="mb-2 flex items-center gap-2">
|
||||||
<span className="truncate font-medium text-dark-100">
|
<span className="min-w-0 truncate font-medium text-dark-100">
|
||||||
{item.username
|
{item.username
|
||||||
? `@${item.username}`
|
? `@${item.username}`
|
||||||
: item.first_name || `#${item.user_id}`}
|
: item.first_name || `#${item.user_id}`}
|
||||||
|
|||||||
@@ -60,9 +60,9 @@ function CopyableField({ label, value }: { label: string; value: string }) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center gap-2 rounded-xl bg-dark-800/50 px-4 py-3">
|
<div className="flex items-center gap-2 rounded-xl bg-dark-800/50 px-4 py-3">
|
||||||
<div className="flex-1 text-left">
|
<div className="min-w-0 flex-1 text-left">
|
||||||
<p className="text-xs text-dark-400">{label}</p>
|
<p className="text-xs text-dark-400">{label}</p>
|
||||||
<p className="mt-0.5 font-mono text-sm text-dark-100">{value}</p>
|
<p className="mt-0.5 break-all font-mono text-sm text-dark-100">{value}</p>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
|
|||||||
@@ -61,9 +61,9 @@ export function UserDetailPanel({ userId, className }: UserDetailPanelProps) {
|
|||||||
{/* Identity */}
|
{/* Identity */}
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
{user.username && (
|
{user.username && (
|
||||||
<div className="flex items-center justify-between text-sm">
|
<div className="flex items-center justify-between gap-2 text-sm">
|
||||||
<span className="text-dark-500">@</span>
|
<span className="shrink-0 text-dark-500">@</span>
|
||||||
<span className="font-mono text-dark-200">{user.username}</span>
|
<span className="min-w-0 truncate font-mono text-dark-200">{user.username}</span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{user.tg_id && (
|
{user.tg_id && (
|
||||||
@@ -196,11 +196,11 @@ export function UserDetailPanel({ userId, className }: UserDetailPanelProps) {
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
{user.campaign_name && (
|
{user.campaign_name && (
|
||||||
<div className="flex items-center justify-between text-sm">
|
<div className="flex items-center justify-between gap-2 text-sm">
|
||||||
<span className="text-dark-400">
|
<span className="shrink-0 text-dark-400">
|
||||||
{t('admin.referralNetwork.user.fromCampaign')}
|
{t('admin.referralNetwork.user.fromCampaign')}
|
||||||
</span>
|
</span>
|
||||||
<span className="text-dark-200">{user.campaign_name}</span>
|
<span className="min-w-0 truncate text-dark-200">{user.campaign_name}</span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -599,16 +599,16 @@ export default function Wheel() {
|
|||||||
key={sub.id}
|
key={sub.id}
|
||||||
onClick={() => setSelectedSubscriptionId(sub.id)}
|
onClick={() => setSelectedSubscriptionId(sub.id)}
|
||||||
disabled={isSpinning}
|
disabled={isSpinning}
|
||||||
className={`flex w-full items-center justify-between rounded-lg px-3 py-2 text-sm transition-all ${
|
className={`flex w-full items-center justify-between gap-2 rounded-lg px-3 py-2 text-sm transition-all ${
|
||||||
selectedSubscriptionId === sub.id
|
selectedSubscriptionId === sub.id
|
||||||
? 'bg-accent-500/15 text-accent-400'
|
? 'bg-accent-500/15 text-accent-400'
|
||||||
: 'text-dark-400 hover:text-dark-200'
|
: 'text-dark-400 hover:text-dark-200'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<span className="font-medium">
|
<span className="min-w-0 truncate font-medium">
|
||||||
{sub.tariff_name || t('subscription.defaultName', 'Подписка')}
|
{sub.tariff_name || t('subscription.defaultName', 'Подписка')}
|
||||||
</span>
|
</span>
|
||||||
<span className="text-xs opacity-60">
|
<span className="shrink-0 text-xs opacity-60">
|
||||||
{sub.days_left} {t('common.units.days', 'дней')}
|
{sub.days_left} {t('common.units.days', 'дней')}
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
Reference in New Issue
Block a user