Skip to content

Commit

Permalink
Implemented correct user roles Fixes #3106 (#3111)
Browse files Browse the repository at this point in the history
* implemented correct user roles

* requested changes added

* requested changes added-1

* requested changes added-2

* requested changes added-3
  • Loading branch information
raggettii authored Jan 1, 2025
1 parent 831a4cf commit cbba422
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 111 deletions.
44 changes: 27 additions & 17 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,24 +30,29 @@ import CommunityProfile from 'screens/CommunityProfile/CommunityProfile';
import OrganizationVenues from 'screens/OrganizationVenues/OrganizationVenues';
import Leaderboard from 'screens/Leaderboard/Leaderboard';

import React from 'react';
import React, { useEffect } from 'react';
// User Portal Components
import Donate from 'screens/UserPortal/Donate/Donate';
import Events from 'screens/UserPortal/Events/Events';
import Posts from 'screens/UserPortal/Posts/Posts';
import Organizations from 'screens/UserPortal/Organizations/Organizations';
import People from 'screens/UserPortal/People/People';
import Settings from 'screens/UserPortal/Settings/Settings';
import Chat from 'screens/UserPortal/Chat/Chat';
// import Chat from 'screens/UserPortal/Chat/Chat';
import { useQuery } from '@apollo/client';
import { CHECK_AUTH } from 'GraphQl/Queries/Queries';
import Advertisements from 'components/Advertisements/Advertisements';
import SecuredRouteForUser from 'components/UserPortal/SecuredRouteForUser/SecuredRouteForUser';

import useLocalStorage from 'utils/useLocalstorage';
import UserScreen from 'screens/UserPortal/UserScreen/UserScreen';
import EventDashboardScreen from 'components/EventDashboardScreen/EventDashboardScreen';
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();
const { setItem } = useLocalStorage();

/**
* This is the main function for our application. It sets up all the routes and components,
Expand Down Expand Up @@ -92,20 +97,21 @@ function app(): JSX.Element {

// TODO: Fetch Installed plugin extras and store for use within MainContent and Side Panel Components.

// const { data, loading } = useQuery(CHECK_AUTH);
const { data, loading } = useQuery(CHECK_AUTH);

// useEffect(() => {
// if (data) {
// setItem('name', `${data.checkAuth.firstName} ${data.checkAuth.lastName}`);
// setItem('id', data.checkAuth._id);
// setItem('email', data.checkAuth.email);
// setItem('IsLoggedIn', 'TRUE');
// setItem('FirstName', data.checkAuth.firstName);
// setItem('LastName', data.checkAuth.lastName);
// setItem('UserImage', data.checkAuth.image);
// setItem('Email', data.checkAuth.email);
// }
// }, [data, loading]);
useEffect(() => {
if (!loading && data?.checkAuth) {
const auth = data.checkAuth;
setItem('IsLoggedIn', 'TRUE');
setItem('id', auth._id);
setItem('name', `${auth.firstName} ${auth.lastName}`);
setItem('FirstName', auth.firstName);
setItem('LastName', auth.lastName);
setItem('email', auth.email);
setItem('Email', auth.email);
setItem('UserImage', auth.image);
}
}, [data, loading, setItem]);

const extraRoutes = Object.entries(installedPlugins).map(
(
Expand Down Expand Up @@ -192,9 +198,12 @@ function app(): JSX.Element {
<Route path="/user/people/:orgId" element={<People />} />
<Route path="/user/donate/:orgId" element={<Donate />} />
<Route path="/user/events/:orgId" element={<Events />} />
<Route path="/user/chat/:orgId" element={<Chat />} />
<Route path="/user/campaigns/:orgId" element={<Campaigns />} />
<Route path="/user/pledges/:orgId" element={<Pledges />} />
<Route
path="/user/leaveOrg/:orgId"
element={<LeaveOrganization />}
/>
<Route
path="/user/volunteer/:orgId"
element={<VolunteerManagement />}
Expand All @@ -207,6 +216,7 @@ function app(): JSX.Element {
</Route>
</Route>
</Route>
{/* <SecuredRouteForUser path="/user/chat" component={Chat} /> */}
<Route path="*" element={<PageNotFound />} />
</Routes>
</>
Expand Down
58 changes: 1 addition & 57 deletions src/screens/UserPortal/People/People.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { Provider } from 'react-redux';
import { store } from 'state/store';
import i18nForTest from 'utils/i18nForTest';
import { StaticMockLink } from 'utils/StaticMockLink';
import type { InterfaceMember } from './People';
// import type { InterfaceMember } from './People';
import People from './People';
import userEvent from '@testing-library/user-event';
import { vi } from 'vitest';
Expand Down Expand Up @@ -168,62 +168,6 @@ describe('Testing People Screen [User Portal]', () => {
expect(screen.queryAllByText('Noble Mittal')).not.toBe([]);
});

function compareProperties(
expectedProps: string[],
actualObject: object,
): boolean {
const actualProps = Object.keys(actualObject);
return expectedProps.every((prop) => actualProps.includes(prop));
}

