import { useEffect, useRef, useState, type ReactNode } from 'react'; import { useTranslation } from 'react-i18next'; import { cn } from '@/lib/utils'; import { ChevronDownIcon } from './DropdownSelect'; import { isSubscriptionLevelAction } from './actionTargets'; import type { BulkActionType } from '../../../api/adminBulkActions'; // ────────────────────────────────────────────────────────────────── // FloatingActionBar // // Bottom-dock selection toolbar for AdminBulkActions. Shows selected // user/subscription counts, the "select-all subscriptions" toggle // (multi-tariff only), and the action dropdown grouped into // subscription-level vs user-level when multi-tariff is on. // // Pure presentational — parent owns selection state, supplies onAction // (opens the modal with the picked action type) and onToggleAll. // ────────────────────────────────────────────────────────────────── interface ActionConfig { type: BulkActionType; labelKey: string; icon: ReactNode; colorClass: string; } export interface FloatingActionBarProps { selectedUserCount: number; selectedSubscriptionCount: number; isMultiTariff: boolean; totalVisibleSubscriptionCount: number; onAction: (type: BulkActionType) => void; onToggleAllSubscriptions: () => void; } export function FloatingActionBar({ selectedUserCount, selectedSubscriptionCount, isMultiTariff, totalVisibleSubscriptionCount, onAction, onToggleAllSubscriptions, }: FloatingActionBarProps) { const { t } = useTranslation(); const [open, setOpen] = useState(false); const menuRef = useRef(null); useEffect(() => { const handler = (e: MouseEvent) => { if (menuRef.current && !menuRef.current.contains(e.target as Node)) { setOpen(false); } }; document.addEventListener('mousedown', handler); return () => document.removeEventListener('mousedown', handler); }, []); const hasAnySelection = selectedUserCount > 0 || selectedSubscriptionCount > 0; if (!hasAnySelection) return null; const actions: ActionConfig[] = [ { type: 'extend_subscription', labelKey: 'admin.bulkActions.actions.extend', icon: , colorClass: 'text-success-400 hover:bg-success-500/10', }, { type: 'activate_subscription', labelKey: 'admin.bulkActions.actions.activate', icon: , colorClass: 'text-success-400 hover:bg-success-500/10', }, { type: 'cancel_subscription', labelKey: 'admin.bulkActions.actions.cancel', icon: , colorClass: 'text-error-400 hover:bg-error-500/10', }, { type: 'change_tariff', labelKey: 'admin.bulkActions.actions.changeTariff', icon: , colorClass: 'text-accent-400 hover:bg-accent-500/10', }, { type: 'add_traffic', labelKey: 'admin.bulkActions.actions.addTraffic', icon: , colorClass: 'text-accent-400 hover:bg-accent-500/10', }, { type: 'set_devices', labelKey: 'admin.bulkActions.actions.setDevices', icon: ( ), colorClass: 'text-accent-400 hover:bg-accent-500/10', }, { type: 'delete_subscription', labelKey: 'admin.bulkActions.actions.deleteSubscription', icon: ( ), colorClass: 'text-error-400 hover:bg-error-500/10', }, { type: 'add_balance', labelKey: 'admin.bulkActions.actions.addBalance', icon: , colorClass: 'text-warning-400 hover:bg-warning-500/10', }, { type: 'grant_subscription', labelKey: 'admin.bulkActions.actions.grantSubscription', icon: , colorClass: 'text-success-400 hover:bg-success-500/10', }, { type: 'assign_promo_group', labelKey: 'admin.bulkActions.actions.assignPromoGroup', icon: , colorClass: 'text-accent-300 hover:bg-accent-300/10', }, { type: 'delete_user', labelKey: 'admin.bulkActions.actions.deleteUser', icon: ( ), colorClass: 'text-error-400 hover:bg-error-500/10', }, ]; return (
{selectedUserCount > 0 && (
{selectedUserCount}
{t('admin.bulkActions.usersSelected', { count: selectedUserCount })}
)} {isMultiTariff && selectedSubscriptionCount > 0 && (
{selectedUserCount > 0 &&
}
{selectedSubscriptionCount}
{t('admin.bulkActions.subscriptionsSelected', { count: selectedSubscriptionCount, })}
)}
{isMultiTariff && totalVisibleSubscriptionCount > 0 && ( <>
)}
{open && (
{isMultiTariff && (
{t('admin.bulkActions.subscriptionTarget')}
)} {actions .filter((a) => isSubscriptionLevelAction(a.type)) .map((a) => { const count = isMultiTariff ? selectedSubscriptionCount : selectedUserCount; const disabled = count === 0; return ( ); })} {isMultiTariff && (
{t('admin.bulkActions.userTarget')}
)} {actions .filter((a) => !isSubscriptionLevelAction(a.type)) .map((a) => { const disabled = selectedUserCount === 0; return ( ); })}
)}
); }