Skip to content

Commit

Permalink
Merge pull request #124 from ConductionNL/feature/XW-95/queryParams
Browse files Browse the repository at this point in the history
feature/XW-95/queryParams
  • Loading branch information
remko48 authored Oct 19, 2023
2 parents fe1d46f + 9547666 commit d1df201
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 8 deletions.
40 changes: 38 additions & 2 deletions pwa/package-lock.json

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

6 changes: 5 additions & 1 deletion pwa/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
"private": true,
"description": "Product Website Template",
"author": "Conduction",
"keywords": ["gatsby"],
"keywords": [
"gatsby"
],
"scripts": {
"develop": "gatsby develop",
"start": "gatsby develop",
Expand Down Expand Up @@ -55,6 +57,7 @@
"@nl-design-system-unstable/zwolle-design-tokens": "^1.0.0-alpha.100",
"@parcel/watcher": "^2.3.0",
"@tabler/icons-react": "2.21.0",
"@types/qs": "^6.9.9",
"@types/react": "^18.0.28",
"@types/react-dom": "^18.0.11",
"@utrecht/component-library-react": "^1.0.0-alpha.394",
Expand All @@ -70,6 +73,7 @@
"i18next": "^21.6.16",
"jwt-decode": "^3.1.2",
"lodash": "^4.17.21",
"qs": "^6.11.2",
"react": "^18.2.0",
"react-collapsible": "^2.10.0",
"react-dom": "^18.2.0",
Expand Down
51 changes: 50 additions & 1 deletion pwa/src/services/filtersToQueryParams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export const filtersToQueryParams = (filters: any): string => {
delete filters[key];
});

let params = "";
let params: string = "";

for (const [key, value] of Object.entries(filters)) {
if (!value) continue;
Expand All @@ -28,4 +28,53 @@ export const filtersToQueryParams = (filters: any): string => {
return params;
};

export const filtersToUrlQueryParams = (filters: any): string => {
Object.keys(filters)
.filter((key) => filterKeysToRemove.includes(key))
.forEach((key) => {
delete filters[key];
});

let params: string = "";

var first_iteration = true;
for (const [key, value] of Object.entries(filters)) {
if (!value) continue;

if (first_iteration) {
if (typeof value === "string") {
params += `?${key}=${value.replace(/\s+/g, "_")}`;
}

if (Array.isArray(value)) {
let arrayParams = "";

value.forEach((value) => {
arrayParams += `?${key}[]=${value.replace(/\s+/g, "_")}`;
});

params += arrayParams;
}

first_iteration = false;
} else {
if (typeof value === "string") {
params += `&${key}=${value.replace(/\s+/g, "_")}`;
}

if (Array.isArray(value)) {
let arrayParams = "";

value.forEach((value) => {
arrayParams += `&${key}[]=${value.replace(/\s+/g, "_")}`;
});

params += arrayParams;
}
}
}

return params;
};

const filterKeysToRemove: string[] = [];
58 changes: 54 additions & 4 deletions pwa/src/templates/templateParts/filters/FiltersTemplate.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,38 @@
import * as React from "react";
import * as styles from "./FiltersTemplate.module.css";
import ResultsDisplaySwitch from "../../../components/resultsDisplaySwitch/ResultsDisplaySwitch";
import _ from "lodash";
import qs from "qs";
import { useForm } from "react-hook-form";
import { InputText, SelectSingle } from "@conduction/components";
import { useFiltersContext } from "../../../context/filters";
import { IFiltersContext, defaultFiltersContext, useFiltersContext } from "../../../context/filters";
import { Button } from "@utrecht/component-library-react/dist/css-module";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faMagnifyingGlass, faSpinner } from "@fortawesome/free-solid-svg-icons";
import { generateYearsArray } from "../../../data/years";
import { TEMP_PUBLICATION_TYPES } from "../../../data/PublicationType";
import { useTranslation } from "react-i18next";
import { filtersToUrlQueryParams } from "../../../services/filtersToQueryParams";
import { navigate } from "gatsby";
import { useGatsbyContext } from "../../../context/gatsby";

interface FiltersTemplateProps {
isLoading: boolean;
}

export const FiltersTemplate: React.FC<FiltersTemplateProps> = ({ isLoading }) => {
const { filters, setFilters } = useFiltersContext();
const { t } = useTranslation();
const { filters, setFilters } = useFiltersContext();
const { gatsbyContext } = useGatsbyContext();
const [queryParams, setQueryParams] = React.useState<IFiltersContext>(defaultFiltersContext);
const filterTimeout = React.useRef<NodeJS.Timeout | null>(null);

const {
control,
register,
handleSubmit,
watch,
setValue,
formState: { errors },
} = useForm();

Expand All @@ -33,9 +41,30 @@ export const FiltersTemplate: React.FC<FiltersTemplateProps> = ({ isLoading }) =
const today = new Date();
const currentYear = today.getFullYear();

const url = gatsbyContext.location.search;
const [, params] = url.split("?");
const parsedParams = qs.parse(params);

const handleSetFormValues = (params: any): void => {
const basicFields: string[] = ["_search", "category"];
basicFields.forEach((field) => setValue(field, params[field]));

setValue(
"year",
generateYearsArray(currentYear - 1995).find((year: any) => {
return year.after === params.Publicatiedatum?.after && year.before === params.Publicatiedatum?.before;
}),
);

setValue(
"category",
TEMP_PUBLICATION_TYPES.find((option) => option.value === params.Categorie?.replace(/_/g, " ")),
);
};

const onSubmit = (data: any) => {
setFilters({
_search: data.title,
_search: data._search,
"Publicatiedatum[after]": data.year?.after,
"Publicatiedatum[before]": data.year?.before,
Categorie: data.category?.value,
Expand All @@ -48,24 +77,45 @@ export const FiltersTemplate: React.FC<FiltersTemplateProps> = ({ isLoading }) =
filterTimeout.current = setTimeout(() => onSubmit(watcher), 500);
}, [watcher]);

React.useEffect(() => {
if (_.isEmpty(parsedParams)) return;

handleSetFormValues(parsedParams);
}, []);

React.useEffect(() => {
//Prevents loop that puts user at top of page after scroll
if (_.isEqual(filters, queryParams)) return;

setQueryParams(filters);
navigate(`/${filtersToUrlQueryParams(filters)}`);
}, [filters]);

return (
<div id="filters" className={styles.container}>
<form onSubmit={handleSubmit(onSubmit)} className={styles.form}>
<InputText
name="title"
name="_search"
placeholder={`${t("Search")}..`}
defaultValue={filters._search}
ariaLabel={t("Enter search query")}
{...{ register, errors }}
/>

<SelectSingle
options={generateYearsArray(currentYear - 1995)}
name="year"
placeholder={t("Year")}
isClearable
defaultValue={generateYearsArray(currentYear - 1995).find((year: any) => {
return (
year.after === filters["Publicatiedatum[after]"] && year.before === filters["Publicatiedatum[before]"]
);
})}
{...{ register, errors, control }}
ariaLabel={t("Select year")}
/>

<SelectSingle
options={TEMP_PUBLICATION_TYPES}
name="category"
Expand Down

0 comments on commit d1df201

Please sign in to comment.