Skip to content

Commit

Permalink
Upgrade react-router-dom and setup layout in routes (PalisadoesFounda…
Browse files Browse the repository at this point in the history
…tion#1666)

* react-router-dom update

* package-lock update

* lint fix
  • Loading branch information
nitishkumar333 authored Mar 5, 2024
1 parent e186ed2 commit 308a00c
Show file tree
Hide file tree
Showing 88 changed files with 2,998 additions and 3,034 deletions.
3 changes: 2 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"graphql": "^15.5.1",
"graphql-tag": "^2.12.6",
"graphql-ws": "^5.14.0",
"history": "^5.3.0",
"i18next": "^21.8.14",
"i18next-browser-languagedetector": "^6.1.4",
"i18next-http-backend": "^1.4.1",
Expand All @@ -45,7 +46,7 @@
"react-icons": "^4.12.0",
"react-infinite-scroll-component": "^6.1.0",
"react-redux": "^7.2.5",
"react-router-dom": "^5.2.0",
"react-router-dom": "^6.22.2",
"react-scripts": "5.0.1",
"react-toastify": "^9.0.3",
"redux": "^4.1.1",
Expand Down
134 changes: 57 additions & 77 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,26 @@
/* eslint-disable */
import { useQuery } from '@apollo/client';
import { CHECK_AUTH } from 'GraphQl/Queries/Queries';
import AddOnStore from 'components/AddOn/core/AddOnStore/AddOnStore';
import Loader from 'components/Loader/Loader';
import SecuredRoute from 'components/SecuredRoute/SecuredRoute';
import SecuredRouteForUser from 'components/UserPortal/SecuredRouteForUser/SecuredRouteForUser';
import React from 'react';
import { Route, Routes } from 'react-router-dom';
import * as installedPlugins from 'components/plugins/index';
import React, { useEffect } from 'react';
import { Route, Switch } from 'react-router-dom';
import BlockUser from 'screens/BlockUser/BlockUser';
import EventDashboard from 'screens/EventDashboard/EventDashboard';
import ForgotPassword from 'screens/ForgotPassword/ForgotPassword';
import SecuredRoute from 'components/SecuredRoute/SecuredRoute';
import LoginPage from 'screens/LoginPage/LoginPage';
import MemberDetail from 'screens/MemberDetail/MemberDetail';
import OrganizationEvents from 'screens/OrganizationEvents/OrganizationEvents';
import OrganizationActionItems from 'screens/OrganizationActionItems/OrganizationActionItems';
import OrganizationPeople from 'screens/OrganizationPeople/OrganizationPeople';
import OrganizationFunds from 'screens/OrganizationFunds/OrganizationFunds';
import OrganizationDashboard from 'screens/OrganizationDashboard/OrganizationDashboard';
import OrgContribution from 'screens/OrgContribution/OrgContribution';
import OrgList from 'screens/OrgList/OrgList';
import OrgPost from 'screens/OrgPost/OrgPost';
import OrgSettings from 'screens/OrgSettings/OrgSettings';
import OrganizationActionItems from 'screens/OrganizationActionItems/OrganizationActionItems';
import OrganizationDashboard from 'screens/OrganizationDashboard/OrganizationDashboard';
import OrganizationEvents from 'screens/OrganizationEvents/OrganizationEvents';
import OrganizationFunds from 'screens/OrganizationFunds/OrganizationFunds';
import OrganizationPeople from 'screens/OrganizationPeople/OrganizationPeople';
import PageNotFound from 'screens/PageNotFound/PageNotFound';
import AddOnStore from 'components/AddOn/core/AddOnStore/AddOnStore';
import ForgotPassword from 'screens/ForgotPassword/ForgotPassword';
import Users from 'screens/Users/Users';
import BlockUser from 'screens/BlockUser/BlockUser';
import EventDashboard from 'screens/EventDashboard/EventDashboard';
import MemberDetail from 'screens/MemberDetail/MemberDetail';
import OrganizationScreen from 'components/OrganizationScreen/OrganizationScreen';
import SuperAdminScreen from 'components/SuperAdminScreen/SuperAdminScreen';

// User Portal Components
import Donate from 'screens/UserPortal/Donate/Donate';
Expand All @@ -35,9 +32,7 @@ import Settings from 'screens/UserPortal/Settings/Settings';
// import UserLoginPage from 'screens/UserPortal/UserLoginPage/UserLoginPage';
// import Chat from 'screens/UserPortal/Chat/Chat';
import Advertisements from 'components/Advertisements/Advertisements';
import useLocalStorage from 'utils/useLocalstorage';

const { setItem } = useLocalStorage();
import SecuredRouteForUser from 'components/UserPortal/SecuredRouteForUser/SecuredRouteForUser';

function app(): JSX.Element {
/*const { updatePluginLinks, updateInstalled } = bindActionCreators(
Expand Down Expand Up @@ -65,77 +60,62 @@ 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);

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('UserType', data.checkAuth.userType);
setItem('FirstName', data.checkAuth.firstName);
setItem('LastName', data.checkAuth.lastName);
setItem('UserImage', data.checkAuth.image);
setItem('Email', data.checkAuth.email);
}
}, [data, loading]);

const extraRoutes = Object.entries(installedPlugins).map(
(plugin: any, index) => {
const extraComponent = plugin[1];
return (
<SecuredRoute
<Route
key={index}
path={`/plugin/${plugin[0].toLowerCase()}`}
component={extraComponent}
element={extraComponent}
/>
);
},
);

if (loading) {
return <Loader />;
}
return (
<>
<Switch>
<Route exact path="/" component={LoginPage} />
<SecuredRoute path="/orgdash" component={OrganizationDashboard} />
<SecuredRoute path="/orgpeople" component={OrganizationPeople} />
<SecuredRoute path="/orglist" component={OrgList} />
<SecuredRoute path="/member" component={MemberDetail} />
<SecuredRoute path="/orgevents" component={OrganizationEvents} />
<SecuredRoute
path="/orgactionitems"
component={OrganizationActionItems}
/>
<SecuredRoute path="/orgfunds" component={OrganizationFunds} />
<SecuredRoute path="/orgcontribution" component={OrgContribution} />
<SecuredRoute path="/orgpost" component={OrgPost} />
<SecuredRoute path="/orgsetting" component={OrgSettings} />
<SecuredRoute path="/orgstore" component={AddOnStore} />
<SecuredRoute path="/orgads" component={Advertisements} />
<SecuredRoute path="/users" component={Users} />
<SecuredRoute path="/blockuser" component={BlockUser} />
<SecuredRoute path="/event/:eventId" component={EventDashboard} />
{extraRoutes}
<Route exact path="/forgotPassword" component={ForgotPassword} />

<Routes>
<Route path="/" element={<LoginPage />} />
<Route element={<SecuredRoute />}>
<Route element={<SuperAdminScreen />}>
<Route path="/orglist" element={<OrgList />} />
<Route path="/member" element={<MemberDetail />} />
<Route path="/users" element={<Users />} />
</Route>
<Route element={<OrganizationScreen />}>
<Route path="/orgdash/:orgId" element={<OrganizationDashboard />} />
<Route path="/orgpeople/:orgId" element={<OrganizationPeople />} />
<Route path="/member/:orgId" element={<MemberDetail />} />
<Route path="/orgevents/:orgId" element={<OrganizationEvents />} />
<Route
path="/orgactionitems/:orgId"
element={<OrganizationActionItems />}
/>
<Route path="/orgfunds/:orgId" element={<OrganizationFunds />} />
<Route path="/orgcontribution" element={<OrgContribution />} />
<Route path="/orgpost/:orgId" element={<OrgPost />} />
<Route path="/orgsetting/:orgId" element={<OrgSettings />} />
<Route path="/orgstore/:orgId" element={<AddOnStore />} />
<Route path="/orgads/:orgId" element={<Advertisements />} />
<Route path="/blockuser/:orgId" element={<BlockUser />} />
{extraRoutes}
</Route>
</Route>
<Route path="/event/:eventId" element={<EventDashboard />} />
<Route path="/forgotPassword" element={<ForgotPassword />} />
{/* User Portal Routes */}
<SecuredRouteForUser
path="/user/organizations"
component={Organizations}
/>
<SecuredRouteForUser path="/user/organization" component={Home} />
<SecuredRouteForUser path="/user/people" component={People} />
<SecuredRouteForUser path="/user/settings" component={Settings} />
<SecuredRouteForUser path="/user/donate" component={Donate} />
<SecuredRouteForUser path="/user/events" component={Events} />
<Route element={<SecuredRouteForUser />}>
<Route path="/user/organizations" element={<Organizations />} />
<Route path="/user/organization/:orgId" element={<Home />} />
<Route path="/user/people/:orgId" element={<People />} />
<Route path="/user/settings" element={<Settings />} />
<Route path="/user/donate/:orgId" element={<Donate />} />
<Route path="/user/events/:orgId" element={<Events />} />
</Route>
{/* <SecuredRouteForUser path="/user/chat" component={Chat} /> */}

<Route exact path="*" component={PageNotFound} />
</Switch>
<Route path="*" element={<PageNotFound />} />
</Routes>
</>
);
}
Expand Down
4 changes: 4 additions & 0 deletions src/GraphQl/Mutations/mutations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,10 @@ export const LOGIN_MUTATION = gql`
_id
userType
adminApproved
firstName
lastName
email
image
}
accessToken
refreshToken
Expand Down
23 changes: 22 additions & 1 deletion src/components/AddOn/core/AddOnEntry/AddOnEntry.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ const client: ApolloClient<NormalizedCacheObject> = new ApolloClient({
cache: new InMemoryCache(),
link: ApolloLink.from([httpLink]),
});
let mockID: string | undefined = '1';
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
useParams: () => ({ orgId: mockID }),
}));

describe('Testing AddOnEntry', () => {
const props = {
Expand Down Expand Up @@ -122,7 +127,7 @@ describe('Testing AddOnEntry', () => {
return { sample: 'sample' };
},
};

mockID = 'undefined';
const { findByText, getByTestId } = render(
<MockedProvider addTypename={false} link={link}>
<Provider store={store}>
Expand Down Expand Up @@ -185,4 +190,20 @@ describe('Testing AddOnEntry', () => {
const btn = getByTestId('AddOnEntry_btn_install');
expect(btn.innerHTML).toMatch(/install/i);
});
test('should be redirected to /orglist if orgId is undefined', async () => {
mockID = undefined;
render(
<ApolloProvider client={client}>
<Provider store={store}>
<BrowserRouter>
<I18nextProvider i18n={i18nForTest}>
{<AddOnEntry uninstalledOrgs={[]} {...props} />}
</I18nextProvider>
</BrowserRouter>
</Provider>
</ApolloProvider>,
);
await wait(100);
expect(window.location.pathname).toEqual('/orglist');
});
});
6 changes: 5 additions & 1 deletion src/components/AddOn/core/AddOnEntry/AddOnEntry.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { UPDATE_INSTALL_STATUS_PLUGIN_MUTATION } from 'GraphQl/Mutations/mutatio
import { useMutation } from '@apollo/client';
import { useTranslation } from 'react-i18next';
import { toast } from 'react-toastify';
import { Navigate, useParams } from 'react-router-dom';

interface InterfaceAddOnEntryProps {
id: string;
Expand All @@ -29,7 +30,10 @@ function addOnEntry({
}: InterfaceAddOnEntryProps): JSX.Element {
const { t } = useTranslation('translation', { keyPrefix: 'addOnEntry' });
//getting orgId from URL
const currentOrg = window.location.href.split('/id=')[1] + '';
const { orgId: currentOrg } = useParams();
if (!currentOrg) {
return <Navigate to={'/orglist'} />;
}
const [buttonLoading, setButtonLoading] = useState(false);
const [isInstalledLocal, setIsInstalledLocal] = useState(
uninstalledOrgs.includes(currentOrg),
Expand Down
42 changes: 25 additions & 17 deletions src/components/AddOn/core/AddOnRegister/AddOnRegister.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ const mocks = [
pluginCreatedBy: 'Test Creator',
pluginDesc: 'Test Description',
pluginInstallStatus: false,
installedOrgs: [undefined],
installedOrgs: ['id'],
},
},
result: {
Expand Down Expand Up @@ -80,26 +80,19 @@ jest.mock('react-toastify', () => ({
},
}));

const mockNavigate = jest.fn();
let mockId: string | undefined = 'id';
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
useParams: () => ({ orgId: mockId }),
useNavigate: () => mockNavigate,
}));

describe('Testing AddOnRegister', () => {
const props = {
id: '6234d8bf6ud937ddk70ecc5c9',
};

const original = window.location;
beforeAll(() => {
Object.defineProperty(window, 'location', {
configurable: true,
value: { reload: jest.fn() },
});
});

afterAll(() => {
Object.defineProperty(window, 'location', {
configurable: true,
value: original,
});
});

test('should render modal and take info to add plugin for registered organization', async () => {
await act(async () => {
render(
Expand Down Expand Up @@ -187,7 +180,22 @@ describe('Testing AddOnRegister', () => {
userEvent.click(screen.getByTestId('addonregisterBtn'));

await wait(3000); // Waiting for 3 seconds to reload the page as timeout is set to 2 seconds in the component
expect(window.location.reload).toHaveBeenCalled();
expect(mockNavigate).toHaveBeenCalledWith(0);
});
});
test('should be redirected to /orglist if orgId is undefined', async () => {
mockId = undefined;
render(
<ApolloProvider client={client}>
<Provider store={store}>
<BrowserRouter>
<I18nextProvider i18n={i18nForTest}>
{<AddOnRegister {...props} />}
</I18nextProvider>
</BrowserRouter>
</Provider>
</ApolloProvider>,
);
expect(window.location.pathname).toEqual('/orglist');
});
});
10 changes: 8 additions & 2 deletions src/components/AddOn/core/AddOnRegister/AddOnRegister.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { useMutation } from '@apollo/client';
import { ADD_PLUGIN_MUTATION } from 'GraphQl/Mutations/mutations';
import { useTranslation } from 'react-i18next';
import { toast } from 'react-toastify';
import { Navigate, useNavigate, useParams } from 'react-router-dom';

interface InterfaceFormStateTypes {
pluginName: string;
Expand All @@ -15,10 +16,15 @@ interface InterfaceFormStateTypes {
installedOrgs: [string] | [];
}

const currentUrl = window.location.href.split('=')[1];
function addOnRegister(): JSX.Element {
const { t } = useTranslation('translation', { keyPrefix: 'addOnRegister' });

const { orgId: currentUrl } = useParams();
const navigate = useNavigate();
if (!currentUrl) {
return <Navigate to={'/orglist'} />;
}

const [show, setShow] = useState(false);

const handleClose = (): void => setShow(false);
Expand Down Expand Up @@ -47,7 +53,7 @@ function addOnRegister(): JSX.Element {
if (data) {
toast.success('Plugin Added Successfully');
setTimeout(() => {
window.location.reload();
navigate(0);
}, 2000);
}
};
Expand Down
5 changes: 4 additions & 1 deletion src/components/AddOn/core/AddOnStore/AddOnStore.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,10 @@ const PLUGIN_LOADING_MOCK = {
loading: true,
},
};

jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
useParams: () => ({ orgId: 'undefined' }),
}));
const ORGANIZATIONS_LIST_MOCK = {
request: {
query: ORGANIZATIONS_LIST,
Expand Down
Loading

0 comments on commit 308a00c

Please sign in to comment.