Refacto Select component to use parent state

This commit is contained in:
DrMint 2022-03-05 13:33:19 +01:00
parent 7c8fb24d67
commit 4c7d7231e3
2 changed files with 26 additions and 34 deletions

View File

@ -1,6 +1,8 @@
import { useEffect, useState } from "react"; import { Dispatch, SetStateAction, useState } from "react";
export type SelectProps = { export type SelectProps = {
setState: Dispatch<SetStateAction<number>>;
state: number;
options: SelectOption[]; options: SelectOption[];
selected?: number; selected?: number;
allowEmpty?: boolean; allowEmpty?: boolean;
@ -14,21 +16,8 @@ export type SelectOption = {
}; };
export default function Select(props: SelectProps): JSX.Element { export default function Select(props: SelectProps): JSX.Element {
const [selected, setSelected] = useState(
props.selected ? props.selected : props.allowEmpty ? -1 : 0
);
const [opened, setOpened] = useState(false); const [opened, setOpened] = useState(false);
useEffect(() => {
if (props.onChange) {
if (selected >= 0) {
props.onChange(props.options[selected].name);
} else {
props.onChange("");
}
}
}, [props, selected]);
return ( return (
<div <div
className={`relative transition-[filter] ${ className={`relative transition-[filter] ${
@ -41,11 +30,11 @@ export default function Select(props: SelectProps): JSX.Element {
}`} }`}
> >
<p onClick={() => setOpened(!opened)} className="w-full"> <p onClick={() => setOpened(!opened)} className="w-full">
{selected === -1 ? "—" : props.options[selected].label} {props.state === -1 ? "—" : props.options[props.state].label}
</p> </p>
{selected >= 0 && props.allowEmpty && ( {props.state >= 0 && props.allowEmpty && (
<span <span
onClick={() => setSelected(-1)} onClick={() => props.setState(-1)}
className="material-icons !text-xs" className="material-icons !text-xs"
> >
close close
@ -62,14 +51,14 @@ export default function Select(props: SelectProps): JSX.Element {
> >
{props.options.map((option, index) => ( {props.options.map((option, index) => (
<> <>
{index !== selected && ( {index !== props.state && (
<div <div
className="bg-light hover:bg-mid transition-colors cursor-pointer p-1 last-of-type:rounded-b-[1em]" className="bg-light hover:bg-mid transition-colors cursor-pointer p-1 last-of-type:rounded-b-[1em]"
key={option.name} key={option.name}
id={option.name} id={option.name}
onClick={() => { onClick={() => {
setOpened(false); setOpened(false);
setSelected(index); props.setState(index);
}} }}
> >
{option.label} {option.label}

View File

@ -33,8 +33,8 @@ export default function Library(props: LibraryProps): JSX.Element {
const langui = props.langui.websiteInterfaces.data[0].attributes; const langui = props.langui.websiteInterfaces.data[0].attributes;
const [showSubitems, setShowSubitems] = useState<boolean>(false); const [showSubitems, setShowSubitems] = useState<boolean>(false);
const [sortingMethod, setSortingMethod] = useState<string>("title"); const [sortingMethod, setSortingMethod] = useState<number>(0);
const [groupingMethod, setGroupingMethod] = useState<string>(""); const [groupingMethod, setGroupingMethod] = useState<number>(-1);
const [filteredItems, setFilteredItems] = useState< const [filteredItems, setFilteredItems] = useState<
LibraryProps["libraryItems"]["libraryItems"]["data"] LibraryProps["libraryItems"]["libraryItems"]["data"]
@ -45,7 +45,7 @@ export default function Library(props: LibraryProps): JSX.Element {
>(sortBy(groupingMethod, filteredItems)); >(sortBy(groupingMethod, filteredItems));
const [groups, setGroups] = useState<GroupLibraryItems>( const [groups, setGroups] = useState<GroupLibraryItems>(
getGroups("", sortedItems) getGroups(groupingMethod, sortedItems)
); );
useEffect(() => { useEffect(() => {
@ -79,7 +79,8 @@ export default function Library(props: LibraryProps): JSX.Element {
{ name: "type", label: "Type" }, { name: "type", label: "Type" },
{ name: "releaseYear", label: "Release year" }, { name: "releaseYear", label: "Release year" },
]} ]}
onChange={setGroupingMethod} state={groupingMethod}
setState={setGroupingMethod}
allowEmpty allowEmpty
/> />
</div> </div>
@ -90,10 +91,11 @@ export default function Library(props: LibraryProps): JSX.Element {
className="w-full" className="w-full"
options={[ options={[
{ name: "title", label: "Title" }, { name: "title", label: "Title" },
{ name: "releaseDate", label: "Release date" },
{ name: "price", label: "Price" }, { name: "price", label: "Price" },
{ name: "releaseDate", label: "Release date" },
]} ]}
onChange={setSortingMethod} state={sortingMethod}
setState={setSortingMethod}
/> />
</div> </div>
@ -153,14 +155,14 @@ export const getStaticProps: GetStaticProps = async (context) => {
}; };
function getGroups( function getGroups(
groupByType: string, groupByType: number,
items: LibraryProps["libraryItems"]["libraryItems"]["data"] items: LibraryProps["libraryItems"]["libraryItems"]["data"]
): GroupLibraryItems { ): GroupLibraryItems {
switch (groupByType) { switch (groupByType) {
case "category": case 0:
return new Map(); return new Map();
case "type": case 1:
const groupType: GroupLibraryItems = new Map(); const groupType: GroupLibraryItems = new Map();
groupType.set("Audio", []); groupType.set("Audio", []);
groupType.set("Game", []); groupType.set("Game", []);
@ -212,7 +214,7 @@ function getGroups(
}); });
return groupType; return groupType;
case "releaseYear": case 2:
const years: number[] = []; const years: number[] = [];
items.map((item) => { items.map((item) => {
if (item.attributes.release_date) { if (item.attributes.release_date) {
@ -266,11 +268,11 @@ function filterItems(
} }
function sortBy( function sortBy(
orderByType: string, orderByType: number,
items: LibraryProps["libraryItems"]["libraryItems"]["data"] items: LibraryProps["libraryItems"]["libraryItems"]["data"]
): LibraryProps["libraryItems"]["libraryItems"]["data"] { ): LibraryProps["libraryItems"]["libraryItems"]["data"] {
switch (orderByType) { switch (orderByType) {
case "title": case 0:
return [...items].sort((a, b) => { return [...items].sort((a, b) => {
const titleA = prettyinlineTitle( const titleA = prettyinlineTitle(
"", "",
@ -284,13 +286,13 @@ function sortBy(
); );
return titleA.localeCompare(titleB); return titleA.localeCompare(titleB);
}); });
case "price": case 1:
return [...items].sort((a, b) => { return [...items].sort((a, b) => {
const priceA = a.attributes.price ? a.attributes.price.amount : 99999; const priceA = a.attributes.price ? a.attributes.price.amount : 99999;
const priceB = b.attributes.price ? b.attributes.price.amount : 99999; const priceB = b.attributes.price ? b.attributes.price.amount : 99999;
return priceA - priceB; return priceA - priceB;
}); });
case "releaseDate": case 2:
return [...items].sort((a, b) => { return [...items].sort((a, b) => {
const dateA = const dateA =
a.attributes.release_date !== null a.attributes.release_date !== null
@ -302,6 +304,7 @@ function sortBy(
: "9999"; : "9999";
return dateA.localeCompare(dateB); return dateA.localeCompare(dateB);
}); });
} default:
return items; return items;
}
} }