nielsr HF staff commited on
Commit
0c2b271
·
1 Parent(s): 6520b36

Improve lines

Browse files
Files changed (1) hide show
  1. src/pages/Calendar.tsx +99 -61
src/pages/Calendar.tsx CHANGED
@@ -170,73 +170,111 @@ const CalendarPage = () => {
170
  );
171
  };
172
 
173
- const renderDayContent = (day: Date) => {
174
- const dayEvents = getDayEvents(day);
175
- const hasDeadlines = dayEvents.deadlines.length > 0;
176
- const hasConferences = dayEvents.conferences.length > 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
177
 
178
- const content = (
179
  <div className="relative w-full h-full flex flex-col items-center">
180
- <span className="mb-1">{format(day, 'd')}</span>
181
- <div className="absolute bottom-0 left-0 right-0 flex flex-col gap-0.5 px-1">
182
- {hasDeadlines && (
 
 
 
 
 
 
183
  <div
184
- className="h-0.5 w-full bg-red-500"
185
- title="Deadline"
186
  />
187
- )}
188
- {dayEvents.conferences.map((conf) => {
189
- const startDate = safeParseISO(conf.start);
190
- const endDate = safeParseISO(conf.end);
191
-
192
- if (!startDate || !endDate) return null;
193
-
194
- const categoryColor = conf.tags?.[0] ? categoryColors[conf.tags[0]] || "bg-purple-600" : "bg-purple-600";
195
-
196
- if (day < startDate || day > endDate) return null;
197
-
198
- const isFirstDayOfMonth = day.getDate() === 1;
199
- const isStartDate = isSameDay(startDate, day);
200
-
201
- const lastDayOfMonth = new Date(day.getFullYear(), day.getMonth() + 1, 0);
202
- const daysUntilMonthEnd = Math.min(
203
- Math.ceil((endDate.getTime() - day.getTime()) / (1000 * 60 * 60 * 24)) + 1,
204
- Math.ceil((lastDayOfMonth.getTime() - day.getTime()) / (1000 * 60 * 60 * 24)) + 1
205
- );
206
-
207
- if (!isStartDate && !isFirstDayOfMonth) return null;
208
-
209
- return (
210
- <div
211
- key={`${conf.id}-${format(day, 'yyyy-MM')}`}
212
- className={`h-0.5 ${categoryColor} absolute`}
213
- style={{ width: `calc(100% * ${daysUntilMonthEnd})` }}
214
- title={conf.title}
215
- />
216
- );
217
- })}
218
  </div>
219
- </div>
220
- );
221
-
222
- if (!hasDeadlines && !hasConferences) return content;
223
 
224
- return (
225
- <TooltipProvider>
226
- <Tooltip>
227
- <TooltipTrigger asChild>
228
- <div
229
- className="w-full h-full cursor-pointer"
230
- onClick={() => setSelectedDayEvents({ date: day, events: dayEvents })}
231
- >
232
- {content}
233
- </div>
234
- </TooltipTrigger>
235
- <TooltipContent>
236
- {renderEventPreview(dayEvents)}
237
- </TooltipContent>
238
- </Tooltip>
239
- </TooltipProvider>
240
  );
241
  };
242
 
 
170
  );
171
  };
172
 
