nielsr HF staff commited on
Commit
7033dcf
·
1 Parent(s): de1321f

Add link to Google Maps

Browse files
src/components/ConferenceDialog.tsx CHANGED
@@ -164,6 +164,10 @@ END:VCALENDAR`;
164
  }
165
  };
166
 
 
 
 
 
167
  return (
168
  <Dialog open={open} onOpenChange={onOpenChange}>
169
  <DialogContent className="dialog-content max-w-md">
@@ -184,7 +188,15 @@ END:VCALENDAR`;
184
  </div>
185
  <div className="flex items-center text-neutral">
186
  <Globe className="h-5 w-5 mr-3 flex-shrink-0" />
187
- <span>{conference.place}</span>
 
 
 
 
 
 
 
 
188
  </div>
189
  <div className="flex items-center text-neutral">
190
  <Clock className="h-5 w-5 mr-3 flex-shrink-0" />
 
164
  }
165
  };
166
 
167
+ const generateGoogleMapsUrl = (venue: string | undefined, place: string): string => {
168
+ return `https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(venue || place)}`;
169
+ };
170
+
171
  return (
172
  <Dialog open={open} onOpenChange={onOpenChange}>
173
  <DialogContent className="dialog-content max-w-md">
 
188
  </div>
189
  <div className="flex items-center text-neutral">
190
  <Globe className="h-5 w-5 mr-3 flex-shrink-0" />
191
+ <a
192
+ href={generateGoogleMapsUrl(conference.venue, conference.place)}
193
+ target="_blank"
194
+ rel="noopener noreferrer"
195
+ className="hover:text-primary hover:underline"
196
+ onClick={(e) => e.stopPropagation()}
197
+ >
198
+ {conference.place}
199
+ </a>
200
  </div>
201
  <div className="flex items-center text-neutral">
202
  <Clock className="h-5 w-5 mr-3 flex-shrink-0" />
src/components/FilterBar.tsx CHANGED
@@ -7,7 +7,7 @@ interface FilterBarProps {
7
  onTagSelect: (tags: Set<string>) => void;
8
  }
9
 
10
- const FilterBar = ({ selectedTags, onTagSelect }: FilterBarProps) => {
11
  const uniqueTags = useMemo(() => {
12
  const tags = new Set<string>();
13
  if (Array.isArray(conferencesData)) {
@@ -26,6 +26,10 @@ const FilterBar = ({ selectedTags, onTagSelect }: FilterBarProps) => {
26
  }));
27
  }, []);
28
 
 
 
 
 
29
  return (
30
  <div className="w-full py-6 bg-white border-b border-neutral-200 animate-fade-in shadow-sm">
31
  <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
@@ -36,7 +40,7 @@ const FilterBar = ({ selectedTags, onTagSelect }: FilterBarProps) => {
36
  title={filter.description}
37
  onClick={() => {
38
  const newTags = new Set(selectedTags);
39
- if (newTags.has(filter.id)) {
40
  newTags.delete(filter.id);
41
  } else {
42
  newTags.add(filter.id);
@@ -46,7 +50,7 @@ const FilterBar = ({ selectedTags, onTagSelect }: FilterBarProps) => {
46
  className={`
47
  px-4 py-2 text-sm font-medium rounded-lg transition-all duration-200
48
  filter-tag
49
- ${selectedTags.has(filter.id)
50
  ? "bg-primary text-white shadow-sm filter-tag-active"
51
  : "bg-neutral-50 text-neutral-600 hover:bg-neutral-100 hover:text-neutral-900"
52
  }
@@ -56,7 +60,7 @@ const FilterBar = ({ selectedTags, onTagSelect }: FilterBarProps) => {
56
  </button>
57
  ))}
58
 
59
- {selectedTags.size > 0 && (
60
  <button
61
  onClick={() => onTagSelect(new Set())}
62
  className="px-4 py-2 text-sm font-medium rounded-lg transition-all duration-200
 
7
  onTagSelect: (tags: Set<string>) => void;
8
  }
9
 
10
+ const FilterBar = ({ selectedTags = new Set(), onTagSelect }: FilterBarProps) => {
11
  const uniqueTags = useMemo(() => {
12
  const tags = new Set<string>();
13
  if (Array.isArray(conferencesData)) {
 
26
  }));
27
  }, []);
28
 
29
+ const isTagSelected = (tagId: string) => {
30
+ return selectedTags?.has(tagId) ?? false;
31
+ };
32
+
33
  return (
34
  <div className="w-full py-6 bg-white border-b border-neutral-200 animate-fade-in shadow-sm">
35
  <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
 
40
  title={filter.description}
41
  onClick={() => {
42
  const newTags = new Set(selectedTags);
43
+ if (isTagSelected(filter.id)) {
44
  newTags.delete(filter.id);
45
  } else {
46
  newTags.add(filter.id);
 
50
  className={`
51
  px-4 py-2 text-sm font-medium rounded-lg transition-all duration-200
52
  filter-tag
53
+ ${isTagSelected(filter.id)
54
  ? "bg-primary text-white shadow-sm filter-tag-active"
55
  : "bg-neutral-50 text-neutral-600 hover:bg-neutral-100 hover:text-neutral-900"
56
  }
 
60
  </button>
61
  ))}
62
 
63
+ {selectedTags?.size > 0 && (
64
  <button
65
  onClick={() => onTagSelect(new Set())}
66
  className="px-4 py-2 text-sm font-medium rounded-lg transition-all duration-200
src/pages/Calendar.tsx CHANGED
@@ -44,6 +44,7 @@ const categoryNames: Record<string, string> = {
44
  const CalendarPage = () => {
45
  const [selectedDate, setSelectedDate] = useState<Date | undefined>(new Date());
46
  const [isYearView, setIsYearView] = useState(true);
 
47
  const [searchQuery, setSearchQuery] = useState("");
48
  const [selectedDayEvents, setSelectedDayEvents] = useState<{ date: Date | null, events: { deadlines: Conference[], conferences: Conference[] } }>({
49
  date: null,
@@ -522,6 +523,11 @@ const CalendarPage = () => {
522
  );
523
  };
524
 
 
 
 
 
 
525
  return (
526
  <div className="min-h-screen bg-neutral-light">
527
  <Header onSearch={setSearchQuery} />
@@ -606,7 +612,8 @@ const CalendarPage = () => {
606
  numberOfMonths={isYearView ? 12 : 1}
607
  showOutsideDays={false}
608
  defaultMonth={new Date(currentYear, 0)}
609
- month={new Date(currentYear, 0)}
 
610
  fromMonth={isYearView ? new Date(currentYear, 0) : undefined}
611
  toMonth={isYearView ? new Date(currentYear, 11) : undefined}
612
  className="bg-white rounded-lg p-6 shadow-sm mx-auto w-full"
@@ -641,7 +648,7 @@ const CalendarPage = () => {
641
  day_today: "bg-neutral-100 text-primary font-semibold",
642
  day_outside: "hidden",
643
  nav: "space-x-1 flex items-center",
644
- nav_button: "h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100",
645
  nav_button_previous: "absolute left-1",
646
  nav_button_next: "absolute right-1"
647
  }}
 
44
  const CalendarPage = () => {
45
  const [selectedDate, setSelectedDate] = useState<Date | undefined>(new Date());
46
  const [isYearView, setIsYearView] = useState(true);
47
+ const [currentMonth, setCurrentMonth] = useState<Date>(new Date());
48
  const [searchQuery, setSearchQuery] = useState("");
49
  const [selectedDayEvents, setSelectedDayEvents] = useState<{ date: Date | null, events: { deadlines: Conference[], conferences: Conference[] } }>({
50
  date: null,
 
523
  );
524
  };
525
 
526
+ const handleMonthChange = (month: Date) => {
527
+ setCurrentMonth(month);
528
+ setSelectedDate(month);
529
+ };
530
+
531
  return (
532
  <div className="min-h-screen bg-neutral-light">
533
  <Header onSearch={setSearchQuery} />
 
612
  numberOfMonths={isYearView ? 12 : 1}
613
  showOutsideDays={false}
614
  defaultMonth={new Date(currentYear, 0)}
615
+ month={isYearView ? new Date(currentYear, 0) : currentMonth}
616
+ onMonthChange={handleMonthChange}
617
  fromMonth={isYearView ? new Date(currentYear, 0) : undefined}
618
  toMonth={isYearView ? new Date(currentYear, 11) : undefined}
619
  className="bg-white rounded-lg p-6 shadow-sm mx-auto w-full"
 
648
  day_today: "bg-neutral-100 text-primary font-semibold",
649
  day_outside: "hidden",
650
  nav: "space-x-1 flex items-center",
651
+ nav_button: isYearView ? "hidden" : "h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100",
652
  nav_button_previous: "absolute left-1",
653
  nav_button_next: "absolute right-1"
654
  }}
src/pages/Index.tsx CHANGED
@@ -50,7 +50,10 @@ const Index = () => {
50
  <Header onSearch={setSearchQuery} />
51
  <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
52
  <div className="space-y-4 py-4">
53
- <FilterBar selectedTags={selectedTags} onTagSelect={setSelectedTags} />
 
 
 
54
  <div className="flex items-center gap-2">
55
  <label htmlFor="show-past" className="text-sm text-neutral-600">
56
  Show past conferences
 
50
  <Header onSearch={setSearchQuery} />
51
  <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
52
  <div className="space-y-4 py-4">
53
+ <FilterBar
54
+ selectedTags={selectedTags}
55
+ onTagSelect={setSelectedTags}
56
+ />
57
  <div className="flex items-center gap-2">
58
  <label htmlFor="show-past" className="text-sm text-neutral-600">
59
  Show past conferences