diff --git a/.eslintrc.js b/.eslintrc.js index f5abea2..8af6a8d 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -4,7 +4,7 @@ module.exports = { es2021: true, jest: true, }, - extends: ['airbnb-base', 'plugin:storybook/recommended'], + extends: ['airbnb-base', 'plugin:storybook/recommended', 'prettier'], parser: '@typescript-eslint/parser', parserOptions: { ecmaVersion: 'latest', @@ -30,9 +30,13 @@ module.exports = { '**/__tests__/**/*.js', '**/.storybook/**/*.*', '**/*{.,_}{test,spec}.{ts,tsx}', + 'app/__mocks__/**/*', + 'app/mocks/**/*', ], peerDependencies: true, }, ], + 'no-unused-vars': 'off', + '@typescript-eslint/no-unused-vars': ['error'], }, }; diff --git a/.husky/pre-commit b/.husky/pre-commit old mode 100644 new mode 100755 index 62bc428..813f2ab --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -20,4 +20,4 @@ yarn style-lint || ( false; ) -echo 'Awesome, you passed all the checks 😍🎉' \ No newline at end of file +echo 'Awesome, you passed all the checks 😍🎉' diff --git a/.husky/pre-push b/.husky/pre-push old mode 100644 new mode 100755 diff --git a/app/api/onboarding/username.client.ts b/app/api/onboarding/username.client.ts index feaa190..873ea2a 100644 --- a/app/api/onboarding/username.client.ts +++ b/app/api/onboarding/username.client.ts @@ -11,7 +11,6 @@ export const isUsernameAvailable = async (host: string, token: string, username: }); return response.data.data.available; } catch (error) { - console.error('err', error); return error; } }; diff --git a/app/components/Button.tsx b/app/components/Button.tsx index b149b3a..f2ea6df 100644 --- a/app/components/Button.tsx +++ b/app/components/Button.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { Icon } from '~/types/Icon'; +import { Icon as IconType } from '~/types/Icon'; interface ButtonProps { size?: 'small' | 'medium' | 'large'; @@ -35,6 +35,7 @@ export const Button: React.FC = ({ : 'bg-white border-gray-400 text-gray-900 hover:bg-gray-300' } ${ + // eslint-disable-next-line no-nested-ternary size === 'small' ? 'py-1 px-2 my-2 text-sm gap-1' : size === 'medium' @@ -53,7 +54,7 @@ export const Button: React.FC = ({ interface LinkButtonProps { href: string; title: string; - icon: Icon; + icon: IconType; } export const LinkButton: React.FC = ({ href, title, icon: Icon }) => ( diff --git a/app/components/SocialAuth.tsx b/app/components/SocialAuth.tsx index a99c674..6c44913 100644 --- a/app/components/SocialAuth.tsx +++ b/app/components/SocialAuth.tsx @@ -1,3 +1,4 @@ +import * as React from 'react'; import { LinkButton } from './Button'; import { Google, Microsoft } from './icons'; @@ -6,12 +7,10 @@ interface SocialAuthProps { microsoft: string; } -export const SocialAuth: React.FC = ({ google, microsoft }) => { - return ( -
- +export const SocialAuth: React.FC = ({ google, microsoft }) => ( +
+ - -
- ); -}; + +
+); diff --git a/app/components/common/drawer/index.test.tsx b/app/components/common/drawer/index.test.tsx index 2031d51..3711c4f 100644 --- a/app/components/common/drawer/index.test.tsx +++ b/app/components/common/drawer/index.test.tsx @@ -55,7 +55,9 @@ describe('Drawer', () => { expect(toggleDrawerMock).toHaveBeenCalledTimes(1); const eventTime = screen.getByText( - `${dayjs(event.start).format('MMMM DD, YYYY h A')} - ${dayjs(event.end).format('MMMM DD, YYYY h A')}`, + `${dayjs(event.start).format('MMMM DD, YYYY h A')} - ${dayjs(event.end).format( + 'MMMM DD, YYYY h A', + )}`, ); expect(eventTime).toBeInTheDocument(); diff --git a/app/components/common/drawer/index.tsx b/app/components/common/drawer/index.tsx index 5640267..6a345f2 100644 --- a/app/components/common/drawer/index.tsx +++ b/app/components/common/drawer/index.tsx @@ -9,53 +9,52 @@ interface DrawerProps { toggleDrawer: () => void; } -const Drawer: React.FC = ({ event, isDrawerVisible, toggleDrawer }) => { - return ( -
-
-
+const Drawer: React.FC = ({ event, isDrawerVisible, toggleDrawer }) => ( +
+
+
+
+
+ +
+

{event.title}

+ +

+ {dayjs(event.start).format('MMMM DD, YYYY h A')} -{' '} + {dayjs(event.end).format('MMMM DD, YYYY h A')} +

+

{event.location}

+

{event.description}

+

People

-
- -
-

{event.title}

- -

- {dayjs(event.start).format('MMMM DD, YYYY h A')} - {dayjs(event.end).format('MMMM DD, YYYY h A')} -

-

{event.location}

-

{event.description}

-

People

-
- {event.attendees?.map(({ attendee }) => ( -
-
-

- {attendee.email} -

-
- ))} -
+ {event.attendees?.map(({ attendee }) => ( +
+
+

+ {attendee.email} +

+
+ ))}
-
+
- ); -}; +
+); export default Drawer; diff --git a/app/components/common/eventCard/index.test.tsx b/app/components/common/eventCard/index.test.tsx index 1f1a593..9bdeb66 100644 --- a/app/components/common/eventCard/index.test.tsx +++ b/app/components/common/eventCard/index.test.tsx @@ -1,10 +1,14 @@ import { render, screen } from '@testing-library/react'; import EventCard from '.'; - - it('renders the event card', () => { - render(); + render( + , + ); const eventCardBox = screen.getByTestId('event-card-box'); const eventCardDates = screen.getByTestId('event-card-dates'); @@ -23,7 +27,10 @@ it('renders the event card attendees', () => { title={'Marketing meet with John'} start={new Date()} end={new Date(new Date().setHours(new Date().getHours() + 2))} - attendees={[{attendee: {email: 'test1@abc.com'}}, {attendee: {email: 'test2@abc.com'}}]} + attendees={[ + { attendee: { email: 'test1@abc.com' } }, + { attendee: { email: 'test2@abc.com' } }, + ]} />, ); const eventCardattendees = screen.getByTestId('event-card-attendees'); @@ -58,8 +65,13 @@ it('renders the event card location', () => { // }); it('renders the event card no details', () => { - render(); + render( + , + ); const eventCardNoDetails = screen.getByTestId('event-card-no-details'); expect(eventCardNoDetails).toBeInTheDocument(); -}); \ No newline at end of file +}); diff --git a/app/components/common/eventCard/index.tsx b/app/components/common/eventCard/index.tsx index d39a64a..e816102 100644 --- a/app/components/common/eventCard/index.tsx +++ b/app/components/common/eventCard/index.tsx @@ -4,77 +4,69 @@ import { DynamicHeroIcon } from '../navbar'; import { CalEvent } from '~/utils/interfaces'; import { GoogleMeet } from '../../../components/icons'; -const EventCard = ({ - title, - start, - end, - attendees, - location, - onlineEventLink -} : CalEvent) => { - const startDate = dayjs(start); +const EventCard = ({ title, start, end, attendees, location, onlineEventLink }: CalEvent) => { + const startDate = dayjs(start); const startTime = startDate.format('YYYY MMM DD h:mm A'); const endTime = dayjs(end).format('YYYY MMM DD h:mm A'); - return( - <> -
-
-
{startTime}
-
-
+ return ( + <> +
+
+
{startTime}
+
+
+
+
{endTime}
-
{endTime}
-
-
-
- {title} -
-
- {attendees && ( -
- {attendees.map(data => data.attendee.email).join(", ")} -
- )} - {!attendees && location && ( -
-
- +
+
+ {title} +
+
+ {attendees && ( +
+ {attendees.map((data) => data.attendee.email).join(', ')} +
+ )} + {!attendees && location && ( +
+
+ +
+
{location}
-
{location}
-
- )} - {!attendees && !location && onlineEventLink && ( - -
- + )} + {!attendees && !location && onlineEventLink && ( + +
+ +
+ + )} + {!attendees && !location && !onlineEventLink && ( +
+ No details provided
- - - )} - {!attendees && !location && !onlineEventLink && ( -
- No details provided -
- )} + )} +
-
- -)}; + + ); +}; -export default EventCard; \ No newline at end of file +export default EventCard; diff --git a/app/components/common/navbar/index.tsx b/app/components/common/navbar/index.tsx index 9fc9dfb..36d74ba 100644 --- a/app/components/common/navbar/index.tsx +++ b/app/components/common/navbar/index.tsx @@ -28,7 +28,7 @@ export const DynamicHeroIcon = ({ name, className }: DynamicHeroIconType) => { const Navbar = () => { const matches = useMatches(); - const {pathname} = matches[matches.length - 1]; + const { pathname } = matches[matches.length - 1]; const [active, setActive] = useState(''); const [showSlider, setShowSlider] = useState(false); @@ -41,8 +41,8 @@ const Navbar = () => { }; useEffect(() => { - setActive(pathname) - },[pathname]); + setActive(pathname); + }, [pathname]); const navbarElements = { navbarPages: [ diff --git a/app/components/common/rdsCalendar/index.test.tsx b/app/components/common/rdsCalendar/index.test.tsx index 4b93352..4da161d 100644 --- a/app/components/common/rdsCalendar/index.test.tsx +++ b/app/components/common/rdsCalendar/index.test.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { render, fireEvent, screen } from '@testing-library/react'; +import { render } from '@testing-library/react'; import '@testing-library/jest-dom'; import { withDragAndDropProps } from 'react-big-calendar/lib/addons/dragAndDrop'; import dayjs from 'dayjs'; @@ -11,7 +11,7 @@ import { CalendarEventProps, CalEvent, UpdateEvent } from '~/utils/interfaces'; const mockedUsedNavigate = jest.fn(); jest.mock('react-router-dom', () => ({ - ...jest.requireActual('react-router-dom') as any, + ...(jest.requireActual('react-router-dom') as any), useNavigate: () => mockedUsedNavigate, })); @@ -25,9 +25,10 @@ interface RdsCalendarProps { updateEvent: (event: CalEvent) => void; } -jest.mock('react-big-calendar/lib/addons/dragAndDrop', () => { - return (Component: React.ComponentType) => Component; -}); +jest.mock( + 'react-big-calendar/lib/addons/dragAndDrop', + () => (Component: React.ComponentType) => Component, +); const mockEventsList: CalEvent[] = [ { @@ -89,8 +90,7 @@ describe('RdsCalendar', () => { // }); it('handles onEventDrop correctly', () => { - const { getByText } = render(); - const eventElement = getByText('Event 1'); + render(); const newStartDate = dayjs().add(3, 'hours').toDate(); const newEndDate = dayjs().add(4, 'hours').toDate(); @@ -123,7 +123,7 @@ describe('RdsCalendar', () => { }); it('handles onEventResize correctly', () => { - const { getByText } = render(); + render(); const newEndDate = dayjs().add(4, 'hours').toDate(); @@ -159,11 +159,6 @@ describe('RdsCalendar', () => { const startTime = dayjs().add(3, 'hours').toDate(); const endTime = dayjs().add(4, 'hours').toDate(); - const newEvent: CalEvent = { - title: '', - start: startTime, - end: endTime, - }; const onSelectSlotMock = { start: startTime, @@ -193,7 +188,12 @@ describe('RdsCalendar', () => { start: slotInfo.start, end: dayjs(slotInfo.start).add(1, 'hour').toDate(), }; - mockSetCalendarEvent((e: any) => ({ ...e, event, show: true, new: true })); + mockSetCalendarEvent((e: any) => ({ + ...e, + event, + show: true, + new: true, + })); }; onSelectSlot(onSelectSlotMock); diff --git a/app/components/common/socialEventCard/index.tsx b/app/components/common/socialEventCard/index.tsx index 45b16ab..0708ea5 100644 --- a/app/components/common/socialEventCard/index.tsx +++ b/app/components/common/socialEventCard/index.tsx @@ -1,5 +1,5 @@ -import { CalEvent } from '~/utils/interfaces'; import dayjs from 'dayjs'; +import { CalEvent } from '~/utils/interfaces'; export default function SocialEventCard({ title, attendees, start, end }: CalEvent) { const startDate = dayjs(start); diff --git a/app/components/icons/Email.tsx b/app/components/icons/Email.tsx index ecc28e4..8c5c243 100644 --- a/app/components/icons/Email.tsx +++ b/app/components/icons/Email.tsx @@ -1,3 +1,4 @@ +import * as React from 'react'; import { IconProps } from '~/types/Icon'; export const Email: React.FC = ({ className }) => ( diff --git a/app/components/icons/Google.tsx b/app/components/icons/Google.tsx index 83b498f..2b15eca 100644 --- a/app/components/icons/Google.tsx +++ b/app/components/icons/Google.tsx @@ -1,28 +1,27 @@ +import * as React from 'react'; import { IconProps } from '~/types/Icon'; -export const Google: React.FC = ({ className }) => { - return ( - - - - - - - - - - - - - ); -}; +export const Google: React.FC = ({ className }) => ( + + + + + + + + + + + + +); diff --git a/app/components/icons/GoogleCalendar.tsx b/app/components/icons/GoogleCalendar.tsx index 62bda47..a51aaed 100644 --- a/app/components/icons/GoogleCalendar.tsx +++ b/app/components/icons/GoogleCalendar.tsx @@ -1,23 +1,22 @@ +import * as React from 'react'; import { IconProps } from '~/types/Icon'; -export const GoogleCalendar: React.FC = ({ className }) => { - return ( - - - - - - - - - - - - ); -}; +export const GoogleCalendar: React.FC = () => ( + + + + + + + + + + + +); diff --git a/app/components/icons/GoogleMeet.tsx b/app/components/icons/GoogleMeet.tsx index 426bf06..2f83a22 100644 --- a/app/components/icons/GoogleMeet.tsx +++ b/app/components/icons/GoogleMeet.tsx @@ -1,17 +1,16 @@ +import * as React from 'react'; import { IconProps } from '~/types/Icon'; -export const GoogleMeet: React.FC = ({ className }) => { - return ( - - - - - - - - - ); -}; +export const GoogleMeet: React.FC = () => ( + + + + + + + + +); diff --git a/app/components/icons/Microsoft.tsx b/app/components/icons/Microsoft.tsx index eda7bfd..bec3583 100644 --- a/app/components/icons/Microsoft.tsx +++ b/app/components/icons/Microsoft.tsx @@ -1,17 +1,16 @@ +import * as React from 'react'; import { IconProps } from '~/types/Icon'; -export const Microsoft: React.FC = ({ className }) => { - return ( - - - - - - - ); -}; +export const Microsoft: React.FC = ({ className }) => ( + + + + + + +); diff --git a/app/components/icons/MicrosoftCalendar.tsx b/app/components/icons/MicrosoftCalendar.tsx index bb3059b..45bc032 100644 --- a/app/components/icons/MicrosoftCalendar.tsx +++ b/app/components/icons/MicrosoftCalendar.tsx @@ -1,114 +1,112 @@ -export const MicrosoftCalendar = () => { - return ( - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ); -}; +export const MicrosoftCalendar = () => ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +); diff --git a/app/components/icons/__test__/GoogleMeet.test.tsx b/app/components/icons/__test__/GoogleMeet.test.tsx index 897b8ac..0ce9c6f 100644 --- a/app/components/icons/__test__/GoogleMeet.test.tsx +++ b/app/components/icons/__test__/GoogleMeet.test.tsx @@ -6,4 +6,4 @@ describe('GoogleMeet', () => { const { container } = render(); expect(container).toBeInTheDocument(); }); -}); \ No newline at end of file +}); diff --git a/app/components/icons/index.tsx b/app/components/icons/index.tsx index 9d405b7..760102b 100644 --- a/app/components/icons/index.tsx +++ b/app/components/icons/index.tsx @@ -3,4 +3,4 @@ export * from './Microsoft'; export * from './GoogleCalendar'; export * from './MicrosoftCalendar'; export * from './Email'; -export * from './GoogleMeet' +export * from './GoogleMeet'; diff --git a/app/components/searchBar/index.test.tsx b/app/components/searchBar/index.test.tsx index a87d43e..84938ed 100644 --- a/app/components/searchBar/index.test.tsx +++ b/app/components/searchBar/index.test.tsx @@ -1,4 +1,4 @@ -import { screen, render, fireEvent, getByTestId, waitFor } from '@testing-library/react'; +import { screen, render, fireEvent, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import SearchBar from '.'; @@ -20,7 +20,7 @@ describe('checks input value to be empty', () => { describe('Accepting Letters', () => { it('checking input letter', () => { - render( {})} />); + render( {})} />); const letters = 'abcdefghizklmnopqrstuvwxyz'; const input = screen.getByTestId('searchBar') as HTMLInputElement; fireEvent.change(input, { target: { value: letters } }); @@ -40,7 +40,7 @@ describe('Accepting Symbols', () => { describe('Checking whether Input matches or not', () => { it('Matching Input', async () => { - render( {})} />); + render( {})} />); const box = screen.getByRole('searchbox') as HTMLInputElement; await userEvent.click(box); await userEvent.keyboard('helloworld'); diff --git a/app/components/searchBar/index.tsx b/app/components/searchBar/index.tsx index 6075fd3..012eede 100644 --- a/app/components/searchBar/index.tsx +++ b/app/components/searchBar/index.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React from 'react'; import { MagnifyingGlassIcon } from '@heroicons/react/24/outline'; @@ -13,20 +13,18 @@ const SearchBar: React.FC = ({ placeholder = 'Search', defaultValue, onChangeValue, -}) => { - return ( -
- - onChangeValue(e.target.value)} - className="block rounded-md border-0 flex-grow p-2 bg-gray-100" - /> -
- ); -}; +}) => ( +
+ + onChangeValue(e.target.value)} + className="block rounded-md border-0 flex-grow p-2 bg-gray-100" + /> +
+); export default SearchBar; diff --git a/app/constants/socialEvents.constants.ts b/app/constants/socialEvents.constants.ts index c536337..f9b2ccd 100644 --- a/app/constants/socialEvents.constants.ts +++ b/app/constants/socialEvents.constants.ts @@ -1,6 +1,7 @@ -import dayjs from "dayjs"; +import dayjs from 'dayjs'; -export const socialMockEvents = [{ +export const socialMockEvents = [ + { id: 1, title: 'stand up feature demo', start: dayjs('2023-06-01').add(1, 'hour').toDate(), @@ -53,4 +54,5 @@ export const socialMockEvents = [{ }, }, ], - }]; \ No newline at end of file + }, +]; diff --git a/app/constants/urls.constants.ts b/app/constants/urls.constants.ts index dee7ffd..9efe171 100644 --- a/app/constants/urls.constants.ts +++ b/app/constants/urls.constants.ts @@ -4,8 +4,14 @@ export const checkUsername = (HOST: string, username: string) => export const defaultCalendarId = 1; export const getUserSelfData = (HOST: string) => `${HOST}/users/self`; export const getUserCalendarId = (HOST: string, username: string) => `${HOST}/calendar/${username}`; -export const getEvents = (HOST: string, calendarId:number = defaultCalendarId, startTime: number, endTime: number) => - `${HOST}/events/calendar/${calendarId}?startTime=${startTime}&endTime=${endTime}`; +export const getEvents = ( + HOST: string, + + // eslint-disable-next-line default-param-last + calendarId: number = defaultCalendarId, + startTime: number, + endTime: number, +) => `${HOST}/events/calendar/${calendarId}?startTime=${startTime}&endTime=${endTime}`; export const getEventById = (HOST: string, id: number) => `${HOST}/events/${id}`; diff --git a/app/env.server.ts b/app/env.server.ts index f70c9ad..87ff33e 100644 --- a/app/env.server.ts +++ b/app/env.server.ts @@ -6,7 +6,7 @@ export const envObj = { global_variables (https://developer.mozilla.org/en-US/docs/Glossary/Global_variable) env vars remix https://remix.run/docs/en/1.14.0/guides/envvars declaring interface inside global scope for type-safety https://www.typescriptlang.org/docs/handbook/declaration-files/templates/global-modifying-module-d-ts.html - + */ declare global { diff --git a/app/mocks/handlers/clientHandler.ts b/app/mocks/handlers/clientHandler.ts index 3977dc3..ac424ca 100644 --- a/app/mocks/handlers/clientHandler.ts +++ b/app/mocks/handlers/clientHandler.ts @@ -3,7 +3,7 @@ import { rest } from 'msw'; const URL = window.ENV.API_HOST; export const clientHandlers = [ - rest.get(`${URL}/users/usernameCheck/:username`, (req, res, ctx) => { - return res(ctx.json({ available: true })); - }), + rest.get(`${URL}/users/usernameCheck/:username`, (req, res, ctx) => + res(ctx.json({ available: true })), + ), ]; diff --git a/app/mocks/handlers/serverHandler.ts b/app/mocks/handlers/serverHandler.ts index fde3c6c..ff22f69 100644 --- a/app/mocks/handlers/serverHandler.ts +++ b/app/mocks/handlers/serverHandler.ts @@ -4,7 +4,7 @@ const URL = process.env.API_HOST; export const serverHandlers = [ // this is a dummy request,exists on client we will change it in further PR's - rest.get(`${URL}/users/usernameCheck/:username`, (req, res, ctx) => { - return res(ctx.json({ available: true })); - }), + rest.get(`${URL}/users/usernameCheck/:username`, (req, res, ctx) => + res(ctx.json({ available: true })), + ), ]; diff --git a/app/models/oauth.server.ts b/app/models/oauth.server.ts index 94b7c45..01dd12c 100644 --- a/app/models/oauth.server.ts +++ b/app/models/oauth.server.ts @@ -1,6 +1,4 @@ -export const getOAuthLinks = async () => { - return { - GOOGLE_OAUTH: process.env.GOOGLE_OAUTH_LINK, - MICROSOFT_OAUTH: process.env.MICROSOFT_OAUTH_LINK, - }; -}; +export const getOAuthLinks = async () => ({ + GOOGLE_OAUTH: process.env.GOOGLE_OAUTH_LINK, + MICROSOFT_OAUTH: process.env.MICROSOFT_OAUTH_LINK, +}); diff --git a/app/models/urls.server.ts b/app/models/urls.server.ts index c4ccb36..5122769 100644 --- a/app/models/urls.server.ts +++ b/app/models/urls.server.ts @@ -1,5 +1,3 @@ -export const getUrls = async () => { - return { - API_HOST: process.env.API_HOST, - }; -}; +export const getUrls = async () => ({ + API_HOST: process.env.API_HOST, +}); diff --git a/app/routes/event/$eventId.tsx b/app/routes/event/$eventId.tsx index ddb6d19..a43a29d 100644 --- a/app/routes/event/$eventId.tsx +++ b/app/routes/event/$eventId.tsx @@ -53,7 +53,7 @@ const EventDetails = () => { useEffect(() => { if (params.eventId !== 'new') { const calEvent = eventsList.find( - (event: CalEvent) => event.id === parseInt(params.eventId as string, 10), + (singleEvent: CalEvent) => singleEvent.id === parseInt(params.eventId as string, 10), ); if (calEvent) { diff --git a/app/routes/events.tsx b/app/routes/events.tsx index 4bea0ba..2e270d0 100644 --- a/app/routes/events.tsx +++ b/app/routes/events.tsx @@ -1,10 +1,8 @@ -import dayjs from 'dayjs'; import { useState } from 'react'; import Drawer from '~/components/common/drawer'; import Navbar from '~/components/common/navbar'; import EventCard from '~/components/common/eventCard'; import { CalEvent } from '~/utils/interfaces'; -import socialEvents from './socialEvents'; import { socialMockEvents } from '~/constants/socialEvents.constants'; const Events = () => { @@ -16,33 +14,33 @@ const Events = () => { setIsDrawerVisible((isDrawerOpen) => !isDrawerOpen); }; - - return ( - -
+
-
- -
-
-
Events
+
+ +
- {socialMockEvents.map(eventData =>
toggleDrawer(eventData)}>
)} +
Events
+
+ {socialMockEvents.map((eventData) => ( +
toggleDrawer(eventData)}> + +
+ ))} +
-
- {selectedEvent && ( - - )} -
- + {selectedEvent && ( + + )} +
); }; diff --git a/app/routes/index.tsx b/app/routes/index.tsx index 3438cac..49eba3a 100644 --- a/app/routes/index.tsx +++ b/app/routes/index.tsx @@ -24,31 +24,38 @@ export const loader: LoaderFunction = async ({ request }) => { const endTime = dayjs().add(1, 'months').endOf('month').unix() * 1000; try { - const {data} = await axios.get(getUserSelfData(process.env.API_HOST ?? '')); - if(data?.username) { - const {data: selfData } = await axios.get(getUserCalendarId(process.env.API_HOST ?? '', data.username)) - if(selfData?.rcal?.ownerId) { - const {data: eventDetails} = await axios.get(getEvents(process.env.API_HOST ?? '', selfData.rcal.ownerId, startTime, endTime), { - headers: { - 'Content-Type': 'application/json', - Cookie: cookie, + const { data } = await axios.get(getUserSelfData(process.env.API_HOST ?? '')); + if (data?.username) { + const { data: selfData } = await axios.get( + getUserCalendarId(process.env.API_HOST ?? '', data.username), + ); + if (selfData?.rcal?.ownerId) { + const { data: eventDetails } = await axios.get( + getEvents(process.env.API_HOST ?? '', selfData.rcal.ownerId, startTime, endTime), + { + headers: { + 'Content-Type': 'application/json', + Cookie: cookie, + }, }, - }); + ); return json({ events: eventDetails?.data, ENV: baseUrls, error: null }); - } else { - toast.error('Unable to get ownerId details'+ selfData, { - toastId: 'events_error', - }); } - } else { - toast.error('Unable to get username details'+ data, { + toast.error(`Unable to get ownerId details${selfData}`, { toastId: 'events_error', }); - } + return null; + } + + toast.error(`Unable to get username details${data}`, { + toastId: 'events_error', + }); + return null; } catch (error) { return { events: null, ENV: baseUrls, error }; } }; + export const unstableShouldReload: ShouldRevalidateFunction = () => false; function CalendarPage() { diff --git a/app/routes/socialEvents.tsx b/app/routes/socialEvents.tsx index eda54ad..d0c0155 100644 --- a/app/routes/socialEvents.tsx +++ b/app/routes/socialEvents.tsx @@ -1,4 +1,3 @@ -import dayjs from 'dayjs'; import { useState } from 'react'; import Drawer from '~/components/common/drawer'; import SocialEventCard from '~/components/common/socialEventCard'; @@ -9,27 +8,36 @@ import { CalEvent } from '~/utils/interfaces'; export default function socialEvents() { const [selectedEvent, setSelectedEvent] = useState(null); const [isDrawerVisible, setIsDrawerVisible] = useState(false); - const toggleDrawer = (event?: CalEvent) => { setSelectedEvent(event || null); setIsDrawerVisible((isDrawerOpen) => !isDrawerOpen); }; - return <> -
- -
- {socialMockEvents.map(socialEvent =>
{ - toggleDrawer(socialEvent)}} className="">
)} -
- {selectedEvent && ( + return ( + <> +
+ +
+ {socialMockEvents.map((socialEvent) => ( +
{ + toggleDrawer(socialEvent); + }} + className="" + > + +
+ ))} +
+ {selectedEvent && ( )} -
- ; +
+ + ); } diff --git a/app/styles/global.css b/app/styles/global.css index f38b8cb..ecce583 100644 --- a/app/styles/global.css +++ b/app/styles/global.css @@ -1,7 +1,7 @@ /* This is a global CSS file */ -@import url('react-big-calendar/lib/css/react-big-calendar.css'); -@import url('react-big-calendar/lib/addons/dragAndDrop/styles.css'); -@import url('react-toastify/dist/ReactToastify.css'); +@import 'react-big-calendar/lib/css/react-big-calendar.css'; +@import 'react-big-calendar/lib/addons/dragAndDrop/styles.css'; +@import 'react-toastify/dist/ReactToastify.css'; /* overriding react-big-calendar's css properties */ .rbc-event { @@ -11,7 +11,7 @@ .rbc-day-slot .rbc-event, .rbc-day-slot .rbc-background-event { border: 1px solid #e7e5e4; - border-radius: 0px 8px 8px 0px; + border-radius: 0 8px 8px 0; } .rbc-event.rbc-selected { @@ -19,7 +19,7 @@ } .rbc-event-content { - color: #000000; + color: #000; font-size: 90%; } @@ -27,7 +27,9 @@ color: #78716c; font-size: 60%; } + .rbc-off-range-bg { background-color: #f5f5f5; } + /* overriding react-big-calendar's css properties */ diff --git a/app/styles/tailwind.css b/app/styles/tailwind.css index ebcfc94..70e2019 100644 --- a/app/styles/tailwind.css +++ b/app/styles/tailwind.css @@ -42,9 +42,11 @@ html { -moz-tab-size: 4; /* 3 */ -o-tab-size: 4; - tab-size: 4; + tab-size: 4; /* 3 */ - font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, + 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', + 'Segoe UI Symbol', 'Noto Color Emoji'; /* 4 */ font-feature-settings: normal; /* 5 */ @@ -85,7 +87,7 @@ Add the correct text decoration in Chrome, Edge, and Safari. abbr:where([title]) { -webkit-text-decoration: underline dotted; - text-decoration: underline dotted; + text-decoration: underline dotted; } /* @@ -129,7 +131,8 @@ code, kbd, samp, pre { - font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; + font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', + 'Courier New', monospace; /* 1 */ font-size: 1em; /* 2 */ @@ -354,7 +357,8 @@ textarea { 2. Set the default placeholder color to the user's configured gray 400 color. */ -input::-moz-placeholder, textarea::-moz-placeholder { +input::-moz-placeholder, +textarea::-moz-placeholder { opacity: 1; /* 1 */ color: #9ca3af; @@ -374,7 +378,7 @@ Set the default cursor for buttons. */ button, -[role="button"] { +[role='button'] { cursor: pointer; } @@ -422,7 +426,9 @@ video { display: none; } -*, ::before, ::after { +*, +::before, +::after { --tw-border-spacing-x: 0; --tw-border-spacing-y: 0; --tw-translate-x: 0; @@ -432,19 +438,19 @@ video { --tw-skew-y: 0; --tw-scale-x: 1; --tw-scale-y: 1; - --tw-pan-x: ; - --tw-pan-y: ; - --tw-pinch-zoom: ; + --tw-pan-x: ; + --tw-pan-y: ; + --tw-pinch-zoom: ; --tw-scroll-snap-strictness: proximity; - --tw-gradient-from-position: ; - --tw-gradient-via-position: ; - --tw-gradient-to-position: ; - --tw-ordinal: ; - --tw-slashed-zero: ; - --tw-numeric-figure: ; - --tw-numeric-spacing: ; - --tw-numeric-fraction: ; - --tw-ring-inset: ; + --tw-gradient-from-position: ; + --tw-gradient-via-position: ; + --tw-gradient-to-position: ; + --tw-ordinal: ; + --tw-slashed-zero: ; + --tw-numeric-figure: ; + --tw-numeric-spacing: ; + --tw-numeric-fraction: ; + --tw-ring-inset: ; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / 0.5); @@ -452,24 +458,24 @@ video { --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000; - --tw-blur: ; - --tw-brightness: ; - --tw-contrast: ; - --tw-grayscale: ; - --tw-hue-rotate: ; - --tw-invert: ; - --tw-saturate: ; - --tw-sepia: ; - --tw-drop-shadow: ; - --tw-backdrop-blur: ; - --tw-backdrop-brightness: ; - --tw-backdrop-contrast: ; - --tw-backdrop-grayscale: ; - --tw-backdrop-hue-rotate: ; - --tw-backdrop-invert: ; - --tw-backdrop-opacity: ; - --tw-backdrop-saturate: ; - --tw-backdrop-sepia: ; + --tw-blur: ; + --tw-brightness: ; + --tw-contrast: ; + --tw-grayscale: ; + --tw-hue-rotate: ; + --tw-invert: ; + --tw-saturate: ; + --tw-sepia: ; + --tw-drop-shadow: ; + --tw-backdrop-blur: ; + --tw-backdrop-brightness: ; + --tw-backdrop-contrast: ; + --tw-backdrop-grayscale: ; + --tw-backdrop-hue-rotate: ; + --tw-backdrop-invert: ; + --tw-backdrop-opacity: ; + --tw-backdrop-saturate: ; + --tw-backdrop-sepia: ; } ::backdrop { @@ -482,19 +488,19 @@ video { --tw-skew-y: 0; --tw-scale-x: 1; --tw-scale-y: 1; - --tw-pan-x: ; - --tw-pan-y: ; - --tw-pinch-zoom: ; + --tw-pan-x: ; + --tw-pan-y: ; + --tw-pinch-zoom: ; --tw-scroll-snap-strictness: proximity; - --tw-gradient-from-position: ; - --tw-gradient-via-position: ; - --tw-gradient-to-position: ; - --tw-ordinal: ; - --tw-slashed-zero: ; - --tw-numeric-figure: ; - --tw-numeric-spacing: ; - --tw-numeric-fraction: ; - --tw-ring-inset: ; + --tw-gradient-from-position: ; + --tw-gradient-via-position: ; + --tw-gradient-to-position: ; + --tw-ordinal: ; + --tw-slashed-zero: ; + --tw-numeric-figure: ; + --tw-numeric-spacing: ; + --tw-numeric-fraction: ; + --tw-ring-inset: ; --tw-ring-offset-width: 0px; --tw-ring-offset-color: #fff; --tw-ring-color: rgb(59 130 246 / 0.5); @@ -502,24 +508,24 @@ video { --tw-ring-shadow: 0 0 #0000; --tw-shadow: 0 0 #0000; --tw-shadow-colored: 0 0 #0000; - --tw-blur: ; - --tw-brightness: ; - --tw-contrast: ; - --tw-grayscale: ; - --tw-hue-rotate: ; - --tw-invert: ; - --tw-saturate: ; - --tw-sepia: ; - --tw-drop-shadow: ; - --tw-backdrop-blur: ; - --tw-backdrop-brightness: ; - --tw-backdrop-contrast: ; - --tw-backdrop-grayscale: ; - --tw-backdrop-hue-rotate: ; - --tw-backdrop-invert: ; - --tw-backdrop-opacity: ; - --tw-backdrop-saturate: ; - --tw-backdrop-sepia: ; + --tw-blur: ; + --tw-brightness: ; + --tw-contrast: ; + --tw-grayscale: ; + --tw-hue-rotate: ; + --tw-invert: ; + --tw-saturate: ; + --tw-sepia: ; + --tw-drop-shadow: ; + --tw-backdrop-blur: ; + --tw-backdrop-brightness: ; + --tw-backdrop-contrast: ; + --tw-backdrop-grayscale: ; + --tw-backdrop-hue-rotate: ; + --tw-backdrop-invert: ; + --tw-backdrop-opacity: ; + --tw-backdrop-saturate: ; + --tw-backdrop-sepia: ; } .container { @@ -1006,12 +1012,16 @@ video { .-translate-y-1\/2 { --tw-translate-y: -50%; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) + skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) + scaleY(var(--tw-scale-y)); } .translate-x-full { --tw-translate-x: 100%; - transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); + transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) + skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) + scaleY(var(--tw-scale-y)); } .cursor-pointer { @@ -1707,14 +1717,18 @@ video { .shadow-lg { --tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); - --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color); - box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), + 0 4px 6px -4px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), + var(--tw-shadow); } .shadow-xl { --tw-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1); - --tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color); - box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); + --tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), + 0 8px 10px -6px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), + var(--tw-shadow); } .outline-none { @@ -1728,19 +1742,28 @@ video { } .filter { - filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); + filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) + var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); } .backdrop-blur-sm { --tw-backdrop-blur: blur(4px); - -webkit-backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); - backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); + -webkit-backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) + var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) + var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) + var(--tw-backdrop-sepia); + backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) + var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) + var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia); } .transition { - transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter; - transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; - transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-backdrop-filter; + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, + opacity, box-shadow, transform, filter, -webkit-backdrop-filter; + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, + opacity, box-shadow, transform, filter, backdrop-filter; + transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, + opacity, box-shadow, transform, filter, backdrop-filter, -webkit-backdrop-filter; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); transition-duration: 150ms; } @@ -1802,8 +1825,10 @@ video { } .focus\:ring-1:focus { - --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); - --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color); + --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) + var(--tw-ring-offset-color); + --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) + var(--tw-ring-color); box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); } @@ -1966,4 +1991,4 @@ video { .lg\:max-w-sm { max-width: 24rem; } -} \ No newline at end of file +} diff --git a/app/types/Icon.ts b/app/types/Icon.ts index d3eaa54..bd0dd07 100644 --- a/app/types/Icon.ts +++ b/app/types/Icon.ts @@ -1,3 +1,5 @@ +import * as React from 'react'; + export type IconProps = { className?: string; }; diff --git a/app/utils/email.utils.ts b/app/utils/email.utils.ts index 6e6f63b..2114f5e 100644 --- a/app/utils/email.utils.ts +++ b/app/utils/email.utils.ts @@ -1 +1,2 @@ +// eslint-disable-next-line no-useless-escape export const isEmail = (email: string) => /[\w\d\.-]+@[\w\d\.-]+\.[\w\d\.-]+/.test(email); diff --git a/app/utils/event.utils.ts b/app/utils/event.utils.ts index f88d52c..0a2c2b6 100644 --- a/app/utils/event.utils.ts +++ b/app/utils/event.utils.ts @@ -5,7 +5,7 @@ import { CalEvent } from '~/utils/interfaces'; // parse event objs from backend to frontend format export const parseEvents = (events: any[]): Array => events?.reduce((acc, event) => { - const { name, startTime, endTime, Attendees, isDeleted, ...remainingEventDetails } = event; + const { name, startTime, endTime, Attendees, ...remainingEventDetails } = event; return [ ...acc, { diff --git a/app/utils/interfaces.ts b/app/utils/interfaces.ts index edc4be7..ae685ca 100644 --- a/app/utils/interfaces.ts +++ b/app/utils/interfaces.ts @@ -16,7 +16,7 @@ export interface CalEvent extends Event { ownerId?: number; calendarId?: number; attendees?: Attendees[]; - onlineEventLink?:string; + onlineEventLink?: string; } export interface CalendarEventProps { diff --git a/package.json b/package.json index 3ebd958..d565377 100644 --- a/package.json +++ b/package.json @@ -16,8 +16,8 @@ "postinstall": "remix setup node", "check-format": "prettier --check .", "format": "prettier --write .", - "check-lint": "eslint .", - "lint": "eslint --fix .", + "check-lint": "eslint ./**/*.{js,ts,tsx,jsx}", + "lint": "eslint --fix ./**/*.{js,ts,tsx,jsx}", "style-lint": "stylelint **/*.css", "start": "remix-serve build", "prepare": "husky install", diff --git a/public/mockServiceWorker.js b/public/mockServiceWorker.js index 87e0f31..14e1d1e 100644 --- a/public/mockServiceWorker.js +++ b/public/mockServiceWorker.js @@ -8,111 +8,111 @@ * - Please do NOT serve this file on production. */ -const INTEGRITY_CHECKSUM = '3d6b9f06410d179a7f7404d4bf4c3c70' -const activeClientIds = new Set() +const INTEGRITY_CHECKSUM = '3d6b9f06410d179a7f7404d4bf4c3c70'; +const activeClientIds = new Set(); self.addEventListener('install', function () { - self.skipWaiting() -}) + self.skipWaiting(); +}); self.addEventListener('activate', function (event) { - event.waitUntil(self.clients.claim()) -}) + event.waitUntil(self.clients.claim()); +}); self.addEventListener('message', async function (event) { - const clientId = event.source.id + const clientId = event.source.id; if (!clientId || !self.clients) { - return + return; } - const client = await self.clients.get(clientId) + const client = await self.clients.get(clientId); if (!client) { - return + return; } const allClients = await self.clients.matchAll({ type: 'window', - }) + }); switch (event.data) { case 'KEEPALIVE_REQUEST': { sendToClient(client, { type: 'KEEPALIVE_RESPONSE', - }) - break + }); + break; } case 'INTEGRITY_CHECK_REQUEST': { sendToClient(client, { type: 'INTEGRITY_CHECK_RESPONSE', payload: INTEGRITY_CHECKSUM, - }) - break + }); + break; } case 'MOCK_ACTIVATE': { - activeClientIds.add(clientId) + activeClientIds.add(clientId); sendToClient(client, { type: 'MOCKING_ENABLED', payload: true, - }) - break + }); + break; } case 'MOCK_DEACTIVATE': { - activeClientIds.delete(clientId) - break + activeClientIds.delete(clientId); + break; } case 'CLIENT_CLOSED': { - activeClientIds.delete(clientId) + activeClientIds.delete(clientId); const remainingClients = allClients.filter((client) => { - return client.id !== clientId - }) + return client.id !== clientId; + }); // Unregister itself when there are no more clients if (remainingClients.length === 0) { - self.registration.unregister() + self.registration.unregister(); } - break + break; } } -}) +}); self.addEventListener('fetch', function (event) { - const { request } = event - const accept = request.headers.get('accept') || '' + const { request } = event; + const accept = request.headers.get('accept') || ''; // Bypass server-sent events. if (accept.includes('text/event-stream')) { - return + return; } // Bypass navigation requests. if (request.mode === 'navigate') { - return + return; } // Opening the DevTools triggers the "only-if-cached" request // that cannot be handled by the worker. Bypass such requests. if (request.cache === 'only-if-cached' && request.mode !== 'same-origin') { - return + return; } // Bypass all requests when there are no active clients. // Prevents the self-unregistered worked from handling requests // after it's been deleted (still remains active until the next reload). if (activeClientIds.size === 0) { - return + return; } // Generate unique request ID. - const requestId = Math.random().toString(16).slice(2) + const requestId = Math.random().toString(16).slice(2); event.respondWith( handleRequest(event, requestId).catch((error) => { @@ -121,8 +121,8 @@ self.addEventListener('fetch', function (event) { '[MSW] Successfully emulated a network error for the "%s %s" request.', request.method, request.url, - ) - return + ); + return; } // At this point, any exception indicates an issue with the original request/response. @@ -132,21 +132,21 @@ self.addEventListener('fetch', function (event) { request.method, request.url, `${error.name}: ${error.message}`, - ) + ); }), - ) -}) + ); +}); async function handleRequest(event, requestId) { - const client = await resolveMainClient(event) - const response = await getResponse(event, client, requestId) + const client = await resolveMainClient(event); + const response = await getResponse(event, client, requestId); // Send back the response clone for the "response:*" life-cycle events. // Ensure MSW is active and ready to handle the message, otherwise // this message will pend indefinitely. if (client && activeClientIds.has(client.id)) { - ;(async function () { - const clonedResponse = response.clone() + (async function () { + const clonedResponse = response.clone(); sendToClient(client, { type: 'RESPONSE', payload: { @@ -155,16 +155,15 @@ async function handleRequest(event, requestId) { ok: clonedResponse.ok, status: clonedResponse.status, statusText: clonedResponse.statusText, - body: - clonedResponse.body === null ? null : await clonedResponse.text(), + body: clonedResponse.body === null ? null : await clonedResponse.text(), headers: Object.fromEntries(clonedResponse.headers.entries()), redirected: clonedResponse.redirected, }, - }) - })() + }); + })(); } - return response + return response; } // Resolve the main client for the given event. @@ -172,49 +171,49 @@ async function handleRequest(event, requestId) { // that registered the worker. It's with the latter the worker should // communicate with during the response resolving phase. async function resolveMainClient(event) { - const client = await self.clients.get(event.clientId) + const client = await self.clients.get(event.clientId); if (client?.frameType === 'top-level') { - return client + return client; } const allClients = await self.clients.matchAll({ type: 'window', - }) + }); return allClients .filter((client) => { // Get only those clients that are currently visible. - return client.visibilityState === 'visible' + return client.visibilityState === 'visible'; }) .find((client) => { // Find the client ID that's recorded in the // set of clients that have registered the worker. - return activeClientIds.has(client.id) - }) + return activeClientIds.has(client.id); + }); } async function getResponse(event, client, requestId) { - const { request } = event - const clonedRequest = request.clone() + const { request } = event; + const clonedRequest = request.clone(); function passthrough() { // Clone the request because it might've been already used // (i.e. its body has been read and sent to the client). - const headers = Object.fromEntries(clonedRequest.headers.entries()) + const headers = Object.fromEntries(clonedRequest.headers.entries()); // Remove MSW-specific request headers so the bypassed requests // comply with the server's CORS preflight check. // Operate with the headers as an object because request "Headers" // are immutable. - delete headers['x-msw-bypass'] + delete headers['x-msw-bypass']; - return fetch(clonedRequest, { headers }) + return fetch(clonedRequest, { headers }); } // Bypass mocking when the client is not active. if (!client) { - return passthrough() + return passthrough(); } // Bypass initial page load requests (i.e. static assets). @@ -222,13 +221,13 @@ async function getResponse(event, client, requestId) { // means that MSW hasn't dispatched the "MOCK_ACTIVATE" event yet // and is not ready to handle requests. if (!activeClientIds.has(client.id)) { - return passthrough() + return passthrough(); } // Bypass requests with the explicit bypass header. // Such requests can be issued by "ctx.fetch()". if (request.headers.get('x-msw-bypass') === 'true') { - return passthrough() + return passthrough(); } // Notify the client that a request has been intercepted. @@ -251,53 +250,53 @@ async function getResponse(event, client, requestId) { bodyUsed: request.bodyUsed, keepalive: request.keepalive, }, - }) + }); switch (clientMessage.type) { case 'MOCK_RESPONSE': { - return respondWithMock(clientMessage.data) + return respondWithMock(clientMessage.data); } case 'MOCK_NOT_FOUND': { - return passthrough() + return passthrough(); } case 'NETWORK_ERROR': { - const { name, message } = clientMessage.data - const networkError = new Error(message) - networkError.name = name + const { name, message } = clientMessage.data; + const networkError = new Error(message); + networkError.name = name; // Rejecting a "respondWith" promise emulates a network error. - throw networkError + throw networkError; } } - return passthrough() + return passthrough(); } function sendToClient(client, message) { return new Promise((resolve, reject) => { - const channel = new MessageChannel() + const channel = new MessageChannel(); channel.port1.onmessage = (event) => { if (event.data && event.data.error) { - return reject(event.data.error) + return reject(event.data.error); } - resolve(event.data) - } + resolve(event.data); + }; - client.postMessage(message, [channel.port2]) - }) + client.postMessage(message, [channel.port2]); + }); } function sleep(timeMs) { return new Promise((resolve) => { - setTimeout(resolve, timeMs) - }) + setTimeout(resolve, timeMs); + }); } async function respondWithMock(response) { - await sleep(response.delay) - return new Response(response.body, response) + await sleep(response.delay); + return new Response(response.body, response); } diff --git a/yarn.lock b/yarn.lock old mode 100644 new mode 100755