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

fixed Event and Holiday Calendar View #2529

Closed
Changes from 4 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
15 changes: 8 additions & 7 deletions .env.example
Original file line number Diff line number Diff line change
@@ -8,20 +8,21 @@ PORT=4321

# Run Talawa-api locally in your system, and put its url into the same.

REACT_APP_TALAWA_URL=
REACT_APP_TALAWA_URL="http://localhost:4000/graphql/"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your PR has too many unnecessary files that don’t relate to your issue. You can from the PR by running the commands below from the root directory of the repository

git add -u
git reset HEAD path/to/file
git commit

Please apply these changes to this file.


# Do you want to setup and use "I'm not a robot" Checkbox (Google Recaptcha)?
# If no, leave blank, else write yes
# Example: REACT_APP_USE_RECAPTCHA=yes

REACT_APP_USE_RECAPTCHA=
REACT_APP_USE_RECAPTCHA=yes

# If you are using Google Recaptcha, i.e., REACT_APP_USE_RECAPTCHA=yes, read the following steps
# Get the google recaptcha site key from google recaptcha admin or https://www.google.com/recaptcha/admin/create
# from here for reCAPTCHA v2 and "I'm not a robot" Checkbox, and paste the key here.
# Note: In domains, fill localhost
# If you are using Google Recaptcha, i.e., REACT_APP_USE_RECAPTCHA=yes, follow these steps:
# 1. Obtain the Google reCAPTCHA site key from https://www.google.com/recaptcha/admin/create
# for reCAPTCHA v2 with the "I'm not a robot" Checkbox option.
# 2. Set "localhost" under allowed domains for local development.
# 3. Replace the placeholder below with your actual site key.

REACT_APP_RECAPTCHA_SITE_KEY=
REACT_APP_RECAPTCHA_SITE_KEY=your-recaptcha-site-key-here

# has to be inserted in the env file to use plugins and other websocket based features.
REACT_APP_BACKEND_WEBSOCKET_URL=ws://localhost:4000/graphql/
3 changes: 0 additions & 3 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npm run format:fix
# npm run lint:fix
npm run lint-staged
3 changes: 3 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -25,6 +25,9 @@
/>
<title>Talawa Admin</title>
</head>
<style>

</style>
<body>
<div id="root"></div>
<script type="module" src="/src/index.tsx"></script>
37 changes: 37 additions & 0 deletions src/components/EventCalendar/EventCalendar.module.css
Original file line number Diff line number Diff line change
@@ -340,3 +340,40 @@
background: rgba(146, 200, 141, 0.5);
border-radius: 10px;
}
.listContainer {
width: fit-content;
display: flex;
align-items: center;
gap: 8px;
}

.holidayIndicator {
background-color: gray;
border-radius: 5px;
width: 20px;
height: 12px;
display: inline-block;
}

