From 8ef8cfc8f08e04772a1f8ec90ac0b3e387ee80e8 Mon Sep 17 00:00:00 2001 From: VividTruthKeeper Date: Mon, 29 Aug 2022 22:08:58 +0500 Subject: [PATCH] calendar back --- src/components/global/Calendar.tsx | 278 ++++++++++++++++++++++++ src/components/main/CalendarSection.tsx | 14 +- src/styles/_main.scss | 29 ++- 3 files changed, 306 insertions(+), 15 deletions(-) create mode 100644 src/components/global/Calendar.tsx diff --git a/src/components/global/Calendar.tsx b/src/components/global/Calendar.tsx new file mode 100644 index 0000000..a17e1aa --- /dev/null +++ b/src/components/global/Calendar.tsx @@ -0,0 +1,278 @@ +// Modules +import { v4 as uuidv4 } from "uuid"; +import React, { SetStateAction, useMemo, useState } from "react"; + +// Import helpers +import { + generateDateMatrix, + matchLocaleLang, + daysLocale, + matchDateToDay, + monthsLocale, + years, +} from "../../helpers/calendar"; + +// Icons +import prev from "../../icons/arrow-prev.svg"; +import next from "../../icons/arrow-next.svg"; +import sharp from "../../icons/sharp.svg"; + +// Types +import { dataItem, dateMatrix } from "../../helpers/calendar"; + +const Calendar = () => { + // Static + const date = new Date(); + const today = date.getDate(); + + // Inner Types + interface dayType { + day: number; + month: number; + } + type monthType = [number, React.Dispatch>]; + type monthSelectType = [boolean, React.Dispatch>]; + type dayStateType = [dayType, React.Dispatch>]; + + // State + const [currentYear, setCurrentYear]: monthType = useState(date.getFullYear()); // Ability to change the year + const [currentMonth, setCurrentMonth]: monthType = useState(date.getMonth()); // Ability to change the month + const [monthSelect, setMonthSelect]: monthSelectType = useState(false); // Month select controller + const [yearSelect, setYearSelect]: monthSelectType = useState(false); // Year select controller + const [selectedDay, setSelectedDay]: dayStateType = useState({ + day: -1, + month: -1, + }); // Ability to select a day + + // Memoized + + const data: dateMatrix = useMemo( + () => generateDateMatrix(currentYear), + [currentYear] + ); // For better performance: generateDateMatrix() is a demanding algorithm + + const dataDays: dataItem[] = useMemo(() => data[0], [data]); // Same + + const sorted: number[][] = useMemo( + () => matchDateToDay(dataDays[currentMonth].data), + [dataDays, currentMonth] + ); // For better performance: matchDateToDay() is a demanding algorithm + + // Chain memo reaction when currentYear changes + + return ( +
+
+
{ + setCurrentMonth((initial) => { + if (initial - 1 < 0) { + return 11; + } else { + return initial - 1; + } + }); + }} + > + +
+ +

+ { + setMonthSelect((initial) => !initial); + setYearSelect(false); + setSelectedDay({ day: -1, month: -1 }); + }} + > + {matchLocaleLang(currentMonth)} + {" "} + { + setYearSelect((initial) => !initial); + setMonthSelect(false); + setSelectedDay({ day: -1, month: -1 }); + }} + > + {data[1] as number} + +

