From fc0ea974d1661b7eb9177b10808c321caf853763 Mon Sep 17 00:00:00 2001 From: Daniel Date: Sat, 18 Dec 2021 18:37:06 -0500 Subject: [PATCH] form: tribes, elements, disciplines, rarity, sets, deckbuilding restriction --- src/components/_mobile/collection/Search.tsx | 262 +++++++++++++++---- 1 file changed, 214 insertions(+), 48 deletions(-) diff --git a/src/components/_mobile/collection/Search.tsx b/src/components/_mobile/collection/Search.tsx index 50b2059..4e6dbfe 100644 --- a/src/components/_mobile/collection/Search.tsx +++ b/src/components/_mobile/collection/Search.tsx @@ -1,9 +1,22 @@ -import React, { FormEvent, useEffect, useReducer, useRef, useState } from 'react'; -import { useHistory, useLocation } from 'react-router-dom'; -import API, { sets } from '../../SpreadsheetData/API'; -import search_api from '../../collection/search/search'; -import { Modal, Fab, Zoom, useTheme, Box, TextField, Button } from '@mui/material'; +/* eslint-disable react-hooks/exhaustive-deps */ +import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; import SearchIcon from '@mui/icons-material/Search'; +import { + Accordion as MUIAccordion, AccordionDetails, AccordionSummary, Box, Button, Checkbox, Dialog, DialogActions, DialogContent, + Fab, FormControlLabel, FormGroup, InputAdornment, Modal, styled, TextField, ToggleButton, ToggleButtonGroup, + Typography, useTheme, Zoom +} from '@mui/material'; +import React, { FormEvent, useEffect, useMemo, useReducer, useRef, useState } from 'react'; +import { useHistory, useLocation } from 'react-router-dom'; +import search_api from '../../collection/search/search'; +import { ElementIcon, TribeIcon } from '../../Snippets'; +import API, { sets } from '../../SpreadsheetData/API'; + +const Accordion = styled(MUIAccordion)(() => ({ + "&.Mui-expanded": { + margin: 0 + } +})); const initInput = (() => { /* @ts-ignore */ @@ -28,9 +41,23 @@ const initInput = (() => { }; })(); +const initExpand = ({ + disciplines: true, + energy: true, + bpmc: true, + types: true, + rarity: false, + sets: false +}); + const queryList = ["sets", "types", "rarity", "tribes", "elements", "mull", "gender"]; const inputReducer = (state: typeof initInput, newState: Partial) => { + console.log(state, newState); + return { ...state, ...newState }; +}; + +const expandReducer = (state: typeof initExpand, newState: Partial) => { return { ...state, ...newState }; }; @@ -40,6 +67,7 @@ function Search ({ setContent, setInfo }) { const location = useLocation(); const prevLocation = useRef(location); const [input, dispatchInput] = useReducer(inputReducer, initInput, (input) => parseQuery(input, location)); + const [expand, dispatchExpand] = useReducer(expandReducer, initExpand, parseExpand); const [loaded, setLoaded] = useState(false); const [open, setOpen] = useState(false); @@ -84,16 +112,19 @@ function Search ({ setContent, setInfo }) { } }; - const handleChange = (event: {target: HTMLInputElement | HTMLTextAreaElement}, obj?: string) => { + const handleChange = (name: string, obj?: string) => (event: {target: HTMLInputElement | HTMLTextAreaElement}) => { const { target } = event; const value = target.type === 'checkbox' ? (target as HTMLInputElement).checked : target.value; - const { name, id } = target; - const i = (name || id); dispatchInput({ - ...((!obj) ? { [i]: value } : { [[obj][i]]: value }) + ...((!obj) ? { [name]: value } : { [obj]: { ...input[obj], [name]: value }}) }); }; + const handleExpand = (field: keyof typeof initExpand) => (event: React.SyntheticEvent, isExpanded: boolean) => { + dispatchExpand({ [field]: isExpanded }); + localStorage.setItem("collapsed", JSON.stringify({ ...expand, [field]: isExpanded })); + }; + const handleOpen = () => { setOpen(true); }; @@ -107,51 +138,175 @@ function Search ({ setContent, setInfo }) { exit: theme.transitions.duration.leavingScreen, }; - const form = ((loaded == false) ? <> : ( - - handleChange(e)} + const generate = (type: string, row: boolean, label: (item: string) => React.ReactNode) => { + console.log(type, input[type]); + return Object.keys(input[type]).map((item, i) => ( + + } label={label(item)} /> + )); + }; + + const tribes = useMemo(() => ( + generate("tribes", true, (item) => + + ) + ), [input.tribes]); + + const elements = useMemo(() => ( + generate("elements", true, (item) => + + ).slice(0, -2) + ), [input.elements]); + + const sets = useMemo(() => ( + generate("sets", false, (set) => + API.sets[set.toUpperCase()] + ) + ), [input.sets]); + + const types = useMemo(() => ( + generate("types", false, (type) => + `${type.charAt(0).toUpperCase()}${type.slice(1)}` + ) + ), [input.types]); + + const rarity = useMemo(() => ( + generate("rarity", false, (item) => + item.split(" ").map((st) => `${st.charAt(0).toUpperCase()}${st.slice(1)}`).join(" ") + ) + ), [input.rarity]); + + const disciplines = useMemo(() => ( + Object.keys(input.disciplines).slice(0, 4).map((item) => ( + + + + ), + }} /> - handleChange(e)} - /> - handleChange(e)} - /> - - - - - - )); + )) + ), [input.disciplines]); return (<> - {form} + {((loaded == false) ? <> : ( + + + + + + {dispatchInput({ flavor: !e.target.checked })}} /> + } label="Ignore Flavortext & Artist" /> + + + + } label="Unique" /> + + } label="Loyal" /> + + } label="Legendary" /> + + + } label="Non-Loyal" /> + + {tribes} + + + {elements} + + } label="None" /> + + {dispatchInput({ "elements": { ...input.elements, "and": value }})} } + > + {(input.elements.none) ? "none" : "or"} + {(input.elements.none) ? "only" : "and"} + + {disciplines} + + }> + Card Type + + + {types} + + + + }> + Rarity + + + {rarity} + + + + }> + Sets + + + {sets} + + + + + + + + ))} { history.push(`/collection/?${queryString}`); }; +const parseExpand = (init: typeof initExpand) => { + let input = Object.assign({}, init); + + const collapsed = localStorage.getItem("collapsed"); + if (collapsed) { + input = { ...input, ...JSON.parse(collapsed) }; + } + + return input; +}; + export default Search;