gpt-engineer-app[bot] commited on
Commit
f4d9004
·
1 Parent(s): b2510cd

Fix calendar display and events

Browse files

- Correct calendar alignment on the page.
- Fix issue where all months display "no events".

Files changed (1) hide show
  1. src/pages/Calendar.tsx +19 -21
src/pages/Calendar.tsx CHANGED
@@ -1,23 +1,19 @@
1
-
2
  import { useState } from "react";
3
  import conferencesData from "@/data/conferences.yml";
4
  import { Conference } from "@/types/conference";
5
  import { Calendar as CalendarIcon, Tag, CircleDot } from "lucide-react";
6
  import { Calendar } from "@/components/ui/calendar";
7
- import { parseISO, format, isValid, startOfMonth, endOfMonth, isSameMonth } from "date-fns";
8
 
9
  const CalendarPage = () => {
10
  const [selectedDate, setSelectedDate] = useState<Date | undefined>(new Date());
11
 
12
- // Helper function to safely parse dates
13
  const safeParseISO = (dateString: string | undefined | number): Date | null => {
14
  if (!dateString || dateString === 'TBD') return null;
15
 
16
- // Convert to string if it's a number
17
  const dateStr = typeof dateString === 'number' ? dateString.toString() : dateString;
18
 
19
  try {
20
- // Try to parse the date, handling different formats
21
  const normalizedDate = dateStr.replace(/(\d{4})-(\d{1})-(\d{1,2})/, '$1-0$2-$3')
22
  .replace(/(\d{4})-(\d{2})-(\d{1})/, '$1-$2-0$3');
23
 
@@ -29,18 +25,19 @@ const CalendarPage = () => {
29
  }
30
  };
31
 
32
- // Get all events (conferences and deadlines) for a given month
33
  const getMonthEvents = (date: Date) => {
34
  return conferencesData.filter((conf: Conference) => {
35
  const deadlineDate = safeParseISO(conf.deadline);
36
  const startDate = safeParseISO(conf.start);
 
37
 
38
  return (deadlineDate && isSameMonth(deadlineDate, date)) ||
39
- (startDate && isSameMonth(startDate, date));
 
 
40
  });
41
  };
42
 
43
- // Get all unique dates (deadlines and conference dates)
44
  const getDatesWithEvents = () => {
45
  const dates = {
46
  conferences: new Set<string>(),
@@ -56,7 +53,6 @@ const CalendarPage = () => {
56
  dates.deadlines.add(format(deadlineDate, 'yyyy-MM-dd'));
57
  }
58
 
59
- // If conference has both start and end dates, add all dates in between
60
  if (startDate && endDate) {
61
  let currentDate = startDate;
62
  while (currentDate <= endDate) {
@@ -64,7 +60,6 @@ const CalendarPage = () => {
64
  currentDate = new Date(currentDate.setDate(currentDate.getDate() + 1));
65
  }
66
  } else if (startDate) {
67
- // If only start date is available, add just that date
68
  dates.conferences.add(format(startDate, 'yyyy-MM-dd'));
69
  }
70
  });
@@ -75,7 +70,6 @@ const CalendarPage = () => {
75
  };
76
  };
77
 
78
- // Get conferences for selected date
79
  const getConferencesForDate = (date: Date) => {
80
  const formattedDate = format(date, 'yyyy-MM-dd');
81
  return conferencesData.filter((conf: Conference) => {
@@ -86,7 +80,6 @@ const CalendarPage = () => {
86
  const deadlineDateStr = deadlineDate ? format(deadlineDate, 'yyyy-MM-dd') : null;
87
  const isDeadlineMatch = deadlineDateStr === formattedDate;
88
 
89
- // Check if the date falls within the conference duration
90
  let isConferenceDate = false;
91
  if (startDate && endDate) {
92
  isConferenceDate = date >= startDate && date <= endDate;
@@ -106,7 +99,6 @@ const CalendarPage = () => {
106
  <div className="max-w-7xl mx-auto">
107
  <h1 className="text-3xl font-bold mb-8 text-center">Calendar Overview</h1>
108
 
109
- {/* Color Legend */}
110
  <div className="flex justify-center gap-6 mb-6">
111
  <div className="flex items-center gap-2">
112
  <CircleDot className="h-4 w-4 text-purple-600" />
@@ -126,11 +118,18 @@ const CalendarPage = () => {
126
  onSelect={setSelectedDate}
127
  className="bg-white rounded-lg p-6 shadow-sm mx-auto w-full"
128
  classNames={{
129
- month: "w-full",
130
- table: "w-full",
 
 
 
131
  cell: "h-14 w-14 text-center text-sm p-0 relative [&:has([aria-selected])]:bg-accent first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md focus-within:relative focus-within:z-20",
132
  day: "h-14 w-14 p-0 font-normal aria-selected:opacity-100 hover:bg-neutral-100 rounded-lg transition-colors",
133
- day_today: "bg-neutral-100 text-primary font-semibold"
 
 
 
 
134
  }}
135
  modifiers={{
136
  conference: datesWithEvents.conferences,
@@ -138,20 +137,19 @@ const CalendarPage = () => {
138
  }}
139
  modifiersStyles={{
140
  conference: {
141
- backgroundColor: '#DDD6FE', // purple-200
142
- color: '#7C3AED', // purple-600
143
  fontWeight: 'bold'
144
  },
145
  deadline: {
146
- backgroundColor: '#FEE2E2', // red-100
147
- color: '#EF4444', // red-500
148
  fontWeight: 'bold'
149
  }
150
  }}
151
  />
152
  </div>
153
 
154
- {/* Month Events */}
155
  {selectedDate && (
156
  <div className="mx-auto w-full max-w-3xl space-y-4">
157
  <h2 className="text-xl font-semibold flex items-center gap-2">
 
 
1
  import { useState } from "react";
2
  import conferencesData from "@/data/conferences.yml";
3
  import { Conference } from "@/types/conference";
4
  import { Calendar as CalendarIcon, Tag, CircleDot } from "lucide-react";
5
  import { Calendar } from "@/components/ui/calendar";
6
+ import { parseISO, format, isValid, isSameMonth } from "date-fns";
7
 
8
  const CalendarPage = () => {
9
  const [selectedDate, setSelectedDate] = useState<Date | undefined>(new Date());
10
 
 
11
  const safeParseISO = (dateString: string | undefined | number): Date | null => {
12
  if (!dateString || dateString === 'TBD') return null;
13
 
 
14
  const dateStr = typeof dateString === 'number' ? dateString.toString() : dateString;
15
 
16
  try {
 
17
  const normalizedDate = dateStr.replace(/(\d{4})-(\d{1})-(\d{1,2})/, '$1-0$2-$3')
18
  .replace(/(\d{4})-(\d{2})-(\d{1})/, '$1-$2-0$3');
19
 
 
25
  }
26
  };
27
 
 
28
  const getMonthEvents = (date: Date) => {
29
  return conferencesData.filter((conf: Conference) => {
30
  const deadlineDate = safeParseISO(conf.deadline);
31
  const startDate = safeParseISO(conf.start);
32
+ const endDate = safeParseISO(conf.end);
33
 
34
  return (deadlineDate && isSameMonth(deadlineDate, date)) ||
35
+ (startDate && (endDate ?
36
+ (isSameMonth(startDate, date) || isSameMonth(endDate, date)) :
37
+ isSameMonth(startDate, date)));
38
  });
39
  };
40
 
 
41
  const getDatesWithEvents = () => {
42
  const dates = {
43
  conferences: new Set<string>(),
 
53
  dates.deadlines.add(format(deadlineDate, 'yyyy-MM-dd'));
54
  }
55
 
 
56
  if (startDate && endDate) {
57
  let currentDate = startDate;
58
  while (currentDate <= endDate) {
 
60
  currentDate = new Date(currentDate.setDate(currentDate.getDate() + 1));
61
  }
62
  } else if (startDate) {
 
63
  dates.conferences.add(format(startDate, 'yyyy-MM-dd'));
64
  }
65
  });
 
70
  };
71
  };
72
 
 
73
  const getConferencesForDate = (date: Date) => {
74
  const formattedDate = format(date, 'yyyy-MM-dd');
75
  return conferencesData.filter((conf: Conference) => {
 
80
  const deadlineDateStr = deadlineDate ? format(deadlineDate, 'yyyy-MM-dd') : null;
81
  const isDeadlineMatch = deadlineDateStr === formattedDate;
82
 
 
83
  let isConferenceDate = false;
84
  if (startDate && endDate) {
85
  isConferenceDate = date >= startDate && date <= endDate;
 
99
  <div className="max-w-7xl mx-auto">
100
  <h1 className="text-3xl font-bold mb-8 text-center">Calendar Overview</h1>
101
 
 
102
  <div className="flex justify-center gap-6 mb-6">
103
  <div className="flex items-center gap-2">
104
  <CircleDot className="h-4 w-4 text-purple-600" />
 
118
  onSelect={setSelectedDate}
119
  className="bg-white rounded-lg p-6 shadow-sm mx-auto w-full"
120
  classNames={{
121
+ months: "flex flex-col sm:flex-row space-y-4 sm:space-x-4 sm:space-y-0",
122
+ month: "space-y-4 w-full",
123
+ caption: "flex justify-center pt-1 relative items-center mb-4",
124
+ caption_label: "text-lg font-semibold",
125
+ table: "w-full border-collapse",
126
  cell: "h-14 w-14 text-center text-sm p-0 relative [&:has([aria-selected])]:bg-accent first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md focus-within:relative focus-within:z-20",
127
  day: "h-14 w-14 p-0 font-normal aria-selected:opacity-100 hover:bg-neutral-100 rounded-lg transition-colors",
128
+ day_today: "bg-neutral-100 text-primary font-semibold",
129
+ nav: "space-x-1 flex items-center",
130
+ nav_button: "h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100",
131
+ nav_button_previous: "absolute left-1",
132
+ nav_button_next: "absolute right-1",
133
  }}
134
  modifiers={{
135
  conference: datesWithEvents.conferences,
 
137
  }}
138
  modifiersStyles={{
139
  conference: {
140
+ backgroundColor: '#DDD6FE',
141
+ color: '#7C3AED',
142
  fontWeight: 'bold'
143
  },
144
  deadline: {
145
+ backgroundColor: '#FEE2E2',
146
+ color: '#EF4444',
147
  fontWeight: 'bold'
148
  }
149
  }}
150
  />
151
  </div>
152
 
 
153
  {selectedDate && (
154
  <div className="mx-auto w-full max-w-3xl space-y-4">
155
  <h2 className="text-xl font-semibold flex items-center gap-2">