nielsr HF staff commited on
Commit
f5b9300
·
1 Parent(s): 1b35277

Add city and country fields

Browse files
src/components/ConferenceCard.tsx CHANGED
@@ -1,6 +1,6 @@
1
  import { CalendarDays, Globe, Tag, Clock, AlarmClock } from "lucide-react";
2
  import { Conference } from "@/types/conference";
3
- import { formatDistanceToNow, parseISO, isValid } from "date-fns";
4
  import ConferenceDialog from "./ConferenceDialog";
5
  import { useState } from "react";
6
 
@@ -15,12 +15,21 @@ const ConferenceCard = ({
15
  link,
16
  note,
17
  abstract_deadline,
 
 
 
18
  ...conferenceProps
19
  }: Conference) => {
20
  const [dialogOpen, setDialogOpen] = useState(false);
21
  const deadlineDate = deadline && deadline !== 'TBD' ? parseISO(deadline) : null;
22
- const daysLeft = deadlineDate && isValid(deadlineDate) ? formatDistanceToNow(deadlineDate, { addSuffix: true }) : 'TBD';
23
-
 
 
 
 
 
 
24
  // Determine countdown color based on days remaining
25
  const getCountdownColor = () => {
26
  if (!deadlineDate || !isValid(deadlineDate)) return "text-neutral-600";
@@ -86,10 +95,12 @@ const ConferenceCard = ({
86
  <CalendarDays className="h-4 w-4 mr-2 flex-shrink-0" />
87
  <span className="text-sm truncate">{date}</span>
88
  </div>
89
- <div className="flex items-center text-neutral">
90
- <Globe className="h-4 w-4 mr-2 flex-shrink-0" />
91
- <span className="text-sm truncate">{place}</span>
92
- </div>
 
 
93
  <div className="flex items-center text-neutral">
94
  <Clock className="h-4 w-4 mr-2 flex-shrink-0" />
95
  <span className="text-sm truncate">
@@ -99,7 +110,7 @@ const ConferenceCard = ({
99
  <div className="flex items-center">
100
  <AlarmClock className={`h-4 w-4 mr-2 flex-shrink-0 ${getCountdownColor()}`} />
101
  <span className={`text-sm font-medium truncate ${getCountdownColor()}`}>
102
- {daysLeft}
103
  </span>
104
  </div>
105
  </div>
@@ -121,7 +132,22 @@ const ConferenceCard = ({
121
  </div>
122
 
123
  <ConferenceDialog
124
- conference={{ title, full_name, date, place, deadline, timezone, tags, link, note, abstract_deadline, ...conferenceProps }}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
125
  open={dialogOpen}
126
  onOpenChange={setDialogOpen}
127
  />
 
1
  import { CalendarDays, Globe, Tag, Clock, AlarmClock } from "lucide-react";
2
  import { Conference } from "@/types/conference";
3
+ import { formatDistanceToNow, parseISO, isValid, isPast } from "date-fns";
4
  import ConferenceDialog from "./ConferenceDialog";
5
  import { useState } from "react";
6
 
 
15
  link,
16
  note,
17
  abstract_deadline,
18
+ city,
19
+ country,
20
+ venue,
21
  ...conferenceProps
22
  }: Conference) => {
23
  const [dialogOpen, setDialogOpen] = useState(false);
24
  const deadlineDate = deadline && deadline !== 'TBD' ? parseISO(deadline) : null;
25
+ const isPastDeadline = deadlineDate ? isPast(deadlineDate) : false;
26
+ const timeRemaining = deadlineDate && !isPastDeadline
27
+ ? formatDistanceToNow(deadlineDate, { addSuffix: true })
28
+ : null;
29
+
30
+ // Create location string by concatenating city and country
31
+ const location = [city, country].filter(Boolean).join(", ");
32
+
33
  // Determine countdown color based on days remaining
34
  const getCountdownColor = () => {
35
  if (!deadlineDate || !isValid(deadlineDate)) return "text-neutral-600";
 
95
  <CalendarDays className="h-4 w-4 mr-2 flex-shrink-0" />
96
  <span className="text-sm truncate">{date}</span>
97
  </div>
98
+ {location && (
99
+ <div className="flex items-center text-neutral">
100
+ <Globe className="h-4 w-4 mr-2 flex-shrink-0" />
101
+ <span className="text-sm truncate">{location}</span>
102
+ </div>
103
+ )}
104
  <div className="flex items-center text-neutral">
105
  <Clock className="h-4 w-4 mr-2 flex-shrink-0" />
106
  <span className="text-sm truncate">
 
110
  <div className="flex items-center">
111
  <AlarmClock className={`h-4 w-4 mr-2 flex-shrink-0 ${getCountdownColor()}`} />
112
  <span className={`text-sm font-medium truncate ${getCountdownColor()}`}>
113
+ {timeRemaining}
114
  </span>
115
  </div>
116
  </div>
 
132
  </div>
133
 
134
  <ConferenceDialog
135
+ conference={{
136
+ title,
137
+ full_name,
138
+ date,
139
+ place,
140
+ deadline,
141
+ timezone,
142
+ tags,
143
+ link,
144
+ note,
145
+ abstract_deadline,
146
+ city,
147
+ country,
148
+ venue,
149
+ ...conferenceProps
150
+ }}
151
  open={dialogOpen}
152
  onOpenChange={setDialogOpen}
153
  />
src/components/ConferenceDialog.tsx CHANGED
@@ -24,9 +24,32 @@ interface ConferenceDialogProps {
24
  }
25
 
26
  const ConferenceDialog = ({ conference, open, onOpenChange }: ConferenceDialogProps) => {
 
27
  const deadlineDate = conference.deadline && conference.deadline !== 'TBD' ? parseISO(conference.deadline) : null;
28
  const [countdown, setCountdown] = useState<string>('');
29
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  useEffect(() => {
31
  const calculateTimeLeft = () => {
32
  if (!deadlineDate || !isValid(deadlineDate)) {
@@ -110,12 +133,12 @@ const ConferenceDialog = ({ conference, open, onOpenChange }: ConferenceDialogPr
110
  const formatDateForApple = (date: Date) => format(date, "yyyyMMdd'T'HHmmss'Z'");
111
 
112
  const title = encodeURIComponent(`${conference.title} deadline`);
113
- const location = encodeURIComponent(conference.place);
114
  const description = encodeURIComponent(
115
  `Paper Submission Deadline for ${conference.full_name || conference.title}\n` +
116
  (conference.abstract_deadline ? `Abstract Deadline: ${conference.abstract_deadline}\n` : '') +
117
  `Dates: ${conference.date}\n` +
118
- `Location: ${conference.place}\n` +
119
  (conference.link ? `Website: ${conference.link}` : '')
120
  );
121
 
@@ -124,7 +147,7 @@ const ConferenceDialog = ({ conference, open, onOpenChange }: ConferenceDialogPr
124
  `&text=${title}` +
125
  `&dates=${formatDateForGoogle(deadlineDate)}/${formatDateForGoogle(endDate)}` +
126
  `&details=${description}` +
127
- `&location=${location}` +
128
  `&sprop=website:${encodeURIComponent(conference.link || '')}`;
129
  window.open(url, '_blank');
130
  } else {
@@ -159,91 +182,92 @@ END:VCALENDAR`;
159
 
160
  return (
161
  <Dialog open={open} onOpenChange={onOpenChange}>
162
- <DialogContent className="max-w-xl">
163
  <DialogHeader>
164
- <DialogTitle>{conference.title} {conference.year}</DialogTitle>
165
- <DialogDescription>
166
  {conference.full_name}
167
  </DialogDescription>
168
  </DialogHeader>
 
 
 
 
 
 
 
 
 
 
169
 
170
- <div className="space-y-4">
171
- <div className="flex items-start gap-2">
172
- <CalendarDays className="h-5 w-5 mt-0.5 text-gray-500" />
173
- <div>
174
- <p className="font-medium">Dates</p>
175
- <p className="text-sm text-gray-500">{conference.date}</p>
 
 
176
  </div>
177
- </div>
178
 
179
- <div className="flex items-start gap-2">
180
- <Clock className="h-5 w-5 mt-0.5 text-gray-500" />
181
- <div className="space-y-2 flex-1">
182
- <p className="font-medium">Important Deadlines</p>
183
- <div className="text-sm text-gray-500 space-y-2">
184
- {conference.abstract_deadline && (
 
 
 
 
 
 
 
185
  <div className="bg-gray-100 rounded-md p-2">
186
- <p>Abstract: {parseISO(conference.abstract_deadline) && isValid(parseISO(conference.abstract_deadline))
187
- ? format(parseISO(conference.abstract_deadline), "MMMM d, yyyy")
188
- : conference.abstract_deadline}
189
  </p>
190
  </div>
191
- )}
192
- <div className="bg-gray-100 rounded-md p-2">
193
- <p>Submission: {conference.deadline && conference.deadline !== 'TBD' && isValid(parseISO(conference.deadline))
194
- ? format(parseISO(conference.deadline), "MMMM d, yyyy")
195
- : conference.deadline}
196
- </p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
197
  </div>
198
- {conference.commitment_deadline && (
199
- <div className="bg-gray-100 rounded-md p-2">
200
- <p>Commitment: {isValid(parseISO(conference.commitment_deadline))
201
- ? format(parseISO(conference.commitment_deadline), "MMMM d, yyyy")
202
- : conference.commitment_deadline}
203
- </p>
204
- </div>
205
- )}
206
- {conference.review_release_date && (
207
- <div className="bg-gray-100 rounded-md p-2">
208
- <p>Reviews Released: {isValid(parseISO(conference.review_release_date))
209
- ? format(parseISO(conference.review_release_date), "MMMM d, yyyy")
210
- : conference.review_release_date}
211
- </p>
212
- </div>
213
- )}
214
- {(conference.rebuttal_period_start || conference.rebuttal_period_end) && (
215
- <div className="bg-gray-100 rounded-md p-2">
216
- <p>Rebuttal Period: {conference.rebuttal_period_start && isValid(parseISO(conference.rebuttal_period_start))
217
- ? format(parseISO(conference.rebuttal_period_start), "MMMM d, yyyy")
218
- : conference.rebuttal_period_start} - {conference.rebuttal_period_end && isValid(parseISO(conference.rebuttal_period_end))
219
- ? format(parseISO(conference.rebuttal_period_end), "MMMM d, yyyy")
220
- : conference.rebuttal_period_end}
221
- </p>
222
- </div>
223
- )}
224
- {conference.final_decision_date && (
225
- <div className="bg-gray-100 rounded-md p-2">
226
- <p>Final Decision: {isValid(parseISO(conference.final_decision_date))
227
- ? format(parseISO(conference.final_decision_date), "MMMM d, yyyy")
228
- : conference.final_decision_date}
229
- </p>
230
- </div>
231
- )}
232
  </div>
233
  </div>
234
  </div>
235
 
236
- <div className="flex items-start gap-2">
237
- <Globe className="h-5 w-5 mt-0.5 text-gray-500" />
238
- <div>
239
- <p className="font-medium">Location</p>
240
- <p className="text-sm text-gray-500">{conference.place}</p>
241
- {conference.venue && (
242
- <p className="text-sm text-gray-500">{conference.venue}</p>
243
- )}
244
- </div>
245
- </div>
246
-
247
  <div className="flex items-center">
248
  <AlarmClock className={`h-5 w-5 mr-3 flex-shrink-0 ${getCountdownColor()}`} />
249
  <div>
 
24
  }
25
 
26
  const ConferenceDialog = ({ conference, open, onOpenChange }: ConferenceDialogProps) => {
27
+ console.log('Conference object:', conference);
28
  const deadlineDate = conference.deadline && conference.deadline !== 'TBD' ? parseISO(conference.deadline) : null;
29
  const [countdown, setCountdown] = useState<string>('');
30
 
31
+ // Replace the current location string creation with this more verbose version
32
+ const getLocationString = () => {
33
+ console.log('Venue:', conference.venue);
34
+ console.log('City:', conference.city);
35
+ console.log('Country:', conference.country);
36
+
37
+ if (conference.venue) {
38
+ return conference.venue;
39
+ }
40
+
41
+ const cityCountryArray = [conference.city, conference.country].filter(Boolean);
42
+ console.log('City/Country array after filter:', cityCountryArray);
43
+
44
+ const cityCountryString = cityCountryArray.join(", ");
45
+ console.log('Final location string:', cityCountryString);
46
+
47
+ return cityCountryString || "Location TBD"; // Fallback if everything is empty
48
+ };
49
+
50
+ // Use the function result
51
+ const location = getLocationString();
52
+
53
  useEffect(() => {
54
  const calculateTimeLeft = () => {
55
  if (!deadlineDate || !isValid(deadlineDate)) {
 
133
  const formatDateForApple = (date: Date) => format(date, "yyyyMMdd'T'HHmmss'Z'");
134
 
135
  const title = encodeURIComponent(`${conference.title} deadline`);
136
+ const locationStr = encodeURIComponent(location);
137
  const description = encodeURIComponent(
138
  `Paper Submission Deadline for ${conference.full_name || conference.title}\n` +
139
  (conference.abstract_deadline ? `Abstract Deadline: ${conference.abstract_deadline}\n` : '') +
140
  `Dates: ${conference.date}\n` +
141
+ `Location: ${location}\n` +
142
  (conference.link ? `Website: ${conference.link}` : '')
143
  );
144
 
 
147
  `&text=${title}` +
148
  `&dates=${formatDateForGoogle(deadlineDate)}/${formatDateForGoogle(endDate)}` +
149
  `&details=${description}` +
150
+ `&location=${locationStr}` +
151
  `&sprop=website:${encodeURIComponent(conference.link || '')}`;
152
  window.open(url, '_blank');
153
  } else {
 
182
 
183
  return (
184
  <Dialog open={open} onOpenChange={onOpenChange}>
185
+ <DialogContent className="max-w-2xl max-h-[90vh] overflow-y-auto">
186
  <DialogHeader>
187
+ <DialogTitle className="text-2xl font-bold text-blue-600">{conference.title}</DialogTitle>
188
+ <DialogDescription className="text-base text-gray-700">
189
  {conference.full_name}
190
  </DialogDescription>
191
  </DialogHeader>
192
+
193
+ <div className="space-y-6 mt-4">
194
+ <div className="space-y-4">
195
+ <div className="flex items-start gap-2">
196
+ <CalendarDays className="h-5 w-5 mt-0.5 text-gray-500" />
197
+ <div>
198
+ <p className="font-medium">Dates</p>
199
+ <p className="text-sm text-gray-500">{conference.date}</p>
200
+ </div>
201
+ </div>
202
 
203
+ <div className="flex items-start gap-2">
204
+ <Globe className="h-5 w-5 mt-0.5 text-gray-500" />
205
+ <div>
206
+ <p className="font-medium">Location</p>
207
+ <p className="text-sm text-gray-500">
208
+ {conference.venue || [conference.city, conference.country].filter(Boolean).join(", ")}
209
+ </p>
210
+ </div>
211
  </div>
 
212
 
213
+ <div className="flex items-start gap-2">
214
+ <Clock className="h-5 w-5 mt-0.5 text-gray-500" />
215
+ <div className="space-y-2 flex-1">
216
+ <p className="font-medium">Important Deadlines</p>
217
+ <div className="text-sm text-gray-500 space-y-2">
218
+ {conference.abstract_deadline && (
219
+ <div className="bg-gray-100 rounded-md p-2">
220
+ <p>Abstract: {parseISO(conference.abstract_deadline) && isValid(parseISO(conference.abstract_deadline))
221
+ ? format(parseISO(conference.abstract_deadline), "MMMM d, yyyy")
222
+ : conference.abstract_deadline}
223
+ </p>
224
+ </div>
225
+ )}
226
  <div className="bg-gray-100 rounded-md p-2">
227
+ <p>Submission: {conference.deadline && conference.deadline !== 'TBD' && isValid(parseISO(conference.deadline))
228
+ ? format(parseISO(conference.deadline), "MMMM d, yyyy")
229
+ : conference.deadline}
230
  </p>
231
  </div>
232
+ {conference.commitment_deadline && (
233
+ <div className="bg-gray-100 rounded-md p-2">
234
+ <p>Commitment: {isValid(parseISO(conference.commitment_deadline))
235
+ ? format(parseISO(conference.commitment_deadline), "MMMM d, yyyy")
236
+ : conference.commitment_deadline}
237
+ </p>
238
+ </div>
239
+ )}
240
+ {conference.review_release_date && (
241
+ <div className="bg-gray-100 rounded-md p-2">
242
+ <p>Reviews Released: {isValid(parseISO(conference.review_release_date))
243
+ ? format(parseISO(conference.review_release_date), "MMMM d, yyyy")
244
+ : conference.review_release_date}
245
+ </p>
246
+ </div>
247
+ )}
248
+ {(conference.rebuttal_period_start || conference.rebuttal_period_end) && (
249
+ <div className="bg-gray-100 rounded-md p-2">
250
+ <p>Rebuttal Period: {conference.rebuttal_period_start && isValid(parseISO(conference.rebuttal_period_start))
251
+ ? format(parseISO(conference.rebuttal_period_start), "MMMM d, yyyy")
252
+ : conference.rebuttal_period_start} - {conference.rebuttal_period_end && isValid(parseISO(conference.rebuttal_period_end))
253
+ ? format(parseISO(conference.rebuttal_period_end), "MMMM d, yyyy")
254
+ : conference.rebuttal_period_end}
255
+ </p>
256
+ </div>
257
+ )}
258
+ {conference.final_decision_date && (
259
+ <div className="bg-gray-100 rounded-md p-2">
260
+ <p>Final Decision: {isValid(parseISO(conference.final_decision_date))
261
+ ? format(parseISO(conference.final_decision_date), "MMMM d, yyyy")
262
+ : conference.final_decision_date}
263
+ </p>
264
+ </div>
265
+ )}
266
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
267
  </div>
268
  </div>
269
  </div>
270
 
 
 
 
 
 
 
 
 
 
 
 
271
  <div className="flex items-center">
272
  <AlarmClock className={`h-5 w-5 mr-3 flex-shrink-0 ${getCountdownColor()}`} />
273
  <div>
src/data/conferences.yml CHANGED
@@ -39,7 +39,7 @@
39
  - title: ICRA
40
  year: 2025
41
  id: icra25
42
- full_name: IEEE International Conference on Robotics and Automation
43
  link: https://2025.ieee-icra.org
44
  deadline: '2024-07-15 12:00:00'
45
  timezone: UTC-4
@@ -57,7 +57,7 @@
57
  - title: WACV
58
  year: 2025
59
  id: wacv25
60
- full_name: IEEE/CVF Winter Conference on Applications of Computer Vision
61
  link: https://wacv2025.thecvf.com/
62
  deadline: '2024-07-15 23:59:59'
63
  timezone: UTC-7
@@ -114,7 +114,7 @@
114
  - title: ICASSP
115
  year: 2025
116
  id: icassp25
117
- full_name: IEEE International Conference on Acoustics, Speech and Signal Processing
118
  link: https://2025.ieeeicassp.org/
119
  deadline: '2024-09-09 23:59:59'
120
  timezone: UTC-12
@@ -290,7 +290,7 @@
290
  - title: CVPR
291
  year: 2025
292
  id: cvpr25
293
- full_name: IEEE/CVF Conference on Computer Vision and Pattern Recognition
294
  link: https://cvpr.thecvf.com/Conferences/2025/CallForPapers
295
  deadline: '2024-11-14 23:59:00'
296
  timezone: UTC-8
@@ -339,7 +339,7 @@
339
  - title: CEC
340
  year: 2025
341
  id: cec2025
342
- full_name: IEEE Congress on Evolutionary Computation
343
  link: https://www.cec2025.org/
344
  deadline: '2025-01-15 23:59:59'
345
  timezone: UTC-12
@@ -533,7 +533,7 @@
533
  - title: IROS
534
  year: 2025
535
  id: iros25
536
- full_name: IEEE\RSJ International Conference on Intelligent Robots and Systems
537
  link: http://www.iros25.org/
538
  deadline: '2025-03-01 23:59:59'
539
  timezone: UTC-8
@@ -576,12 +576,12 @@
576
  - title: ICCV
577
  year: 2025
578
  id: iccv25
579
- full_name: IEEE International Conference on Computer Vision
580
  link: https://iccv.thecvf.com/Conferences/2025
581
  deadline: '2025-03-08 09:59:59'
582
  timezone: UTC+0
583
  city: Honolulu
584
- country: USA
585
  date: October 19-25, 2025
586
  tags:
587
  - machine-learning
@@ -696,7 +696,7 @@
696
  - title: ICDM
697
  year: 2025
698
  id: icdm25
699
- full_name: IEEE International Conference on Data Mining
700
  link: https://www3.cs.stonybrook.edu/~icdm2025/index.html
701
  deadline: '2025-06-06 23:59:59'
702
  timezone: AoE
 
39
  - title: ICRA
40
  year: 2025
41
  id: icra25
42
+ full_name: International Conference on Robotics and Automation
43
  link: https://2025.ieee-icra.org
44
  deadline: '2024-07-15 12:00:00'
45
  timezone: UTC-4
 
57
  - title: WACV
58
  year: 2025
59
  id: wacv25
60
+ full_name: Winter Conference on Applications of Computer Vision
61
  link: https://wacv2025.thecvf.com/
62
  deadline: '2024-07-15 23:59:59'
63
  timezone: UTC-7
 
114
  - title: ICASSP
115
  year: 2025
116
  id: icassp25
117
+ full_name: International Conference on Acoustics, Speech and Signal Processing
118
  link: https://2025.ieeeicassp.org/
119
  deadline: '2024-09-09 23:59:59'
120
  timezone: UTC-12
 
290
  - title: CVPR
291
  year: 2025
292
  id: cvpr25
293
+ full_name: Conference on Computer Vision and Pattern Recognition
294
  link: https://cvpr.thecvf.com/Conferences/2025/CallForPapers
295
  deadline: '2024-11-14 23:59:00'
296
  timezone: UTC-8
 
339
  - title: CEC
340
  year: 2025
341
  id: cec2025
342
+ full_name: Congress on Evolutionary Computation
343
  link: https://www.cec2025.org/
344
  deadline: '2025-01-15 23:59:59'
345
  timezone: UTC-12
 
533
  - title: IROS
534
  year: 2025
535
  id: iros25
536
+ full_name: International Conference on Intelligent Robots and Systems
537
  link: http://www.iros25.org/
538
  deadline: '2025-03-01 23:59:59'
539
  timezone: UTC-8
 
576
  - title: ICCV
577
  year: 2025
578
  id: iccv25
579
+ full_name: International Conference on Computer Vision
580
  link: https://iccv.thecvf.com/Conferences/2025
581
  deadline: '2025-03-08 09:59:59'
582
  timezone: UTC+0
583
  city: Honolulu
584
+ country: Hawaii
585
  date: October 19-25, 2025
586
  tags:
587
  - machine-learning
 
696
  - title: ICDM
697
  year: 2025
698
  id: icdm25
699
+ full_name: International Conference on Data Mining
700
  link: https://www3.cs.stonybrook.edu/~icdm2025/index.html
701
  deadline: '2025-06-06 23:59:59'
702
  timezone: AoE
src/pages/Index.tsx CHANGED
@@ -10,7 +10,7 @@ import { extractCountry } from "@/utils/countryExtractor";
10
  import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
11
  import { Button } from "@/components/ui/button";
12
  import { Checkbox } from "@/components/ui/checkbox";
13
- import { X, ChevronRight, Filter } from "lucide-react";
14
  import { getAllCountries } from "@/utils/countryExtractor";
15
 
16
  const Index = () => {
@@ -177,16 +177,15 @@ const Index = () => {
177
  <Popover>
178
  <PopoverTrigger asChild>
179
  <Button variant="outline" size="sm" className="h-8 gap-1">
180
- <Filter className="h-4 w-4" />
181
  Filter by Country
182
  </Button>
183
  </PopoverTrigger>
184
- <PopoverContent className="w-80 p-4 bg-white" align="start">
185
  <div className="space-y-4">
186
  <div>
187
- <div className="flex items-center justify-between mb-4">
188
  <h4 className="text-sm font-medium text-gray-800">Country</h4>
189
- <ChevronRight className="h-4 w-4 text-gray-500" />
190
  </div>
191
  <div className="max-h-60 overflow-y-auto space-y-2 bg-white">
192
  {getAllCountries(conferencesData as Conference[]).map(country => (
 
10
  import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
11
  import { Button } from "@/components/ui/button";
12
  import { Checkbox } from "@/components/ui/checkbox";
13
+ import { X, ChevronRight, Filter, Globe } from "lucide-react";
14
  import { getAllCountries } from "@/utils/countryExtractor";
15
 
16
  const Index = () => {
 
177
  <Popover>
178
  <PopoverTrigger asChild>
179
  <Button variant="outline" size="sm" className="h-8 gap-1">
180
+ <Globe className="h-4 w-4" />
181
  Filter by Country
182
  </Button>
183
  </PopoverTrigger>
184
+ <PopoverContent className="w-64 p-4 bg-white" align="start">
185
  <div className="space-y-4">
186
  <div>
187
+ <div className="mb-4">
188
  <h4 className="text-sm font-medium text-gray-800">Country</h4>
 
189
  </div>
190
  <div className="max-h-60 overflow-y-auto space-y-2 bg-white">
191
  {getAllCountries(conferencesData as Conference[]).map(country => (