From a873aff012bd4089dd46df39020fcb284e239a64 Mon Sep 17 00:00:00 2001 From: pixelerate Date: Tue, 5 Dec 2023 00:14:22 +0000 Subject: [PATCH 1/7] good lord it finally works --- src/components/SearchInput.tsx | 4 +- src/components/content/MPIndex.tsx | 10 ++++- src/components/filters/Filters.tsx | 67 ++++++++++++++---------------- src/data/types.ts | 1 + src/data/utils/utils.test.ts | 1 + src/data/utils/utils.ts | 5 ++- src/state/actions.ts | 5 +++ src/state/reducer.ts | 15 ++++++- src/state/store.ts | 1 + 9 files changed, 67 insertions(+), 42 deletions(-) diff --git a/src/components/SearchInput.tsx b/src/components/SearchInput.tsx index 3de60b0..5ddcf75 100644 --- a/src/components/SearchInput.tsx +++ b/src/components/SearchInput.tsx @@ -8,7 +8,7 @@ export const SearchInput: React.FC = () => { dispatch({ type: SET_SEARCH_INPUT_ACTION, payload: { value } }); }; return ( - <> +
@@ -34,6 +34,6 @@ export const SearchInput: React.FC = () => { onChange={(e) => handleSearchChange(e.currentTarget.value)} />
- + ); }; diff --git a/src/components/content/MPIndex.tsx b/src/components/content/MPIndex.tsx index 5b4fb31..a70d668 100644 --- a/src/components/content/MPIndex.tsx +++ b/src/components/content/MPIndex.tsx @@ -1,6 +1,6 @@ import React, { useMemo, useState } from "react"; import { Accordion } from "./Accordion"; -import { filterProfiles } from "../../data/utils/utils"; +import { filterProfiles, sortByWin } from "../../data/utils/utils"; import { useSelector } from "react-redux"; import { AppState } from "../../state/store"; import { MP } from "../../data/types"; @@ -26,7 +26,13 @@ const MPIndex: React.FC = () => { ) : (
- +
)} diff --git a/src/components/filters/Filters.tsx b/src/components/filters/Filters.tsx index c7aae87..1b40654 100644 --- a/src/components/filters/Filters.tsx +++ b/src/components/filters/Filters.tsx @@ -1,48 +1,45 @@ -import React from "react"; +import React, { useState } from "react"; import { SearchInput } from "../SearchInput"; - +import { useDispatch } from "react-redux"; +import { SET_SORTBY_ACTION } from "../../state/actions"; export const Filters: React.FC = () => { return ( -
+
+
); }; -// type SelectedSortDirection = "ascending" | "descending"; +type SelectedSortDirection = "ascending" | "descending"; // TODO: Not make this break everything -// const SortByDropdown: React.FC = () => { -// const dispatch = useDispatch(); -// const profiles = useSelector((state: AppState) => state.data.profiles); +const SortByDropdown: React.FC = () => { + const dispatch = useDispatch(); -// const [sortDirection, setSortDirection] = useState< -// SelectedSortDirection | undefined -// >(undefined); + const [sortDirection, setSortDirection] = useState< + SelectedSortDirection | undefined + >(undefined); -// const handleSelectChange = (value: SelectedSortDirection) => { -// const sortedProfiles = sortByWin(profiles, value === "descending"); -// dispatch({ -// type: SET_DATA_ACTION, -// payload: { profiles: sortedProfiles, status: "complete" }, -// }); -// setSortDirection(value); -// }; + const handleSelectChange = (value: SelectedSortDirection) => { + dispatch({ + type: SET_SORTBY_ACTION, + payload: { descending: value === "descending" }, + }); + setSortDirection(value); + }; -// return ( -// -// ); -// }; + return ( + + ); +}; diff --git a/src/data/types.ts b/src/data/types.ts index 931cdee..0c62aa3 100644 --- a/src/data/types.ts +++ b/src/data/types.ts @@ -78,4 +78,5 @@ export type ViewType = "about" | "index"; export type Filters = { policies: Record, Policy>; searchInput: string; + sortDescending?: boolean; }; diff --git a/src/data/utils/utils.test.ts b/src/data/utils/utils.test.ts index b0da5cf..d1264a4 100644 --- a/src/data/utils/utils.test.ts +++ b/src/data/utils/utils.test.ts @@ -501,6 +501,7 @@ const blankFilters = (): Filters => ({ positive: undefined, }, }, + sortDescending: true, }); describe("filterProfiles", () => { diff --git a/src/data/utils/utils.ts b/src/data/utils/utils.ts index 2206744..b031052 100644 --- a/src/data/utils/utils.ts +++ b/src/data/utils/utils.ts @@ -225,7 +225,7 @@ const sortAB = (a: number | undefined, b: number | undefined): number => { }; export const sortByWin = (profiles: MP[], descending: boolean): MP[] => { - return profiles.sort((a, b) => { + const sorted = profiles.sort((a, b) => { const aPercent = a.winningProbability ? a.winningProbability.percentage : undefined; @@ -235,6 +235,9 @@ export const sortByWin = (profiles: MP[], descending: boolean): MP[] => { const sorted = sortAB(aPercent, bPercent); return descending ? -sorted : sorted; }); + console.log(profiles.length); + console.log(sorted.length); + return sorted; }; export const filterProfiles = (profiles: MP[], filters: Filters): MP[] => { diff --git a/src/state/actions.ts b/src/state/actions.ts index abeeee0..20ca96a 100644 --- a/src/state/actions.ts +++ b/src/state/actions.ts @@ -4,6 +4,7 @@ export const SET_VIEW_ACTION = "set-view"; export const SET_DATA_ACTION = "set-data"; export const SET_POLICY_STANCE_ACTION = "set-policy-stance"; export const SET_SEARCH_INPUT_ACTION = "set-search-input"; +export const SET_SORTBY_ACTION = "set-sort-by-input"; export type Action = | { type: typeof SET_VIEW_ACTION; payload: { view: ViewType } } @@ -15,6 +16,10 @@ export type Action = type: typeof SET_POLICY_STANCE_ACTION; payload: { category: PolicyType; positive?: boolean }; } + | { + type: typeof SET_SORTBY_ACTION; + payload: { descending: boolean }; + } | { type: typeof SET_SEARCH_INPUT_ACTION; payload: { value: string }; diff --git a/src/state/reducer.ts b/src/state/reducer.ts index 325f63d..3285785 100644 --- a/src/state/reducer.ts +++ b/src/state/reducer.ts @@ -4,6 +4,7 @@ import { SET_DATA_ACTION, SET_VIEW_ACTION, SET_SEARCH_INPUT_ACTION, + SET_SORTBY_ACTION, } from "./actions"; import { AppState, initState } from "./store"; @@ -33,11 +34,11 @@ export default function appReducer( } case SET_POLICY_STANCE_ACTION: { const { category, positive } = action.payload; - const { policies, searchInput } = state.activeFilters; + const { policies } = state.activeFilters; return { ...state, activeFilters: { - searchInput, + ...state.activeFilters, policies: { ...policies, [category]: { positive } }, }, }; @@ -52,6 +53,16 @@ export default function appReducer( }, }; } + case SET_SORTBY_ACTION: { + const { descending } = action.payload; + return { + ...state, + activeFilters: { + ...state.activeFilters, + sortDescending: descending, + }, + }; + } default: { return state; } diff --git a/src/state/store.ts b/src/state/store.ts index 4d667b9..782c6ab 100644 --- a/src/state/store.ts +++ b/src/state/store.ts @@ -57,6 +57,7 @@ export const initState: AppState = { positive: undefined, }, }, + sortDescending: true, }, }; From 061f3a028003fe79ac971901e982a5dac65c3312 Mon Sep 17 00:00:00 2001 From: pixelerate Date: Sun, 10 Dec 2023 18:58:33 +0000 Subject: [PATCH 2/7] Update MPIndex.tsx --- src/components/content/MPIndex.tsx | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/components/content/MPIndex.tsx b/src/components/content/MPIndex.tsx index a70d668..3d04849 100644 --- a/src/components/content/MPIndex.tsx +++ b/src/components/content/MPIndex.tsx @@ -14,7 +14,16 @@ const MPIndex: React.FC = () => { const [mps, setMPs] = useState(filterProfiles(profiles, filters)); useMemo(() => { - setMPs(filterProfiles(profiles, filters)); + if (filters.sortDescending !== undefined) { + setMPs( + sortByWin( + filterProfiles(profiles, filters).slice(), + filters.sortDescending + ) + ); + } else { + setMPs(filterProfiles(profiles, filters)); + } }, [filters, profiles]); return ( @@ -26,13 +35,7 @@ const MPIndex: React.FC = () => { ) : (
- +
)} From b25b86031065c2a78a4c02a899590aa143855eb5 Mon Sep 17 00:00:00 2001 From: pixelerate Date: Tue, 12 Dec 2023 19:29:40 +0000 Subject: [PATCH 3/7] link template and sort working --- src/components/Header.tsx | 2 + src/components/atoms/Link.tsx | 10 ++++ src/components/content/About.tsx | 28 +++-------- src/components/content/FormattedContent.tsx | 19 ++------ src/components/filters/Filters.tsx | 52 +++++++++++++-------- src/components/sidebar/Footer.tsx | 31 ++++-------- 6 files changed, 63 insertions(+), 79 deletions(-) create mode 100644 src/components/atoms/Link.tsx diff --git a/src/components/Header.tsx b/src/components/Header.tsx index 96c206d..d171b28 100644 --- a/src/components/Header.tsx +++ b/src/components/Header.tsx @@ -3,6 +3,7 @@ import { ProjectTitle } from "./atoms/ProjectTitle"; import { ViewType } from "../data/types"; import { SET_VIEW_ACTION } from "../state/actions"; import { useDispatch } from "react-redux"; +import { SortByDropdown } from "./filters/Filters"; export const Header: React.FC<{ view: "about" | "index"; @@ -41,6 +42,7 @@ export const Header: React.FC<{ About
+ diff --git a/src/components/atoms/Link.tsx b/src/components/atoms/Link.tsx new file mode 100644 index 0000000..b6034da --- /dev/null +++ b/src/components/atoms/Link.tsx @@ -0,0 +1,10 @@ +const TextLink: React.FC<{ children: React.ReactNode; link: string }> = ({ + children, + link, +}) => ( + + {children} + +); + +export default TextLink; diff --git a/src/components/content/About.tsx b/src/components/content/About.tsx index 0bd4c83..bfc8208 100644 --- a/src/components/content/About.tsx +++ b/src/components/content/About.tsx @@ -1,4 +1,5 @@ import React from "react"; +import TextLink from "../atoms/Link"; const faqs: { question: string; answer: JSX.Element }[] = [ { @@ -131,14 +132,9 @@ const faqs: { question: string; answer: JSX.Element }[] = [

This tool was made by volunteer researchers from the{" "} - + Movement Research Unit - + . We do practical research in support of social movements and campaign groups. @@ -151,25 +147,15 @@ const faqs: { question: string; answer: JSX.Element }[] = [

There are two ways: you can{" "} - + get involved - + {" "} (no research experience necessary) or you can{" "} - + donate - + {" "} to cover our running costs.

diff --git a/src/components/content/FormattedContent.tsx b/src/components/content/FormattedContent.tsx index a6400e1..c2e9465 100644 --- a/src/components/content/FormattedContent.tsx +++ b/src/components/content/FormattedContent.tsx @@ -1,5 +1,6 @@ import React from "react"; import { extractLinks } from "../../data/utils/string"; +import TextLink from "../atoms/Link"; export const FormattedContent: React.FC<{ subHeader: string; @@ -21,14 +22,7 @@ export const FormattedContent: React.FC<{
  • {formattedPoint.content}{" "} {formattedPoint.link?.[0] && ( - - (source) - + (source) )}
  • ))} @@ -37,14 +31,7 @@ export const FormattedContent: React.FC<{ <> {formattedContent[0].content}{" "} {formattedContent[0].link && formattedContent[0].link.length > 0 && ( - - (source) - + (source) )} )} diff --git a/src/components/filters/Filters.tsx b/src/components/filters/Filters.tsx index 1b40654..8ac48ea 100644 --- a/src/components/filters/Filters.tsx +++ b/src/components/filters/Filters.tsx @@ -2,24 +2,22 @@ import React, { useState } from "react"; import { SearchInput } from "../SearchInput"; import { useDispatch } from "react-redux"; import { SET_SORTBY_ACTION } from "../../state/actions"; +import TextLink from "../atoms/Link"; export const Filters: React.FC = () => { - return ( -
    - - -
    - ); + return ; }; type SelectedSortDirection = "ascending" | "descending"; +const DESCENDING_OPT_TEXT = "Most Likely"; +const ASCENDING_OPT_TEXT = "Least Likely"; // TODO: Not make this break everything -const SortByDropdown: React.FC = () => { +export const SortByDropdown: React.FC = () => { const dispatch = useDispatch(); const [sortDirection, setSortDirection] = useState< SelectedSortDirection | undefined - >(undefined); + >("descending"); const handleSelectChange = (value: SelectedSortDirection) => { dispatch({ @@ -30,16 +28,32 @@ const SortByDropdown: React.FC = () => { }; return ( - +
    + + Sort by likeliness to win:{" "} + + (source) + + + +
    ); }; diff --git a/src/components/sidebar/Footer.tsx b/src/components/sidebar/Footer.tsx index f39dace..6b5167a 100644 --- a/src/components/sidebar/Footer.tsx +++ b/src/components/sidebar/Footer.tsx @@ -1,4 +1,5 @@ import React from "react"; +import TextLink from "../atoms/Link"; // TODO: Make templates for some of these links that get reused export const Footer: React.FC = () => { @@ -7,32 +8,16 @@ export const Footer: React.FC = () => {

    Built by volunteers at the{" "} - - Movement Research Unit. - + + Movement Research Unit + + .

    Questions or changes: mps@mvmtresearch.org

    - + Support our work. - - - Get involved. - + + Get involved. ); }; From 7f7038a7c98bf2e260c6e0a98009dc2e9a9db0ef Mon Sep 17 00:00:00 2001 From: pixelerate Date: Tue, 12 Dec 2023 19:55:07 +0000 Subject: [PATCH 4/7] Move about filters --- src/components/Header.tsx | 8 ++++---- src/components/Main.tsx | 2 +- src/components/content/MPIndex.tsx | 5 ++--- src/components/filters/Filters.tsx | 4 ---- src/components/{ => filters}/SearchInput.tsx | 4 ++-- src/components/sidebar/SidebarContent.tsx | 2 ++ 6 files changed, 11 insertions(+), 14 deletions(-) rename src/components/{ => filters}/SearchInput.tsx (91%) diff --git a/src/components/Header.tsx b/src/components/Header.tsx index d171b28..439e9e3 100644 --- a/src/components/Header.tsx +++ b/src/components/Header.tsx @@ -3,7 +3,7 @@ import { ProjectTitle } from "./atoms/ProjectTitle"; import { ViewType } from "../data/types"; import { SET_VIEW_ACTION } from "../state/actions"; import { useDispatch } from "react-redux"; -import { SortByDropdown } from "./filters/Filters"; +import { SearchInput } from "./filters/SearchInput"; export const Header: React.FC<{ view: "about" | "index"; @@ -16,14 +16,14 @@ export const Header: React.FC<{ return (
    ); diff --git a/src/components/Main.tsx b/src/components/Main.tsx index a1bc8da..25a9953 100644 --- a/src/components/Main.tsx +++ b/src/components/Main.tsx @@ -4,7 +4,7 @@ import MPIndex from "./content/MPIndex"; const Main: React.FC<{ view: "about" | "index" }> = ({ view }) => { return ( -
    +
    {view === "about" && } {view === "index" && }
    diff --git a/src/components/content/MPIndex.tsx b/src/components/content/MPIndex.tsx index 3d04849..65057f0 100644 --- a/src/components/content/MPIndex.tsx +++ b/src/components/content/MPIndex.tsx @@ -5,7 +5,7 @@ import { useSelector } from "react-redux"; import { AppState } from "../../state/store"; import { MP } from "../../data/types"; import { Spinner } from "../atoms/Spinner"; -import { Filters } from "../filters/Filters"; +import { SearchInput } from "../filters/SearchInput"; const MPIndex: React.FC = () => { const filters = useSelector((state: AppState) => state.activeFilters); @@ -33,8 +33,7 @@ const MPIndex: React.FC = () => {
    ) : ( -
    - +
    )} diff --git a/src/components/filters/Filters.tsx b/src/components/filters/Filters.tsx index 8ac48ea..da6efb4 100644 --- a/src/components/filters/Filters.tsx +++ b/src/components/filters/Filters.tsx @@ -1,11 +1,7 @@ import React, { useState } from "react"; -import { SearchInput } from "../SearchInput"; import { useDispatch } from "react-redux"; import { SET_SORTBY_ACTION } from "../../state/actions"; import TextLink from "../atoms/Link"; -export const Filters: React.FC = () => { - return ; -}; type SelectedSortDirection = "ascending" | "descending"; const DESCENDING_OPT_TEXT = "Most Likely"; diff --git a/src/components/SearchInput.tsx b/src/components/filters/SearchInput.tsx similarity index 91% rename from src/components/SearchInput.tsx rename to src/components/filters/SearchInput.tsx index 5ddcf75..53af3ec 100644 --- a/src/components/SearchInput.tsx +++ b/src/components/filters/SearchInput.tsx @@ -1,6 +1,6 @@ import React from "react"; import { useDispatch } from "react-redux"; -import { SET_SEARCH_INPUT_ACTION } from "../state/actions"; +import { SET_SEARCH_INPUT_ACTION } from "../../state/actions"; export const SearchInput: React.FC = () => { const dispatch = useDispatch(); @@ -8,7 +8,7 @@ export const SearchInput: React.FC = () => { dispatch({ type: SET_SEARCH_INPUT_ACTION, payload: { value } }); }; return ( -
    +
    diff --git a/src/components/sidebar/SidebarContent.tsx b/src/components/sidebar/SidebarContent.tsx index d9a4e35..f033f1f 100644 --- a/src/components/sidebar/SidebarContent.tsx +++ b/src/components/sidebar/SidebarContent.tsx @@ -2,6 +2,7 @@ import React from "react"; import { ProjectTitle } from "../atoms/ProjectTitle"; import { Footer } from "./Footer"; import { PolicyStance } from "../filters/PolicyStance"; +import { SortByDropdown } from "../filters/Filters"; export const SidebarContent: React.FC = () => { return ( @@ -10,6 +11,7 @@ export const SidebarContent: React.FC = () => {
    +
    From 657ae93bcbd95b254e77096582331dd1d7784c58 Mon Sep 17 00:00:00 2001 From: pixelerate Date: Tue, 12 Dec 2023 19:58:56 +0000 Subject: [PATCH 5/7] Add github link --- src/components/filters/Filters.tsx | 1 - src/components/sidebar/Footer.tsx | 10 +++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/components/filters/Filters.tsx b/src/components/filters/Filters.tsx index da6efb4..bcb618d 100644 --- a/src/components/filters/Filters.tsx +++ b/src/components/filters/Filters.tsx @@ -7,7 +7,6 @@ type SelectedSortDirection = "ascending" | "descending"; const DESCENDING_OPT_TEXT = "Most Likely"; const ASCENDING_OPT_TEXT = "Least Likely"; -// TODO: Not make this break everything export const SortByDropdown: React.FC = () => { const dispatch = useDispatch(); diff --git a/src/components/sidebar/Footer.tsx b/src/components/sidebar/Footer.tsx index 6b5167a..ff61e2b 100644 --- a/src/components/sidebar/Footer.tsx +++ b/src/components/sidebar/Footer.tsx @@ -1,7 +1,7 @@ import React from "react"; import TextLink from "../atoms/Link"; +import { GithubLogo } from "@phosphor-icons/react"; -// TODO: Make templates for some of these links that get reused export const Footer: React.FC = () => { return (
    @@ -18,6 +18,14 @@ export const Footer: React.FC = () => { Support our work. Get involved. + + + Contribute on Github{" "} + + + + +
    ); }; From 908cf996bd54866483effb184749edbf0245803f Mon Sep 17 00:00:00 2001 From: pixelerate Date: Tue, 12 Dec 2023 20:01:12 +0000 Subject: [PATCH 6/7] Update MPIndex.tsx --- src/components/content/MPIndex.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/content/MPIndex.tsx b/src/components/content/MPIndex.tsx index 65057f0..a0be64f 100644 --- a/src/components/content/MPIndex.tsx +++ b/src/components/content/MPIndex.tsx @@ -5,7 +5,6 @@ import { useSelector } from "react-redux"; import { AppState } from "../../state/store"; import { MP } from "../../data/types"; import { Spinner } from "../atoms/Spinner"; -import { SearchInput } from "../filters/SearchInput"; const MPIndex: React.FC = () => { const filters = useSelector((state: AppState) => state.activeFilters); From c7a09b75511bb5c5d7e13d13868394b5e9c1db48 Mon Sep 17 00:00:00 2001 From: pixelerate Date: Tue, 12 Dec 2023 20:10:28 +0000 Subject: [PATCH 7/7] Update utils.ts --- src/data/utils/utils.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/data/utils/utils.ts b/src/data/utils/utils.ts index b7aa591..25235fa 100644 --- a/src/data/utils/utils.ts +++ b/src/data/utils/utils.ts @@ -235,8 +235,6 @@ export const sortByWin = (profiles: MP[], descending: boolean): MP[] => { const sorted = sortAB(aPercent, bPercent); return descending ? -sorted : sorted; }); - console.log(profiles.length); - console.log(sorted.length); return sorted; };