File size: 4,476 Bytes
38de65f
 
08d905b
 
 
 
 
 
 
 
 
 
f46336a
38de65f
de1321f
08d905b
de1321f
08d905b
38de65f
 
08d905b
 
 
 
 
 
38de65f
 
 
 
 
 
 
 
 
de1321f
38de65f
 
 
 
de1321f
38de65f
 
f46336a
7033dcf
 
 
 
08d905b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f46336a
08d905b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f46336a
08d905b
 
 
50f641f
08d905b
 
50f641f
08d905b
 
 
50f641f
08d905b
 
 
 
50f641f
08d905b
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import { useMemo } from "react";
import conferencesData from "@/data/conferences.yml";
import { X, ChevronRight, Filter } from "lucide-react";
import { getAllCountries } from "@/utils/countryExtractor";
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@/components/ui/popover";
import { Button } from "@/components/ui/button";
import { Checkbox } from "@/components/ui/checkbox";
import { Conference } from "@/types/conference";

interface FilterBarProps {
  selectedTags: Set<string>;
  selectedCountries: Set<string>;
  onTagSelect: (tags: Set<string>) => void;
  onCountrySelect: (countries: Set<string>) => void;
}

const FilterBar = ({ 
  selectedTags = new Set(), 
  selectedCountries = new Set(),
  onTagSelect,
  onCountrySelect
}: 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;
  };

  const handleTagChange = (tagId: string) => {
    const newSelectedTags = new Set(selectedTags);
    if (newSelectedTags.has(tagId)) {
      newSelectedTags.delete(tagId);
    } else {
      newSelectedTags.add(tagId);
    }
    onTagSelect(newSelectedTags);
  };

  const clearAllFilters = () => {
    onTagSelect(new Set());
    onCountrySelect(new Set());
  };

  return (
    <div className="bg-white shadow rounded-lg p-4">
      <div className="flex flex-col space-y-4">
        <div className="flex flex-wrap items-center gap-2">
          <Popover>
            <PopoverTrigger asChild>
              <Button variant="outline" size="sm" className="h-8 gap-1">
                <Filter className="h-4 w-4" />
                Filter by Tag
              </Button>
            </PopoverTrigger>
            <PopoverContent className="w-80 p-4" align="start">
              <div className="space-y-4">
                <div>
                  <div className="flex items-center justify-between mb-4">
                    <h4 className="text-sm font-medium text-gray-800">Tags</h4>
                    <ChevronRight className="h-4 w-4 text-gray-500" />
                  </div>
                  <div className="max-h-60 overflow-y-auto space-y-2">
                    {uniqueTags.map(tag => (
                      <div key={tag.id} className="flex items-center space-x-2 hover:bg-gray-50 p-1 rounded">
                        <Checkbox 
                          id={`tag-${tag.id}`}
                          checked={isTagSelected(tag.id)}
                          onCheckedChange={() => handleTagChange(tag.id)}
                        />
                        <label 
                          htmlFor={`tag-${tag.id}`}
                          className="text-sm font-medium text-gray-700 cursor-pointer w-full py-1"
                        >
                          {tag.label}
                        </label>
                      </div>
                    ))}
                  </div>
                </div>
              </div>
            </PopoverContent>
          </Popover>

          {/* Clear all filters button */}
          {(selectedTags.size > 0 || selectedCountries.size > 0) && (
            <Button 
              variant="ghost" 
              size="sm" 
              onClick={clearAllFilters}
              className="text-neutral-500 hover:text-neutral-700"
            >
              Clear all
            </Button>
          )}
          
          {/* Display selected tags */}
          {Array.from(selectedTags).map(tag => (
            <button
              key={tag}
              className="inline-flex items-center px-3 py-1 rounded-full text-sm bg-blue-100 text-blue-800 hover:bg-blue-200 font-medium"
              onClick={() => handleTagChange(tag)}
            >
              {tag.split("-").map(word => 
                word.charAt(0).toUpperCase() + word.slice(1)
              ).join(" ")}
              <X className="ml-1 h-3 w-3" />
            </button>
          ))}
        </div>
      </div>
    </div>
  );
};

export default FilterBar;