feat: /capture and / are static
This commit is contained in:
parent
98c7c31a0f
commit
f056d257b2
|
@ -1,33 +1,18 @@
|
||||||
import { GetServerSideProps, NextPage } from 'next';
|
import { GetStaticProps, NextPage } from 'next';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { getFrontpage } from '../backend/frontpage';
|
import { getFrontpage } from '../backend/frontpage';
|
||||||
import CommonDisplay, { QueryParameters } from '../web/display/commonDisplay';
|
import CommonDisplay from '../web/display/commonDisplay';
|
||||||
import { displayForecastsWrapperForCapture } from '../web/display/displayForecastsWrappers';
|
import { displayForecastsWrapperForCapture } from '../web/display/displayForecastsWrappers';
|
||||||
import { platformsWithLabels } from '../web/platforms';
|
|
||||||
import Layout from './layout';
|
import Layout from './layout';
|
||||||
|
|
||||||
/* get Props */
|
/* get Props */
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
initialQueryParameters: QueryParameters;
|
|
||||||
defaultResults: any;
|
defaultResults: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getServerSideProps: GetServerSideProps<Props> = async (
|
export const getStaticProps: GetStaticProps<Props> = async (context) => {
|
||||||
context
|
|
||||||
) => {
|
|
||||||
let urlQuery = context.query;
|
|
||||||
|
|
||||||
let initialQueryParameters: QueryParameters = {
|
|
||||||
query: "",
|
|
||||||
numDisplay: 21,
|
|
||||||
starsThreshold: 2,
|
|
||||||
forecastsThreshold: 0,
|
|
||||||
forecastingPlatforms: platformsWithLabels, // weird key value format,
|
|
||||||
...urlQuery,
|
|
||||||
};
|
|
||||||
|
|
||||||
let frontPageForecasts = await getFrontpage();
|
let frontPageForecasts = await getFrontpage();
|
||||||
frontPageForecasts = frontPageForecasts.map((forecast) => ({
|
frontPageForecasts = frontPageForecasts.map((forecast) => ({
|
||||||
...forecast,
|
...forecast,
|
||||||
|
@ -39,19 +24,18 @@ export const getServerSideProps: GetServerSideProps<Props> = async (
|
||||||
|
|
||||||
return {
|
return {
|
||||||
props: {
|
props: {
|
||||||
initialQueryParameters: initialQueryParameters,
|
|
||||||
defaultResults: frontPageForecasts,
|
defaultResults: frontPageForecasts,
|
||||||
},
|
},
|
||||||
|
revalidate: 3600 * 6,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Body */
|
/* Body */
|
||||||
const Home: NextPage<Props> = ({ defaultResults, initialQueryParameters }) => {
|
const CapturePage: NextPage<Props> = ({ defaultResults }) => {
|
||||||
return (
|
return (
|
||||||
<Layout page={"capture"}>
|
<Layout page={"capture"}>
|
||||||
<CommonDisplay
|
<CommonDisplay
|
||||||
defaultResults={defaultResults}
|
defaultResults={defaultResults}
|
||||||
initialQueryParameters={initialQueryParameters}
|
|
||||||
hasSearchbar={true}
|
hasSearchbar={true}
|
||||||
hasCapture={true}
|
hasCapture={true}
|
||||||
hasAdvancedOptions={false}
|
hasAdvancedOptions={false}
|
||||||
|
@ -63,4 +47,4 @@ const Home: NextPage<Props> = ({ defaultResults, initialQueryParameters }) => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Home;
|
export default CapturePage;
|
||||||
|
|
|
@ -1,33 +1,18 @@
|
||||||
import { GetServerSideProps, NextPage } from 'next';
|
import { GetStaticProps, NextPage } from 'next';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { getFrontpage } from '../backend/frontpage';
|
import { getFrontpage } from '../backend/frontpage';
|
||||||
import CommonDisplay, { QueryParameters } from '../web/display/commonDisplay';
|
import CommonDisplay from '../web/display/commonDisplay';
|
||||||
import { displayForecastsWrapperForSearch } from '../web/display/displayForecastsWrappers';
|
import { displayForecastsWrapperForSearch } from '../web/display/displayForecastsWrappers';
|
||||||
import { platformsWithLabels } from '../web/platforms';
|
|
||||||
import Layout from './layout';
|
import Layout from './layout';
|
||||||
|
|
||||||
/* get Props */
|
/* get Props */
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
initialQueryParameters: QueryParameters;
|
|
||||||
defaultResults: any;
|
defaultResults: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getServerSideProps: GetServerSideProps<Props> = async (
|
export const getStaticProps: GetStaticProps<Props> = async (context) => {
|
||||||
context
|
|
||||||
) => {
|
|
||||||
let urlQuery = context.query;
|
|
||||||
|
|
||||||
let initialQueryParameters: QueryParameters = {
|
|
||||||
query: "",
|
|
||||||
numDisplay: 21,
|
|
||||||
starsThreshold: 2,
|
|
||||||
forecastsThreshold: 0,
|
|
||||||
forecastingPlatforms: platformsWithLabels, // weird key value format,
|
|
||||||
...urlQuery,
|
|
||||||
};
|
|
||||||
|
|
||||||
let frontPageForecasts = await getFrontpage();
|
let frontPageForecasts = await getFrontpage();
|
||||||
frontPageForecasts = frontPageForecasts.map((forecast) => ({
|
frontPageForecasts = frontPageForecasts.map((forecast) => ({
|
||||||
...forecast,
|
...forecast,
|
||||||
|
@ -39,19 +24,18 @@ export const getServerSideProps: GetServerSideProps<Props> = async (
|
||||||
|
|
||||||
return {
|
return {
|
||||||
props: {
|
props: {
|
||||||
initialQueryParameters: initialQueryParameters,
|
|
||||||
defaultResults: frontPageForecasts,
|
defaultResults: frontPageForecasts,
|
||||||
},
|
},
|
||||||
|
revalidate: 3600 * 6,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Body */
|
/* Body */
|
||||||
const Home: NextPage<Props> = ({ defaultResults, initialQueryParameters }) => {
|
const IndexPage: NextPage<Props> = ({ defaultResults }) => {
|
||||||
return (
|
return (
|
||||||
<Layout page={"search"}>
|
<Layout page={"search"}>
|
||||||
<CommonDisplay
|
<CommonDisplay
|
||||||
defaultResults={defaultResults}
|
defaultResults={defaultResults}
|
||||||
initialQueryParameters={initialQueryParameters}
|
|
||||||
hasSearchbar={true}
|
hasSearchbar={true}
|
||||||
hasCapture={false}
|
hasCapture={false}
|
||||||
hasAdvancedOptions={true}
|
hasAdvancedOptions={true}
|
||||||
|
@ -63,4 +47,4 @@ const Home: NextPage<Props> = ({ defaultResults, initialQueryParameters }) => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Home;
|
export default IndexPage;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
|
import { useRouter } from 'next/router';
|
||||||
import React, { Fragment, useEffect, useState } from 'react';
|
import React, { Fragment, useEffect, useState } from 'react';
|
||||||
|
|
||||||
import { platformNames, PlatformWithLabel } from '../platforms';
|
import { platformsWithLabels, PlatformWithLabel } from '../platforms';
|
||||||
import searchAccordingToQueryData from '../worker/searchAccordingToQueryData';
|
import searchAccordingToQueryData from '../worker/searchAccordingToQueryData';
|
||||||
import ButtonsForStars from './buttonsForStars';
|
import ButtonsForStars from './buttonsForStars';
|
||||||
import Form from './form';
|
import Form from './form';
|
||||||
|
@ -20,7 +21,6 @@ export interface QueryParameters extends QueryParametersWithoutNum {
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
defaultResults: any;
|
defaultResults: any;
|
||||||
initialQueryParameters: QueryParameters;
|
|
||||||
hasSearchbar: boolean;
|
hasSearchbar: boolean;
|
||||||
hasCapture: boolean;
|
hasCapture: boolean;
|
||||||
hasAdvancedOptions: boolean;
|
hasAdvancedOptions: boolean;
|
||||||
|
@ -34,28 +34,17 @@ interface Props {
|
||||||
}) => React.ReactNode;
|
}) => React.ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Helper functions */
|
const defaultQueryParameters: QueryParametersWithoutNum = {
|
||||||
|
query: "",
|
||||||
// URL slugs
|
starsThreshold: 2,
|
||||||
let transformObjectIntoUrlSlug = (obj: QueryParameters) => {
|
forecastsThreshold: 0,
|
||||||
let results = [];
|
forecastingPlatforms: platformsWithLabels, // weird key value format,
|
||||||
for (let key in obj) {
|
|
||||||
if (typeof obj[key] === "number" || typeof obj[key] === "string") {
|
|
||||||
results.push(`${key}=${obj[key]}`);
|
|
||||||
} else if (key === "forecastingPlatforms") {
|
|
||||||
let arr = obj[key].map((x) => x.value);
|
|
||||||
let arrstring = arr.join("|");
|
|
||||||
results.push(`${key}=${arrstring}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let string = "?" + results.join("&");
|
|
||||||
return string;
|
|
||||||
};
|
};
|
||||||
|
const defaultNumDisplay = 21;
|
||||||
|
|
||||||
/* Body */
|
/* Body */
|
||||||
const CommonDisplay: React.FC<Props> = ({
|
const CommonDisplay: React.FC<Props> = ({
|
||||||
defaultResults,
|
defaultResults,
|
||||||
initialQueryParameters,
|
|
||||||
hasSearchbar,
|
hasSearchbar,
|
||||||
hasCapture,
|
hasCapture,
|
||||||
hasAdvancedOptions,
|
hasAdvancedOptions,
|
||||||
|
@ -63,14 +52,18 @@ const CommonDisplay: React.FC<Props> = ({
|
||||||
displaySeeMoreHint,
|
displaySeeMoreHint,
|
||||||
displayForecastsWrapper,
|
displayForecastsWrapper,
|
||||||
}) => {
|
}) => {
|
||||||
|
const router = useRouter();
|
||||||
/* States */
|
/* States */
|
||||||
|
|
||||||
const [queryParameters, setQueryParameters] =
|
const [queryParameters, setQueryParameters] =
|
||||||
useState<QueryParametersWithoutNum>(initialQueryParameters);
|
useState<QueryParametersWithoutNum>(defaultQueryParameters);
|
||||||
|
|
||||||
const [numDisplay, setNumDisplay] = useState(
|
const [numDisplay, setNumDisplay] = useState(0);
|
||||||
initialQueryParameters.numDisplay || 21
|
|
||||||
);
|
const [ready, setReady] = useState(false);
|
||||||
|
|
||||||
|
// used to distinguish numDisplay updates which force search and don't force search, see effects below
|
||||||
|
const [forceSearch, setForceSearch] = useState(0);
|
||||||
|
|
||||||
const [results, setResults] = useState([]);
|
const [results, setResults] = useState([]);
|
||||||
const [advancedOptions, showAdvancedOptions] = useState(false);
|
const [advancedOptions, showAdvancedOptions] = useState(false);
|
||||||
|
@ -78,13 +71,29 @@ const CommonDisplay: React.FC<Props> = ({
|
||||||
useState(0);
|
useState(0);
|
||||||
const [showIdToggle, setShowIdToggle] = useState(false);
|
const [showIdToggle, setShowIdToggle] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!router.isReady) return;
|
||||||
|
|
||||||
|
setQueryParameters({
|
||||||
|
...defaultQueryParameters,
|
||||||
|
...router.query,
|
||||||
|
});
|
||||||
|
setNumDisplay(
|
||||||
|
typeof router.query.numDisplay === "string"
|
||||||
|
? parseInt(router.query.numDisplay)
|
||||||
|
: defaultNumDisplay
|
||||||
|
);
|
||||||
|
setReady(true);
|
||||||
|
}, [router.isReady]);
|
||||||
|
|
||||||
/* Functions which I want to have access to the Home namespace */
|
/* Functions which I want to have access to the Home namespace */
|
||||||
// I don't want to create an "defaultResults" object for each search.
|
// I don't want to create an "defaultResults" object for each search.
|
||||||
async function executeSearchOrAnswerWithDefaultResults(
|
async function executeSearchOrAnswerWithDefaultResults() {
|
||||||
queryData: QueryParameters
|
const queryData = {
|
||||||
) {
|
...queryParameters,
|
||||||
// the queryData object has the same contents as queryParameters.
|
numDisplay,
|
||||||
// but I wanted to spare myself having to think about namespace conflicts.
|
};
|
||||||
|
|
||||||
let filterManually = (queryData: QueryParameters, results) => {
|
let filterManually = (queryData: QueryParameters, results) => {
|
||||||
if (
|
if (
|
||||||
queryData.forecastingPlatforms &&
|
queryData.forecastingPlatforms &&
|
||||||
|
@ -136,43 +145,46 @@ const CommonDisplay: React.FC<Props> = ({
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
const updateRoute = () => {
|
||||||
setResults([]);
|
const stringify = (key: string, value: any) => {
|
||||||
let newTimeoutId = setTimeout(async () => {
|
if (key === "forecastingPlatforms") {
|
||||||
let urlSlug = transformObjectIntoUrlSlug({
|
return value.map((x) => x.value).join("|");
|
||||||
...queryParameters,
|
} else {
|
||||||
numDisplay,
|
return String(value);
|
||||||
});
|
|
||||||
let urlWithoutDefaultParameters = urlSlug
|
|
||||||
.replace("?query=&", "?")
|
|
||||||
.replace("&starsThreshold=2", "")
|
|
||||||
.replace("&numDisplay=21", "")
|
|
||||||
.replace("&forecastsThreshold=0", "")
|
|
||||||
.replace(`&forecastingPlatforms=${platformNames.join("|")}`, "");
|
|
||||||
console.log(urlWithoutDefaultParameters);
|
|
||||||
if (urlWithoutDefaultParameters != "?query=") {
|
|
||||||
if (typeof window !== "undefined") {
|
|
||||||
if (!window.location.href.includes(urlWithoutDefaultParameters)) {
|
|
||||||
window.history.replaceState(
|
|
||||||
null,
|
|
||||||
"Metaforecast",
|
|
||||||
urlWithoutDefaultParameters
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const query = {};
|
||||||
|
for (const key of Object.keys(defaultQueryParameters)) {
|
||||||
|
const value = stringify(key, queryParameters[key]);
|
||||||
|
const defaultValue = stringify(key, defaultQueryParameters[key]);
|
||||||
|
if (value === defaultValue) continue;
|
||||||
|
query[key] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
executeSearchOrAnswerWithDefaultResults({
|
if (numDisplay !== defaultNumDisplay) query["numDisplay"] = numDisplay;
|
||||||
...queryParameters,
|
|
||||||
numDisplay,
|
router.replace({
|
||||||
|
pathname: router.pathname,
|
||||||
|
query,
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(updateRoute, [numDisplay]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!ready) return;
|
||||||
|
setResults([]);
|
||||||
|
let newTimeoutId = setTimeout(() => {
|
||||||
|
updateRoute();
|
||||||
|
executeSearchOrAnswerWithDefaultResults();
|
||||||
}, 500);
|
}, 500);
|
||||||
|
|
||||||
// avoid sending results if user has not stopped typing.
|
// avoid sending results if user has not stopped typing.
|
||||||
return () => {
|
return () => {
|
||||||
clearTimeout(newTimeoutId);
|
clearTimeout(newTimeoutId);
|
||||||
};
|
};
|
||||||
}, [queryParameters]);
|
}, [ready, queryParameters, forceSearch]);
|
||||||
|
|
||||||
/* State controllers */
|
/* State controllers */
|
||||||
|
|
||||||
|
@ -195,7 +207,7 @@ const CommonDisplay: React.FC<Props> = ({
|
||||||
};
|
};
|
||||||
let onChangeSliderForNumDisplay = (event) => {
|
let onChangeSliderForNumDisplay = (event) => {
|
||||||
setNumDisplay(Math.round(event[0]));
|
setNumDisplay(Math.round(event[0]));
|
||||||
// FIXME - force new search if numDisplay is greater than last search limit
|
setForceSearch(forceSearch + 1); // FIXME - force new search iff numDisplay is greater than last search limit
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Change the forecast threshold */
|
/* Change the forecast threshold */
|
||||||
|
|
Loading…
Reference in New Issue
Block a user