refactor(items): Move filter and display to seperate file

This commit is contained in:
alexsparkes
2024-06-21 15:28:57 +01:00
parent 2250a86ef9
commit 3c73f03b78
5 changed files with 127 additions and 107 deletions

View File

@@ -0,0 +1,85 @@
// src/components/ItemUtilities/ItemUtilities.js
import React, { useCallback, useMemo } from 'react';
import { motion } from 'framer-motion';
import { PiGridFourFill } from 'react-icons/pi';
import { MdFormatListBulleted } from 'react-icons/md';
import clsx from 'clsx';
import variables from 'config/variables';
const filterTypes = [
{ key: 'all', label: 'marketplace:photo_packs' },
{ key: 'photo_packs', label: 'marketplace:photo_packs' },
{ key: 'quote_packs', label: 'marketplace:quote_packs' },
{ key: 'preset_settings', label: 'marketplace:preset_settings' },
];
const ItemUtilities = ({ itemsFilter, setItemsFilter, itemsView, setItemsView }) => {
const FilterOptions = useCallback(() => {
return (
<div className="flex flex-row gap-2 my-3">
{filterTypes.map(({ key, label }) => (
<div
key={key}
onClick={() => setItemsFilter(key)}
className={clsx(
'cursor-pointer transition-all duration-200 rounded-full px-6 py-2 text-base',
{
'bg-white text-black': itemsFilter === key,
'bg-[#333] hover:bg-[#222222] text-white': itemsFilter !== key,
},
)}
>
{key !== 'all' ? <>{variables.getMessage(`${label}`) || 'marketplace'}</> : <>All</>}
</div>
))}
</div>
);
}, [itemsFilter]);
const viewOptions = useMemo(
() => [
{ id: 'grid', icon: <PiGridFourFill /> },
{ id: 'list', icon: <MdFormatListBulleted /> },
],
[],
);
const ItemView = useCallback(() => {
return (
<div className="flex space-x-1">
{viewOptions.map((option) => (
<button
key={option.id}
onClick={() => setItemsView(option.id)}
className={`${
itemsView === option.id ? '' : 'hover:text-white/70'
} transition-all duration-800 ease-in-out flex flex-row gap-2 items-center relative rounded-sm px-2 py-2 text-xl text-white outline-sky-400 focus-visible:outline-2`}
style={{
WebkitTapHighlightColor: 'transparent',
}}
>
{itemsView === option.id && (
<motion.span
layoutId="viewSelectorBubble"
className="absolute inset-0 z-10 bg-[#333] mix-blend-lighten rounded-xl"
transition={{ type: 'spring', bounce: 0.2, duration: 0.6 }}
/>
)}
{option.icon}
</button>
))}
</div>
);
}, [itemsView, setItemsView, viewOptions]);
return (
<div className="w-full flex flex-row justify-between items-center">
{itemsFilter && <FilterOptions />}
<div className="flex flex-row gap-2 ml-auto">
<ItemView />
</div>
</div>
);
};
export { ItemUtilities as default, ItemUtilities };

View File

@@ -0,0 +1 @@
export * from './ItemUtilities';

View File

@@ -2,3 +2,4 @@ export * from './Carousel';
export * from './SideloadFailedModal';
export * from './Lightbox';
export * from './ItemCard';
export * from './ItemUtilities';

View File

