Improve the frontend
This commit is contained in:
126
frontend/src/components/domain/dashboard/AlertBulkActions.tsx
Normal file
126
frontend/src/components/domain/dashboard/AlertBulkActions.tsx
Normal file
@@ -0,0 +1,126 @@
|
||||
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;
|
||||
Reference in New Issue
Block a user