diff --git a/src/components/anchor-picker/index.tsx b/src/components/anchor-picker/index.tsx index 604967d..06d73bc 100644 --- a/src/components/anchor-picker/index.tsx +++ b/src/components/anchor-picker/index.tsx @@ -5,34 +5,19 @@ import { isEqual } from 'lodash-es'; import { useCallback, useState } from 'react'; import PickerToolbar from '@/components/picker-toolbar'; -import { - EmployType, - ALL_EMPLOY_TYPES, - FULL_PRICE_OPTIONS, - PART_PRICE_OPTIONS, - EMPLOY_TYPE_TITLE_MAP, -} from '@/constants/job'; -import { - ALL_ANCHOR_READ_TYPES, - ALL_GENDER_TYPES, - ANCHOR_READ_TITLE_MAP, - AnchorReadType, - GENDER_TYPE_TITLE_MAP, - GenderType, -} from '@/constants/material'; +import { FULL_PRICE_OPTIONS, PART_PRICE_OPTIONS } from '@/constants/job'; +import { ALL_ANCHOR_READ_TYPES, ANCHOR_READ_TITLE_MAP, AnchorReadType } from '@/constants/material'; import { IAnchorFilters } from '@/types/material'; -import { isUndefined } from '@/utils/common'; import './index.less'; +type MoreFilter = Omit; interface IProps { - value: IAnchorFilters; - onConfirm: (newValue: IAnchorFilters) => void; + value: MoreFilter; + onConfirm: (newValue: MoreFilter) => void; } const PREFIX = 'anchor-picker'; -const getDefaultGender = (value: IAnchorFilters) => value.gender; -const getDefaultEmploy = (value: IAnchorFilters) => value.employType; const getDefaultReadType = (value: IAnchorFilters) => value.readType; const getDefaultCategory = (value: IAnchorFilters) => value.category || ''; const getSalaryValue = (value: IAnchorFilters, full: boolean) => { @@ -47,9 +32,7 @@ const getSalaryValue = (value: IAnchorFilters, full: boolean) => { function AnchorPicker(props: IProps) { const { value, onConfirm } = props; - const [gender, setGender] = useState(getDefaultGender(value)); const [readType, setReadType] = useState(getDefaultReadType(value)); - const [employType, setEmployType] = useState(getDefaultEmploy(value)); const [fullSalary, setFullSalary] = useState(getSalaryValue(value, true)); const [partSalary, setPartSalary] = useState(getSalaryValue(value, false)); const [category, setCategory] = useState(getDefaultCategory(value)); @@ -59,9 +42,7 @@ function AnchorPicker(props: IProps) { }, []); const handleClickReset = useCallback(() => { - setGender(undefined); setReadType(undefined); - setEmployType(undefined); setFullSalary(null); setPartSalary(null); setCategory(''); @@ -83,10 +64,6 @@ function AnchorPicker(props: IProps) { const handleClickConfirm = useCallback(() => { const filters: IAnchorFilters = {}; - if (!isUndefined(gender)) { - filters.gender = gender === GenderType.All ? undefined : gender; - } - employType && (filters.employType = employType); readType && (filters.readType = readType); category && (filters.category = category); if (fullSalary) { @@ -98,34 +75,10 @@ function AnchorPicker(props: IProps) { filters.highPriceForPartyTime = partSalary.maxSalary; } onConfirm(filters); - }, [gender, employType, readType, category, fullSalary, partSalary, onConfirm]); + }, [readType, category, fullSalary, partSalary, onConfirm]); return (
-
性别
-
- {ALL_GENDER_TYPES.map((type: GenderType) => ( -
setGender(type)} - className={classNames(`${PREFIX}__item`, { selected: type === gender })} - > - {GENDER_TYPE_TITLE_MAP[type]} -
- ))} -
-
全职/兼职
-
- {ALL_EMPLOY_TYPES.map(type => ( -
setEmployType(type)} - className={classNames(`${PREFIX}__item`, { selected: type === employType })} - > - {EMPLOY_TYPE_TITLE_MAP[type]} -
- ))} -
已读/未读
{ALL_ANCHOR_READ_TYPES.map(type => ( diff --git a/src/components/gender-select/index.tsx b/src/components/gender-select/index.tsx new file mode 100644 index 0000000..ecc8209 --- /dev/null +++ b/src/components/gender-select/index.tsx @@ -0,0 +1,13 @@ +import Select, { ISelectProps } from '@/components/select'; +import { GENDER_OPTIONS, GenderType } from '@/constants/material'; + +interface IProps extends Omit, 'options'> { + value: GenderType; +} + +function GenderSelect(props: IProps) { + const { value: selectValue, onSelect } = props; + return ; +} + +export default TopCategorySelect; diff --git a/src/constants/job.ts b/src/constants/job.ts index c5774f3..28b7041 100644 --- a/src/constants/job.ts +++ b/src/constants/job.ts @@ -7,6 +7,7 @@ export enum JobType { Jewelry = 'JEWELRY', // 珠宝 Appliance = 'APPLIANCE', // 家电 Furniture = 'FURNITURE', // 日用家具 + OutdoorSports = 'OUTDOOR_SPORTS', PetFamily = 'PET_FAMILY', // 母婴宠物 Luxury = 'LUXURY', // 奢品 LocalLive = 'LOCAL_LIVE', // 本地生活 @@ -87,6 +88,7 @@ export const JOB_TYPE_TITLE_MAP: { [key in JobType]: string } = { [JobType.Jewelry]: '珠宝', [JobType.Appliance]: '家电', [JobType.Furniture]: '日用家具', + [JobType.OutdoorSports]: '户外运动', [JobType.PetFamily]: '母婴宠物', [JobType.Luxury]: '奢品', [JobType.LocalLive]: '本地生活', @@ -173,6 +175,7 @@ export const JOB_TYPE_SELECT_OPTIONS = [ { label: JOB_TYPE_TITLE_MAP[JobType.Jewelry], value: JobType.Jewelry }, { label: JOB_TYPE_TITLE_MAP[JobType.Appliance], value: JobType.Appliance }, { label: JOB_TYPE_TITLE_MAP[JobType.Furniture], value: JobType.Furniture }, + { label: JOB_TYPE_TITLE_MAP[JobType.OutdoorSports], value: JobType.OutdoorSports }, { label: JOB_TYPE_TITLE_MAP[JobType.PetFamily], value: JobType.PetFamily }, { label: JOB_TYPE_TITLE_MAP[JobType.Luxury], value: JobType.Luxury }, { label: JOB_TYPE_TITLE_MAP[JobType.LocalLive], value: JobType.LocalLive }, @@ -181,6 +184,11 @@ export const JOB_TYPE_SELECT_OPTIONS = [ { label: JOB_TYPE_TITLE_MAP[JobType.Other], value: JobType.Other }, ]; +export const JOB_TYPE_SELECT_OPTIONS_WITH_ALL = [ + { label: JOB_TYPE_TITLE_MAP[JobType.All], value: JobType.All }, + ...JOB_TYPE_SELECT_OPTIONS, +]; + const MAX_SALARY = 10000000; export const PART_EMPLOY_SALARY_OPTIONS = [ { label: '不限' }, diff --git a/src/constants/material.ts b/src/constants/material.ts index bb6b5ae..7549d10 100644 --- a/src/constants/material.ts +++ b/src/constants/material.ts @@ -84,14 +84,25 @@ export const WORK_YEAR_OPTIONS = [ { label: WORK_YEAR_LABELS[WorkedYears.MoreThreeYear], value: WorkedYears.MoreThreeYear }, ]; -export const ALL_GENDER_TYPES = [GenderType.All, GenderType.MEN, GenderType.WOMEN]; - export const GENDER_TYPE_TITLE_MAP = { [GenderType.All]: '不限', [GenderType.WOMEN]: '女', [GenderType.MEN]: '男', }; - +export const GENDER_OPTIONS = [ + { + value: GenderType.All, + label: GENDER_TYPE_TITLE_MAP[GenderType.All], + }, + { + value: GenderType.WOMEN, + label: GENDER_TYPE_TITLE_MAP[GenderType.WOMEN], + }, + { + value: GenderType.MEN, + label: GENDER_TYPE_TITLE_MAP[GenderType.MEN], + }, +]; export const ALL_ANCHOR_READ_TYPES = Object.values(AnchorReadType); export const ANCHOR_READ_TITLE_MAP = { diff --git a/src/pages/anchor/index.less b/src/pages/anchor/index.less index 77f2317..179a906 100644 --- a/src/pages/anchor/index.less +++ b/src/pages/anchor/index.less @@ -52,7 +52,11 @@ font-size: 28px; line-height: 32px; color: @blColor; + gap: 20px; + &-item { + display: flex; + } .title { margin-right: 5px; } @@ -61,11 +65,17 @@ padding: 0 24px; } &__overlay-outer { - top: 82px; + top: 72px; } &__overlay-inner { width: 100%; + max-height: 100%; + overflow: hidden; + .bl-select__items-container { + max-height: calc(100vh - 560rpx); + overflow-y: auto; + } } &__tips-container { @@ -91,8 +101,6 @@ margin-top: 50px; } - - &__popup { &-content { .flex-column(); diff --git a/src/pages/anchor/index.tsx b/src/pages/anchor/index.tsx index 15ad941..4f720b0 100644 --- a/src/pages/anchor/index.tsx +++ b/src/pages/anchor/index.tsx @@ -5,11 +5,13 @@ import { Popup } from '@taroify/core'; import { ArrowDown, ArrowUp } from '@taroify/icons'; import classNames from 'classnames'; import { isEqual } from 'lodash-es'; -import { useCallback, useEffect, useState } from 'react'; +import { useCallback, useEffect, useMemo, useState } from 'react'; import AnchorList, { IAnchorListProps } from '@/components/anchor-list'; import AnchorPicker from '@/components/anchor-picker'; import CustomNavigationBar from '@/components/custom-navigation-bar'; +import EmployTypeSelect from '@/components/employ-type-select'; +import GenderSelect from '@/components/gender-select'; import HomePage from '@/components/home-page'; import Overlay from '@/components/overlay'; import PageLoading from '@/components/page-loading'; @@ -17,8 +19,8 @@ import PartnerBanner from '@/components/partner-banner'; import SafeBottomPadding from '@/components/safe-bottom-padding'; import SwitchBar from '@/components/switch-bar'; import { APP_TAB_BAR_ID, EventName, OpenSource, PageType, PageUrl, RoleType } from '@/constants/app'; -import { EmployType } from '@/constants/job'; -import { ALL_ANCHOR_SORT_TYPES, ANCHOR_SORT_TYPE_TITLE_MAP, AnchorSortType } from '@/constants/material'; +import { EmployType, JobType } from '@/constants/job'; +import { ALL_ANCHOR_SORT_TYPES, ANCHOR_SORT_TYPE_TITLE_MAP, AnchorSortType, GenderType } from '@/constants/material'; import useInviteCode from '@/hooks/use-invite-code'; import useListHeight, { IUseListHeightProps } from '@/hooks/use-list-height'; import useLocation from '@/hooks/use-location'; @@ -36,6 +38,7 @@ import { getCommonShareMessage } from '@/utils/share'; import Toast from '@/utils/toast'; import './index.less'; +import TopCategorySelect from '@/components/top-category-select'; const PREFIX = 'page-anchor'; const LIST_CONTAINER_CLASS = `${PREFIX}__list-container`; @@ -78,12 +81,22 @@ function ListWrapper(props: IAnchorListProps) { return ; } +enum FilterType { + gender, + employType, + topCategory, + more, +} + export default function AnchorPage() { const location = useLocation(); const [loading, setLoading] = useState(true); const [selectJob, setSelectJob] = useState(); - const [filters, setFilters] = useState({ employType: EmployType.All }); - const [showFilter, setShowFilter] = useState(false); + const [moreFilters, setMoreFilters] = useState({}); + const [gender, setGender] = useState(GenderType.All); + const [employType, setEmployType] = useState(EmployType.All); + const [topCategory, setTopCategory] = useState(JobType.All); + const [showFilter, setShowFilter] = useState(null); const [sortType, setSortType] = useState(AnchorSortType.Active); const [openPopup, setOpenPopup] = useState(false); const [coordinate, setCoordinate] = useState({ @@ -106,20 +119,35 @@ export default function AnchorPage() { [selectJob] ); - const handleClickSalarySelect = useCallback(() => { - setShowFilter(!showFilter); - }, [showFilter]); + const handleClickFilterSelect = (type: FilterType) => () => { + setShowFilter(type === showFilter ? null : type); + }; - const handleHideFilter = useCallback(() => setShowFilter(false), []); + const handleHideFilter = useCallback(() => setShowFilter(null), []); const handleFilterChange = useCallback( (newFilters: IAnchorFilters) => { - !isEqual(newFilters, filters) && setFilters(newFilters); - setShowFilter(false); + !isEqual(newFilters, moreFilters) && setMoreFilters(newFilters); + setShowFilter(null); }, - [filters] + [moreFilters] ); + const handleChangeSelectGender = useCallback((value: GenderType) => { + setGender(value); + setShowFilter(null); + }, []); + + const handleChangeSelectEmployType = useCallback((value: EmployType) => { + setEmployType(value); + setShowFilter(null); + }, []); + + const handleChangeSelectTopCategory = useCallback((value: JobType) => { + setTopCategory(value); + setShowFilter(null); + }, []); + const handleClickSortType = useCallback(async (type: AnchorSortType) => setSortType(type), []); const handleJobChange = useCallback( @@ -205,6 +233,15 @@ export default function AnchorPage() { useDidShow(() => requestUnreadMessageCount()); + const filters = useMemo( + () => ({ + ...moreFilters, + topCategory, + gender: gender === -1 ? undefined : gender, + employType, + }), + [moreFilters, gender, employType, topCategory] + ); return ( {!!loading && } @@ -224,9 +261,23 @@ export default function AnchorPage() {
))}
-
-
筛选
- {showFilter ? : } +
+
+
性别
+ {showFilter === FilterType.gender ? : } +
+
+
类型
+ {showFilter === FilterType.employType ? : } +
+
+
品类
+ {showFilter === FilterType.topCategory ? : } +
+
+
更多
+ {showFilter === FilterType.more ? : } +
@@ -243,12 +294,36 @@ export default function AnchorPage() { className={LIST_CONTAINER_CLASS} /> - + + + + + + + + + +