fix: marketplace list

This commit is contained in:
StyleZhang 2024-10-31 18:54:13 +08:00
parent bca99cf4f8
commit b5be6bacef
4 changed files with 62 additions and 17 deletions

View File

@ -1,7 +1,7 @@
import { MarketplaceContextProvider } from './context'
import Description from './description'
import IntersectionLine from './intersection-line'
import SearchBox from './search-box'
import SearchBoxWrapper from './search-box/search-box-wrapper'
import PluginTypeSwitch from './plugin-type-switch'
import ListWrapper from './list/list-wrapper'
import { getMarketplaceCollectionsAndPlugins } from './utils'
@ -18,7 +18,7 @@ const Marketplace = async ({
<MarketplaceContextProvider>
<Description />
<IntersectionLine />
<SearchBox />
<SearchBoxWrapper />
<PluginTypeSwitch />
<ListWrapper
marketplaceCollections={marketplaceCollections}

View File

@ -5,7 +5,20 @@ import TagsFilter from './tags-filter'
import ActionButton from '@/app/components/base/action-button'
import cn from '@/utils/classnames'
const SearchBox = () => {
type SearchBoxProps = {
search: string
onSearchChange: (search: string) => void
inputClassName?: string
tags: string[]
onTagsChange: (tags: string[]) => void
}
const SearchBox = ({
search,
onSearchChange,
inputClassName,
tags,
onTagsChange,
}: SearchBoxProps) => {
const intersected = useMarketplaceContext(v => v.intersected)
const searchPluginText = useMarketplaceContext(v => v.searchPluginText)
const handleSearchPluginTextChange = useMarketplaceContext(v => v.handleSearchPluginTextChange)
@ -14,18 +27,22 @@ const SearchBox = () => {
<div
className={cn(
'sticky top-3 flex items-center mx-auto p-1.5 w-[640px] h-11 border border-components-chat-input-border bg-components-panel-bg-blur rounded-xl shadow-md z-[11]',
inputClassName,
!intersected && 'w-[508px] transition-[width] duration-300',
)}
>
<TagsFilter />
<TagsFilter
tags={tags}
onTagsChange={onTagsChange}
/>
<div className='mx-1 w-[1px] h-3.5 bg-divider-regular'></div>
<div className='grow flex items-center p-1 pl-2'>
<div className='flex items-center mr-2 py-0.5 w-full'>
<input
className='grow block outline-none appearance-none body-md-medium text-text-secondary'
value={searchPluginText}
value={search}
onChange={(e) => {
handleSearchPluginTextChange(e.target.value)
onSearchChange(e.target.value)
}}
/>
{

View File

@ -0,0 +1,24 @@
'use client'
import { useMarketplaceContext } from '../context'
import SearchBox from './index'
import cn from '@/utils/classnames'
const SearchBoxWrapper = () => {
const intersected = useMarketplaceContext(v => v.intersected)
const searchPluginText = useMarketplaceContext(v => v.searchPluginText)
const handleSearchPluginTextChange = useMarketplaceContext(v => v.handleSearchPluginTextChange)
const filterPluginTags = useMarketplaceContext(v => v.filterPluginTags)
const handleFilterPluginTagsChange = useMarketplaceContext(v => v.handleFilterPluginTagsChange)
return (
<SearchBox
inputClassName={cn(!intersected && 'w-[508px] transition-[width] duration-300')}
search={searchPluginText}
onSearchChange={handleSearchPluginTextChange}
tags={filterPluginTags}
onTagsChange={handleFilterPluginTagsChange}
/>
)
}
export default SearchBoxWrapper

View File

@ -6,7 +6,6 @@ import {
RiCloseCircleFill,
RiFilter3Line,
} from '@remixicon/react'
import { useMarketplaceContext } from '../context'
import {
PortalToFollowElem,
PortalToFollowElemContent,
@ -16,9 +15,14 @@ import Checkbox from '@/app/components/base/checkbox'
import cn from '@/utils/classnames'
import Input from '@/app/components/base/input'
const TagsFilter = () => {
const filterPluginTags = useMarketplaceContext(v => v.filterPluginTags)
const handleFilterPluginTagsChange = useMarketplaceContext(v => v.handleFilterPluginTagsChange)
type TagsFilterProps = {
tags: string[]
onTagsChange: (tags: string[]) => void
}
const TagsFilter = ({
tags,
onTagsChange,
}: TagsFilterProps) => {
const [open, setOpen] = useState(false)
const [searchText, setSearchText] = useState('')
const options = [
@ -33,12 +37,12 @@ const TagsFilter = () => {
]
const filteredOptions = options.filter(option => option.text.toLowerCase().includes(searchText.toLowerCase()))
const handleCheck = (id: string) => {
if (filterPluginTags.includes(id))
handleFilterPluginTagsChange(filterPluginTags.filter((tag: string) => tag !== id))
if (tags.includes(id))
onTagsChange(tags.filter((tag: string) => tag !== id))
else
handleFilterPluginTagsChange([...filterPluginTags, id])
onTagsChange([...tags, id])
}
const selectedTagsLength = filterPluginTags.length
const selectedTagsLength = tags.length
return (
<PortalToFollowElem
@ -66,7 +70,7 @@ const TagsFilter = () => {
!selectedTagsLength && 'All Tags'
}
{
!!selectedTagsLength && filterPluginTags.slice(0, 2).join(',')
!!selectedTagsLength && tags.slice(0, 2).join(',')
}
{
selectedTagsLength > 2 && (
@ -80,7 +84,7 @@ const TagsFilter = () => {
!!selectedTagsLength && (
<RiCloseCircleFill
className='w-4 h-4 text-text-quaternary cursor-pointer'
onClick={() => handleFilterPluginTagsChange([])}
onClick={() => onTagsChange([])}
/>
)
}
@ -111,7 +115,7 @@ const TagsFilter = () => {
>
<Checkbox
className='mr-1'
checked={filterPluginTags.includes(option.value)}
checked={tags.includes(option.value)}
/>
<div className='px-1 system-sm-medium text-text-secondary'>
{option.text}