Files
boluo-app-main/src/components/anchor-picker/index.tsx
2025-03-31 22:34:22 +08:00

187 lines
6.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { BaseEventOrig, Input, InputProps } from '@tarojs/components';
import classNames from 'classnames';
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 { IAnchorFilters } from '@/types/material';
import { isUndefined } from '@/utils/common';
import './index.less';
interface IProps {
value: IAnchorFilters;
onConfirm: (newValue: IAnchorFilters) => 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) => {
const min = full ? value.lowPriceForFullTime : value.lowPriceForPartyTime;
const max = full ? value.highPriceForFullTime : value.highPriceForPartyTime;
if (!min || !max) {
return null;
}
const options = full ? FULL_PRICE_OPTIONS : PART_PRICE_OPTIONS;
return options.find(v => v.value && v.value.minSalary <= min && v.value.maxSalary >= max)?.value;
};
function AnchorPicker(props: IProps) {
const { value, onConfirm } = props;
const [gender, setGender] = useState<GenderType | undefined>(getDefaultGender(value));
const [readType, setReadType] = useState<AnchorReadType | undefined>(getDefaultReadType(value));
const [employType, setEmployType] = useState<EmployType | undefined>(getDefaultEmploy(value));
const [fullSalary, setFullSalary] = useState(getSalaryValue(value, true));
const [partSalary, setPartSalary] = useState(getSalaryValue(value, false));
const [category, setCategory] = useState(getDefaultCategory(value));
const handleInputCategory = useCallback((e: BaseEventOrig<InputProps.inputEventDetail>) => {
setCategory(e.detail.value || '');
}, []);
const handleClickReset = useCallback(() => {
setGender(undefined);
setReadType(undefined);
setEmployType(undefined);
setFullSalary(null);
setPartSalary(null);
setCategory('');
}, []);
const handleSelectFull = useCallback(
(newSalary?: { minSalary: number; maxSalary: number }) => {
setFullSalary(newSalary === fullSalary ? null : newSalary);
},
[fullSalary]
);
const handleSelectPart = useCallback(
(newSalary?: { minSalary: number; maxSalary: number }) => {
setPartSalary(newSalary === partSalary ? null : newSalary);
},
[partSalary]
);
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) {
filters.lowPriceForFullTime = fullSalary.minSalary;
filters.highPriceForFullTime = fullSalary.maxSalary;
}
if (partSalary) {
filters.lowPriceForPartyTime = partSalary.minSalary;
filters.highPriceForPartyTime = partSalary.maxSalary;
}
onConfirm(filters);
}, [gender, employType, readType, category, fullSalary, partSalary, onConfirm]);
return (
<div className={PREFIX}>
<div className={`${PREFIX}__title`}></div>
<div className={`${PREFIX}__container`}>
{ALL_GENDER_TYPES.map((type: GenderType) => (
<div
key={type}
onClick={() => setGender(type)}
className={classNames(`${PREFIX}__item`, { selected: type === gender })}
>
{GENDER_TYPE_TITLE_MAP[type]}
</div>
))}
</div>
<div className={`${PREFIX}__title`}>/</div>
<div className={`${PREFIX}__container`}>
{ALL_EMPLOY_TYPES.map(type => (
<div
key={type}
onClick={() => setEmployType(type)}
className={classNames(`${PREFIX}__item`, { selected: type === employType })}
>
{EMPLOY_TYPE_TITLE_MAP[type]}
</div>
))}
</div>
<div className={`${PREFIX}__title`}>/</div>
<div className={`${PREFIX}__container`}>
{ALL_ANCHOR_READ_TYPES.map(type => (
<div
key={type}
onClick={() => setReadType(type)}
className={classNames(`${PREFIX}__item`, { selected: type === readType })}
>
{ANCHOR_READ_TITLE_MAP[type]}
</div>
))}
</div>
<div className={`${PREFIX}__title`}></div>
<div className={`${PREFIX}__container`}>
{FULL_PRICE_OPTIONS.map(option => (
<div
key={option.label}
onClick={() => handleSelectFull(option.value)}
className={classNames(`${PREFIX}__item`, { selected: isEqual(option.value, fullSalary) })}
>
{option.label}
</div>
))}
</div>
<div className={`${PREFIX}__title`}></div>
<div className={`${PREFIX}__container`}>
{PART_PRICE_OPTIONS.map(option => (
<div
key={option.label}
onClick={() => handleSelectPart(option.value)}
className={classNames(`${PREFIX}__item`, { selected: isEqual(option.value, partSalary) })}
>
{option.label}
</div>
))}
</div>
<div className={`${PREFIX}__title`}></div>
<Input
maxlength={20}
value={category}
confirmType="done"
placeholder="如 服装"
onInput={handleInputCategory}
className={`${PREFIX}__input`}
placeholderClass={`${PREFIX}__input-placeholder`}
/>
<PickerToolbar
cancelText="重置"
confirmText="确定"
className={`${PREFIX}__toolbar`}
onClickCancel={handleClickReset}
onClickConfirm={handleClickConfirm}
/>
</div>
);
}
export default AnchorPicker;