Files
bakery-ia/frontend/src/components/domain/dashboard/AlertBulkActions.tsx
2025-10-21 19:50:07 +02:00

127 lines
4.1 KiB
TypeScript

import React, { useState } from 'react';
import { Check, Trash2, Clock, X } from 'lucide-react';
import { Button } from '../../ui/Button';
import AlertSnoozeMenu from './AlertSnoozeMenu';
export interface AlertBulkActionsProps {
selectedCount: number;
onMarkAsRead: () => void;
onRemove: () => void;
onSnooze: (duration: '15min' | '1hr' | '4hr' | 'tomorrow' | number) => void;
onDeselectAll: () => void;
onSelectAll: () => void;
totalCount: number;
}
const AlertBulkActions: React.FC<AlertBulkActionsProps> = ({
selectedCount,
onMarkAsRead,
onRemove,
onSnooze,
onDeselectAll,
onSelectAll,
totalCount,
}) => {
const [showSnoozeMenu, setShowSnoozeMenu] = useState(false);
if (selectedCount === 0) {
return null;
}
const handleSnooze = (duration: '15min' | '1hr' | '4hr' | 'tomorrow' | number) => {
onSnooze(duration);
setShowSnoozeMenu(false);
};
const allSelected = selectedCount === totalCount;
return (
<div className="sticky top-0 z-20 bg-gradient-to-r from-[var(--color-primary)] to-[var(--color-primary-dark)] text-white px-4 py-3 rounded-xl shadow-xl flex items-center justify-between gap-3 animate-in slide-in-from-top-2 duration-300">
<div className="flex items-center gap-3 flex-1 min-w-0">
<div className="flex items-center gap-2 px-3 py-1.5 bg-white/20 backdrop-blur-sm rounded-lg">
<span className="text-sm font-bold">{selectedCount}</span>
<span className="text-xs font-medium opacity-90">
{selectedCount === 1 ? 'seleccionado' : 'seleccionados'}
</span>
</div>
{!allSelected && totalCount > selectedCount && (
<button
onClick={onSelectAll}
className="text-sm font-medium hover:underline opacity-90 hover:opacity-100 transition-opacity whitespace-nowrap"
aria-label={`Select all ${totalCount} alerts`}
>
Seleccionar todos ({totalCount})
</button>
)}
</div>
<div className="flex items-center gap-2 relative flex-shrink-0">
{/* Quick Actions */}
<Button
variant="outline"
size="sm"
onClick={onMarkAsRead}
className="bg-white/15 text-white border-white/30 hover:bg-white/25 backdrop-blur-sm h-9 px-3"
aria-label="Mark all selected as read"
>
<Check className="w-4 h-4 sm:mr-2" />
<span className="hidden sm:inline">Marcar leídos</span>
</Button>
<div className="relative">
<Button
variant="outline"
size="sm"
onClick={() => setShowSnoozeMenu(!showSnoozeMenu)}
className="bg-white/15 text-white border-white/30 hover:bg-white/25 backdrop-blur-sm h-9 px-3"
aria-label="Snooze selected alerts"
>
<Clock className="w-4 h-4 sm:mr-2" />
<span className="hidden sm:inline">Posponer</span>
</Button>
{showSnoozeMenu && (
<>
<div
className="fixed inset-0 z-20"
onClick={() => setShowSnoozeMenu(false)}
aria-hidden="true"
/>
<div className="absolute right-0 top-full mt-2 z-30">
<AlertSnoozeMenu
onSnooze={handleSnooze}
onCancel={() => setShowSnoozeMenu(false)}
/>
</div>
</>
)}
</div>
<Button
variant="outline"
size="sm"
onClick={onRemove}
className="bg-red-500/25 text-white border-red-300/40 hover:bg-red-500/40 backdrop-blur-sm h-9 px-3"
aria-label="Delete selected alerts"
>
<Trash2 className="w-4 h-4 sm:mr-2" />
<span className="hidden sm:inline">Eliminar</span>
</Button>
{/* Close button */}
<button
onClick={onDeselectAll}
className="ml-1 p-2 hover:bg-white/15 rounded-lg transition-colors"
aria-label="Deselect all"
title="Cerrar selección"
>
<X className="w-4 h-4" />
</button>
</div>
</div>
);
};
export default AlertBulkActions;