Files
zkill-susser-frontend/src/components/FilterBar.tsx
gpt-engineer-app[bot] 64f7791b7a Changes
2026-01-05 20:50:50 +00:00

129 lines
3.3 KiB
TypeScript

import { X } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { EveIcon } from './EveIcon';
import { FilterState, ItemNames } from '@/types/api';
interface FilterBarProps {
filters: FilterState;
itemNames: ItemNames;
totalKillmails: number;
onRemoveShip: () => void;
onRemoveSystem: (id: number) => void;
onRemoveModule: (id: number) => void;
onRemoveGroup: (id: number) => void;
onClearAll: () => void;
}
export function FilterBar({
filters,
itemNames,
totalKillmails,
onRemoveShip,
onRemoveSystem,
onRemoveModule,
onRemoveGroup,
onClearAll,
}: FilterBarProps) {
const hasFilters = Boolean(
filters.ship ||
filters.systems.length > 0 ||
filters.modules.length > 0 ||
filters.groups.length > 0
);
if (!hasFilters) {
return (
<div className="flex items-center gap-2 px-4 py-3 bg-secondary/50 rounded-md border border-border">
<span className="text-primary font-semibold">
{totalKillmails.toLocaleString()}
</span>
<span className="text-muted-foreground">killmails total</span>
</div>
);
}
return (
<div className="flex flex-wrap items-center gap-2 px-4 py-3 bg-secondary/50 rounded-md border border-border eve-border-glow">
<span className="text-primary font-semibold">
{totalKillmails.toLocaleString()}
</span>
<span className="text-muted-foreground">killmails</span>
<span className="text-muted-foreground mx-2">|</span>
{filters.ship && (
<FilterChip
id={filters.ship}
name={itemNames[filters.ship] || `#${filters.ship}`}
label="Ship"
onRemove={onRemoveShip}
/>
)}
{filters.systems.map(id => (
<FilterChip
key={id}
id={id}
name={itemNames[id] || `#${id}`}
label="System"
onRemove={() => onRemoveSystem(id)}
/>
))}
{filters.modules.map(id => (
<FilterChip
key={id}
id={id}
name={itemNames[id] || `#${id}`}
label="Module"
onRemove={() => onRemoveModule(id)}
/>
))}
{filters.groups.map(id => (
<FilterChip
key={id}
id={id}
name={itemNames[id] || `Group #${id}`}
label="Group"
onRemove={() => onRemoveGroup(id)}
showIcon={false}
/>
))}
<Button
variant="ghost"
size="sm"
onClick={onClearAll}
className="ml-auto text-muted-foreground hover:text-destructive"
>
Clear all
</Button>
</div>
);
}
interface FilterChipProps {
id: number;
name: string;
label: string;
onRemove: () => void;
showIcon?: boolean;
}
function FilterChip({ id, name, label, onRemove, showIcon = true }: FilterChipProps) {
return (
<div className="flex items-center gap-1.5 pl-1 pr-2 py-1 bg-primary/20 border border-primary/40 rounded text-sm">
{showIcon && <EveIcon typeId={id} size={20} />}
<span className="text-xs text-primary/70">{label}:</span>
<span className="font-medium">{name}</span>
<button
onClick={onRemove}
className="ml-1 text-muted-foreground hover:text-destructive transition-colors"
>
<X className="h-3 w-3" />
</button>
</div>
);
}