Skip to content

Commit

Permalink
refactor: use redux initial state to get values from url
Browse files Browse the repository at this point in the history
Signed-off-by: Nishant Mittal <[email protected]>
  • Loading branch information
nishantwrp committed Dec 25, 2022
1 parent b968330 commit cef9a75
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 51 deletions.
60 changes: 16 additions & 44 deletions src/pages/index.jsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import React, { useEffect } from "react"
import React, { useEffect, useState } from "react"
import Fuse from "fuse.js"
import { graphql } from "gatsby"
import { useBreakpoint } from "gatsby-plugin-breakpoints"
import { navigate } from "@reach/router"

import "./index.css"

Expand All @@ -11,9 +10,10 @@ import OrgCard from "../components/org-card"
import SEO from "../components/seo"
import Notification from "../components/notification"
import { Grid } from "semantic-ui-react"
import { useAppDispatch, useAppSelector } from "../store"
import { getSearch, setSearch } from "../store/search"
import { getFilters, setFilters } from "../store/filters"
import { useAppSelector } from "../store"
import { getSearch } from "../store/search"
import { getFilters } from "../store/filters"
import { setSearchParams } from "../utils/searchParams"

const getOrganizations = data => {
return data.allOrganization.edges.map(orgNode => {
Expand Down Expand Up @@ -110,54 +110,26 @@ const getFilteredOrganizations = (data, searchQuery, filters) => {
return filteredOrganizations
}

const IndexPage = ({ data, location }) => {
const dispatch = useAppDispatch()
const IndexPage = ({ data }) => {
const searchQuery = useAppSelector(getSearch)
const filters = useAppSelector(getFilters)

// Any url would work here.
const currentURL = new URL("https://www.gsocorganizations.dev/")

try {
currentURL.search = location.search
} catch (err) {}

const getSearchQueryInUrl = () => {
return currentURL.searchParams.get("search") || ""
}

const getFiltersFromUrl = () => {
return (
JSON.parse(currentURL.searchParams.get("filters")) || {
years: [],
categories: [],
technologies: [],
topics: [],
}
)
}
const [orgCards, setOrgCards] = useState([])

useEffect(() => {
dispatch(setSearch(getSearchQueryInUrl()))
dispatch(setFilters(getFiltersFromUrl()))
}, [])
// Update the search params in the url if filters or search query
// change.
const searchParams = {};

useEffect(() => {
// Don't append search params if there is no filter or searchQurey.
if (searchQuery !== "") {
currentURL.searchParams.set("search", searchQuery)
} else {
currentURL.searchParams.delete("search")
if (searchQuery) {
searchParams["search"] = searchQuery;
}

if (Object.values(filters).filter(arr => arr.length !== 0).length !== 0) {
currentURL.searchParams.set("filters", JSON.stringify(filters))
} else {
currentURL.searchParams.delete("filters")
searchParams["filters"] = JSON.stringify(filters);
}
navigate(currentURL.search === "" ? "/" : currentURL.search)
}, [searchQuery, filters])

const [orgCards, setOrgCards] = React.useState([])
setSearchParams(searchParams);
}, [searchQuery, filters])

React.useEffect(() => {
let filteredOrganizations = getFilteredOrganizations(
Expand Down
13 changes: 8 additions & 5 deletions src/store/filters.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import { createSlice } from "@reduxjs/toolkit"
import { getSearchParam } from "../utils/searchParams";

const filtersSlice = createSlice({
name: "filters",
initialState: {
years: [],
categories: [],
technologies: [],
topics: [],
initialState: () => {
return JSON.parse(getSearchParam("filters")) || {
years: [],
categories: [],
technologies: [],
topics: [],
};
},
reducers: {
addFilter: (state, action) => {
Expand Down
7 changes: 5 additions & 2 deletions src/store/search.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { createSlice } from "@reduxjs/toolkit"
import { getSearchParam } from "../utils/searchParams"

const searchSlice = createSlice({
name: "search",
initialState: {
value: "",
initialState: () => {
return {
value: getSearchParam("search") || ""
}
},
reducers: {
setSearch: (state, action) => {
Expand Down
33 changes: 33 additions & 0 deletions src/utils/searchParams.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
* Updates the search params in the browser using JS history API.
* This will not re-render the complete application. Using this API
* may cause the react-router to go out of sync and give false values if
* accessed elsewhere.
* @param {{ [param: string]: string }} params
*/
export const setSearchParams = (params) => {
if (typeof window !== 'undefined' && window) {
const url = new URL(window.location);
url.search = "";
for (const [param, value] of Object.entries(params)) {
url.searchParams.set(param, value);
};
window.history.pushState({}, "", url);
} else {
console.error("error setting search params. window is not defined.");
}
};

/**
* Gets the value of the search param in the url. Returns null if doesn't exist.
* @param {string} param
* @returns {string | null}
*/
export const getSearchParam = (param) => {
if (typeof window !== 'undefined' && window) {
return new URL(window.location).searchParams.get(param);
} else {
console.error("error getting search params. window is not defined.");
return null;
}
};

0 comments on commit cef9a75

Please sign in to comment.