+
{ + setCurrentMonth((initial) => { + if (initial + 1 > 11) { + return 0; + } else { + return initial + 1; + } + }); + }} + > + +
+
+
+
+ {monthsLocale.map((month, i) => { + return ( + { + setMonthSelect(false); + setCurrentMonth(i); + }} + > + {month} + + ); + })} +
+
+ {years.map((year) => { + return ( + { + setYearSelect(false); + setCurrentYear(year); + }} + > + {year} + + ); + })} +
+ + + + + + + + + + + + {sorted + ? sorted.map((arr) => { + if (arr.filter((x) => x === 0).length !== 7) { + return ( + + {arr.map((el) => { + if (el !== 0) { + if ( + today === el && + currentMonth === date.getMonth() && + currentYear === date.getFullYear() + ) { + return ( + + ); + } else { + return ( + + ); + } + } else { + return ; + } + })} + + ); + } else { + return ""; + } + }) + : ""} + +
{daysLocale[0]}{daysLocale[1]}{daysLocale[2]}{daysLocale[3]}{daysLocale[4]}{daysLocale[5]}{daysLocale[6]}
+ ) => { + const target = e.target as HTMLElement; + const span = target.innerText; + setSelectedDay({ + day: parseInt(span), + month: currentMonth, + }); + }} + > + {el} +
+
+ +
+
{`${el} ${matchLocaleLang( + currentMonth + )} ${currentYear}`}
+ Нет событий +
+
+ ) => { + const target = e.target as HTMLElement; + const span = target.innerText; + setSelectedDay({ + day: parseInt(span), + month: currentMonth, + }); + }} + > + {el} +
+
+ +
+
{`${el} ${matchLocaleLang( + currentMonth + )} ${currentYear}`}
+ Нет событий +
+
+ +
+
+ ); +}; + +export default Calendar; diff --git a/src/components/main/CalendarSection.tsx b/src/components/main/CalendarSection.tsx index 8140bc2..7db855a 100644 --- a/src/components/main/CalendarSection.tsx +++ b/src/components/main/CalendarSection.tsx @@ -8,6 +8,7 @@ import { ErrorBoundary } from "react-error-boundary"; // Components import VideoPlayer from "../global/VideoPlayer"; +import Calendar from "../global/Calendar"; import EmptyState from "../global/EmptyState"; // Types @@ -33,10 +34,7 @@ const CalendarSection = () => { }, ]); - const widthBounds: Record = { - 1120: useMediaQuery("(max-width: 1120)"), - 750: useMediaQuery("(max-width: 750px)"), - }; + const widthBounds: boolean = useMediaQuery("(max-width: 750px)"); useEffect(() => { getVideos(setVideoData, setVideo); @@ -63,9 +61,7 @@ const CalendarSection = () => { modules={[]} spaceBetween={24} autoHeight={true} - slidesPerView={ - widthBounds["750"] ? 2 : widthBounds["1120"] ? 4 : 5 - } + slidesPerView={widthBounds ? 2 : 3} loop={false} > {videoData[0].id !== -1 @@ -97,11 +93,11 @@ const CalendarSection = () => { - {/*
+
}> -
*/} +
diff --git a/src/styles/_main.scss b/src/styles/_main.scss index 51c327a..ad8f447 100644 --- a/src/styles/_main.scss +++ b/src/styles/_main.scss @@ -157,11 +157,14 @@ .calendars { padding: 4rem 0 8rem 0; - display: flex; + display: grid; + grid-template-columns: 91.1rem 1fr; + gap: 12rem; } .calendars-left { width: 100%; + max-width: 91.1rem; display: flex; flex-direction: column; gap: 2rem; @@ -184,6 +187,11 @@ } } +.calendars-right { + display: flex; + align-items: center; +} + .swiper-darkener { position: absolute; top: 0; @@ -205,11 +213,20 @@ } @media screen and (max-width: 1500px) { + .calendars-left { + max-width: 80rem; + } .calendars { display: flex; } } +@media screen and (max-width: 1360px) { + .calendars-left { + max-width: 70rem; + } +} + @media screen and (max-width: 1300px) { .slider-prev, .slider-next, @@ -226,11 +243,11 @@ } } -// @media screen and (max-width: 1260px) { -// .calendars-left { -// max-width: 64rem; -// } -// } +@media screen and (max-width: 1260px) { + .calendars-left { + max-width: 64rem; + } +} @media screen and (max-width: 1200px) { .calendars-left {