mirror of
https://github.com/mue/mue.git
synced 2026-07-16 21:44:22 +02:00
refactor(items): Move filter and display to seperate file
This commit is contained in:
@@ -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 };
|
||||
@@ -0,0 +1 @@
|
||||
export * from './ItemUtilities';
|
||||
@@ -2,3 +2,4 @@ export * from './Carousel';
|
||||
export * from './SideloadFailedModal';
|
||||
export * from './Lightbox';
|
||||
export * from './ItemCard';
|
||||
export * from './ItemUtilities';
|
||||
@@ -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 />}
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user