mirror of
https://github.com/mue/mue.git
synced 2026-07-10 14:04:32 +02:00
feat(marketplace): add filter options and sorting functionality to Items component
This commit is contained in:
@@ -517,3 +517,60 @@ p.author {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.filter-options-container {
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
gap: 20px;
|
||||
margin: 20px 0;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.filter-chips {
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
gap: 12px;
|
||||
align-items: center;
|
||||
|
||||
.filter-chip {
|
||||
all: unset;
|
||||
padding: 8px 20px;
|
||||
border-radius: 24px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
white-space: nowrap;
|
||||
user-select: none;
|
||||
|
||||
@include themed {
|
||||
background-color: t($modal-sidebarActive);
|
||||
color: t($color);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
@include themed {
|
||||
background-color: rgba(255, 255, 255, 0.15);
|
||||
}
|
||||
}
|
||||
|
||||
&.active {
|
||||
@include themed {
|
||||
background-color: #fff;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
@include themed {
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
outline: 2px solid rgba(255, 255, 255, 0.5);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,31 @@
|
||||
import variables from 'config/variables';
|
||||
import React, { memo } from 'react';
|
||||
import React, { memo, useState } from 'react';
|
||||
import { MdAutoFixHigh, MdOutlineArrowForward, MdOutlineOpenInNew } from 'react-icons/md';
|
||||
import placeholderIcon from 'assets/icons/marketplace-placeholder.png';
|
||||
|
||||
import { Button } from 'components/Elements';
|
||||
import Dropdown from '../../../../components/Form/Settings/Dropdown/Dropdown';
|
||||
|
||||
function filterItems(item, filter) {
|
||||
function filterItems(item, filter, categoryFilter) {
|
||||
const lowerCaseFilter = filter.toLowerCase();
|
||||
return (
|
||||
const textMatch =
|
||||
item.name?.toLowerCase().includes(lowerCaseFilter) ||
|
||||
filter === '' ||
|
||||
item.author?.toLowerCase().includes(lowerCaseFilter) ||
|
||||
item.type?.toLowerCase().includes(lowerCaseFilter)
|
||||
);
|
||||
item.type?.toLowerCase().includes(lowerCaseFilter);
|
||||
|
||||
// Apply category filter
|
||||
if (categoryFilter === 'all') {
|
||||
return textMatch;
|
||||
}
|
||||
|
||||
const categoryMap = {
|
||||
quotes: 'quote_packs',
|
||||
photos: 'photo_packs',
|
||||
presets: 'preset_settings',
|
||||
};
|
||||
|
||||
return textMatch && item.type === categoryMap[categoryFilter];
|
||||
}
|
||||
|
||||
function ItemCard({ item, toggleFunction, type, onCollection, isCurator }) {
|
||||
@@ -71,7 +84,27 @@ function Items({
|
||||
filter,
|
||||
moreByCreator,
|
||||
showCreateYourOwn,
|
||||
filterOptions = false,
|
||||
onSortChange,
|
||||
}) {
|
||||
const [selectedCategory, setSelectedCategory] = useState('all');
|
||||
const [sortType, setSortType] = useState(localStorage.getItem('sortMarketplace') || 'a-z');
|
||||
|
||||
const filterCategories = [
|
||||
{ id: 'all', label: 'All' },
|
||||
{ id: 'quotes', label: 'Quotes' },
|
||||
{ id: 'photos', label: 'Photos' },
|
||||
{ id: 'presets', label: 'Presets' },
|
||||
];
|
||||
|
||||
const handleSortChange = (value) => {
|
||||
setSortType(value);
|
||||
localStorage.setItem('sortMarketplace', value);
|
||||
if (onSortChange) {
|
||||
onSortChange(value);
|
||||
}
|
||||
};
|
||||
|
||||
const shouldShowCollection =
|
||||
((collection && !onCollection && (filter === null || filter === '')) ||
|
||||
(type === 'collections' && !onCollection && (filter === null || filter === ''))) &&
|
||||
@@ -114,9 +147,34 @@ function Items({
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
{/* Items Filter Options */}
|
||||
{filterOptions && (
|
||||
<div className="filter-options-container">
|
||||
<div className="filter-chips">
|
||||
{filterCategories.map((category) => (
|
||||
<button
|
||||
key={category.id}
|
||||
className={`filter-chip ${selectedCategory === category.id ? 'active' : ''}`}
|
||||
onClick={() => setSelectedCategory(category.id)}
|
||||
>
|
||||
{category.label}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
<Dropdown
|
||||
label={variables.getMessage('modals.main.addons.sort.title')}
|
||||
name="sortMarketplace"
|
||||
onChange={(value) => handleSortChange(value)}
|
||||
items={[
|
||||
{ value: 'a-z', text: variables.getMessage('modals.main.addons.sort.a_z') },
|
||||
{ value: 'z-a', text: variables.getMessage('modals.main.addons.sort.z_a') },
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div className={`items ${moreByCreator ? 'creatorItems' : ''}`}>
|
||||
{items
|
||||
?.filter((item) => filterItems(item, filter))
|
||||
?.filter((item) => filterItems(item, filter, filterOptions ? selectedCategory : 'all'))
|
||||
.map((item, index) => (
|
||||
<ItemCard
|
||||
isCurator={isCurator}
|
||||
|
||||
@@ -12,7 +12,6 @@ import {
|
||||
|
||||
import ItemPage from './ItemPage';
|
||||
import Items from '../components/Items/Items';
|
||||
import Dropdown from '../../../components/Form/Settings/Dropdown/Dropdown';
|
||||
import { Header } from 'components/Layout/Settings';
|
||||
import { Button } from 'components/Elements';
|
||||
|
||||
@@ -355,7 +354,10 @@ class Marketplace extends PureComponent {
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
// Handle navigation trigger changes
|
||||
if (this.props.navigationTrigger && this.props.navigationTrigger !== prevProps.navigationTrigger) {
|
||||
if (
|
||||
this.props.navigationTrigger &&
|
||||
this.props.navigationTrigger !== prevProps.navigationTrigger
|
||||
) {
|
||||
const { type, data } = this.props.navigationTrigger;
|
||||
|
||||
if (type === 'product' && data) {
|
||||
@@ -478,11 +480,11 @@ class Marketplace extends PureComponent {
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<div className="flexTopMarketplace">
|
||||
{/* <div className="flexTopMarketplace">
|
||||
<span className="mainTitle">
|
||||
{variables.getMessage('modals.main.navbar.marketplace')}
|
||||
</span>
|
||||
</div>
|
||||
</div> */}
|
||||
<div className="headerExtras marketplaceCondition">
|
||||
{this.props.type !== 'collections' && (
|
||||
<div>
|
||||
@@ -499,15 +501,6 @@ class Marketplace extends PureComponent {
|
||||
</form>
|
||||
</div>
|
||||
)}
|
||||
<Dropdown
|
||||
label={variables.getMessage('modals.main.addons.sort.title')}
|
||||
name="sortMarketplace"
|
||||
onChange={(value) => this.changeSort(value)}
|
||||
items={[
|
||||
{ value: 'a-z', text: variables.getMessage('modals.main.addons.sort.a_z') },
|
||||
{ value: 'z-a', text: variables.getMessage('modals.main.addons.sort.z_a') },
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
@@ -541,6 +534,7 @@ class Marketplace extends PureComponent {
|
||||
)
|
||||
) : (
|
||||
<Items
|
||||
filterOptions={true}
|
||||
type={this.props.type}
|
||||
items={this.state.items}
|
||||
collection={this.state.displayedCollection}
|
||||
@@ -548,6 +542,7 @@ class Marketplace extends PureComponent {
|
||||
toggleFunction={(input) => this.toggle('item', input)}
|
||||
collectionFunction={(input) => this.toggle('collection', input)}
|
||||
filter={this.state.filter}
|
||||
onSortChange={(value) => this.changeSort(value)}
|
||||
showCreateYourOwn={true}
|
||||
/>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user