diff --git a/public/locales/en/translation.json b/public/locales/en/translation.json index 57b4c5de98..5f6d319588 100644 --- a/public/locales/en/translation.json +++ b/public/locales/en/translation.json @@ -1405,6 +1405,9 @@ "userPledges": { "title": "My Pledges" }, + "leaveOrganization": { + "title": "Leave Organization" + }, "eventVolunteers": { "volunteers": "Volunteers", "volunteer": "Volunteer", diff --git a/public/locales/fr/translation.json b/public/locales/fr/translation.json index d089aefeb5..8dc5fa888a 100644 --- a/public/locales/fr/translation.json +++ b/public/locales/fr/translation.json @@ -1405,6 +1405,9 @@ "userPledges": { "title": "Mes Promesses" }, + "leaveOrganization": { + "title": "Quitter l'organisation" + }, "eventVolunteers": { "volunteers": "Bénévoles", "volunteer": "Bénévole", diff --git a/public/locales/hi/translation.json b/public/locales/hi/translation.json index 2645340b23..2865e72e1f 100644 --- a/public/locales/hi/translation.json +++ b/public/locales/hi/translation.json @@ -1405,6 +1405,9 @@ "userPledges": { "title": "मेरी प्रतिज्ञाएँ" }, + "leaveOrganization": { + "title": "संगठन छोड़ें" + }, "eventVolunteers": { "volunteers": "स्वयंसेवक", "volunteer": "स्वयंसेवक", diff --git a/public/locales/sp/translation.json b/public/locales/sp/translation.json index 7aa1d6ffc0..da91efb41d 100644 --- a/public/locales/sp/translation.json +++ b/public/locales/sp/translation.json @@ -1407,6 +1407,9 @@ "userPledges": { "title": "Mis Promesas" }, + "leaveOrganization": { + "title": "Dejar la organización" + }, "eventVolunteers": { "volunteers": "Voluntarios", "volunteer": "Voluntario", diff --git a/public/locales/zh/translation.json b/public/locales/zh/translation.json index adafbdbe45..5fbbf4b870 100644 --- a/public/locales/zh/translation.json +++ b/public/locales/zh/translation.json @@ -1405,6 +1405,9 @@ "userPledges": { "title": "我的承诺" }, + "leaveOrganization": { + "title": "离开组织" + }, "eventVolunteers": { "volunteers": "志愿者", "volunteer": "志愿者", diff --git a/src/App.tsx b/src/App.tsx index 37f3bc301e..4d2ca76010 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -50,6 +50,7 @@ import EventDashboardScreen from 'components/EventDashboardScreen/EventDashboard import Campaigns from 'screens/UserPortal/Campaigns/Campaigns'; import Pledges from 'screens/UserPortal/Pledges/Pledges'; import VolunteerManagement from 'screens/UserPortal/Volunteer/VolunteerManagement'; +import LeaveOrganization from 'screens/UserPortal/LeaveOrganization/LeaveOrganization'; const { setItem } = useLocalStorage(); @@ -198,6 +199,10 @@ function app(): JSX.Element { } /> } /> } /> + } + /> } diff --git a/src/components/AddOn/support/components/MainContent/MainContent.test.tsx b/src/components/AddOn/support/components/MainContent/MainContent.spec.tsx similarity index 70% rename from src/components/AddOn/support/components/MainContent/MainContent.test.tsx rename to src/components/AddOn/support/components/MainContent/MainContent.spec.tsx index 81adbc916e..90988e8d2b 100644 --- a/src/components/AddOn/support/components/MainContent/MainContent.test.tsx +++ b/src/components/AddOn/support/components/MainContent/MainContent.spec.tsx @@ -1,5 +1,6 @@ import React from 'react'; import { render } from '@testing-library/react'; +import { describe, it, expect } from 'vitest'; import { Provider } from 'react-redux'; import { BrowserRouter } from 'react-router-dom'; @@ -11,7 +12,7 @@ describe('Testing MainContent component', () => { children: 'This is a dummy text', }; - test('should render props and children for the Main Content', () => { + it('should render props and children for the Main Content', () => { const { getByTestId, getByText } = render( @@ -20,7 +21,7 @@ describe('Testing MainContent component', () => { , ); - expect(getByTestId('mainContentCheck')).toBeInTheDocument(); - expect(getByText(props.children)).toBeInTheDocument(); + expect(getByTestId('mainContentCheck')).not.toBeNull(); + expect(getByText(props.children)).not.toBeNull(); }); }); diff --git a/src/components/AddOn/support/services/Plugin.helper.test.ts b/src/components/AddOn/support/services/Plugin.helper.spec.ts similarity index 65% rename from src/components/AddOn/support/services/Plugin.helper.test.ts rename to src/components/AddOn/support/services/Plugin.helper.spec.ts index 39f0a5d12c..51c8ec4bc5 100644 --- a/src/components/AddOn/support/services/Plugin.helper.test.ts +++ b/src/components/AddOn/support/services/Plugin.helper.spec.ts @@ -1,14 +1,27 @@ import PluginHelper from './Plugin.helper'; +import { vi } from 'vitest'; + +/** + * This file contains unit tests for the PluginHelper component. + * + * The tests cover: + * - Verification that the class contains the required method definitions. + * - Correct functionality of the `generateLinks` method, including returning proper objects. + * - Proper behavior of the `fetchStore` method, including handling of mocked JSON responses. + * - Functionality of the `fetchInstalled` method, verifying it returns the expected JSON data. + * + * These tests use Vitest for test execution and mock the global `fetch` function for asynchronous tests. + */ describe('Testing src/components/AddOn/support/services/Plugin.helper.ts', () => { - test('Class should contain the required method definitions', () => { + it('Class should contain the required method definitions', () => { const pluginHelper = new PluginHelper(); expect(pluginHelper).toHaveProperty('fetchStore'); expect(pluginHelper).toHaveProperty('fetchInstalled'); expect(pluginHelper).toHaveProperty('generateLinks'); expect(pluginHelper).toHaveProperty('generateLinks'); }); - test('generateLinks should return proper objects', () => { + it('generateLinks should return proper objects', () => { const obj = { enabled: true, name: 'demo', @@ -28,9 +41,9 @@ describe('Testing src/components/AddOn/support/services/Plugin.helper.ts', () => }); it('fetchStore should return expected JSON', async () => { const helper = new PluginHelper(); - const spy = jest.spyOn(global, 'fetch').mockImplementation(() => { + const spy = vi.spyOn(global, 'fetch').mockImplementation(() => { const response = new Response(); - response.json = jest + response.json = vi .fn() .mockReturnValue(Promise.resolve({ data: 'mock data' })); return Promise.resolve(response); @@ -46,11 +59,11 @@ describe('Testing src/components/AddOn/support/services/Plugin.helper.ts', () => { name: 'plugin1', component: 'Component1', enabled: true }, { name: 'plugin2', component: 'Component2', enabled: false }, ]; - jest.spyOn(global, 'fetch').mockImplementation(() => { + vi.spyOn(global, 'fetch').mockImplementation(() => { const response = new Response(); - response.json = jest.fn().mockReturnValue(Promise.resolve(mockResponse)); + response.json = vi.fn().mockReturnValue(Promise.resolve(mockResponse)); return Promise.resolve(response); - }) as jest.Mock; + }); const result = await pluginHelper.fetchInstalled(); expect(result).toEqual(mockResponse); }); diff --git a/src/components/Advertisements/Advertisements.test.tsx b/src/components/Advertisements/Advertisements.spec.tsx similarity index 96% rename from src/components/Advertisements/Advertisements.test.tsx rename to src/components/Advertisements/Advertisements.spec.tsx index 88bbb1255c..1e2d92b392 100644 --- a/src/components/Advertisements/Advertisements.test.tsx +++ b/src/components/Advertisements/Advertisements.spec.tsx @@ -1,4 +1,6 @@ import React, { act } from 'react'; +import { describe, test, expect, vi } from 'vitest'; + import { ApolloClient, ApolloLink, @@ -7,25 +9,28 @@ import { InMemoryCache, } from '@apollo/client'; import { MockedProvider } from '@apollo/client/testing'; + import { fireEvent, render, screen } from '@testing-library/react'; -import 'jest-location-mock'; import type { DocumentNode, NormalizedCacheObject } from '@apollo/client'; import userEvent from '@testing-library/user-event'; import { BACKEND_URL } from 'Constant/constant'; -import { ADD_ADVERTISEMENT_MUTATION } from 'GraphQl/Mutations/mutations'; + +import { ADD_ADVERTISEMENT_MUTATION } from '../../GraphQl/Mutations/mutations'; import { ORGANIZATIONS_LIST, ORGANIZATION_ADVERTISEMENT_LIST, PLUGIN_GET, -} from 'GraphQl/Queries/Queries'; +} from '../../GraphQl/Queries/Queries'; + import { I18nextProvider } from 'react-i18next'; + import { Provider } from 'react-redux'; import { BrowserRouter } from 'react-router-dom'; import { ToastContainer } from 'react-toastify'; -import { store } from 'state/store'; -import i18nForTest from 'utils/i18nForTest'; -import useLocalStorage from 'utils/useLocalstorage'; +import { store } from '../../state/store'; +import i18nForTest from '../../utils/i18nForTest'; +import useLocalStorage from '../../utils/useLocalstorage'; import Advertisement from './Advertisements'; const { getItem } = useLocalStorage(); @@ -50,18 +55,22 @@ const client: ApolloClient = new ApolloClient({ link: ApolloLink.from([httpLink]), }); -jest.mock('components/AddOn/support/services/Plugin.helper', () => ({ +vi.mock('components/AddOn/support/services/Plugin.helper', () => ({ __esModule: true, - default: jest.fn().mockImplementation(() => ({ - fetchInstalled: jest.fn().mockResolvedValue([]), - fetchStore: jest.fn().mockResolvedValue([]), + default: vi.fn().mockImplementation(() => ({ + fetchInstalled: vi.fn().mockResolvedValue([]), + fetchStore: vi.fn().mockResolvedValue([]), })), })); let mockID: string | undefined = '1'; -jest.mock('react-router-dom', () => ({ - ...jest.requireActual('react-router-dom'), - useParams: () => ({ orgId: mockID }), -})); + +vi.mock('react-router-dom', async () => { + const actual = await vi.importActual('react-router-dom'); + return { + ...actual, + useParams: () => ({ orgId: mockID }), + }; +}); const today = new Date(); const tomorrow = today; @@ -466,18 +475,16 @@ describe('Testing Advertisement Component', () => { /\b(?:Sun|Mon|Tue|Wed|Thu|Fri|Sat)\s+(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+(\d{1,2})\s+(\d{4})\b/, ); let dateObject = new Date(); - if (dateMatch) { const monthName = dateMatch[1]; const day = parseInt(dateMatch[2], 10); const year = parseInt(dateMatch[3], 10); - const monthIndex = 'JanFebMarAprMayJunJulAugSepOctNovDec'.indexOf(monthName) / 3; dateObject = new Date(year, monthIndex, day); } - + console.log(dateObject); expect(dateObject.getTime()).toBeLessThan(new Date().getTime()); }); diff --git a/src/components/AgendaItems/AgendaItemsCreateModal.test.tsx b/src/components/AgendaItems/AgendaItemsCreateModal.spec.tsx similarity index 96% rename from src/components/AgendaItems/AgendaItemsCreateModal.test.tsx rename to src/components/AgendaItems/AgendaItemsCreateModal.spec.tsx index 5b7339ad67..35ea8c7681 100644 --- a/src/components/AgendaItems/AgendaItemsCreateModal.test.tsx +++ b/src/components/AgendaItems/AgendaItemsCreateModal.spec.tsx @@ -19,6 +19,8 @@ import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import AgendaItemsCreateModal from './AgendaItemsCreateModal'; import { toast } from 'react-toastify'; import convertToBase64 from 'utils/convertToBase64'; +import type { MockedFunction } from 'vitest'; +import { describe, test, expect, vi } from 'vitest'; const mockFormState = { title: 'Test Title', @@ -28,9 +30,9 @@ const mockFormState = { urls: ['https://example.com'], agendaItemCategoryIds: ['category'], }; -const mockHideCreateModal = jest.fn(); -const mockSetFormState = jest.fn(); -const mockCreateAgendaItemHandler = jest.fn(); +const mockHideCreateModal = vi.fn(); +const mockSetFormState = vi.fn(); +const mockCreateAgendaItemHandler = vi.fn(); const mockT = (key: string): string => key; const mockAgendaItemCategories = [ { @@ -64,14 +66,14 @@ const mockAgendaItemCategories = [ }, }, ]; -jest.mock('react-toastify', () => ({ +vi.mock('react-toastify', () => ({ toast: { - success: jest.fn(), - error: jest.fn(), + success: vi.fn(), + error: vi.fn(), }, })); -jest.mock('utils/convertToBase64'); -const mockedConvertToBase64 = convertToBase64 as jest.MockedFunction< +vi.mock('utils/convertToBase64'); +const mockedConvertToBase64 = convertToBase64 as MockedFunction< typeof convertToBase64 >; diff --git a/src/components/CheckIn/TableRow.test.tsx b/src/components/CheckIn/TableRow.spec.tsx similarity index 91% rename from src/components/CheckIn/TableRow.test.tsx rename to src/components/CheckIn/TableRow.spec.tsx index 1a08f40a3d..4e11302fe7 100644 --- a/src/components/CheckIn/TableRow.test.tsx +++ b/src/components/CheckIn/TableRow.spec.tsx @@ -11,10 +11,15 @@ import { LocalizationProvider } from '@mui/x-date-pickers'; import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs'; import { MockedProvider } from '@apollo/react-testing'; import { checkInMutationSuccess, checkInMutationUnsuccess } from './mocks'; +import { vi } from 'vitest'; + +/** + * Test suite for the `TableRow` component, focusing on the CheckIn table functionality. + */ describe('Testing Table Row for CheckIn Table', () => { beforeEach(() => { - jest.clearAllMocks(); + vi.clearAllMocks(); }); test('If the user is not checked in, button to check in should be displayed, and the user should be able to check in successfully', async () => { @@ -26,7 +31,7 @@ describe('Testing Table Row for CheckIn Table', () => { checkIn: null, eventId: `event123`, }, - refetch: jest.fn(), + refetch: vi.fn(), }; const { findByText } = render( @@ -63,7 +68,7 @@ describe('Testing Table Row for CheckIn Table', () => { }, eventId: 'event123', }, - refetch: jest.fn(), + refetch: vi.fn(), }; const { findByText } = render( @@ -81,8 +86,8 @@ describe('Testing Table Row for CheckIn Table', () => { , ); - global.URL.createObjectURL = jest.fn(() => 'mockURL'); - global.window.open = jest.fn(); + global.URL.createObjectURL = vi.fn(() => 'mockURL'); + global.window.open = vi.fn(); expect(await findByText('Checked In')).toBeInTheDocument(); expect(await findByText('Download Tag')).toBeInTheDocument(); @@ -93,7 +98,7 @@ describe('Testing Table Row for CheckIn Table', () => { expect(await findByText('PDF generated successfully!')).toBeInTheDocument(); // Cleanup mocks - jest.clearAllMocks(); + vi.clearAllMocks(); }); test('Upon failing of check in mutation, the appropriate error message should be shown', async () => { @@ -105,7 +110,7 @@ describe('Testing Table Row for CheckIn Table', () => { checkIn: null, eventId: `event123`, }, - refetch: jest.fn(), + refetch: vi.fn(), }; const { findByText } = render( @@ -143,7 +148,7 @@ describe('Testing Table Row for CheckIn Table', () => { }, eventId: `event123`, }, - refetch: jest.fn(), + refetch: vi.fn(), }; const { findByText } = render( @@ -162,8 +167,8 @@ describe('Testing Table Row for CheckIn Table', () => { ); // Mocking the PDF generation function to throw an error - global.URL.createObjectURL = jest.fn(() => 'mockURL'); - global.window.open = jest.fn(); + global.URL.createObjectURL = vi.fn(() => 'mockURL'); + global.window.open = vi.fn(); fireEvent.click(await findByText('Download Tag')); diff --git a/src/components/DynamicDropDown/DynamicDropDown.test.tsx b/src/components/DynamicDropDown/DynamicDropDown.spec.tsx similarity index 91% rename from src/components/DynamicDropDown/DynamicDropDown.test.tsx rename to src/components/DynamicDropDown/DynamicDropDown.spec.tsx index dac98ca9e6..85c3208a20 100644 --- a/src/components/DynamicDropDown/DynamicDropDown.test.tsx +++ b/src/components/DynamicDropDown/DynamicDropDown.spec.tsx @@ -11,11 +11,12 @@ import { BrowserRouter } from 'react-router-dom'; import { I18nextProvider } from 'react-i18next'; import i18nForTest from 'utils/i18nForTest'; import userEvent from '@testing-library/user-event'; +import { vi, expect, it } from 'vitest'; describe('DynamicDropDown component', () => { - test('renders and handles selection correctly', async () => { + it('renders and handles selection correctly', async () => { const formData = { fieldName: 'value2' }; - const setFormData = jest.fn(); + const setFormData = vi.fn(); render( @@ -60,10 +61,10 @@ describe('DynamicDropDown component', () => { expect(dropdownButton).toHaveTextContent('Label 2'); }); }); - test('calls custom handleChange function when provided', async () => { + it('calls custom handleChange function when provided', async () => { const formData = { fieldName: 'value1' }; - const setFormData = jest.fn(); - const customHandleChange = jest.fn(); + const setFormData = vi.fn(); + const customHandleChange = vi.fn(); render( @@ -103,9 +104,9 @@ describe('DynamicDropDown component', () => { ); expect(setFormData).not.toHaveBeenCalled(); }); - test('handles keyboard navigation correctly', async () => { + it('handles keyboard navigation correctly', async () => { const formData = { fieldName: 'value1' }; - const setFormData = jest.fn(); + const setFormData = vi.fn(); render( diff --git a/src/components/EventManagement/Dashboard/EventDashboard.module.css b/src/components/EventManagement/Dashboard/EventDashboard.module.css deleted file mode 100644 index 37336002bb..0000000000 --- a/src/components/EventManagement/Dashboard/EventDashboard.module.css +++ /dev/null @@ -1,101 +0,0 @@ -.eventContainer { - display: flex; - align-items: start; -} - -.eventDetailsBox { - position: relative; - box-sizing: border-box; - background: #ffffff; - width: 66%; - padding: 0.3rem; - box-shadow: 0 3px 8px rgba(0, 0, 0, 0.1); - border-radius: 20px; - margin-bottom: 0; - margin-top: 20px; -} -.ctacards { - padding: 20px; - width: 100%; - display: flex; - background-color: #ffffff; - margin: 0 4px; - justify-content: space-between; - box-shadow: 0 3px 8px rgba(0, 0, 0, 0.1); - align-items: center; - border-radius: 20px; -} -.ctacards span { - color: rgb(181, 181, 181); - font-size: small; -} -/* .eventDetailsBox::before { - content: ''; - position: absolute; - top: 0; - height: 100%; - width: 6px; - background-color: #31bb6b; - border-radius: 20px; -} */ - -.time { - display: flex; - justify-content: space-between; - padding: 15px; - padding-bottom: 0px; - width: 33%; - - box-sizing: border-box; - background: #ffffff; - box-shadow: 0 3px 8px rgba(0, 0, 0, 0.1); - border-radius: 20px; - margin-bottom: 0; - margin-top: 20px; - margin-left: 10px; -} - -.startTime, -.endTime { - display: flex; - font-size: 20px; -} - -.to { - padding-right: 10px; -} - -.startDate, -.endDate { - color: #808080; - font-size: 14px; -} - -.titlename { - font-weight: 600; - font-size: 25px; - padding: 15px; - padding-bottom: 0px; - width: 50%; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - -.description { - color: #737373; - font-weight: 300; - font-size: 14px; - word-wrap: break-word; - padding: 15px; - padding-bottom: 0px; -} - -.toporgloc { - font-size: 16px; - padding: 0.5rem; -} - -.toporgloc span { - color: #737373; -} diff --git a/src/components/EventManagement/Dashboard/EventDashboard.tsx b/src/components/EventManagement/Dashboard/EventDashboard.tsx index d3552702c6..1995a640c9 100644 --- a/src/components/EventManagement/Dashboard/EventDashboard.tsx +++ b/src/components/EventManagement/Dashboard/EventDashboard.tsx @@ -1,6 +1,6 @@ import React, { useState } from 'react'; import { Col, Row } from 'react-bootstrap'; -import styles from './EventDashboard.module.css'; +import styles from '../../../style/app.module.css'; import { useTranslation } from 'react-i18next'; import { EVENT_DETAILS } from 'GraphQl/Queries/Queries'; import { useQuery } from '@apollo/client'; diff --git a/src/components/EventManagement/EventAgendaItems/EventAgendaItems.module.css b/src/components/EventManagement/EventAgendaItems/EventAgendaItems.module.css deleted file mode 100644 index 9d1c32b766..0000000000 --- a/src/components/EventManagement/EventAgendaItems/EventAgendaItems.module.css +++ /dev/null @@ -1,22 +0,0 @@ -.eventAgendaItemContainer h2 { - margin: 0.6rem 0; -} - -.btnsContainer { - display: flex; - gap: 10px; -} - -@media (max-width: 768px) { - .btnsContainer { - margin-bottom: 0; - display: flex; - flex-direction: column; - } - - .createAgendaItemButton { - position: absolute; - top: 1rem; - right: 2rem; - } -} diff --git a/src/components/EventManagement/EventAgendaItems/EventAgendaItems.tsx b/src/components/EventManagement/EventAgendaItems/EventAgendaItems.tsx index b49ade4626..9b758a555a 100644 --- a/src/components/EventManagement/EventAgendaItems/EventAgendaItems.tsx +++ b/src/components/EventManagement/EventAgendaItems/EventAgendaItems.tsx @@ -20,7 +20,7 @@ import type { import AgendaItemsContainer from 'components/AgendaItems/AgendaItemsContainer'; import AgendaItemsCreateModal from 'components/AgendaItems/AgendaItemsCreateModal'; -import styles from './EventAgendaItems.module.css'; +import styles from '../../../style/app.module.css'; import Loader from 'components/Loader/Loader'; /** diff --git a/src/components/EventManagement/EventAttendance/EventAttendance.tsx b/src/components/EventManagement/EventAttendance/EventAttendance.tsx index 17f063f6b5..06b047a973 100644 --- a/src/components/EventManagement/EventAttendance/EventAttendance.tsx +++ b/src/components/EventManagement/EventAttendance/EventAttendance.tsx @@ -16,7 +16,7 @@ import { Table, FormControl, } from 'react-bootstrap'; -import styles from './EventsAttendance.module.css'; +import styles from '../../../style/app.module.css'; import { useLazyQuery } from '@apollo/client'; import { EVENT_ATTENDEES } from 'GraphQl/Queries/Queries'; import { useParams, Link } from 'react-router-dom'; diff --git a/src/components/EventManagement/EventAttendance/EventsAttendance.module.css b/src/components/EventManagement/EventAttendance/EventsAttendance.module.css deleted file mode 100644 index 2ee236a4da..0000000000 --- a/src/components/EventManagement/EventAttendance/EventsAttendance.module.css +++ /dev/null @@ -1,35 +0,0 @@ -.input { - display: flex; - width: 100%; - position: relative; -} -.customcell { - background-color: #31bb6b !important; - color: white !important; - font-size: medium !important; - font-weight: 500 !important; - padding-top: 10px !important; - padding-bottom: 10px !important; -} - -.eventsAttended, -.membername { - color: blue; -} -.actionBtn { - /* color:#39a440 !important; */ - background-color: #ffffff !important; -} -.actionBtn:hover, -.actionBtn:focus, -.actionBtn:active { - color: #39a440 !important; -} - -.table-body > .table-row { - background-color: #fff !important; -} - -.table-body > .table-row:nth-child(2n) { - background: #afffe8 !important; -} diff --git a/src/components/IconComponent/IconComponent.tsx b/src/components/IconComponent/IconComponent.tsx index 8430aca131..dd104c0408 100644 --- a/src/components/IconComponent/IconComponent.tsx +++ b/src/components/IconComponent/IconComponent.tsx @@ -19,6 +19,7 @@ import PostsIcon from 'assets/svgs/posts.svg?react'; import SettingsIcon from 'assets/svgs/settings.svg?react'; import VenueIcon from 'assets/svgs/venues.svg?react'; import RequestsIcon from 'assets/svgs/requests.svg?react'; +import ExitToAppIcon from '@mui/icons-material/ExitToApp'; import { MdOutlineVolunteerActivism } from 'react-icons/md'; import React from 'react'; @@ -134,6 +135,13 @@ const iconComponent = (props: InterfaceIconComponent): JSX.Element => { stroke={props.fill} /> ); + case 'Leave Organization': + return ( + + ); case 'Volunteer': return ( { - test('should render props and text elements test for the page component', () => { + it('should render props and text elements test for the page component', () => { const props = { id: '123', image: 'https://via.placeholder.com/80', @@ -20,7 +30,7 @@ describe('Testing the Organization Card', () => { expect(screen.getByText(props.lastName)).toBeInTheDocument(); }); - test('Should render text elements when props value is not passed', () => { + it('Should render text elements when props value is not passed', () => { const props = { id: '123', image: '', diff --git a/src/screens/CommunityProfile/CommunityProfile.module.css b/src/screens/CommunityProfile/CommunityProfile.module.css deleted file mode 100644 index 1e6eac2bae..0000000000 --- a/src/screens/CommunityProfile/CommunityProfile.module.css +++ /dev/null @@ -1,41 +0,0 @@ -.card { - width: fit-content; -} - -.cardHeader { - padding: 1.25rem 1rem 1rem 1rem; - border-bottom: 1px solid var(--bs-gray-200); - display: flex; - justify-content: space-between; - align-items: center; -} - -.cardHeader .cardTitle { - font-size: 1.5rem; -} - -.formLabel { - font-weight: normal; - padding-bottom: 0; - font-size: 1rem; - color: black; -} -.cardBody { - min-height: 180px; -} - -.cardBody .textBox { - margin: 0 0 3rem 0; - color: var(--bs-secondary); -} - -.socialInput { - height: 2.5rem; -} - -@media (max-width: 520px) { - .btn { - flex-direction: column; - justify-content: center; - } -} diff --git a/src/screens/CommunityProfile/CommunityProfile.tsx b/src/screens/CommunityProfile/CommunityProfile.tsx index d96c923eb3..05f328ced0 100644 --- a/src/screens/CommunityProfile/CommunityProfile.tsx +++ b/src/screens/CommunityProfile/CommunityProfile.tsx @@ -18,7 +18,7 @@ import { SlackLogo, } from 'assets/svgs/social-icons'; import convertToBase64 from 'utils/convertToBase64'; -import styles from './CommunityProfile.module.css'; +import styles from '../../style/app.module.css'; import { errorHandler } from 'utils/errorHandler'; import UpdateSession from '../../components/UpdateSession/UpdateSession'; @@ -90,7 +90,7 @@ const CommunityProfile = (): JSX.Element => { React.useEffect(() => { const preLoginData: PreLoginImageryDataType | undefined = data?.getCommunityData; - preLoginData && + if (preLoginData) { setProfileVariable({ name: preLoginData.name ?? '', websiteLink: preLoginData.websiteLink ?? '', @@ -104,6 +104,7 @@ const CommunityProfile = (): JSX.Element => { reddit: preLoginData.socialMediaUrls.reddit ?? '', slack: preLoginData.socialMediaUrls.slack ?? '', }); + } }, [data]); /** diff --git a/src/screens/Leaderboard/Leaderboard.tsx b/src/screens/Leaderboard/Leaderboard.tsx index c5ad7a2efe..e0ea513e9c 100644 --- a/src/screens/Leaderboard/Leaderboard.tsx +++ b/src/screens/Leaderboard/Leaderboard.tsx @@ -14,7 +14,7 @@ import silver from 'assets/images/silver.png'; import bronze from 'assets/images/bronze.png'; import type { InterfaceVolunteerRank } from 'utils/interfaces'; -import styles from '../OrganizationActionItems/OrganizationActionItems.module.css'; +import styles from '../../style/app.module.css'; import Loader from 'components/Loader/Loader'; import { DataGrid, @@ -200,7 +200,7 @@ function leaderboard(): JSX.Element { diff --git a/src/screens/ManageTag/ManageTag.test.tsx b/src/screens/ManageTag/ManageTag.spec.tsx similarity index 87% rename from src/screens/ManageTag/ManageTag.test.tsx rename to src/screens/ManageTag/ManageTag.spec.tsx index 598a15cc9a..5d86ed3c17 100644 --- a/src/screens/ManageTag/ManageTag.test.tsx +++ b/src/screens/ManageTag/ManageTag.spec.tsx @@ -11,7 +11,6 @@ import { waitForElementToBeRemoved, } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import 'jest-location-mock'; import { I18nextProvider } from 'react-i18next'; import { Provider } from 'react-redux'; import { MemoryRouter, Route, Routes } from 'react-router-dom'; @@ -22,6 +21,7 @@ import i18n from 'utils/i18nForTest'; import ManageTag from './ManageTag'; import { MOCKS, MOCKS_ERROR_ASSIGNED_MEMBERS } from './ManageTagMocks'; import { type ApolloLink } from '@apollo/client'; +import { vi, beforeEach, afterEach, expect, it } from 'vitest'; const translations = { ...JSON.parse( @@ -42,21 +42,21 @@ async function wait(ms = 500): Promise { }); } -jest.mock('react-toastify', () => ({ +vi.mock('react-toastify', () => ({ toast: { - success: jest.fn(), - info: jest.fn(), - error: jest.fn(), + success: vi.fn(), + info: vi.fn(), + error: vi.fn(), }, })); /* eslint-disable @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports */ -jest.mock('../../components/AddPeopleToTag/AddPeopleToTag', () => { - return require('./ManageTagMockComponents/MockAddPeopleToTag').default; +vi.mock('../../components/AddPeopleToTag/AddPeopleToTag', async () => { + return await import('./ManageTagMockComponents/MockAddPeopleToTag'); }); -jest.mock('../../components/TagActions/TagActions', () => { - return require('./ManageTagMockComponents/MockTagActions').default; +vi.mock('../../components/TagActions/TagActions', async () => { + return await import('./ManageTagMockComponents/MockTagActions'); }); /* eslint-enable @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports */ @@ -93,18 +93,17 @@ const renderManageTag = (link: ApolloLink): RenderResult => { describe('Manage Tag Page', () => { beforeEach(() => { - jest.mock('react-router-dom', () => ({ - ...jest.requireActual('react-router-dom'), - useParams: () => ({ orgId: 'orgId' }), + vi.mock('react-router-dom', async () => ({ + ...(await vi.importActual('react-router-dom')), })); }); afterEach(() => { - jest.clearAllMocks(); + vi.clearAllMocks(); cleanup(); }); - test('Component loads correctly', async () => { + it('Component loads correctly', async () => { const { getByText } = renderManageTag(link); await wait(); @@ -114,7 +113,7 @@ describe('Manage Tag Page', () => { }); }); - test('renders error component on unsuccessful userTag assigned members query', async () => { + it('renders error component on unsuccessful userTag assigned members query', async () => { const { queryByText } = renderManageTag(link2); await wait(); @@ -124,7 +123,7 @@ describe('Manage Tag Page', () => { }); }); - test('opens and closes the add people to tag modal', async () => { + it('opens and closes the add people to tag modal', async () => { renderManageTag(link); await waitFor(() => { @@ -146,7 +145,7 @@ describe('Manage Tag Page', () => { }); }); - test('opens and closes the unassign tag modal', async () => { + it('opens and closes the unassign tag modal', async () => { renderManageTag(link); await wait(); @@ -168,7 +167,7 @@ describe('Manage Tag Page', () => { ); }); - test('opens and closes the assignToTags modal', async () => { + it('opens and closes the assignToTags modal', async () => { renderManageTag(link); // Wait for the assignToTags button to be present @@ -193,7 +192,7 @@ describe('Manage Tag Page', () => { }); }); - test('opens and closes the removeFromTags modal', async () => { + it('opens and closes the removeFromTags modal', async () => { renderManageTag(link); // Wait for the removeFromTags button to be present @@ -218,7 +217,7 @@ describe('Manage Tag Page', () => { }); }); - test('opens and closes the edit tag modal', async () => { + it('opens and closes the edit tag modal', async () => { renderManageTag(link); await wait(); @@ -240,7 +239,7 @@ describe('Manage Tag Page', () => { ); }); - test('opens and closes the remove tag modal', async () => { + it('opens and closes the remove tag modal', async () => { renderManageTag(link); await wait(); @@ -262,7 +261,7 @@ describe('Manage Tag Page', () => { ); }); - test("navigates to the member's profile after clicking the view option", async () => { + it("navigates to the member's profile after clicking the view option", async () => { renderManageTag(link); await wait(); @@ -277,7 +276,7 @@ describe('Manage Tag Page', () => { }); }); - test('navigates to the subTags screen after clicking the subTags option', async () => { + it('navigates to the subTags screen after clicking the subTags option', async () => { renderManageTag(link); await wait(); @@ -292,7 +291,7 @@ describe('Manage Tag Page', () => { }); }); - test('navigates to the manageTag screen after clicking a tag in the breadcrumbs', async () => { + it('navigates to the manageTag screen after clicking a tag in the breadcrumbs', async () => { renderManageTag(link); await wait(); @@ -309,7 +308,7 @@ describe('Manage Tag Page', () => { }); }); - test('navigates to organization tags screen screen after clicking tha all tags option in the breadcrumbs', async () => { + it('navigates to organization tags screen screen after clicking tha all tags option in the breadcrumbs', async () => { renderManageTag(link); await wait(); @@ -324,7 +323,7 @@ describe('Manage Tag Page', () => { }); }); - test('searchs for tags where the name matches the provided search input', async () => { + it('searchs for tags where the name matches the provided search input', async () => { renderManageTag(link); await wait(); @@ -345,7 +344,7 @@ describe('Manage Tag Page', () => { }); }); - test('fetches the tags by the sort order, i.e. latest or oldest first', async () => { + it('fetches the tags by the sort order, i.e. latest or oldest first', async () => { renderManageTag(link); await wait(); @@ -402,7 +401,7 @@ describe('Manage Tag Page', () => { }); }); - test('Fetches more assigned members with infinite scroll', async () => { + it('Fetches more assigned members with infinite scroll', async () => { const { getByText } = renderManageTag(link); await wait(); @@ -433,7 +432,7 @@ describe('Manage Tag Page', () => { }); }); - test('unassigns a tag from a member', async () => { + it('unassigns a tag from a member', async () => { renderManageTag(link); await wait(); @@ -452,7 +451,7 @@ describe('Manage Tag Page', () => { }); }); - test('successfully edits the tag name', async () => { + it('successfully edits the tag name', async () => { renderManageTag(link); await wait(); @@ -482,7 +481,7 @@ describe('Manage Tag Page', () => { }); }); - test('successfully removes the tag and redirects to orgTags page', async () => { + it('successfully removes the tag and redirects to orgTags page', async () => { renderManageTag(link); await wait(); diff --git a/src/screens/ManageTag/ManageTag.tsx b/src/screens/ManageTag/ManageTag.tsx index 428dad7981..7eb6a3221d 100644 --- a/src/screens/ManageTag/ManageTag.tsx +++ b/src/screens/ManageTag/ManageTag.tsx @@ -132,7 +132,8 @@ function ManageTag(): JSX.Element { }; }, ) => { - if (!fetchMoreResult) /* istanbul ignore next */ return prevResult; + /* istanbul ignore next -- @preserve */ + if (!fetchMoreResult) return prevResult; return { getAssignedUsers: { @@ -174,7 +175,7 @@ function ManageTag(): JSX.Element { toggleUnassignUserTagModal(); toast.success(t('successfullyUnassigned') as string); } catch (error: unknown) { - /* istanbul ignore next */ + /* istanbul ignore next -- @preserve */ if (error instanceof Error) { toast.error(error.message); } @@ -209,13 +210,14 @@ function ManageTag(): JSX.Element { }, }); + /* istanbul ignore else -- @preserve */ if (data) { toast.success(t('tagUpdationSuccess')); userTagAssignedMembersRefetch(); setEditUserTagModalIsOpen(false); } } catch (error: unknown) { - /* istanbul ignore next */ + /* istanbul ignore next -- @preserve */ if (error instanceof Error) { toast.error(error.message); } @@ -235,7 +237,7 @@ function ManageTag(): JSX.Element { toggleRemoveUserTagModal(); toast.success(t('tagRemovalSuccess') as string); } catch (error: unknown) { - /* istanbul ignore next */ + /* istanbul ignore next -- @preserve */ if (error instanceof Error) { toast.error(error.message); } @@ -258,7 +260,7 @@ function ManageTag(): JSX.Element { const userTagAssignedMembers = userTagAssignedMembersData?.getAssignedUsers.usersAssignedTo.edges.map( (edge) => edge.node, - ) ?? /* istanbul ignore next */ []; + ) ?? /* istanbul ignore next -- @preserve */ []; // get the ancestorTags array and push the current tag in it // used for the tag breadcrumbs @@ -290,7 +292,7 @@ function ManageTag(): JSX.Element { minWidth: 100, align: 'center', headerAlign: 'center', - headerClassName: `${styles.tableHeader}`, + headerClassName: `${styles.tableHeaders}`, sortable: false, renderCell: (params: GridCellParams) => { return
{params.row.id}
; @@ -302,7 +304,7 @@ function ManageTag(): JSX.Element { flex: 2, minWidth: 100, sortable: false, - headerClassName: `${styles.tableHeader}`, + headerClassName: `${styles.tableHeaders}`, renderCell: (params: GridCellParams) => { return (
@@ -319,7 +321,7 @@ function ManageTag(): JSX.Element { minWidth: 100, headerAlign: 'center', sortable: false, - headerClassName: `${styles.tableHeader}`, + headerClassName: `${styles.tableHeaders}`, renderCell: (params: GridCellParams) => { return (
@@ -452,7 +454,7 @@ function ManageTag(): JSX.Element { > {tag.name} {orgUserTagAncestors.length - 1 !== index && ( - /* istanbul ignore next */ + /* istanbul ignore next -- @preserve */ )}
@@ -469,7 +471,7 @@ function ManageTag(): JSX.Element { hasMore={ userTagAssignedMembersData?.getAssignedUsers .usersAssignedTo.pageInfo.hasNextPage ?? - /* istanbul ignore next */ false + /* istanbul ignore next -- @preserve */ false } loader={} scrollableTarget="manageTagScrollableDiv" @@ -480,18 +482,19 @@ function ManageTag(): JSX.Element { hideFooter={true} getRowId={(row) => row.id} slots={{ - noRowsOverlay: /* istanbul ignore next */ () => ( - - {t('noAssignedMembersFound')} - - ), + noRowsOverlay: + /* istanbul ignore next -- @preserve */ () => ( + + {t('noAssignedMembersFound')} + + ), }} sx={dataGridStyle} - getRowClassName={() => `${styles.rowBackground}`} + getRowClassName={() => `${styles.rowBackgrounds}`} autoHeight rowHeight={65} rows={userTagAssignedMembers?.map( diff --git a/src/screens/OrgList/OrgList.module.css b/src/screens/OrgList/OrgList.module.css deleted file mode 100644 index 6aa245983e..0000000000 --- a/src/screens/OrgList/OrgList.module.css +++ /dev/null @@ -1,324 +0,0 @@ -.btnsContainer { - display: flex; - margin: 2.5rem 0 2.5rem 0; -} - -.btnsContainer .btnsBlock { - display: flex; -} - -.orgCreationBtn { - width: 100%; - border: None; -} - -.enableEverythingBtn { - width: 100%; - border: None; -} - -.pluginStoreBtn { - width: 100%; - background-color: white; - color: #555555; - border: 0.5px solid #555555; -} - -.pluginStoreBtn:hover, -.pluginStoreBtn:focus { - background-color: #dfe1e2 !important; - color: #555555 !important; - border-color: #555555 !important; -} - -.line::before { - content: ''; - display: inline-block; - width: 100px; - border-top: 1px solid #000; - margin: 0 10px; -} - -.line::before { - left: 0; -} - -.line::after { - right: 0; -} - -.flexContainer { - display: flex; - justify-content: center; - align-items: center; - width: 100%; -} - -.orText { - display: block; - position: absolute; - top: calc(-0.7rem + 0.5rem); - left: calc(50% - 2.6rem); - margin: 0 auto; - padding: 0.5rem 2rem; - z-index: 100; - background: var(--bs-white); - color: var(--bs-secondary); -} - -.sampleOrgSection { - display: grid; - grid-template-columns: repeat(1, 1fr); - row-gap: 1em; -} - -.sampleOrgCreationBtn { - width: 100%; - background-color: transparent; - color: #707070; - border-color: #707070; - display: flex; - justify-content: center; - align-items: center; -} - -.sampleHover:hover { - border-color: grey; - color: grey; -} - -.sampleOrgSection { - font-family: Arial, Helvetica, sans-serif; - width: 100%; - display: grid; - grid-auto-columns: repeat(1, 1fr); - justify-content: center; - flex-direction: column; - align-items: center; -} - -.sampleModalTitle { - background-color: green; -} - -.btnsContainer .btnsBlock button { - margin-left: 1rem; - display: flex; - justify-content: center; - align-items: center; -} - -.btnsContainer .input { - flex: 1; - position: relative; -} - -.btnsContainer input { - outline: 1px solid var(--bs-gray-400); -} - -.btnsContainer .input button { - width: 52px; -} - -.listBox { - display: flex; - flex-wrap: wrap; - overflow: unset !important; -} - -.listBox .itemCard { - width: 50%; -} - -.notFound { - flex: 1; - display: flex; - justify-content: center; - align-items: center; - flex-direction: column; -} - -@media (max-width: 1440px) { - .contract { - padding-left: calc(250px + 2rem + 1.5rem); - } - - .listBox .itemCard { - width: 100%; - } -} - -@media (max-width: 1020px) { - .btnsContainer { - flex-direction: column; - margin: 1.5rem 0; - } - - .btnsContainer .btnsBlock { - margin: 1.5rem 0 0 0; - justify-content: space-between; - } - - .btnsContainer .btnsBlock button { - margin: 0; - } - - .btnsContainer .btnsBlock div button { - margin-right: 1.5rem; - } -} - -/* For mobile devices */ - -@media (max-width: 520px) { - .btnsContainer { - margin-bottom: 0; - } - - .btnsContainer .btnsBlock { - display: block; - margin-top: 1rem; - margin-right: 0; - } - - .btnsContainer .btnsBlock div { - flex: 1; - } - - .btnsContainer .btnsBlock div[title='Sort organizations'] { - margin-right: 0.5rem; - } - - .btnsContainer .btnsBlock button { - margin-bottom: 1rem; - margin-right: 0; - width: 100%; - } -} - -/* Loading OrgList CSS */ -.itemCard .loadingWrapper { - background-color: var(--bs-white); - margin: 0.5rem; - height: calc(120px + 2rem); - padding: 1rem; - border-radius: 8px; - outline: 1px solid var(--bs-gray-200); - position: relative; -} - -.itemCard .loadingWrapper .innerContainer { - display: flex; -} - -.itemCard .loadingWrapper .innerContainer .orgImgContainer { - width: 120px; - height: 120px; - border-radius: 4px; -} - -.itemCard .loadingWrapper .innerContainer .content { - flex: 1; - display: flex; - flex-direction: column; - margin-left: 1rem; -} - -.titlemodaldialog { - color: #707070; - font-size: 20px; - margin-bottom: 20px; - padding-bottom: 5px; -} - -form label { - font-weight: bold; - padding-bottom: 1px; - font-size: 14px; - color: #707070; -} - -form > input { - display: block; - margin-bottom: 20px; - border: 1px solid #e8e5e5; - box-shadow: 2px 1px #e8e5e5; - padding: 10px 20px; - border-radius: 5px; - background: none; - width: 100%; - transition: all 0.3s ease-in-out; - -webkit-transition: all 0.3s ease-in-out; - -moz-transition: all 0.3s ease-in-out; - -ms-transition: all 0.3s ease-in-out; - -o-transition: all 0.3s ease-in-out; -} - -.itemCard .loadingWrapper .innerContainer .content h5 { - height: 24px; - width: 60%; - margin-bottom: 0.8rem; -} - -.modalbody { - width: 50px; -} - -.pluginStoreBtnContainer { - display: flex; - gap: 1rem; -} - -.itemCard .loadingWrapper .innerContainer .content h6[title='Location'] { - display: block; - width: 45%; - height: 18px; -} - -.itemCard .loadingWrapper .innerContainer .content h6 { - display: block; - width: 30%; - height: 16px; - margin-bottom: 0.8rem; -} - -.itemCard .loadingWrapper .button { - position: absolute; - height: 48px; - width: 92px; - bottom: 1rem; - right: 1rem; - z-index: 1; -} - -@media (max-width: 450px) { - .itemCard .loadingWrapper { - height: unset; - margin: 0.5rem 0; - padding: 1.25rem 1.5rem; - } - - .itemCard .loadingWrapper .innerContainer { - flex-direction: column; - } - - .itemCard .loadingWrapper .innerContainer .orgImgContainer { - height: 200px; - width: 100%; - margin-bottom: 0.8rem; - } - - .itemCard .loadingWrapper .innerContainer .content { - margin-left: 0; - } - - .itemCard .loadingWrapper .button { - bottom: 0; - right: 0; - border-radius: 0.5rem; - position: relative; - margin-left: auto; - display: block; - } -} diff --git a/src/screens/OrgList/OrgList.tsx b/src/screens/OrgList/OrgList.tsx index baafb17ffd..37a4276982 100644 --- a/src/screens/OrgList/OrgList.tsx +++ b/src/screens/OrgList/OrgList.tsx @@ -27,6 +27,7 @@ import type { InterfaceUserType, } from 'utils/interfaces'; import useLocalStorage from 'utils/useLocalstorage'; +// import styles from '../../style/app.module.css'; import styles from '../../style/app.module.css'; import OrganizationModal from './OrganizationModal'; @@ -38,7 +39,6 @@ function orgList(): JSX.Element { function openDialogModal(redirectOrgId: string): void { setDialogRedirectOrgId(redirectOrgId); - // console.log(redirectOrgId, dialogRedirectOrgId); setdialogModalIsOpen(true); } @@ -330,7 +330,7 @@ function orgList(): JSX.Element { return ( <> {/* Buttons Container */} -
+
-
+