import { useTranslation } from 'react-i18next';
import type {
UserDetailResponse,
UserSubscriptionInfo,
PanelSyncStatusResponse,
} from '../../../api/adminUsers';
// ──────────────────────────────────────────────────────────────────
// Icons (sync-tab-local — not used outside this view)
// ──────────────────────────────────────────────────────────────────
const ArrowDownIcon = ({ className = 'w-5 h-5' }: { className?: string }) => (
);
const ArrowUpIcon = ({ className = 'w-5 h-5' }: { className?: string }) => (
);
// ──────────────────────────────────────────────────────────────────
// Sync tab — compares bot DB vs panel data, offers a 2-way push
// ──────────────────────────────────────────────────────────────────
export interface SyncTabProps {
user: UserDetailResponse;
syncStatus: PanelSyncStatusResponse | null;
userSubscriptions: UserSubscriptionInfo[];
activeSubscriptionId: number | null;
onActiveSubscriptionChange: (id: number | null) => void;
actionLoading: boolean;
onSyncFromPanel: () => void;
onSyncToPanel: () => void;
locale: string;
}
export function SyncTab({
user,
syncStatus,
userSubscriptions,
activeSubscriptionId,
onActiveSubscriptionChange,
actionLoading,
onSyncFromPanel,
onSyncToPanel,
locale,
}: SyncTabProps) {
const { t } = useTranslation();
return (
{/* Subscription selector for multi-tariff */}
{userSubscriptions.length > 1 && (
{t('admin.users.detail.sync.selectSubscription')}
)}
{/* Sync status */}
{syncStatus && (
{syncStatus.has_differences ? (
{t('admin.users.detail.sync.hasDifferences')}
) : (
{t('admin.users.detail.sync.synced')}
)}
{syncStatus.differences.length > 0 && (
{syncStatus.differences.map((diff, i) => (
• {diff}
))}
)}
{t('admin.users.detail.sync.bot')}
{t('admin.users.detail.sync.statusLabel')}:
{syncStatus.bot_subscription_status || '-'}
{t('admin.users.detail.sync.until')}:
{syncStatus.bot_subscription_end_date
? new Date(syncStatus.bot_subscription_end_date).toLocaleDateString(locale)
: '-'}
{t('admin.users.detail.sync.traffic')}:
{syncStatus.bot_traffic_used_gb.toFixed(2)} {t('common.units.gb')}
{t('admin.users.detail.sync.devices')}:
{syncStatus.bot_device_limit}
{t('admin.users.detail.sync.squads')}:
{syncStatus.bot_squads?.length || 0}
{t('admin.users.detail.sync.panel')}
{t('admin.users.detail.sync.statusLabel')}:
{syncStatus.panel_status || '-'}
{t('admin.users.detail.sync.until')}:
{syncStatus.panel_expire_at
? new Date(syncStatus.panel_expire_at).toLocaleDateString(locale)
: '-'}
{t('admin.users.detail.sync.traffic')}:
{syncStatus.panel_traffic_used_gb.toFixed(2)} {t('common.units.gb')}
{t('admin.users.detail.sync.devices')}:
{syncStatus.panel_device_limit}
{t('admin.users.detail.sync.squads')}:
{syncStatus.panel_squads?.length || 0}
)}
{/* UUID info */}
{syncStatus?.subscription_tariff_name && (
{syncStatus.subscription_tariff_name}
)}
Remnawave UUID
{syncStatus?.remnawave_uuid ||
user.remnawave_uuid ||
t('admin.users.detail.sync.notLinked')}
{/* Sync buttons */}
);
}