Skip to content

Commit

Permalink
Refactor slot types and weekly availability component
Browse files Browse the repository at this point in the history
  • Loading branch information
teetangh committed Dec 12, 2024
1 parent 02f2398 commit e48fcd1
Show file tree
Hide file tree
Showing 3 changed files with 278 additions and 79 deletions.
146 changes: 126 additions & 20 deletions app/explore/experts/[consultantId]/components/WeeklyAvailability.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,44 @@ function convertUTCToLocal(date: Date): Date {
return new Date(date.getTime() - (offset * 60 * 1000));
}

function getDayBefore(day: DayOfWeek): DayOfWeek {
const days = [
DayOfWeek.SUNDAY,
DayOfWeek.MONDAY,
DayOfWeek.TUESDAY,
DayOfWeek.WEDNESDAY,
DayOfWeek.THURSDAY,
DayOfWeek.FRIDAY,
DayOfWeek.SATURDAY
];
const index = days.indexOf(day);
return days[(index - 1 + 7) % 7];
}

function getDayAfter(day: DayOfWeek): DayOfWeek {
const days = [
DayOfWeek.SUNDAY,
DayOfWeek.MONDAY,
DayOfWeek.TUESDAY,
DayOfWeek.WEDNESDAY,
DayOfWeek.THURSDAY,
DayOfWeek.FRIDAY,
DayOfWeek.SATURDAY
];
const index = days.indexOf(day);
return days[(index + 1) % 7];
}

const formatTime = (isoString: string): string => {
try {
// Convert UTC time to local time
// Create a base date for today
const baseDate = new Date();
// Parse the time from the ISO string
const utcDate = new Date(isoString);
const localDate = convertUTCToLocal(utcDate);
// Set the hours and minutes on the base date
baseDate.setHours(utcDate.getUTCHours(), utcDate.getUTCMinutes(), 0, 0);
// Convert to local time
const localDate = convertUTCToLocal(baseDate);

return localDate.toLocaleTimeString([], {
hour: "2-digit",
Expand All @@ -43,27 +76,100 @@ export const WeeklyAvailability: React.FC<WeeklyAvailabilityProps> = ({
selectedSlotId,
}) => {
const daysOfWeek = [
"MONDAY",
"TUESDAY",
"WEDNESDAY",
"THURSDAY",
"FRIDAY",
"SATURDAY",
"SUNDAY",
DayOfWeek.MONDAY,
DayOfWeek.TUESDAY,
DayOfWeek.WEDNESDAY,
DayOfWeek.THURSDAY,
DayOfWeek.FRIDAY,
DayOfWeek.SATURDAY,
DayOfWeek.SUNDAY,
];
const dayLabels = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];

// Group slots by day and sort by time
const slotsByDay = daysOfWeek.map((day) => ({
day,
slots: slots
.filter((slot) => slot.dayOfWeekforStartTimeInUTC === day)
.sort((a, b) => {
const timeA = new Date(a.slotStartTimeInUTC).getTime();
const timeB = new Date(b.slotStartTimeInUTC).getTime();
return timeA - timeB;
}),
}));
const slotsByDay = daysOfWeek.map((day) => {
// Get slots that:
// 1. Start on this day
// 2. End on this day (started previous day)
// 3. Start on this day and end next day
const daySlots = slots.filter((slot) => {
const previousDay = getDayBefore(day);
const nextDay = getDayAfter(day);

// Include slots that:
// 1. Start on this day
// 2. End on this day (started previous day)
// 3. Start on this day and end next day
// 4. Start on previous day and end on next day (crosses entire day)
return (
slot.dayOfWeekforStartTimeInUTC === day ||
slot.dayOfWeekforEndTimeInUTC === day ||
(slot.dayOfWeekforStartTimeInUTC === previousDay &&
slot.dayOfWeekforEndTimeInUTC === nextDay)
);
});

// For each slot, determine if it needs to be split at midnight
const processedSlots = daySlots.flatMap((slot) => {
// Create a base date for today
const baseDate = new Date();
// Parse the times from the ISO strings
const startTime = new Date(slot.slotStartTimeInUTC);
const endTime = new Date(slot.slotEndTimeInUTC);

// Set the hours and minutes on the base date
const localStartTime = new Date(baseDate);
localStartTime.setHours(startTime.getUTCHours(), startTime.getUTCMinutes(), 0, 0);

const localEndTime = new Date(baseDate);
localEndTime.setHours(endTime.getUTCHours(), endTime.getUTCMinutes(), 0, 0);

// Convert to local time
const convertedStartTime = convertUTCToLocal(localStartTime);
const convertedEndTime = convertUTCToLocal(localEndTime);

// If the slot crosses midnight
if (convertedEndTime < convertedStartTime) {
// Create two slots: one ending at midnight, one starting at midnight
const midnightEnd = new Date(convertedStartTime);
midnightEnd.setHours(23, 59, 59, 999);

const midnightStart = new Date(convertedEndTime);
midnightStart.setHours(0, 0, 0, 0);

return [
{
...slot,
slotStartTimeInUTC: convertedStartTime.toISOString(),
slotEndTimeInUTC: midnightEnd.toISOString(),
},
{
...slot,
slotStartTimeInUTC: midnightStart.toISOString(),
slotEndTimeInUTC: convertedEndTime.toISOString(),
},
];
}

return [{
...slot,
slotStartTimeInUTC: convertedStartTime.toISOString(),
slotEndTimeInUTC: convertedEndTime.toISOString(),
}];
});

// Sort slots by start time
const sortedSlots = processedSlots.sort((a, b) => {
const timeA = new Date(a.slotStartTimeInUTC).getTime();
const timeB = new Date(b.slotStartTimeInUTC).getTime();
return timeA - timeB;
});

return {
day,
slots: sortedSlots,
};
});

return (
<div className="bg-white rounded-lg shadow-lg p-8 border border-gray-200">
Expand All @@ -89,7 +195,7 @@ export const WeeklyAvailability: React.FC<WeeklyAvailabilityProps> = ({

return (
<div
key={slot.id}
key={`${slot.id}-${startTime}-${endTime}`}
className={`bg-blue-50 rounded-md p-2 cursor-pointer ${
selectedSlotId === slot.id
? "bg-blue-200"
Expand Down
Loading

0 comments on commit e48fcd1

Please sign in to comment.