describe('InterfaceMember properties comparison', () => {
it('should have all required properties', () => {
const expectedProperties = [
'firstName',
'lastName',
'image',
'_id',
'email',
'__typename',
];

const mockValidData: InterfaceMember = {
firstName: 'John',
lastName: 'Doe',
image: 'https://example.com/john.jpg',
_id: '1',
email: 'john.doe@example.com',
__typename: 'User',
};

const result = compareProperties(expectedProperties, mockValidData);
expect(result).toBe(true);
});

it('should fail if __typename is replaced with username', () => {
const expectedProperties = [
'firstName',
'lastName',
'image',
'_id',
'email',
'__typename', // Expect this property
];

const mockInvalidData = {
firstName: 'John',
lastName: 'Doe',
image: 'https://example.com/john.jpg',
_id: '1',
email: 'john.doe@example.com',
username: 'Member', // Incorrect property
};

const result = compareProperties(expectedProperties, mockInvalidData);
expect(result).toBe(false);
});
});

it('Search works properly by pressing enter', async () => {
render(
<MockedProvider addTypename={false} link={link}>
Expand Down
78 changes: 41 additions & 37 deletions src/screens/UserPortal/People/People.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ interface InterfaceOrganizationCardProps {
sno: string;
}

export interface InterfaceMember {
interface InterfaceMember {
firstName: string;
lastName: string;
image: string;
_id: string;
email: string;
__typename: string;
userType: string;
}

/**
Expand All @@ -37,20 +37,19 @@ export interface InterfaceMember {
* and paginate through the list.
*/
export default function people(): JSX.Element {
// i18n translation hook for user organization related translations
const { t } = useTranslation('translation', {
keyPrefix: 'people',
});

// i18n translation hook for common translations
const { t: tCommon } = useTranslation('common');

// State for managing current page in pagination
const [page, setPage] = useState<number>(0);

// State for managing the number of rows per page in pagination
const [rowsPerPage, setRowsPerPage] = useState<number>(5);
const [members, setMembers] = useState([]);
const [members, setMembers] = useState<InterfaceMember[]>([]);
const [allMembers, setAllMembers] = useState<InterfaceMember[]>([]);
const [admins, setAdmins] = useState<InterfaceMember[]>([]);
const [mode, setMode] = useState<number>(0);

// Extracting organization ID from URL parameters
Expand All @@ -69,29 +68,18 @@ export default function people(): JSX.Element {
},
},
);

// Query to fetch list of admins of the organization
const { data: data2 } = useQuery(ORGANIZATION_ADMINS_LIST, {
variables: { id: organizationId },
});

/**
* Handles page change in pagination.
*
*/
/* istanbul ignore next */
const handleChangePage = (
_event: React.MouseEvent<HTMLButtonElement> | null,
newPage: number,
): void => {
setPage(newPage);
};

/**
* Handles change in the number of rows per page.
*
*/
/* istanbul ignore next */
const handleChangeRowsPerPage = (
event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,
): void => {
Expand All @@ -101,20 +89,12 @@ export default function people(): JSX.Element {
setPage(0);
};

/**
* Searches for members based on the filter value.
*
*/
const handleSearch = (newFilter: string): void => {
refetch({
firstName_contains: newFilter,
});
};

/**
* Handles search operation triggered by pressing the Enter key.
*
*/
const handleSearchByEnter = (
e: React.KeyboardEvent<HTMLInputElement>,
): void => {
Expand All @@ -124,34 +104,58 @@ export default function people(): JSX.Element {
}
};

/**
* Handles search operation triggered by clicking the search button.
*/
const handleSearchByBtnClick = (): void => {
const inputValue =
(document.getElementById('searchPeople') as HTMLInputElement)?.value ||
'';
handleSearch(inputValue);
};

useEffect(() => {
if (data2) {
const admin = data2.organizations[0].admins[0];
const updatedAdmin: InterfaceMember = {
...admin,
userType: 'Admin',
};
setAdmins([updatedAdmin]);
}
}, [data2]);

useEffect(() => {
if (data) {
setMembers(data.organizationsMemberConnection.edges);
const updatedAdmins = data.organizationsMemberConnection.edges.map(
(memberData: InterfaceMember) => ({
...memberData, // Spread the existing properties
userType: admins?.some((admin) => admin._id === memberData._id)
? 'Admin'
: 'Member',
}),
);

setAllMembers(updatedAdmins);
setMembers(updatedAdmins);
}
}, [data]);
}, [data, admins]);

/**
* Updates the list of members based on the selected filter mode.
*/
/* istanbul ignore next */
if (admins && admins.length > 0) {
const adminIds = admins.map((adm) => adm._id);
for (let i = 0; i < allMembers.length; i++) {
if (adminIds.includes(allMembers[i]._id)) {
allMembers[i].userType = 'Admin';
} else {
allMembers[i].userType = 'Member';
}
}
}
useEffect(() => {
if (mode == 0) {
if (data) {
setMembers(data.organizationsMemberConnection.edges);
setMembers(allMembers);
}
} else if (mode == 1) {
if (data2) {
setMembers(data2.organizations[0].admins);
setMembers(admins);
}
}
}, [mode]);
Expand Down Expand Up @@ -243,7 +247,7 @@ export default function people(): JSX.Element {
image: member.image,
id: member._id,
email: member.email,
role: member.__typename,
role: member.userType,
sno: (index + 1).toString(),
};
return <PeopleCard key={index} {...cardProps} />;
Expand Down

0 comments on commit cbba422

Please sign in to comment.