Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Analytics: code clean up and optimization #2208

Merged
merged 17 commits into from
Nov 6, 2024
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion platform/src/common/components/AQNumberCard/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ const AQNumberCard = () => {
};

const SkeletonCard = () => (
<div className="w-full border border-gray-200 rounded-xl px-4 py-6">
<div className="w-full border border-gray-200 bg-white rounded-xl px-4 py-6">
<div className="w-full bg-gray-200 animate-pulse rounded-xl px-4 py-10">
<div className="h-6 w-3/4 bg-gray-300 rounded"></div>
<div className="mt-2 h-4 w-1/2 bg-gray-300 rounded"></div>
Expand Down
151 changes: 82 additions & 69 deletions platform/src/common/components/Calendar/Calendar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import {
isSameMonth,
startOfWeek,
endOfWeek,
startOfDay,
} from 'date-fns';
import PropTypes from 'prop-types';
import Footer from './components/Footer';
import ShortCuts from './components/ShortCuts';
import CalendarHeader from './components/CalendarHeader';
Expand All @@ -31,8 +31,8 @@ const getDayClassNames = (day, month, selectedRange) => {
selectedRange.end &&
isWithinInterval(day, selectedRange) &&
!isStartOrEndDay;
const isStartOfWeek = day.getDay() === 0;
const isEndOfWeek = day.getDay() === 6;
const isStartOfWeek = day.getDay() === 1; // Monday
const isEndOfWeek = day.getDay() === 0; // Sunday

let classNames = 'flex justify-center items-center ';

Expand All @@ -54,40 +54,63 @@ const getDayClassNames = (day, month, selectedRange) => {
return classNames;
};

/**
* Calendar Component
* @param {Object} props - Component props.
* @returns {JSX.Element} - Rendered component.
*/
const Calendar = ({
initialMonth1,
initialMonth2,
handleValueChange,
closeDatePicker,
showTwoCalendars = true,
}) => {
// Days of the week, starting with Monday
const daysOfWeek = useMemo(
() => ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
() => ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
[],
);
const [month1, setMonth1] = useState(initialMonth1);
const [month2, setMonth2] = useState(initialMonth2);

// Initialize current date at the start of the day to avoid timezone issues
const today = startOfDay(new Date());

// State hooks for months and selected date range
const [month1, setMonth1] = useState(
showTwoCalendars
? initialMonth1 || startOfMonth(today)
: startOfMonth(today),
);
const [month2, setMonth2] = useState(
showTwoCalendars
? initialMonth2 || addMonths(startOfMonth(today), 1)
: null,
);
const [selectedRange, setSelectedRange] = useState({
start: null,
end: null,
start: showTwoCalendars ? null : today,
end: showTwoCalendars ? null : today,
});

/**
* Handles the selection of a day.
* @param {Date} day - The day that was clicked.
*/
const handleDayClick = useCallback(
(day) => {
const normalizedDay = startOfDay(day);
let newSelectedRange = { ...selectedRange };

if (
!newSelectedRange.start ||
(newSelectedRange.start && newSelectedRange.end)
) {
newSelectedRange = { start: day, end: null };
newSelectedRange = { start: normalizedDay, end: null };
} else if (!newSelectedRange.end) {
newSelectedRange.end = isBefore(day, newSelectedRange.start)
? newSelectedRange.start
: day;
newSelectedRange.start = isBefore(day, newSelectedRange.start)
? day
: newSelectedRange.start;
const isBeforeStart = isBefore(normalizedDay, newSelectedRange.start);
newSelectedRange = {
start: isBeforeStart ? normalizedDay : newSelectedRange.start,
end: isBeforeStart ? newSelectedRange.start : normalizedDay,
};
}

setSelectedRange(newSelectedRange);
Expand All @@ -100,40 +123,41 @@ const Calendar = ({
[selectedRange, showTwoCalendars, handleValueChange, closeDatePicker],
);

/**
* Renders the days of the month.
* @param {Date} month - The month for which to render days.
* @returns {JSX.Element[]} - Array of day elements.
*/
const renderDays = useCallback(
(month) => {
const startDay = showTwoCalendars
? startOfWeek(startOfMonth(month))
: startOfMonth(month);
const endDay = showTwoCalendars
? endOfWeek(endOfMonth(month))
: endOfMonth(month);
const startDay = startOfWeek(startOfMonth(month), { weekStartsOn: 1 }); // Monday
const endDay = endOfWeek(endOfMonth(month), { weekStartsOn: 1 }); // Sunday
const daysOfMonth = eachDayOfInterval({
start: startDay,
end: endDay,
});

return daysOfMonth.map((day) => {
const isToday = isSameDay(day, new Date());
const isCurrentMonth = isSameMonth(day, month);
const normalizedDay = startOfDay(day);
const isToday = isSameDay(normalizedDay, today);
const isCurrentMonth = isSameMonth(normalizedDay, month);
const dayClasses = getDayClassNames(
day,
normalizedDay,
month,
selectedRange,
isToday,
showTwoCalendars,
);

return (
<div key={day.toISOString()} className={dayClasses}>
<div key={normalizedDay.toISOString()} className={dayClasses}>
<button
onClick={() => handleDayClick(day)}
onClick={() => handleDayClick(normalizedDay)}
className={`
w-10 h-10 text-sm flex justify-center items-center
${
(selectedRange.start &&
isSameDay(day, selectedRange.start)) ||
(selectedRange.end && isSameDay(day, selectedRange.end))
isSameDay(normalizedDay, selectedRange.start)) ||
(selectedRange.end &&
isSameDay(normalizedDay, selectedRange.end))
? 'bg-blue-600 dark:bg-blue-500 rounded-full text-white hover:text-white'
: ''
}
Expand All @@ -146,24 +170,29 @@ const Calendar = ({
? 'text-gray-300'
: 'hidden'
}
hover:border-blue-600 hover:text-blue-600 hover:rounded-full hover:border dark:hover:border-gray-500 dark:focus:outline-none dark:focus:ring-1 dark:focus:ring-gray-600
hover:border-blue-600 hover:text-blue-600 hover:rounded-full hover:border dark:hover:border-gray-500
disabled:text-gray-300 disabled:pointer-events-none md:w-14 lg:w-16
`}
aria-pressed={
isSameDay(day, selectedRange.start) ||
isSameDay(day, selectedRange.end)
isSameDay(normalizedDay, selectedRange.start) ||
isSameDay(normalizedDay, selectedRange.end)
}
aria-label={`Select ${format(day, 'PPP')}`}
aria-label={`Select ${format(normalizedDay, 'PPP')}`}
>
{format(day, 'd')}
{format(normalizedDay, 'd')}
</button>
</div>
);
});
},
[showTwoCalendars, selectedRange, handleDayClick],
[showTwoCalendars, selectedRange, handleDayClick, today],
);

/**
* Calendar Section Component
* @param {Object} props - Component props.
* @returns {JSX.Element} - Rendered component.
*/
const CalendarSectionComponent = ({ month, onNextMonth, onPrevMonth }) => (
<div
className={`${
Expand Down Expand Up @@ -192,27 +221,16 @@ const Calendar = ({
</div>
);

// Memoize the CalendarSection component
// Memoize the CalendarSection component to prevent unnecessary re-renders
const CalendarSection = React.memo(CalendarSectionComponent);

// Assign displayName to fix the ESLint error
CalendarSection.displayName = 'CalendarSection';

// Memoization dependencies handled here
useCallback(CalendarSection, [
daysOfWeek,
renderDays,
selectedRange,
handleValueChange,
showTwoCalendars,
]);

CalendarSection.propTypes = {
month: PropTypes.instanceOf(Date).isRequired,
onNextMonth: PropTypes.func.isRequired,
onPrevMonth: PropTypes.func.isRequired,
};

/**
* Handles navigating to the next month.
* @param {Date} currentMonth - The current month.
* @param {Date} otherMonth - The other month being displayed.
* @param {Function} setMonth - State setter for the month.
*/
const handleNextMonth = useCallback(
(currentMonth, otherMonth, setMonth) => {
const nextMonth = addMonths(currentMonth, 1);
Expand All @@ -223,6 +241,12 @@ const Calendar = ({
[showTwoCalendars],
);

/**
* Handles navigating to the previous month.
* @param {Date} currentMonth - The current month.
* @param {Date} otherMonth - The other month being displayed.
* @param {Function} setMonth - State setter for the month.
*/
const handlePrevMonth = useCallback(
(currentMonth, otherMonth, setMonth) => {
const prevMonth = subMonths(currentMonth, 1);
Expand Down Expand Up @@ -254,13 +278,15 @@ const Calendar = ({
<ShortCuts setSelectedRange={setSelectedRange} />
)}

{/* First Calendar */}
<CalendarSection
month={month1}
onNextMonth={() => handleNextMonth(month1, month2, setMonth1)}
onPrevMonth={() => handlePrevMonth(month1, month2, setMonth1)}
/>

{showTwoCalendars && (
{/* Second Calendar (if showTwoCalendars is true) */}
{showTwoCalendars && month2 && (
<CalendarSection
month={month2}
onNextMonth={() => handleNextMonth(month2, month1, setMonth2)}
Expand All @@ -269,6 +295,7 @@ const Calendar = ({
)}
</div>

{/* Footer (only for two calendars) */}
{showTwoCalendars && (
<Footer
selectedRange={selectedRange}
Expand All @@ -283,20 +310,6 @@ const Calendar = ({
);
};

Calendar.propTypes = {
initialMonth1: PropTypes.instanceOf(Date),
initialMonth2: PropTypes.instanceOf(Date),
handleValueChange: PropTypes.func.isRequired,
closeDatePicker: PropTypes.func.isRequired,
showTwoCalendars: PropTypes.bool,
};

Calendar.defaultProps = {
initialMonth1: new Date(),
initialMonth2: addMonths(new Date(), 1),
showTwoCalendars: true,
};

Calendar.displayName = 'Calendar';

export default Calendar;
16 changes: 1 addition & 15 deletions platform/src/common/components/Calendar/DatePicker.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// DatePicker.js
import React, { useState, useEffect, useRef } from 'react';
import PropTypes from 'prop-types';
import { format, subMonths } from 'date-fns';
import { format } from 'date-fns';
import { usePopper } from 'react-popper';
import { Transition } from '@headlessui/react';
import Calendar from './Calendar';
Expand Down Expand Up @@ -120,8 +119,6 @@ const DatePicker = ({ customPopperStyle, alignment, onChange }) => {
>
<Calendar
showTwoCalendars={false}
initialMonth1={subMonths(new Date(), 1)}
initialMonth2={new Date()}
handleValueChange={handleValueChange}
closeDatePicker={() => setIsOpen(false)}
/>
Expand All @@ -131,15 +128,4 @@ const DatePicker = ({ customPopperStyle, alignment, onChange }) => {
);
};

DatePicker.propTypes = {
customPopperStyle: PropTypes.object,
alignment: PropTypes.oneOf(['left', 'right']),
onChange: PropTypes.func.isRequired,
};

DatePicker.defaultProps = {
customPopperStyle: {},
alignment: 'left',
};

export default DatePicker;
10 changes: 0 additions & 10 deletions platform/src/common/components/Layout/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,6 @@ const Layout = ({
const isCollapsed = useSelector((state) => state.sidebar.isCollapsed);
const isOpen = useSelector((state) => state.modal.openModal);

// Error Handling (Assuming useUserChecklists returns error)
const { error } = useUserChecklists();

// Handler to close the modal
const handleCloseModal = () => {
dispatch(setOpenModal(false));
Expand Down Expand Up @@ -78,13 +75,6 @@ const Layout = ({
/>
)}

{/* Error Message */}
{error && (
<div className="w-full p-4 bg-red-100 text-red-700 rounded-md">
{error}
</div>
)}

{/* Children */}
<div className="text-[#1C1D20] transition-all duration-300 ease-in-out overflow-hidden">
{children}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ const CustomFields = ({
) : useCalendar ? (
<DatePicker
customPopperStyle={{ left: '-7px' }}
onChange={(date) => handleSelect({ name: date })}
onChange={(date) => {
handleSelect({ name: date });
}}
/>
) : (
<CustomDropdown
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ const TableRowComponent = ({ item, isSelected, onToggleSite, index }) => (
</tr>
);

// Wrap the named function with React.memo and assign displayName
const TableRow = React.memo(TableRowComponent);
TableRow.displayName = 'TableRow';

Expand Down Expand Up @@ -216,7 +215,13 @@ const DataTable = ({

// Handle edge case if filteredData is empty
if (filteredData.length === 0) {
return <p>No data available</p>;
return (
<tr>
<td colSpan="5" className="p-4 text-center text-gray-500">
No data available
</td>
</tr>
);
}

return filteredData
Expand Down
Loading
Loading