Skip to content

Commit

Permalink
Fix: Refactored event formatting feature (#46)
Browse files Browse the repository at this point in the history
* enhance: Enhanced ui & completed calendar month-mode

* feat: Added moon phase & astro, worked on responsivness for medium screens

* feat: Added moon phase, astro hide/show control feature

* fix: Fixed select dropdown height bug

* chore: Minor UI adustments

* feat: YearMode, WeekMode & Enhance layouts for better mobile screen view

* fix: Fixed type error during build time

* feat: Implemented event calendar

* chore: Updated GUIDE_FOR_ADDING_EVENT_CALENDAR.md

* chore: Synced forked repo

* chore: Added event reader function

* chore: Updated GUIDE_FOR_ADDING_EVENT_CALENDAR.md

* chore: Updated GUIDE_FOR_ADDING_EVENT_CALENDAR.md

* feat: Update DayDialog UI

* fix: check box error

* fix: Refactored event calendar implementation & Added localStorage feature to persist user actions

* chore: Config build output dir

* chore: Config build output dir vercel

* chore: Config turbo.json

* chore: Config turbo.json

* fix: Refactored event formatting feature

* chore: Refactored event formatting feature

* chore: Adjust font sizes and weight for Geist san font

* chore: Adjust font sizes and weight for Geist san

* chore: Removed month name in month cell
  • Loading branch information
YakuBrangJa authored Oct 31, 2023
1 parent ab775f8 commit 1460b64
Show file tree
Hide file tree
Showing 56 changed files with 1,179 additions and 884 deletions.
1 change: 1 addition & 0 deletions apps/myanmar_calendar/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"@radix-ui/react-slot": "^1.0.2",
"@radix-ui/react-switch": "^1.0.3",
"@reduxjs/toolkit": "^1.9.6",
"@tailwindcss/typography": "^0.5.10",
"@vercel/analytics": "^1.0.1",
"@vitejs/plugin-react": "^4.1.0",
"burma-calendar": "workspace:*",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@ const calendar_modes = {
function Calendar() {
const calendarMode = useSelector((state: RootState) => state.calendarState.calendarMode);
// const sidebarOpen = useSelector((state: RootState) => state.systemState.sidebarOpen);
// const sidebarOpen = useSelector((state: RootState) => state.systemState.sidebarOpen);

return (
<section
aria-label="Calendar"
className={cn(
"flex-1 h-[calc(100vh-theme(spacing.nav-h))] supports-[height:100cqh]:h-[calc(100cqh-theme(spacing.nav-h))] supports-[height:100svh]:h-[calc(100svh-theme(spacing.nav-h))] border-l border-gray-300 __scrollbar-md"
)}>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,157 +1,149 @@
import {ScrollArea, ScrollBar, ScrollViewport} from "@/components/ui/areas/ScrollArea";
import event_calendars from "@/event_calendars";
import {cn} from "@/lib/utils";
import {CalendarStateInterface} from "@/store/calendarState";
import {setDayDialongTargetDay} from "@/store/modelControlState";
import {brightenColor} from "@/utils/brightenColor";
import {engToMyanmarNumber} from "@/utils/engToMyanmarNumber";
import {modifyColorOpacity} from "@/utils/modifyColorOpacity";
import {englishToMyanmarDate, i18n} from "burma-calendar";
import {format, isSameMonth, isSameWeek, isToday, lastDayOfMonth} from "date-fns";
import React, {Fragment, useEffect, useRef, useState} from "react";
import {useDispatch} from "react-redux";
import { ScrollArea, ScrollBar, ScrollViewport } from "@/components/ui/areas/ScrollArea";
import { getDayEvents } from "@/event_calendars/formatEvent";
import { cn } from "@/lib/utils";
import { CalendarStateInterface } from "@/store/calendarState";
import { setDayDialongTargetDay } from "@/store/modelControlState";
import { engToMyanmarNumber } from "@/utils/engToMyanmarNumber";
import { modifyColorOpacity } from "@/utils/styleHelpers";
import { englishToMyanmarDate, i18n } from "burma-calendar";
import { format, isSameMonth, isSameWeek, isToday, lastDayOfMonth } from "date-fns";
import React, { Fragment, useEffect, useRef, useState } from "react";
import { useDispatch } from "react-redux";

interface MonthCellT {
day: Date;
calendarState: CalendarStateInterface;
day: Date;
calendarState: CalendarStateInterface;
}

function MonthCell({day, calendarState}: MonthCellT) {
const dispatch = useDispatch();
const {calendarLanguage, activeDate, preferance, eventCalendars} = calendarState;
const [dayIsToday, setDayIsToday] = useState(isToday(day));
function MonthCell({ day, calendarState }: MonthCellT) {
const dispatch = useDispatch();
const { calendarLanguage, activeDate, show, eventCalendars } = calendarState;
const [dayIsToday, setDayIsToday] = useState(isToday(day));

let activeDateObj = new Date(activeDate);

let activeDateObj = new Date(activeDate);
const dayBelongsInActiveMonth = isSameMonth(day, activeDateObj);
const dayIsInEndWeek = isSameWeek(lastDayOfMonth(activeDateObj), day);

const dayBelongsInActiveMonth = isSameMonth(day, activeDateObj);
const dayIsInEndWeek = isSameWeek(lastDayOfMonth(activeDateObj), day);
const mmDate = i18n(engToMyanmarNumber(englishToMyanmarDate(day).date), "myanmar", "myanmar" as any);
const myanmarDate = englishToMyanmarDate(day);
const moonAlign = myanmarDate.moonPhase === "လပြည့်" || myanmarDate.moonPhase === "လကွယ်";

const mmDate = i18n(engToMyanmarNumber(englishToMyanmarDate(day).date), "myanmar", "myanmar" as any);
const myanmarDate = englishToMyanmarDate(day);
const moonAlign = myanmarDate.moonPhase === "လပြည့်" || myanmarDate.moonPhase === "လကွယ်";
const dayUpdateIntervalRef = useRef<any>();
React.useEffect(() => {
dayUpdateIntervalRef.current = setInterval(() => {
setDayIsToday(isToday(day));
}, 1000 * 60 * 60 * 24);

const dayUpdateIntervalRef = useRef<any>();
React.useEffect(() => {
dayUpdateIntervalRef.current = setInterval(() => {
setDayIsToday(isToday(day));
}, 1000 * 60 * 60 * 24);
return () => clearInterval(dayUpdateIntervalRef.current);
}, [day]);

return () => clearInterval(dayUpdateIntervalRef.current);
}, [day]);
const checkedEvents = getDayEvents(
day,
eventCalendars.filter((calendar) => calendar.checked === true)
);

// Eg; event_calendars(day, ["international", "publicHolidays"])
const checkedEvents = event_calendars(
day,
Object.keys(eventCalendars).filter((calendar) => {
if (eventCalendars[calendar].checked === true) return calendar;
})
);

return (
// min-h-[8.5rem]
<div
className={cn(
"border-b border-r flex gap-1 flex-col items-stretch border-gray-300 p-2 py-[0.25rem] pb-[0.3rem] min-h-[8.5rem] hover:bg-gray-50",
dayIsInEndWeek ? "min-h-[8.65rem] pb-[0.45rem]" : ""
)}
onClick={() => {
dispatch(setDayDialongTargetDay(day.toISOString()));
}}>
{/* ------ CELL TOP ------- */}
<div className=" flex justify-between items-start">
<time
dateTime={format(day, "yyyy-MM-dd")}
className={cn("flex justify-start -mt-[0.05rem] text-gray-500 flex-1 text-[0.975rem] leading-5", dayBelongsInActiveMonth ? "text-gray-500" : "text-gray-300")}>
{mmDate}
</time>
<time
className={cn(
"flex justify-center items-center font-semibold text-[1.12rem] h-[1.6rem] leading-7",
dayBelongsInActiveMonth ? "text-gray-600" : "text-gray-300",
dayIsToday && dayBelongsInActiveMonth ? "text-gray-50 bg-red-500 rounded-full w-[1.6rem]" : "",
)}
dateTime={format(day, "yyyy-MM-dd")}>
{format(day, "d")}{" "}

</time>
{/* ASTRO */}
<div
className={cn("flex flex-1 self-stretch min-w-[1.5rem] justify-end items-center gap-1 transition-all", preferance.astroEvent ? "opacity-100" : "opacity-0")}>
{/* long text on large screen */}
<span
className={`hidden md3:inline text-[0.65rem] whitespace-nowrap ${myanmarDate.pyathada ? "text-red-500" : "text-blue-500"}`}>{myanmarDate.pyathada || myanmarDate.yatyaza}</span>
{/* short text on small screen */}
<span
className={`inline md3:hidden text-[0.65rem] ${myanmarDate.pyathada ? "text-red-400" : "text-blue-500"}`}>{myanmarDate.pyathada ? "ပြ" : "ရာ"}</span>
</div>
</div>
return (
// min-h-[8.5rem]
<div
className={cn(
"border-b border-r flex gap-1 flex-col items-stretch border-gray-300 p-2 py-[0.25rem] pb-[0.3rem] min-h-[8.5rem] hover:bg-gray-50",
dayIsInEndWeek ? "min-h-[8.65rem] pb-[0.45rem]" : ""
)}
onClick={() => {
dispatch(setDayDialongTargetDay(day.toISOString()));
}}>
{/* ------ CELL TOP ------- */}
<div className=" flex justify-between items-start">
<time
dateTime={format(day, "yyyy-MM-dd")}
className={cn("flex justify-start -mt-[0.05rem] text-gray-500 flex-1 text-[0.875rem] leading-5", dayBelongsInActiveMonth ? "text-gray-500" : "text-gray-300")}>
{mmDate}
</time>
<time
className={cn(
"flex justify-center font-medium text-[1.025rem] h-[1.6rem] leading-7",
dayBelongsInActiveMonth ? "text-gray-600" : "text-gray-300",
dayIsToday ? "text-gray-50 bg-red-500" : " ",
format(day, "d") == "1" ? "rounded-md px-[0.35rem]" : "rounded-full w-[1.6rem]"
)}
dateTime={format(day, "yyyy-MM-dd")}>
{format(day, "d")}{" "}
{/* {format(day, "d") == "1" && (
<span className={cn("text-[1.025rem] ml-[0.3rem]", dayBelongsInActiveMonth ? "text-gray-600" : "text-gray-300", dayIsToday ? "text-gray-100" : "")}>{format(day, "MMM")}</span>
)} */}
</time>
{/* ASTRO */}
<div className={cn("flex flex-1 self-stretch min-w-[1.5rem] justify-end items-center gap-1 transition-all", show.astroEvent ? "opacity-100" : "opacity-0")}>
{/* long text on large screen */}
<span className={`hidden md3:inline text-[0.65rem] whitespace-nowrap ${myanmarDate.pyathada ? "text-red-500" : "text-blue-500"}`}>{myanmarDate.pyathada || myanmarDate.yatyaza}</span>
{/* short text on small screen */}
<span className={`inline md3:hidden text-[0.65rem] ${myanmarDate.pyathada ? "text-red-400" : "text-blue-500"}`}>{myanmarDate.pyathada ? "ပြ" : "ရာ"}</span>
</div>
</div>

{/* ------ CELL MIDDLE ------- */}
{/* <ScrollArea
{/* ------ CELL MIDDLE ------- */}
{/* <ScrollArea
className="flex-1 h-fit w-full overflow-hidden"
type="hover"
scrollHideDelay={100}>
<ScrollViewport className="max-h-full w-full"> */}
<div className="flex-1 __scrollbar-xs">
<ul className=" space-y-[0.15rem] ">
{checkedEvents.map((eventCalendar) => (
<Fragment key={eventCalendar.eventType}>
{eventCalendar.events.map((event) => (
// h-[1.25rem]
<li
key={event}
className="rounded-sm flex items-start py-[0.335rem] px-1 gap-1 bg-gray-100"
style={{
backgroundColor: modifyColorOpacity(eventCalendars[eventCalendar.eventType].tagColor, 0.15),
// backgroundColor: brightenColor(eventCalendars[eventCalendar.eventType].tagColor, 85),
}}>
<div className="flex-1 __scrollbar-xxs">
<ul className=" space-y-[0.15rem] ">
{checkedEvents.map((eventCalendar) => (
<Fragment key={eventCalendar.id}>
{eventCalendar.events.map((event) => (
// h-[1.25rem]
<li
key={event}
className="rounded-sm flex items-start py-[0.335rem] px-1 gap-1 bg-gray-100"
style={{
backgroundColor: modifyColorOpacity(eventCalendar.tagColor, 0.15),
// backgroundColor: brightenColor(eventCalendars[eventCalendar.eventType].tagColor, 85),
}}>
<span
className="inline-block w-[0.35rem] h-[0.35rem] rounded-full bg-gray-500 mt-[0.15rem] flex-shrink-0"
style={{
backgroundColor: eventCalendar.tagColor,
}}></span>
<span
className="inline-block w-[0.35rem] h-[0.35rem] rounded-full bg-gray-500 mt-[0.15rem] flex-shrink-0"
style={{
backgroundColor: eventCalendars[eventCalendar.eventType].tagColor,
}}></span>
<span
className="text-[0.7rem] text-gray-600 -mt-[0.1rem] font-semibold leading-[0.7rem]"
style={{
color: eventCalendars[eventCalendar.eventType].tagColor,
}}>
className="text-[0.7rem] text-gray-600 -mt-[0.025rem] font-semibold leading-[0.7rem]"
style={{
color: eventCalendar.tagColor,
}}>
{event}
</span>
</li>
))}
</Fragment>
))}
</ul>
</div>
{/* <ScrollBar
</li>
))}
</Fragment>
))}
</ul>
</div>
{/* <ScrollBar
className=""
thumbClassName="bg-gray-300"
/>
</ScrollViewport>
</ScrollArea> */}

{/* ------ CELL BOTTOM ------- */}
{(mmDate == "၁" || moonAlign) && preferance.moonPhase && (
<div className="flex justify-between items-center h-[1.1rem] flex-shrink-0">
<div></div>
{/* MOON PHASE */}
<div
className={cn("flex gap-1 items-center transition-all", preferance.moonPhase ? "opacity-100" : "opacity-0")}>
{(mmDate == "၁" || moonAlign) && (
<span
className="hidden md2:inline text-[0.68rem] leading-[1.3rem] text-gray-600 whitespace-nowrap overflow-x-hidden">
{/* ------ CELL BOTTOM ------- */}
{(mmDate == "၁" || moonAlign) && show.moonPhase && (
<div className="flex justify-between items-center h-[1.1rem] flex-shrink-0">
<div aria-hidden="true"></div>
{/* MOON PHASE */}
<div className={cn("flex gap-1 items-center transition-all", show.moonPhase ? "opacity-100" : "opacity-0")}>
{(mmDate == "၁" || moonAlign) && (
<span className="hidden md2:inline text-[0.68rem] leading-[1.3rem] text-gray-600 whitespace-nowrap overflow-x-hidden">
{myanmarDate.month}
{myanmarDate.moonPhase}
{myanmarDate.moonPhase}
</span>
)}
{moonAlign && <span
className={`w-[0.91rem] h-[0.91rem] flex-shrink-0 rounded-full ${myanmarDate.moonPhase === "လပြည့်" ? "bg-red-500" : "bg-gray-600"}`}></span>}
</div>
</div>
)}
{moonAlign && <span className={`w-[0.91rem] h-[0.91rem] flex-shrink-0 rounded-full ${myanmarDate.moonPhase === "လပြည့်" ? "bg-red-500" : "bg-gray-600"}`}></span>}
</div>
</div>
);
)}
</div>
);
}

export default MonthCell;
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,19 @@ function MonthMode() {
});

return (
<>
<div
aria-label="Calendar month view"
className="h-full">
<div className="grid grid-cols-7 sticky top-0 h-[2.25rem] border-gray-300 bg-white">
{Object.values(WEEK_DAYS).map((weekday) => (
<span
<div
key={weekday.short}
className={cn(
"flex justify-center items-stretch border-r border-gray-300 h-full capitalize font-semibold text-[0.9rem] px-2 py-[0.35rem] pb-[0.25rem]",
"flex justify-center items-stretch border-r border-gray-300 h-full capitalize font-medium text-[0.85rem] px-2 py-[0.35rem] pb-[0.25rem]",
weekday.short === "sun" || weekday.short === "sat" ? "text-red-500" : "text-gray-500"
)}>
<span className=" flex justify-center items-center rounded-md bg-gray-100 w-full h-full">{weekday.short}</span>
</span>
<span className=" flex justify-center items-center rounded-md bg-gray-100 w-full h-full">{weekday.short}</span>
</div>
))}
</div>
{/* min-h-[41rem] */}
Expand All @@ -42,7 +44,7 @@ function MonthMode() {
/>
))}
</div>
</>
</div>
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ interface WeekColumnPropsI {
}

function WeekColumn({ day, calendarState }: WeekColumnPropsI) {
const { preferance } = calendarState;
const { show } = calendarState;
const myanmar_calendar = englishToMyanmarDate(day);
const mmDate = i18n(engToMyanmarNumber(myanmar_calendar.date), "myanmar", "myanmar" as any);

Expand All @@ -23,7 +23,7 @@ function WeekColumn({ day, calendarState }: WeekColumnPropsI) {
</span>
</div> */}
<div className="p-2">
{preferance.astroEvent && (myanmar_calendar.pyathada || myanmar_calendar.yatyaza) && (
{show.astroEvent && (myanmar_calendar.pyathada || myanmar_calendar.yatyaza) && (
<span
className={cn(
"h-[2.3rem] bg-gray-100 w-full px-2 flex items-center justify-center text-[0.825rem] font-semibold rounded-md",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ function WeekColumnHead({ day, scrollReachedTop }: { day: Date; scrollReachedTop
key={day.toString()}
className={cn("group/weekHeader flex flex-col items-center justify-between border-b border-gray-300 last:mr-1", !scrollReachedTop && " border-b-gray-100")}>
<div className="flex flex-col items-center pt-2 gap-[0.1rem]">
<div className={cn("font-semibold text-gray-500 text-sm", isWeekend(day) && "text-red-500")}>{format(day, "iii")}</div>
<div className={cn("font-medium text-gray-500 text-sm", isWeekend(day) && "text-red-500")}>{format(day, "iii")}</div>
<time
onClick={() => {
dispatch(setDayDialongTargetDay(day.toISOString()));
}}
dateTime={format(day, "yyyy-MM-dd")}
className={cn(
" text-[1.3rem] font-semibold text-gray-500 flex items-center justify-center rounded-full w-[1.9rem] h-[1.9rem] cursor-pointer",
" text-[1.15rem] font-semibold text-gray-500 flex items-center justify-center rounded-full w-[1.9rem] h-[1.9rem] cursor-pointer",
dayIsToday ? "bg-red-500 hover:bg-red-600 active:bg-red-700 text-white" : " hover:bg-gray-200 active:bg-gray-300 hover:text-gray-600 "
)}>
{format(day, "d")}
Expand Down
Loading

0 comments on commit 1460b64

Please sign in to comment.