129 lines
3.3 KiB
TypeScript
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>
|
|
);
|
|
}
|