Spaces:
Sleeping
Sleeping
File size: 2,564 Bytes
38de65f 50f641f f46336a 38de65f de1321f 38de65f 7033dcf 38de65f de1321f 38de65f de1321f 38de65f f46336a 7033dcf f46336a 50f641f f46336a 50f641f 38de65f f46336a 9fb6103 de1321f 7033dcf de1321f 50f641f 7033dcf 50f641f f46336a 9fb6103 f46336a 50f641f 7033dcf 50f641f de1321f 50f641f f46336a |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
import { useMemo } from "react";
import conferencesData from "@/data/conferences.yml";
import { X } from "lucide-react";
interface FilterBarProps {
selectedTags: Set<string>;
onTagSelect: (tags: Set<string>) => void;
}
const FilterBar = ({ selectedTags = new Set(), onTagSelect }: FilterBarProps) => {
const uniqueTags = useMemo(() => {
const tags = new Set<string>();
if (Array.isArray(conferencesData)) {
conferencesData.forEach(conf => {
if (Array.isArray(conf.tags)) {
conf.tags.forEach(tag => tags.add(tag));
}
});
}
return Array.from(tags).map(tag => ({
id: tag,
label: tag.split("-").map(word =>
word.charAt(0).toUpperCase() + word.slice(1)
).join(" "),
description: `${tag} Conferences`
}));
}, []);
const isTagSelected = (tagId: string) => {
return selectedTags?.has(tagId) ?? false;
};
return (
<div className="w-full py-6 bg-white border-b border-neutral-200 animate-fade-in shadow-sm">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="flex flex-wrap gap-3">
{uniqueTags.map((filter) => (
<button
key={filter.id}
title={filter.description}
onClick={() => {
const newTags = new Set(selectedTags);
if (isTagSelected(filter.id)) {
newTags.delete(filter.id);
} else {
newTags.add(filter.id);
}
onTagSelect(newTags);
}}
className={`
px-4 py-2 text-sm font-medium rounded-lg transition-all duration-200
filter-tag
${isTagSelected(filter.id)
? "bg-primary text-white shadow-sm filter-tag-active"
: "bg-neutral-50 text-neutral-600 hover:bg-neutral-100 hover:text-neutral-900"
}
`}
>
{filter.label}
</button>
))}
{selectedTags?.size > 0 && (
<button
onClick={() => onTagSelect(new Set())}
className="px-4 py-2 text-sm font-medium rounded-lg transition-all duration-200
bg-red-50 text-red-600 hover:bg-red-100 hover:text-red-700
flex items-center gap-2"
>
<X className="h-4 w-4" />
Deselect All
</button>
)}
</div>
</div>
</div>
);
};
export default FilterBar;
|