glide-design-system
Version:
Glide design system is an open-source React component library. It offers numerous benefits that make them essential tools for design and development teams.
215 lines (195 loc) • 6.07 kB
JavaScript
import React, { useState, useEffect, useRef } from "react";
import classes from "./WeekCalender.module.css";
const WeekCalender = ({
setWeekDays,
setDate,
onWeekNumberChange,
onSetYearChange,
selectedYear,
containerClassName,
buttonClassName,
}) => {
const weekNumberRef = useRef();
const [weekNumber, setWeekNumber] = useState();
const [year, setYear] = useState(new Date().getFullYear());
const [currentWeekNumber, setCurrentWeekNumber] = useState();
/**
* Handles the action to move to the previous week, if available.
*/
const previousDateHanlder = () => {
if (weekNumber !== 1) {
onWeekNumberChange && onWeekNumberChange(weekNumber - 1);
setWeekNumber(weekNumber - 1);
}
};
/**
* Updates the year based on the value from the event target.
*
* @param {Event} e - The event object containing the new year value.
* @returns {void}
*/
const getYear = (e) => {
setYear(e?.target?.value * 1);
onSetYearChange && onSetYearChange(e?.target?.value * 1);
};
/**
* Handles the action to move to the next week, if available.
*/
const nextDateHandler = () => {
if (weekNumber !== 52) {
onWeekNumberChange && onWeekNumberChange(weekNumber + 1);
setWeekNumber(weekNumber + 1);
}
};
/**
* Calculates and returns the current week number.
*
* @returns {number} The current week number.
*/
const currentWeekNumberHandler = () => {
let d = new Date();
d.setHours(0, 0, 0, 0);
d.setDate(d.getDate() + 4 - (d.getDay() || 7));
let yearStart = new Date(d.getFullYear(), 0, 1);
let weekNo = Math.ceil(((d - yearStart) / 86400000 + 1) / 7);
onWeekNumberChange && onWeekNumberChange(weekNo);
setWeekNumber(weekNo);
return weekNo;
};
/**
* Updates the week number based on the value from the event target.
*
* @param {Event} e - The event object containing the new week number value.
* @returns {void}
*/
const getWeekNumbers = (e) => {
onWeekNumberChange && onWeekNumberChange(e.target.value * 1);
setWeekNumber(e.target.value * 1);
};
function getWeekDates(year, week) {
if (week && year) {
// Get the first day of the year
let firstDayOfYear = new Date(year, 0, 1);
// Get the day of the week for the first day of the year
let dayOfWeek = firstDayOfYear.getDay();
// Find the first Thursday of the year
let firstThursday = new Date(firstDayOfYear);
firstThursday.setDate(firstDayOfYear.getDate() + (4 - (dayOfWeek || 7)));
// Calculate the start date of the requested week
let weekStartDate = new Date(firstThursday);
weekStartDate.setDate(
firstThursday.getDate() - firstThursday.getDay() + 1 + (week - 1) * 7
);
weekStartDate.setDate(weekStartDate.getDate() - 1);
let weekDates = [];
let weekDays = [];
for (let i = 0; i < 7; i++) {
let date = new Date(weekStartDate);
date.setDate(weekStartDate.getDate() + i);
weekDays.push(date);
setDate(weekDays);
weekDates.push(formatDate(date));
}
setWeekDays(weekDates);
return weekDates;
}
}
function formatDate(date) {
const days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
const months = [
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec",
];
let day = days[date.getDay()];
let month = months[date.getMonth()];
let dayOfMonth = date.getDate();
let year = date.getFullYear();
return `${day} ${month} ${dayOfMonth} ${year}`;
}
useEffect(() => {
currentWeekNumberHandler();
const handleClickOutside = (event) => {
if (
weekNumberRef.current &&
!weekNumberRef.current.contains(event.target)
) {
document.getElementById("week-number").style.display = "none";
}
};
document.addEventListener("mousedown", handleClickOutside);
return () => {
document.removeEventListener("mousedown", handleClickOutside);
};
}, []);
useEffect(() => {
getWeekDates(year, weekNumber);
}, [weekNumber, year]);
return (
<div
className={`${classes.paginationContainer} ${
containerClassName && containerClassName
}`}
>
<button
disabled={weekNumber === 1}
onClick={previousDateHanlder}
className={`${classes.paginatonBtn} ${
buttonClassName && buttonClassName
}`}
>
<span
style={{ fontSize: "30px", color: "#0a5b99" }}
className="material-symbols-outlined"
>
navigate_before
</span>
</button>
<div className={classes.weekNumberContainer} id="week-number">
<select
value={weekNumber}
className={classes.selectItem}
onChange={getWeekNumbers}
>
{Array.from(
{ length: selectedYear === year ? currentWeekNumber : 52 },
(_, index) => {
return <option value={index + 1}>Week-{index + 1}</option>; // In this example, we're returning the index itself
}
)}
</select>
<select value={year} onChange={getYear} className={classes.selectItem}>
<option value={year}>{year}</option>
<option value={year - 1}>{year - 1}</option>
<option value={year - 2}>{year - 2}</option>
<option value={year - 3}>{year - 3}</option>
<option value={year - 4}>{year - 4}</option>
<option value={year - 5}>{year - 5}</option>
</select>
</div>
<button
onClick={nextDateHandler}
className={`${classes.paginatonBtn} ${
buttonClassName && buttonClassName
}`}
>
<span
style={{ fontSize: "30px", color: "#0a5b99" }}
className="material-symbols-outlined"
>
navigate_next
</span>
</button>
</div>
);
};
export default WeekCalender;