Skip to content

Commit

Permalink
feat(calendar): add readable week view
Browse files Browse the repository at this point in the history
  • Loading branch information
domhhv committed Jan 2, 2025
1 parent 28629c6 commit e711aee
Show file tree
Hide file tree
Showing 9 changed files with 330 additions and 290 deletions.
1 change: 1 addition & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
min-height: 100vh;
display: flex;
flex-direction: column;
position: relative;
}

#root.initialized {
Expand Down
70 changes: 39 additions & 31 deletions src/components/calendar-month/CalendarCell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ const CalendarCell = ({
const cellDate = new Date(fullYear, monthNumber - 1, dateNumber);
const isTodayCell = isToday(cellDate);
const date = format(cellDate, 'yyyy-MM-dd');
const isDesktop = screenSize >= 1024;

const occurrences = isCalendarDay(date) ? occurrencesByDate[date] || [] : [];
const isMobile = screenSize < 768;
Expand All @@ -80,33 +81,40 @@ const CalendarCell = ({
return onAddNote(dateNumber, monthNumber, fullYear);
}, [fetchingOccurrences, user, dateNumber, monthNumber, fullYear, onAddNote]);

const handleAddOccurrenceClick = React.useCallback(() => {
if (fetchingOccurrences || !user) {
return null;
}

if (!isToday) {
if (rangeStatus === 'below-range') {
return onNavigateBack?.();
const handleAddOccurrenceClick = React.useCallback(
(e?: React.MouseEvent) => {
if (fetchingOccurrences || !user) {
return null;
}

if (rangeStatus === 'above-range') {
return onNavigateForward?.();
if (!isTodayCell) {
if (rangeStatus === 'below-range') {
return onNavigateBack?.();
}

if (rangeStatus === 'above-range') {
return onNavigateForward?.();
}
}
}

return onAddOccurrence(dateNumber, monthNumber, fullYear);
}, [
dateNumber,
fetchingOccurrences,
fullYear,
monthNumber,
onAddOccurrence,
onNavigateBack,
onNavigateForward,
rangeStatus,
user,
]);
if (isMobile || e?.currentTarget instanceof HTMLButtonElement) {
return onAddOccurrence(dateNumber, monthNumber, fullYear);
}
},
[
dateNumber,
fetchingOccurrences,
fullYear,
monthNumber,
onAddOccurrence,
onNavigateBack,
onNavigateForward,
rangeStatus,
user,
isMobile,
isTodayCell,
]
);

React.useEffect(() => {
const cell = cellRef.current;
Expand Down Expand Up @@ -137,11 +145,11 @@ const CalendarCell = ({
};

const renderToday = () => {
if (!isToday) {
if (!isTodayCell) {
return null;
}

return <CalendarBlank size={14} weight="bold" />;
return <CalendarBlank size={20} weight="fill" />;
};

const cellRootClassName = clsx(
Expand All @@ -167,7 +175,7 @@ const CalendarCell = ({
className={cellRootClassName}
ref={cellRef}
tabIndex={0}
onClick={isMobile ? handleAddOccurrenceClick : undefined}
onClick={handleAddOccurrenceClick}
>
<div className={cellHeaderClassName}>
<p className="font-bold">{dateNumber}</p>
Expand All @@ -177,13 +185,13 @@ const CalendarCell = ({
{!isFuture(cellDate) && (
<Tooltip content="Log habit" closeDelay={0}>
<Button
className="h-6 min-w-fit px-4 opacity-100 transition-opacity group-hover/cell:opacity-100 md:opacity-0"
className="h-5 min-w-fit px-2 opacity-100 transition-opacity group-hover/cell:opacity-100 md:opacity-0 lg:h-6 lg:px-4"
radius="sm"
onClick={handleAddOccurrenceClick}
color="primary"
isDisabled={fetchingOccurrences || !user}
>
<CalendarPlus weight="bold" size={18} />
<CalendarPlus weight="bold" size={isDesktop ? 18 : 14} />
</Button>
</Tooltip>
)}
Expand All @@ -193,7 +201,7 @@ const CalendarCell = ({
>
<Button
className={clsx(
'h-6 min-w-fit px-4 opacity-0 transition-opacity group-hover/cell:opacity-100',
'h-5 min-w-fit px-2 opacity-0 transition-opacity group-hover/cell:opacity-100 lg:h-6 lg:px-4',
hasNote && 'opacity-100'
)}
radius="sm"
Expand All @@ -202,9 +210,9 @@ const CalendarCell = ({
isDisabled={fetchingNotes || !user}
>
{hasNote ? (
<NotePencil weight="bold" size={18} />
<NotePencil weight="bold" size={isDesktop ? 18 : 14} />
) : (
<NoteBlank weight="bold" size={14} />
<NoteBlank weight="bold" size={isDesktop ? 18 : 14} />
)}
</Button>
</Tooltip>
Expand Down
11 changes: 6 additions & 5 deletions src/components/calendar-month/CalendarGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +106,14 @@ const CalendarGrid = ({
const dates = state.getDatesInWeek(weekIndex);

return (
<div key={weekIndex} className="group flex items-center gap-2">
<div
key={weekIndex}
className="group relative flex items-end gap-1 md:gap-2"
>
<Button
className={clsx(
'h-[110px] min-w-fit basis-[40px] p-0',
'hidden' // TODO: show the week number button, open weekly view (WIP) on click
'absolute -left-[24px] bottom-0 h-[107px] w-[20px] min-w-fit p-0 md:-left-[48px] md:w-[40px]',
'hhidden' // TODO: show the week number button, open weekly view (WIP) on click
)}
variant="light"
onClick={() => handleWeekClick(dates[0])}
Expand All @@ -133,8 +136,6 @@ const CalendarGrid = ({

const { month, day, year } = calendarDate;

console.log({ month2: month });

const rangeStatus: CellRangeStatus =
(month < activeMonth ||
(month === 12 && activeMonth === 1)) &&
Expand Down
2 changes: 1 addition & 1 deletion src/components/calendar-month/MonthCalendar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ const MonthCalendar = () => {
});

const calendarContainerClassName = clsx(
'flex h-full w-full max-w-full flex-1 flex-col gap-2 p-0 px-2 pb-8 lg:gap-4 lg:px-0 lg:px-16 lg:py-4',
'flex h-full w-full max-w-full flex-1 flex-col gap-2 p-0 px-8 pb-8 lg:gap-4 lg:px-16 lg:py-4',
isOccurrenceDialogOpen && 'pointer-events-none'
);

Expand Down
24 changes: 13 additions & 11 deletions src/components/calendar-month/OccurrenceChip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import React from 'react';

export type OccurrenceChipProps = {
occurrences: Occurrence[];
onDelete: (
onDelete?: (
occurrenceId: number,
clickEvent: React.MouseEvent<HTMLButtonElement>
) => void;
Expand Down Expand Up @@ -61,16 +61,18 @@ const OccurrenceChip = ({
<span className="font-normal">: {note.content}</span>
)}
</div>
<Button
isIconOnly
variant="solid"
color="danger"
onClick={(clickEvent) => onDelete(t.occurrenceId, clickEvent)}
role="habit-chip-delete-button"
className="h-6 w-6 min-w-0 rounded-lg"
>
<Trash size={14} fill="bold" className="fill-white" />
</Button>
{onDelete && (
<Button
isIconOnly
variant="solid"
color="danger"
onClick={(clickEvent) => onDelete(t.occurrenceId, clickEvent)}
role="habit-chip-delete-button"
className="h-6 w-6 min-w-0 rounded-lg"
>
<Trash size={14} fill="bold" className="fill-white" />
</Button>
)}
</li>
);
})}
Expand Down
Loading

0 comments on commit e711aee

Please sign in to comment.