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

Display conference dates/deadlines

Browse files

The calendar now displays conference dates and submission deadlines from the data in `src/data/conferences.yml`.

Files changed (1) hide show
  1. src/pages/Calendar.tsx +47 -34
src/pages/Calendar.tsx CHANGED
@@ -1,3 +1,4 @@
 
1
  import { useState } from "react";
2
  import conferencesData from "@/data/conferences.yml";
3
  import { Conference } from "@/types/conference";
@@ -12,6 +13,7 @@ const CalendarPage = () => {
12
  const [isYearView, setIsYearView] = useState(false);
13
  const [searchQuery, setSearchQuery] = useState("");
14
 
 
15
  const safeParseISO = (dateString: string | undefined | number): Date | null => {
16
  if (!dateString) return null;
17
  if (dateString === 'TBD') return null;
@@ -23,9 +25,12 @@ const CalendarPage = () => {
23
 
24
  const dateStr = typeof dateString === 'number' ? dateString.toString() : dateString;
25
 
26
- const normalizedDate = dateStr
27
- .replace(/(\d{4})-(\d{1})-(\d{1,2})/, '$1-0$2-0$3')
28
- .replace(/(\d{4})-(\d{2})-(\d{1})/, '$1-$2-0$1');
 
 
 
29
 
30
  const parsedDate = parseISO(normalizedDate);
31
  return isValid(parsedDate) ? parsedDate : null;
@@ -36,42 +41,50 @@ const CalendarPage = () => {
36
  };
37
 
38
  const getEvents = (date: Date) => {
39
- return conferencesData
40
- .filter((conf: Conference) => {
41
- const matchesSearch = searchQuery === "" ||
42
- conf.title.toLowerCase().includes(searchQuery.toLowerCase()) ||
43
- (conf.full_name && conf.full_name.toLowerCase().includes(searchQuery.toLowerCase()));
44
-
45
- if (!matchesSearch) return false;
46
-
47
- const deadlineDate = safeParseISO(conf.deadline);
48
- const startDate = safeParseISO(conf.start);
49
- const endDate = safeParseISO(conf.end);
50
-
51
- const dateMatches = isYearView ? isSameYear : isSameMonth;
52
-
53
- const deadlineInPeriod = deadlineDate && dateMatches(deadlineDate, date);
54
-
55
- let conferenceInPeriod = false;
56
- if (startDate && endDate) {
57
- let currentDate = new Date(startDate);
58
- while (currentDate <= endDate) {
59
- if (dateMatches(currentDate, date)) {
60
- conferenceInPeriod = true;
61
- break;
62
- }
63
- currentDate.setDate(currentDate.getDate() + 1);
64
  }
65
- } else if (startDate) {
66
- conferenceInPeriod = dateMatches(startDate, date);
67
  }
 
 
 
68
 
69
- return deadlineInPeriod || conferenceInPeriod;
70
- });
71
  };
72
 
73
  const getDayEvents = (date: Date) => {
74
  return conferencesData.reduce((acc, conf) => {
 
 
 
 
 
 
 
 
 
75
  const deadlineDate = safeParseISO(conf.deadline);
76
  const startDate = safeParseISO(conf.start);
77
  const endDate = safeParseISO(conf.end);
@@ -175,8 +188,8 @@ const CalendarPage = () => {
175
  head_cell: "text-muted-foreground rounded-md w-10 font-normal text-[0.8rem]",
176
  row: "flex w-full mt-2",
177
  cell: `h-10 w-10 text-center text-sm p-0 relative focus-within:relative focus-within:z-20
178
- [&:has([aria-selected])]:bg-accent first:[&:has([aria-selected])]:rounded-l-md
179
- last:[&:has([aria-selected])]:rounded-r-md hover:bg-neutral-50`,
180
  day: "h-10 w-10 p-0 font-normal hover:bg-neutral-100 rounded-lg transition-colors",
181
  day_today: "bg-neutral-100 text-primary font-semibold",
182
  nav: "space-x-1 flex items-center",
 
1
+
2
  import { useState } from "react";
3
  import conferencesData from "@/data/conferences.yml";
4
  import { Conference } from "@/types/conference";
 
13
  const [isYearView, setIsYearView] = useState(false);
14
  const [searchQuery, setSearchQuery] = useState("");
15
 
16
+ // Helper function to safely parse dates
17
  const safeParseISO = (dateString: string | undefined | number): Date | null => {
18
  if (!dateString) return null;
19
  if (dateString === 'TBD') return null;
 
25
 
26
  const dateStr = typeof dateString === 'number' ? dateString.toString() : dateString;
27
 
28
+ // Handle both "YYYY-MM-DD" and "YYYY-M-D" formats
29
+ let normalizedDate = dateStr;
30
+ const parts = dateStr.split('-');
31
+ if (parts.length === 3) {
32
+ normalizedDate = `${parts[0]}-${parts[1].padStart(2, '0')}-${parts[2].padStart(2, '0')}`;
33
+ }
34
 
35
  const parsedDate = parseISO(normalizedDate);
36
  return isValid(parsedDate) ? parsedDate : null;
 
41
  };
42
 
43
  const getEvents = (date: Date) => {
44
+ return conferencesData.filter((conf: Conference) => {
45
+ const matchesSearch = searchQuery === "" ||
46
+ conf.title.toLowerCase().includes(searchQuery.toLowerCase()) ||
47
+ (conf.full_name && conf.full_name.toLowerCase().includes(searchQuery.toLowerCase()));
48
+
49
+ if (!matchesSearch) return false;
50
+
51
+ const deadlineDate = safeParseISO(conf.deadline);
52
+ const startDate = safeParseISO(conf.start);
53
+ const endDate = safeParseISO(conf.end);
54
+
55
+ const dateMatches = isYearView ? isSameYear : isSameMonth;
56
+
57
+ const deadlineInPeriod = deadlineDate && dateMatches(deadlineDate, date);
58
+
59
+ let conferenceInPeriod = false;
60
+ if (startDate && endDate) {
61
+ let currentDate = new Date(startDate);
62
+ while (currentDate <= endDate) {
63
+ if (dateMatches(currentDate, date)) {
64
+ conferenceInPeriod = true;
65
+ break;
 
 
 
66
  }
67
+ currentDate.setDate(currentDate.getDate() + 1);
 
68
  }
69
+ } else if (startDate) {
70
+ conferenceInPeriod = dateMatches(startDate, date);
71
+ }
72
 
73
+ return deadlineInPeriod || conferenceInPeriod;
74
+ });
75
  };
76
 
77
  const getDayEvents = (date: Date) => {
78
  return conferencesData.reduce((acc, conf) => {
79
+ // Check if the conference matches the search query
80
+ const matchesSearch = searchQuery === "" ||
81
+ conf.title.toLowerCase().includes(searchQuery.toLowerCase()) ||
82
+ (conf.full_name && conf.full_name.toLowerCase().includes(searchQuery.toLowerCase()));
83
+
84
+ if (!matchesSearch) {
85
+ return acc;
86
+ }
87
+
88
  const deadlineDate = safeParseISO(conf.deadline);
89
  const startDate = safeParseISO(conf.start);
90
  const endDate = safeParseISO(conf.end);
 
188
  head_cell: "text-muted-foreground rounded-md w-10 font-normal text-[0.8rem]",
189
  row: "flex w-full mt-2",
190
  cell: `h-10 w-10 text-center text-sm p-0 relative focus-within:relative focus-within:z-20
191
+ [&:has([aria-selected])]:bg-accent first:[&:has([aria-selected])]:rounded-l-md
192
+ last:[&:has([aria-selected])]:rounded-r-md hover:bg-neutral-50`,
193
  day: "h-10 w-10 p-0 font-normal hover:bg-neutral-100 rounded-lg transition-colors",
194
  day_today: "bg-neutral-100 text-primary font-semibold",
195
  nav: "space-x-1 flex items-center",