173
+ // Add these helper functions at the top of the file
174
+ const isEndOfWeek = (date: Date) => date.getDay() === 6; // Saturday
175
+ const isStartOfWeek = (date: Date) => date.getDay() === 0; // Sunday
176
+ const isSameWeek = (date1: Date, date2: Date) => {
177
+ const diff = Math.abs(date1.getTime() - date2.getTime());
178
+ const diffDays = Math.floor(diff / (1000 * 60 * 60 * 24));
179
+ return diffDays <= 6 &&
180
+ Math.floor(date1.getTime() / (1000 * 60 * 60 * 24 * 7)) ===
181
+ Math.floor(date2.getTime() / (1000 * 60 * 60 * 24 * 7));
182
+ };
183
+
184
+ // Update the getConferenceLineStyle function
185
+ const getConferenceLineStyle = (date: Date) => {
186
+ const styles = [];
187
+
188
+ for (const conf of conferencesData) {
189
+ const startDate = safeParseISO(conf.start);
190
+ const endDate = safeParseISO(conf.end);
191
+
192
+ if (startDate && endDate && date >= startDate && date <= endDate) {
193
+ const isFirst = isSameDay(date, startDate);
194
+ const isLast = isSameDay(date, endDate);
195
+
196
+ // Check if previous and next days are part of the same conference and week
197
+ const prevDate = new Date(date);
198
+ prevDate.setDate(date.getDate() - 1);
199
+ const nextDate = new Date(date);
200
+ nextDate.setDate(date.getDate() + 1);
201
+
202
+ const hasPrevDay = prevDate >= startDate && isSameWeek(date, prevDate);
203
+ const hasNextDay = nextDate <= endDate && isSameWeek(date, nextDate);
204
+
205
+ let lineStyle = "h-1 absolute bottom-0";
206
+
207
+ if (hasPrevDay && hasNextDay) {
208
+ // Middle of a sequence
209
+ lineStyle += " w-[calc(100%+1rem)] -left-2";
210
+ } else if (hasPrevDay) {
211
+ // End of a sequence
212
+ lineStyle += " w-[calc(100%+0.5rem)] left-0";
213
+ } else if (hasNextDay) {
214
+ // Start of a sequence
215
+ lineStyle += " w-[calc(100%+0.5rem)] right-0";
216
+ } else {
217
+ // Single day
218
+ lineStyle += " w-full";
219
+ }
220
+
221
+ // Get the color based on the first tag or default to purple
222
+ const color = conf.tags?.[0] ? categoryColors[conf.tags[0]] : "bg-purple-500";
223
+
224
+ styles.push({
225
+ style: lineStyle,
226
+ color: color
227
+ });
228
+ }
229
+ }
230
+
231
+ return styles;
232
+ };
233
+
234
+ // Update the renderDayContent function
235
+ const renderDayContent = (date: Date) => {
236
+ const dayEvents = getDayEvents(date);
237
+ const hasEvents = dayEvents.deadlines.length > 0 || dayEvents.conferences.length > 0;
238
+
239
+ // Get conference line styles first
240
+ const conferenceStyles = getConferenceLineStyle(date);
241
+
242
+ // Get deadline style
243
+ const hasDeadline = dayEvents.deadlines.length > 0;
244
+ const deadlineStyle = hasDeadline ? "h-1 w-full bg-red-500" : "";
245
 
246
+ return (
247
  <div className="relative w-full h-full flex flex-col items-center">
248
+ {/* Day number at the top */}
249
+ <div className="flex-grow flex items-center justify-center mb-2">
250
+ <span>{format(date, 'd')}</span>
251
+ </div>
252
+
253
+ {/* Event indicator lines at the bottom */}
254
+ <div className="absolute bottom-0 w-full flex flex-col gap-[2px]">
255
+ {/* Conference lines */}
256
+ {conferenceStyles.map((style, index) => (
257
  <div
258
+ key={`conf-${index}`}
259
+ className={`${style.style} ${style.color}`}
260
  />
261
+ ))}
262
+ {/* Deadline line */}
263
+ {deadlineStyle && <div className={deadlineStyle} />}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
264
  </div>
 
 
 
 
265
 
266
+ {/* Tooltip trigger covering the whole cell */}
267
+ {hasEvents && (
268
+ <TooltipProvider>
269
+ <Tooltip>
270
+ <TooltipTrigger className="absolute inset-0" />
271
+ <TooltipContent>
272
+ {renderEventPreview(dayEvents)}
273
+ </TooltipContent>
274
+ </Tooltip>
275
+ </TooltipProvider>
276
+ )}
277
+ </div>
 
 
 
 
278
  );
279
  };
280