Skip to content

Commit

Permalink
Feature/add pagination to organisation listing page (#162)
Browse files Browse the repository at this point in the history
* Refactor code

* Update to use theme folder structure. (#161)

* Add pagination to organisations page

* Update organisation file name [#87]

* Fix filename case errors.

* Rename pages directory.

* Rename components files.

* Rename files in data folder.

* Fix path imports.

* Fix file name conflicts.

---------

Co-authored-by: karthik-Jay <[email protected]>
Co-authored-by: Karthik Jayaraman <[email protected]>
  • Loading branch information
3 people authored Jun 22, 2024
1 parent f57f90d commit 70cf063
Showing 98 changed files with 416 additions and 318 deletions.
2 changes: 1 addition & 1 deletion src/App.test.tsx → src/app.test.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from "react"
import { screen } from "@testing-library/react"
import { render } from "./test-utils"
import App from "./App"
import App from "./app"

test("renders learn react link", () => {
render(<App />)
61 changes: 24 additions & 37 deletions src/App.tsx → src/app.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,35 @@
import {
ChakraProvider,
Box,
Text,
Center,
VStack,
Image,
ChakraProvider,
Flex,
HStack,
Image,
Text,
VStack,
} from "@chakra-ui/react";
import { AuthProvider } from "./services/firebase/authProvider";
import { useGetWindowDimensionsHook } from "./utilities/useGetDdimensionsHook";
import logo from "./assets/images/logo/Mendisphere Logo colour.png";
import Header from "./components/Header";
import Footer from "./components/Footer";
import { AuthProvider } from "./services/firebase/authProvider";
import mendisphereTheme from "./theme/index";
import { Route, Routes } from "react-router-dom";
import { Paths } from "./routing/Paths";
import Home from "./pages/Home";
import Login from "./pages/Login";
import UserDashboard from "./pages/UserDashboard";
import Registration from "./pages/Registration";
import ProfileSetup from "./pages/Registration/ProfileSetup";
import OrganisationList from "./pages/OrganisationList";
import OrganisationProfile from "./pages/OrganisationProfile";
import FirestoreMockPage from "./mocks/FirestoreMock";
import mendisphereTheme from "./theme";
import Routing, { Paths } from "./routing";
import Header from "./components/header";
import Footer from "./components/footer";

function App() {
const { width } = useGetWindowDimensionsHook();

const isNotDesktopWidth = width <= 720;

// Get current page
const currentPage = window.location.pathname;

// Check the current page is not login and registration page
const isShowHeaderAndFooter = ![
Paths.login,
Paths.signup,
Paths.profileSetup,
].includes(currentPage);

if (isNotDesktopWidth) {
return (
<ChakraProvider theme={mendisphereTheme}>
@@ -93,27 +94,13 @@ function App() {
</ChakraProvider>
);
}

return (
<ChakraProvider theme={mendisphereTheme}>
<AuthProvider>
<Routes>
<Route path={Paths.home} element={<Home />} />
<Route path={Paths.login} element={<Login />} />
<Route path={Paths.dashboard} element={<UserDashboard />} />
<Route path={Paths.signup} element={<Registration />} />
<Route path={Paths.profileSetup} element={<ProfileSetup />} />
<Route
path={Paths.organisationListing}
element={<OrganisationList />}
/>
<Route
path={Paths.organisationProfile}
element={<OrganisationProfile />}
/>
{process.env.NODE_ENV === "development" && (
<Route path="firestore-mock" element={<FirestoreMockPage />} />
)}
</Routes>
{isShowHeaderAndFooter && <Header />}
<Routing />
{isShowHeaderAndFooter && <Footer />}
</AuthProvider>
</ChakraProvider>
);
1 change: 0 additions & 1 deletion src/components/Breadcrumbs/index.ts

This file was deleted.

1 change: 0 additions & 1 deletion src/components/Container/index.ts

This file was deleted.

1 change: 0 additions & 1 deletion src/components/Footer/index.ts

This file was deleted.

1 change: 0 additions & 1 deletion src/components/Header/index.ts

This file was deleted.

1 change: 0 additions & 1 deletion src/components/NavigationButton/index.ts

This file was deleted.

1 change: 0 additions & 1 deletion src/components/ScrollAnimation/index.ts

This file was deleted.

Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@ import {
} from "@chakra-ui/react";
import { HomeIcon } from "@primer/octicons-react";
import { Organisation } from "../../data/model/organisation";
import { Paths } from "../../routing/Paths";
import { Paths } from "../../routing";

const currentPageStyle = {
color: "#3959FF",
1 change: 1 addition & 0 deletions src/components/breadcrumbs/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from "./breadcrumbs";
File renamed without changes.
1 change: 1 addition & 0 deletions src/components/container/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from "./container";
File renamed without changes.
1 change: 1 addition & 0 deletions src/components/footer/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from "./footer";
Original file line number Diff line number Diff line change
@@ -9,11 +9,11 @@ import {
Spacer,
} from "@chakra-ui/react";
import { Link as ReactRouterLink } from "react-router-dom";
import NavigationButton from "../NavigationButton";
import { Paths } from "../../routing/Paths";
import NavigationButton from "../navigationButton";
import "../../pages/style.scss";

import logo from "../../assets/images/logo/Mendisphere Logo colour.png";
import { Paths } from "../../routing";

const Header = () => {
const [mobileNav, setMobileNav] = useState(false);
@@ -33,7 +33,8 @@ const Header = () => {
return (
<Box>
<Flex
h="8vh"
h="fit-content"
minH="70px"
borderBottom="1px"
borderColor="#d3d3d3"
top={0}
1 change: 1 addition & 0 deletions src/components/header/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from "./header";
1 change: 1 addition & 0 deletions src/components/navigationButton/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from "./navigationButton";
1 change: 1 addition & 0 deletions src/components/scrollAnimation/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { Animate } from "./scrollAnimation";
File renamed without changes.
71 changes: 41 additions & 30 deletions src/data/model/organisation.ts
Original file line number Diff line number Diff line change
@@ -8,12 +8,14 @@ import {
SnapshotOptions,
QuerySnapshot,
where,
Query,
query,
QueryConstraint,
getDoc,
doc,
limit,
startAfter,
DocumentSnapshot,
getCountFromServer,
} from "firebase/firestore";
import { Collections } from "../../services/firebase/names";
import { db } from "../../services/firebase/firebaseConfig";
@@ -119,16 +121,17 @@ export type OrganisationListingQueryFilters = {
export async function getOrganisationsForListingsPage(
filters?: OrganisationListingQueryFilters,
skipOrgName?: string,
limitNum: number = 0
): Promise<Organisation[]> {
console.log(
`Getting organisation with filters: ${JSON.stringify(filters, null, 2)}`
);

limitNum: number = 0,
lastVisible?: DocumentSnapshot<DocumentData>
): Promise<{
organisations: Organisation[];
lastVisible: DocumentSnapshot<DocumentData> | null;
totalCount: number;
}> {
const queryConstraints: QueryConstraint[] = [];
let onlyServicesFilter = false;

if (filters !== undefined) {
if (filters) {
if ((filters.specialisations?.length ?? 0) > 10) {
return Promise.reject(
new RangeError(
@@ -170,45 +173,53 @@ export async function getOrganisationsForListingsPage(
}

if (filters.services !== undefined && !queryConstraints.length) {
// must perform this condition at the end
// current limitation in firestore does not allow the use of
// 'array-contains-any' and 'in' clause in the same query

onlyServicesFilter = true;
queryConstraints.push(
where("services", "array-contains-any", filters.services)
);
}
}

if (limitNum > 0) {
queryConstraints.push(limit(limitNum));
if (skipOrgName) {
queryConstraints.push(where("name", "!=", skipOrgName));
}

if (skipOrgName !== undefined) {
queryConstraints.push(where("name", "!=", skipOrgName));
if (lastVisible) {
queryConstraints.push(startAfter(lastVisible));
}
// define the organisation collection reference
const orgsRef: Query<Organisation> = collection(
db,
Collections.organisations
).withConverter<Organisation>(organisationConverter);

// get organisations with the supplied filters
const orgsRef = collection(db, Collections.organisations).withConverter(
organisationConverter
);

// Get total count
const totalCountSnapshot = await getCountFromServer(
query(orgsRef, ...queryConstraints)
);
const totalCount = totalCountSnapshot.data().count;

if (limitNum > 0) {
queryConstraints.push(limit(limitNum));
}

// Get paginated organisations
const querySnapshot: QuerySnapshot<Organisation> = await getDocs(
query(orgsRef, ...queryConstraints)
);

const orgs: Organisation[] = [];
querySnapshot.forEach((doc) => orgs.push(doc.data()));

if (filters?.services !== undefined && !onlyServicesFilter) {
return orgs.filter((org) =>
org.services.some((s) => filters?.services?.includes(s))
);
}
querySnapshot.forEach((doc) => {
orgs.push(doc.data());
});

return orgs;
return {
organisations: orgs,
lastVisible:
querySnapshot.docs.length > 0
? querySnapshot.docs[querySnapshot.docs.length - 1]
: null,
totalCount: totalCount,
};
}

// get an organisation for profile page
5 changes: 4 additions & 1 deletion src/data/model/user.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { doc, setDoc } from "firebase/firestore";
import {
doc,
setDoc,
} from "firebase/firestore";
import { Collections } from "../../services/firebase/names";
import { db } from "../../services/firebase/firebaseConfig";
import { UserRole } from "../enums/user-role.enum";
2 changes: 1 addition & 1 deletion src/index.tsx
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@ import { ColorModeScript } from "@chakra-ui/react";
import * as React from "react";
import * as ReactDOM from "react-dom/client";
import { BrowserRouter } from "react-router-dom";
import App from "./App";
import App from "./app";
import reportWebVitals from "./reportWebVitals";
import * as serviceWorker from "./serviceWorker";
import 'typeface-inter'
10 changes: 5 additions & 5 deletions src/mocks/FirestoreMock.tsx → src/mocks/firestoreMock.tsx
Original file line number Diff line number Diff line change
@@ -8,14 +8,14 @@ import {
import { db, storage } from "../services/firebase/firebaseConfig";
import { Collections, StorageDirectory } from "../services/firebase/names";
import { IPCStatus } from "../data/enums/ipc-status.enum";
import { testOrgs } from "./TestOrganisationsMock";
import { testOrgs } from "./testOrganisationsMock";
import { listingsFolder } from "../services/firebase/storage";
import { getDownloadURL, ref, uploadBytes } from "@firebase/storage";
import { createOrganisationSummary } from "../data/model/organisationSummary";
import { createOrganisationProfileOurStory } from "../data/model/organisationProfile/organisationProfileOurStory";
import { createOrganisationProfilePeopleSpotlight } from "../data/model/organisationProfile/organisationProfilePeopleSpotlight";
import { faker } from "@faker-js/faker";
import { QuillEditor } from "./QuillEditor";
import { listingsFolder } from "../services/firebase/storage";
import { QuillEditor } from "./quillEditor";

class FirestoreMockPage extends Component {
parseData = async () => {
@@ -111,8 +111,8 @@ class FirestoreMockPage extends Component {
};

getOrgs = async () => {
getOrganisationsForListingsPage().then((orgs) =>
orgs.forEach((o) => console.log(o))
getOrganisationsForListingsPage().then((res) =>
res.organisations.forEach((o) => console.log(o))
);
};

File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
1 change: 0 additions & 1 deletion src/pages/Home/index.ts

This file was deleted.

1 change: 0 additions & 1 deletion src/pages/Login/index.ts

This file was deleted.

Loading

0 comments on commit 70cf063

Please sign in to comment.