More filtering options in Library
This commit is contained in:
		
							parent
							
								
									8684640ef4
								
							
						
					
					
						commit
						7c8fb24d67
					
				| @ -30,7 +30,7 @@ export default function LibraryItemsPreview( | ||||
|         {item.thumbnail.data ? ( | ||||
|           <Img | ||||
|             image={item.thumbnail.data.attributes} | ||||
|             quality={ImageQuality.Medium} | ||||
|             quality={ImageQuality.Small} | ||||
|           /> | ||||
|         ) : ( | ||||
|           <div className="w-full aspect-[21/29.7] bg-light rounded-lg"></div> | ||||
|  | ||||
| @ -13,22 +13,22 @@ export type SelectOption = { | ||||
|   label: string; | ||||
| }; | ||||
| 
 | ||||
| export function selectOptionsIncludes( | ||||
|   options: SelectOption[], | ||||
|   newOption: SelectOption | ||||
| ) { | ||||
|   options.map((option) => { | ||||
|     if (option.label === newOption.label) return true; | ||||
|   }); | ||||
|   return false; | ||||
| } | ||||
| 
 | ||||
| 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); | ||||
| 
 | ||||
|   useEffect(() => { | ||||
|     if (props.onChange) { | ||||
|       if (selected >= 0) { | ||||
|         props.onChange(props.options[selected].name); | ||||
|       } else { | ||||
|         props.onChange(""); | ||||
|       } | ||||
|     } | ||||
|   }, [props, selected]); | ||||
| 
 | ||||
|   return ( | ||||
|     <div | ||||
|       className={`relative transition-[filter] ${ | ||||
| @ -45,10 +45,7 @@ export default function Select(props: SelectProps): JSX.Element { | ||||
|         </p> | ||||
|         {selected >= 0 && props.allowEmpty && ( | ||||
|           <span | ||||
|             onClick={() => { | ||||
|               setSelected(-1); | ||||
|               props.onChange && props.onChange(""); | ||||
|             }} | ||||
|             onClick={() => setSelected(-1)} | ||||
|             className="material-icons !text-xs" | ||||
|           > | ||||
|             close | ||||
| @ -73,7 +70,6 @@ export default function Select(props: SelectProps): JSX.Element { | ||||
|                 onClick={() => { | ||||
|                   setOpened(false); | ||||
|                   setSelected(index); | ||||
|                   props.onChange && props.onChange(props.options[index].name); | ||||
|                 }} | ||||
|               > | ||||
|                 {option.label} | ||||
|  | ||||
							
								
								
									
										26
									
								
								src/components/Switch.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								src/components/Switch.tsx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,26 @@ | ||||
| import { Dispatch, SetStateAction } from "react"; | ||||
| 
 | ||||
| export type SwitchProps = { | ||||
|   setState: Dispatch<SetStateAction<boolean>>; | ||||
|   state: boolean; | ||||
|   className?: string; | ||||
| }; | ||||
| 
 | ||||
| export default function Select(props: SwitchProps): JSX.Element { | ||||
|   return ( | ||||
|     <div | ||||
|       className={`h-6 w-12 rounded-full border-2 border-mid grid transition-colors relative cursor-pointer ${ | ||||
|         props.className | ||||
|       } ${props.state ? "bg-mid" : "bg-light"}`}
 | ||||
|       onClick={() => { | ||||
|         props.setState(!props.state); | ||||
|       }} | ||||
|     > | ||||
|       <div | ||||
|         className={`bg-dark aspect-square rounded-full absolute top-0 bottom-0 left-0 transition-transform ${ | ||||
|           props.state && "translate-x-[115%]" | ||||
|         }`}
 | ||||
|       ></div> | ||||
|     </div> | ||||
|   ); | ||||
| } | ||||
| @ -126,7 +126,6 @@ query getChronologyItems($language_code: String) { | ||||
| 
 | ||||
| query getLibraryItemsPreview($language_code: String) { | ||||
|   libraryItems( | ||||
|     filters: { root_item: { eq: true } } | ||||
|     pagination: { limit: -1 } | ||||
|   ) { | ||||
|     data { | ||||
| @ -135,6 +134,7 @@ query getLibraryItemsPreview($language_code: String) { | ||||
|         title | ||||
|         subtitle | ||||
|         slug | ||||
|         root_item | ||||
|         thumbnail { | ||||
|           data { | ||||
|             attributes { | ||||
|  | ||||
| @ -238,6 +238,7 @@ export type GetLibraryItemsPreviewQuery = { | ||||
|         title: string; | ||||
|         subtitle: string; | ||||
|         slug: string; | ||||
|         root_item: boolean; | ||||
|         thumbnail: { | ||||
|           __typename: "UploadFileEntityResponse"; | ||||
|           data: { | ||||
|  | ||||
| @ -17,6 +17,7 @@ import LibraryItemsPreview from "components/Library/LibraryItemsPreview"; | ||||
| import Select from "components/Select"; | ||||
| import { useEffect, useState } from "react"; | ||||
| import { prettyDate, prettyinlineTitle } from "queries/helpers"; | ||||
| import Switch from "components/Switch"; | ||||
| 
 | ||||
| type LibraryProps = { | ||||
|   libraryItems: GetLibraryItemsPreviewQuery; | ||||
| @ -31,21 +32,31 @@ type GroupLibraryItems = Map< | ||||
| export default function Library(props: LibraryProps): JSX.Element { | ||||
|   const langui = props.langui.websiteInterfaces.data[0].attributes; | ||||
| 
 | ||||
|   const [showSubitems, setShowSubitems] = useState<boolean>(false); | ||||
|   const [sortingMethod, setSortingMethod] = useState<string>("title"); | ||||
|   const [groupingMethod, setGroupingMethod] = useState<string>(""); | ||||
| 
 | ||||
|   const [filteredItems, setFilteredItems] = useState< | ||||
|     LibraryProps["libraryItems"]["libraryItems"]["data"] | ||||
|   >(filterItems(showSubitems, props.libraryItems.libraryItems.data)); | ||||
| 
 | ||||
|   const [sortedItems, setSortedItem] = useState< | ||||
|     LibraryProps["libraryItems"]["libraryItems"]["data"] | ||||
|   >(sortBy("title", props.libraryItems.libraryItems.data)); | ||||
| 
 | ||||
|   const [sortingMethod, setSortingMethod] = useState<string>("title"); | ||||
|   >(sortBy(groupingMethod, filteredItems)); | ||||
| 
 | ||||
|   const [groups, setGroups] = useState<GroupLibraryItems>( | ||||
|     getGroups("", sortedItems) | ||||
|   ); | ||||
| 
 | ||||
|   const [groupingMethod, setGroupingMethod] = useState<string>(""); | ||||
|   useEffect(() => { | ||||
|     setFilteredItems( | ||||
|       filterItems(showSubitems, props.libraryItems.libraryItems.data) | ||||
|     ); | ||||
|   }, [showSubitems, props.libraryItems.libraryItems.data]); | ||||
| 
 | ||||
|   useEffect(() => { | ||||
|     setSortedItem(sortBy(sortingMethod, props.libraryItems.libraryItems.data)); | ||||
|   }, [props.libraryItems.libraryItems.data, sortingMethod]); | ||||
|     setSortedItem(sortBy(sortingMethod, filteredItems)); | ||||
|   }, [filteredItems, sortingMethod]); | ||||
| 
 | ||||
|   useEffect(() => { | ||||
|     setGroups(getGroups(groupingMethod, sortedItems)); | ||||
| @ -85,6 +96,11 @@ export default function Library(props: LibraryProps): JSX.Element { | ||||
|           onChange={setSortingMethod} | ||||
|         /> | ||||
|       </div> | ||||
| 
 | ||||
|       <div className="flex flex-row gap-2 place-items-center"> | ||||
|         <p className="flex-shrink-0">Show subitems:</p> | ||||
|         <Switch state={showSubitems} setState={setShowSubitems} /> | ||||
|       </div> | ||||
|     </SubPanel> | ||||
|   ); | ||||
|   const contentPanel = ( | ||||
| @ -93,10 +109,10 @@ export default function Library(props: LibraryProps): JSX.Element { | ||||
|         <> | ||||
|           {items.length > 0 && ( | ||||
|             <> | ||||
|               <h2 className="text-2xl pb-2">{name}</h2> | ||||
|               <h2 className="text-2xl pb-2 pt-10 first-of-type:pt-0">{name}</h2> | ||||
|               <div | ||||
|                 key={name} | ||||
|                 className="grid gap-8 items-end mobile:grid-cols-2 desktop:grid-cols-[repeat(auto-fill,_minmax(13rem,1fr))] pb-12" | ||||
|                 className="grid gap-8 items-end mobile:grid-cols-2 desktop:grid-cols-[repeat(auto-fill,_minmax(13rem,1fr))] pb-12 border-b-[3px] border-dotted last-of-type:border-0" | ||||
|               > | ||||
|                 {items.map((item) => ( | ||||
|                   <LibraryItemsPreview key={item.id} item={item.attributes} /> | ||||
| @ -168,7 +184,26 @@ function getGroups( | ||||
|               groupType.get("Video")?.push(item); | ||||
|               break; | ||||
|             case "ComponentMetadataOther": | ||||
|               groupType.get("Other")?.push(item); | ||||
|               switch ( | ||||
|                 item.attributes.metadata[0].subtype.data.attributes.slug | ||||
|               ) { | ||||
|                 case "audio-case": | ||||
|                   groupType.get("Audio")?.push(item); | ||||
|                   break; | ||||
| 
 | ||||
|                 case "video-case": | ||||
|                   groupType.get("Video")?.push(item); | ||||
|                   break; | ||||
| 
 | ||||
|                 case "game-case": | ||||
|                   groupType.get("Game")?.push(item); | ||||
|                   break; | ||||
| 
 | ||||
|                 default: | ||||
|                   groupType.get("Other")?.push(item); | ||||
|                   break; | ||||
|               } | ||||
| 
 | ||||
|               break; | ||||
|           } | ||||
|         } else { | ||||
| @ -210,6 +245,26 @@ function getGroups( | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| function filterItems( | ||||
|   showSubitems: boolean, | ||||
|   items: LibraryProps["libraryItems"]["libraryItems"]["data"] | ||||
| ): LibraryProps["libraryItems"]["libraryItems"]["data"] { | ||||
|   return [...items].filter((item) => { | ||||
|     let result = true; | ||||
|     if (!showSubitems && !item.attributes.root_item) result = false; | ||||
|     if ( | ||||
|       item.attributes.metadata.length > 0 && | ||||
|       item.attributes.metadata[0].__typename === "ComponentMetadataOther" && | ||||
|       (item.attributes.metadata[0].subtype.data.attributes.slug === | ||||
|         "variant-set" || | ||||
|         item.attributes.metadata[0].subtype.data.attributes.slug === | ||||
|           "relation-set") | ||||
|     ) | ||||
|       result = false; | ||||
|     return result; | ||||
|   }); | ||||
| } | ||||
| 
 | ||||
| function sortBy( | ||||
|   orderByType: string, | ||||
|   items: LibraryProps["libraryItems"]["libraryItems"]["data"] | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 DrMint
						DrMint