Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions apps/web/src/components/schedule/ScheduleTimelineBare.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { type EventType as Event } from "@/lib/types/events";
import { getClientTimeZone } from "@/lib/utils/client/shared";
import c from "config";
import { ReactNode } from "react";

const daysOfWeek = [
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
];

function splitByDay(schedule: Event[]) {
const days: Map<string, Event[]> = new Map();
schedule.forEach((event) => {
const day = daysOfWeek[event.startTime.getDay()];
const existing = days.get(day);
if (existing) existing.push(event);
else days.set(day, [event]);
});
return days;
}
Comment on lines +16 to +25
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check the database schema definition for the startTime field type
ast-grep --pattern 'startTime: $_'

# Also check how events are typically fetched to see if dates are already parsed
rg -n "startTime" --type ts -C 3 -g '!node_modules'

Repository: acmutsa/HackKit

Length of output: 13607


🏁 Script executed:

#!/bin/bash
# Find the Event type definition used in ScheduleTimelineBare.tsx
echo "=== Checking ScheduleTimelineBare.tsx imports and type definitions ==="
head -30 apps/web/src/components/schedule/ScheduleTimelineBare.tsx

echo -e "\n=== Searching for Event type definition ==="
rg "type Event\b|interface Event\b" --type ts

echo -e "\n=== Finding where splitByDay is called from ==="
rg "splitByDay" --type ts -B 3 -A 3

Repository: acmutsa/HackKit

Length of output: 3507


🏁 Script executed:

#!/bin/bash
# Find the EventType definition in lib/types/events.ts
echo "=== Full EventType definition ==="
cat apps/web/src/lib/types/events.ts

echo -e "\n=== Checking if Event is re-exported elsewhere ==="
rg "export.*Event" apps/web/src/lib/types/events.ts

Repository: acmutsa/HackKit

Length of output: 1288


🏁 Script executed:

#!/bin/bash
# Verify Drizzle ORM type inference for timestamp_ms mode
echo "=== Checking Drizzle documentation or code for timestamp_ms behavior ==="
rg "timestamp_ms|mode.*timestamp" --type ts -C 2

# Also check if there's any conversion happening in data fetching
echo -e "\n=== Checking getAllEvents function (main data fetcher) ==="
sed -n '20,35p' packages/db/functions/events.ts

Repository: acmutsa/HackKit

Length of output: 2988


Convert event.startTime to a Date before calling .getDay().

The startTime field is stored as an integer (milliseconds) in the database and typed as number by Drizzle ORM's timestamp_ms mode. Calling .getDay() directly will throw a runtime error. Convert it to a Date object first, as done elsewhere in the codebase (e.g., EventColumns.tsx):

Suggested fix:
 schedule.forEach((event) => {
-	const day = daysOfWeek[event.startTime.getDay()];
+	const day = daysOfWeek[new Date(event.startTime).getDay()];
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
function splitByDay(schedule: Event[]) {
const days: Map<string, Event[]> = new Map();
schedule.forEach((event) => {
const day = daysOfWeek[event.startTime.getDay()];
const existing = days.get(day);
if (existing) existing.push(event);
else days.set(day, [event]);
});
return days;
}
function splitByDay(schedule: Event[]) {
const days: Map<string, Event[]> = new Map();
schedule.forEach((event) => {
const day = daysOfWeek[new Date(event.startTime).getDay()];
const existing = days.get(day);
if (existing) existing.push(event);
else days.set(day, [event]);
});
return days;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/src/components/schedule/ScheduleTimelineBare.tsx` around lines 16 -
25, In splitByDay, event.startTime is a numeric timestamp so calling .getDay()
will fail; convert it to a Date first (e.g., const dayIndex = new
Date(event.startTime).getDay()) and use daysOfWeek[dayIndex] when computing day;
update the reference inside splitByDay (and any related uses of event.startTime
in that function) to use the Date-converted value so grouping works correctly.


type DayHeaderProps = { dayName: string };
const DefaultDayHeader = ({ dayName }: DayHeaderProps) => (
<tr key={dayName + " title"} className="border-b py-8">
<td>
<h2 className="w-full px-4 py-4 text-5xl font-black">{dayName}</h2>
</td>
</tr>
);

type RowProps = { event: Event; userTimeZone: string };

export default function ScheduleTimelineBare({
schedule,
timezone,
DayHeader = DefaultDayHeader,
RenderEventRow,
}: {
schedule: Event[];
timezone?: string;
DayHeader?: React.ComponentType<DayHeaderProps>;
RenderEventRow: React.ComponentType<RowProps>;
}) {
const userTimeZone = timezone ?? getClientTimeZone(c.hackathonTimezone);
const days = Array.from(splitByDay(schedule).entries());

return (
<div className="mx-auto mt-5 w-[99vw] lg:w-3/4">
<table className="w-full">
<tbody>
{days.map(
([dayName, arr]): ReactNode => (
<>
<DayHeader dayName={dayName} />
{arr.map((event) => (
<RenderEventRow
key={event.id}
event={event}
userTimeZone={userTimeZone}
/>
))}
</>
),
)}
Comment on lines +56 to +69
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Missing key on React Fragment in .map() will cause warnings and reconciliation issues.

The shorthand fragment syntax <>...</> cannot accept a key prop. When rendering fragments inside .map(), you must use the explicit <React.Fragment key={...}> syntax.

🐛 Proposed fix
+import React from "react";

Then update the render:

 {days.map(
-  ([dayName, arr]): ReactNode => (
-    <>
+  ([dayName, arr]) => (
+    <React.Fragment key={dayName}>
       <DayHeader dayName={dayName} />
       {arr.map((event) => (
         <RenderEventRow
           key={event.id}
           event={event}
           userTimeZone={userTimeZone}
         />
       ))}
-    </>
+    </React.Fragment>
   ),
 )}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{days.map(
([dayName, arr]): ReactNode => (
<>
<DayHeader dayName={dayName} />
{arr.map((event) => (
<RenderEventRow
key={event.id}
event={event}
userTimeZone={userTimeZone}
/>
))}
</>
),
)}
{days.map(
([dayName, arr]) => (
<React.Fragment key={dayName}>
<DayHeader dayName={dayName} />
{arr.map((event) => (
<RenderEventRow
key={event.id}
event={event}
userTimeZone={userTimeZone}
/>
))}
</React.Fragment>
),
)}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/web/src/components/schedule/ScheduleTimelineBare.tsx` around lines 56 -
69, The fragment returned inside days.map currently uses the shorthand <>...</>
which cannot accept a key; replace it with an explicit React.Fragment and add a
stable key (for example using dayName or a composite like `${dayName}-${index}`)
so React can reconcile correctly—update the fragment wrapping DayHeader and the
arr.map of RenderEventRow in the days.map callback to use React.Fragment with
that key while keeping DayHeader and RenderEventRow unchanged (they still use
event.id and userTimeZone).

</tbody>
</table>
</div>
);
}
Loading