@@ -1,15 +1,27 @@
import variables from 'config/variables';
import { NewItems as Items } from '../components/Items/Items';
// src/library/Library.js
import React, { useState, useEffect, useCallback, useMemo } from 'react';
import { useMarketData } from 'features/marketplace/api/MarketplaceDataContext';
import { useTab } from 'components/Elements/MainModal/backend/TabContext';
import { ItemPage } from '../views/ItemPage';
import { NewItems as Items } from '../components/Items/Items';
import ItemPage from '../views/ItemPage';
import { MdOutlineExtensionOff } from 'react-icons/md';
import { ItemUtilities } from '../components/Elements';
import variables from 'config/variables';
const filterItems = (items, filter) => {
if (filter === 'all') return items;
return items.filter((item) => item.type === filter);
};
const Library = () => {
let installed = JSON.parse(localStorage.getItem('installed'));
const { selectedItem } = useMarketData();
const { subTab, changeTab } = useTab();
const [itemsView, setItemsView] = useState('list');
const [itemsFilter, setItemsFilter] = useState('all');
const [filteredItems, setFilteredItems] = useState([]);
// Ensure installed is an array
if (!Array.isArray(installed)) {
installed = [];
@@ -36,7 +48,17 @@ const Library = () => {
return (
<>
{subTab === '' && selectedItem === null && <Items items={installed} view="list" />}
{subTab === '' && selectedItem === null && (
<>
<ItemUtilities
//itemsFilter={itemsFilter}
//setItemsFilter={setItemsFilter}
itemsView={itemsView}
setItemsView={setItemsView}
/>
<Items items={installed} view={itemsView} />
</>
)}
{subTab !== '' && selectedItem !== null && <ItemPage />}
</>
);

View File

@@ -1,33 +1,20 @@
import { memo, useCallback, useEffect, useState, useMemo } from 'react';
import variables from 'config/variables';
// src/marketplace/Marketplace.js
import { memo, useEffect, useState, useCallback, useMemo } from 'react';
import { useMarketData } from 'features/marketplace/api/MarketplaceDataContext';
import MarketplaceTab from '../../marketplace/views/Browse';
import { useTab } from 'components/Elements/MainModal/backend/TabContext';
import { ItemPage } from '../../marketplace/views/ItemPage';
import { CollectionPage } from '../../marketplace/views/CollectionPage';
import { NewItems as Items } from '../../marketplace/components/Items/Items';
import { AnimatePresence, motion } from 'framer-motion';
import Collection from '../../marketplace/components/Collection/Collection';
import clsx from 'clsx';
import { PiGridFourFill } from 'react-icons/pi';
import { MdFormatListBulleted } from 'react-icons/md';
const filterTypes = [
{ key: 'all', label: 'marketplace:photo_packs' },
{ key: 'photo_packs', label: 'marketplace:photo_packs' },
{ key: 'quote_packs', label: 'marketplace:quote_packs' },
{ key: 'preset_settings', label: 'marketplace:preset_settings' },
];
import { Collection } from '../../marketplace/components/Collection';
import { NewItems as Items } from '../../marketplace/components/Items/Items';
import ItemPage from '../../marketplace/views/ItemPage';
import CollectionPage from '../../marketplace/views/CollectionPage';
import { ItemUtilities } from '../../marketplace/components/Elements';
const filterItems = (items, filter) => {
if (filter === 'all') return items;
return items.filter((item) => item.type === filter);
};
function Marketplace(props) {
function Marketplace() {
const {
done,
items = [],
@@ -53,64 +40,6 @@ function Marketplace(props) {
}
};
const FilterOptions = useCallback(() => {
return (
<div className="flex flex-row gap-2 my-3">
{filterTypes.map(({ key, label }) => (
<div
key={key}
onClick={() => setItemsFilter(key)}
className={clsx(
'cursor-pointer transition-all duration-200 rounded-full px-6 py-2 text-base',
{
'bg-white text-black': itemsFilter === key,
'bg-[#333] hover:bg-[#222222] text-white': itemsFilter !== key,
},
)}
>
{key !== 'all' ? <>{variables.getMessage(`${label}`) || 'marketplace'}</> : <>All</>}
</div>
))}
</div>
);
}, [itemsFilter]);
const viewOptions = useMemo(
() => [
{ id: 'grid', icon: <PiGridFourFill /> },
{ id: 'list', icon: <MdFormatListBulleted /> },
],
[],
);
const ItemView = useCallback(() => {
return (
<div className="flex space-x-1">
{viewOptions.map((option) => (
<button
key={option.id}
onClick={() => setItemsView(option.id)}
className={`${
itemsView === option.id ? '' : 'hover:text-white/70'
} transition-all duration-800 ease-in-out flex flex-row gap-2 items-center relative rounded-sm px-2 py-2 text-xl text-white outline-sky-400 focus-visible:outline-2`}
style={{
WebkitTapHighlightColor: 'transparent',
}}
>
{itemsView === option.id && (
<motion.span
layoutId="viewSelectorBubble"
className="absolute inset-0 z-10 bg-[#333] mix-blend-lighten rounded-xl"
transition={{ type: 'spring', bounce: 0.2, duration: 0.6 }}
/>
)}
{option.icon}
</button>
))}
</div>
);
}, [itemsView, setItemsView, viewOptions]);
useEffect(() => {
if (navigator.onLine === false || localStorage.getItem('offlineMode') === 'true') {
return;
@@ -135,12 +64,12 @@ function Marketplace(props) {
<>
<Collection collection={collection} />
<motion.div key="items">
<div className="w-full flex flex-row justify-between items-center">
<FilterOptions />
<div className="flex flex-row gap-2">
<ItemView />
</div>
</div>
<ItemUtilities
itemsFilter={itemsFilter}
setItemsFilter={setItemsFilter}
itemsView={itemsView}
setItemsView={setItemsView}
/>
<Items items={filteredItems} view={itemsView} />
</motion.div>
</>
@@ -153,24 +82,6 @@ function Marketplace(props) {
{selectedCollection !== null && (
<CollectionPage />
)}
{/*{subTab === '' ? (
<>
<Collection collection={collection} />
<motion.div key="items">
<div className="w-full flex flex-row justify-between items-center">
<FilterOptions />
<div className="flex flex-row gap-2">
<ItemView />
</div>
</div>
<Items items={filteredItems} view={itemsView} />
</motion.div>
</>
) : (
<motion.div key="itempage">
<ItemPage />
</motion.div>
)}*/}
</motion.div>
</AnimatePresence>
);