.holidayText {
font-size: 14px;
color: #555555;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Align holiday indicator color with existing theme.

There's an inconsistency between the new .holidayIndicator using gray and the existing .holidays__color using rgba(0, 0, 0, 0.15). Consider using the same color scheme for consistency.

.holidayIndicator {
-  background-color: gray;
+  background-color: rgba(0, 0, 0, 0.15);
  border-radius: 5px;
  width: 20px;
  height: 12px;
  display: inline-block;
}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
.holidayIndicator {
background-color: gray;
border-radius: 5px;
width: 20px;
height: 12px;
display: inline-block;
}
.holidayText {
font-size: 14px;
color: #555555;
}
.holidayIndicator {
background-color: rgba(0, 0, 0, 0.15);
border-radius: 5px;
width: 20px;
height: 12px;
display: inline-block;
}
.holidayText {
font-size: 14px;
color: #555555;
}

.eventsLegend {
display: flex;
align-items: center;
gap: 8px;
}

.organizationIndicator {
background-color: #42a5f5;
border-radius: 5px;
width: 20px;
height: 12px;
display: inline-block;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Align organization indicator color with existing theme.

There's an inconsistency between the new .organizationIndicator using #42a5f5 and the existing .orgEvent__color using rgba(82, 172, 255, 0.5). Consider using the same color scheme for consistency.

.organizationIndicator {
-  background-color: #42a5f5;
+  background-color: rgba(82, 172, 255, 0.5);
  border-radius: 5px;
  width: 20px;
  height: 12px;
  display: inline-block;
}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
.organizationIndicator {
background-color: #42a5f5;
border-radius: 5px;
width: 20px;
height: 12px;
display: inline-block;
}
.organizationIndicator {
background-color: rgba(82, 172, 255, 0.5);
border-radius: 5px;
width: 20px;
height: 12px;
display: inline-block;
}


.legendText {
font-size: 14px;
color: #555555;
}
229 changes: 128 additions & 101 deletions src/components/EventCalendar/EventCalendar.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
/* eslint-disable react/jsx-key */
import EventListCard from 'components/EventListCard/EventListCard';
import dayjs from 'dayjs';
import Button from 'react-bootstrap/Button';
import React, { useState, useEffect } from 'react';
import styles from './EventCalendar.module.css';
import { ChevronLeft, ChevronRight } from '@mui/icons-material';
import CurrentHourIndicator from 'components/CurrentHourIndicator/CurrentHourIndicator';
import { ViewType } from 'screens/OrganizationEvents/OrganizationEvents';
import HolidayCard from '../HolidayCards/HolidayCard';
import { holidays, hours, months, weekdays } from './constants';
import type { InterfaceRecurrenceRule } from 'utils/recurrenceUtils';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Screens designs have changed significantly recently. We have an issue to refactor events. You should ask to be assigned the issue as part of completing this PR.

  1. The file you edited will be affected src/components/EventCalendar/EventCalendar.tsx
  2. Refactor CSS files in src/screens/OrganizationEvents #2514

import YearlyEventCalender from './YearlyEventCalender';

interface InterfaceEventListCardProps {
userRole?: string;
key?: string;
@@ -75,7 +74,7 @@ const Calendar: React.FC<InterfaceCalendarProps> = ({
);
const [expanded, setExpanded] = useState<number>(-1);
const [windowWidth, setWindowWidth] = useState<number>(window.screen.width);

console.log(hours);
useEffect(() => {
function handleResize(): void {
setWindowWidth(window.screen.width);
@@ -320,112 +319,140 @@ const Calendar: React.FC<InterfaceCalendarProps> = ({
</div>
</div>
</div>
{hours.map((hour, index) => {
const timeEventsList: JSX.Element[] =
events
?.filter((datas) => {
const currDate = new Date(
currentYear,
currentMonth,
currentDate,
);

if (
parseInt(datas.startTime?.slice(0, 2) as string).toString() ==
(index % 24).toString() &&
datas.startDate == dayjs(currDate).format('YYYY-MM-DD')
) {
return datas;
}
})
.map((datas: InterfaceEventListCardProps) => {
const attendees: { _id: string }[] = [];
datas.attendees?.forEach((attendee: { _id: string }) => {
const r = {
_id: attendee._id,
};

attendees.push(r);
});
{
// Render Holidays and Events Section for the Current Month
<div
style={{
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'flex-start',
padding: '20px',
gap: '20px',
backgroundColor: '#f9f9f9',
}}
>
{/* Holidays Card */}
<div
style={{
flex: 1,
padding: '20px',
backgroundColor: '#fff8e1',
borderRadius: '10px',
boxShadow: '0px 2px 4px rgba(0, 0, 0, 0.1)',
}}
>
<h3
style={{
fontSize: '16px',
fontWeight: '600',
color: '#333333',
marginBottom: '15px',
}}
>
Holidays
</h3>
<ul
style={{
listStyle: 'none',
padding: '0',
margin: '0',
}}
>
{/* Filter holidays to show only those in the current month */}
{holidays
?.filter(
(holiday) =>
dayjs(holiday.date, 'MM-DD').month() === currentMonth,
)
.map((holiday, index) => (
<li
key={index}
style={{
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
marginBottom: '10px',
fontSize: '14px',
color: '#555555',
}}
>
{/* Show month name and holiday date */}
<span style={{ fontWeight: '500', color: '#ff9800' }}>
{months[parseInt(holiday.date.slice(0, 2), 10) - 1]}{' '}
{holiday.date.slice(3)}
</span>
<span>{holiday.name}</span>
</li>
))}
</ul>
</div>
Comment on lines +334 to +388
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Componentize the Holiday and Events cards

The holiday and events sections contain repeated patterns and complex nested structures. Consider extracting these into separate components for better maintainability and reusability.

+ // HolidayCard.tsx
+ interface HolidayCardProps {
+   holidays: Array<{ date: string; name: string }>;
+   currentMonth: number;
+ }
+ 
+ const HolidayCard: React.FC<HolidayCardProps> = ({ holidays, currentMonth }) => {
+   return (
+     <div className={styles.holidayCard}>
+       <h3 className={styles.cardTitle}>Holidays</h3>
+       <ul className={styles.holidayList}>
+         {holidays
+           ?.filter((holiday) => dayjs(holiday.date, 'MM-DD').month() === currentMonth)
+           .map((holiday, index) => (
+             <li key={index} className={styles.holidayItem}>
+               <span className={styles.holidayDate}>
+                 {dayjs(holiday.date, 'MM-DD').format('MMM DD')}
+               </span>
+               <span className={styles.holidayName}>{holiday.name}</span>
+             </li>
+           ))}
+       </ul>
+     </div>
+   );
+ };

Also applies to: 390-452


return (
<EventListCard
refetchEvents={refetchEvents}
userRole={userRole}
key={datas._id}
id={datas._id}
eventLocation={datas.location}
eventName={datas.title}
eventDescription={datas.description}
startDate={datas.startDate}
endDate={datas.endDate}
startTime={datas.startTime}
endTime={datas.endTime}
allDay={datas.allDay}
recurring={datas.recurring}
recurrenceRule={datas.recurrenceRule}
isRecurringEventException={datas.isRecurringEventException}
isPublic={datas.isPublic}
isRegisterable={datas.isRegisterable}
registrants={attendees}
creator={datas.creator}
/>
);
}) || [];
/*istanbul ignore next*/
return (
<div key={hour} className={styles.calendar_hour_block}>
<div className={styles.calendar_hour_text_container}>
<p className={styles.calendar_hour_text}>{`${hour}`}</p>
</div>
<div className={styles.dummyWidth}></div>
{/* Events Card */}
<div
style={{
flex: 1,
padding: '20px',
backgroundColor: '#ffffff',
borderRadius: '10px',
boxShadow: '0px 2px 4px rgba(0, 0, 0, 0.1)',
}}
>
<h3
style={{
fontSize: '16px',
fontWeight: '600',
color: '#333333',
marginBottom: '15px',
}}
>
Events
</h3>
<div
className={
timeEventsList?.length > 0
? styles.event_list_parent_current
: styles.event_list_parent
}
style={{
display: 'flex',
flexDirection: 'column',
gap: '12px',
}}
>
{index % 24 == new Date().getHours() &&
new Date().getDate() == currentDate && (
<CurrentHourIndicator />
)}
<div className={styles.listContainer}>
<span className={styles.holidayIndicator}></span>
<span className={styles.holidayText}>Holidays</span>
</div>

{/* Events Created by Organization */}
<div className={styles.eventsLegend}>
<span className={styles.organizationIndicator}></span>
<span className={styles.legendText}>
Events Created by Organization
</span>
</div>

{/* Events Created by User */}
<div
className={
expanded === index
? styles.expand_list_container
: styles.list_container
}
style={{ width: 'fit-content' }}
style={{
display: 'flex',
alignItems: 'center',
gap: '8px',
}}
>
<div
className={
expanded === index
? styles.expand_event_list
: styles.event_list
}
>
{/*istanbul ignore next*/}
{expanded === index
? timeEventsList
: timeEventsList?.slice(0, 1)}
</div>
{(timeEventsList?.length > 1 ||
(windowWidth <= 700 && timeEventsList?.length > 0)) && (
<button
className={styles.btn__more}
onClick={() => {
toggleExpand(index);
}}
>
{expanded === index ? 'View less' : 'View all'}
</button>
)}
<span
style={{
backgroundColor: '#8bc34a',
borderRadius: '5px',
width: '20px',
height: '12px',
display: 'inline-block',
}}
></span>
<span style={{ fontSize: '14px', color: '#555555' }}>
Events Created by User
</span>
</div>
</div>
</div>
);
})}
</div>
}
</>
);
};