import { Button } from '@tarojs/components'; import Taro, { NodesRef, useLoad } from '@tarojs/taro'; import { Tabs } from '@taroify/core'; import { ArrowDown, ArrowUp } from '@taroify/icons'; import classNames from 'classnames'; import { useCallback, useEffect, useRef, useState } from 'react'; import JobList from '@/components/job-list'; import JobPicker from '@/components/job-picker'; import Overlay from '@/components/overlay'; import SafeBottomPadding from '@/components/safe-bottom-padding'; import SearchInput from '@/components/search'; import { EventName, OpenSource, PageUrl } from '@/constants/app'; import { CacheKey } from '@/constants/cache-key'; import { CITY_CODE_TO_NAME_MAP } from '@/constants/city'; import { JOB_TABS, JobType, EmployType } from '@/constants/job'; import useListHeight, { IUseListHeightProps } from '@/hooks/use-list-height'; import { logWithPrefix } from '@/utils/common'; import { getPageQuery, navigateTo } from '@/utils/route'; import './index.less'; const PREFIX = 'page-search-job'; const LIST_CLASS = 'search-job-list-container'; const SAFE_PADDING_BOTTOM_CLASS = `${PREFIX}__safe-padding-bottom`; const CALC_LIST_PROPS: IUseListHeightProps = { selectors: [`.${LIST_CLASS}`, `.${PREFIX}`, `.${SAFE_PADDING_BOTTOM_CLASS}`], calc: ( rects: [ NodesRef.BoundingClientRectCallbackResult, NodesRef.BoundingClientRectCallbackResult, NodesRef.BoundingClientRectCallbackResult, ] ) => { const [listRect, pageRect, safePaddingRect] = rects; return pageRect.bottom - listRect.top - safePaddingRect.height; }, }; const log = logWithPrefix(PREFIX); export default function JobSearch() { const listHeight = useListHeight(CALC_LIST_PROPS); const [focus, setFocus] = useState(true); const [employType, setEmployType] = useState(EmployType.All); const [tabType, setTabType] = useState(JobType.All); const [value, setValue] = useState(''); const [keyWord, setKeyWord] = useState(''); const [cityCode, setCityCode] = useState(''); const [showMenu, setShowMenu] = useState(false); const historyRef = useRef([]); const showContent = keyWord.length > 0; const handleUpdateHistory = useCallback((historyKeyword: string) => { const newHistory = [...new Set([historyKeyword, ...historyRef.current])].slice(0, 20); historyRef.current = newHistory; Taro.setStorageSync(CacheKey.JOB_SEARCH_HISTORY, newHistory); log('handleUpdateHistory', newHistory); }, []); const handleClickHistoryItem = useCallback( (historyKeyword: string) => { setValue(historyKeyword); setKeyWord(historyKeyword); handleUpdateHistory(historyKeyword); }, [handleUpdateHistory] ); const handleClickSearch = useCallback(() => { if (value === keyWord) { return; } setFocus(false); setKeyWord(value); handleUpdateHistory(value); }, [value, keyWord, handleUpdateHistory]); const handleSearchClear = useCallback(() => { setValue(''); setKeyWord(''); }, []); const handleSearchBlur = useCallback(() => setFocus(false), []); const handleSearchFocus = useCallback(() => setFocus(true), []); const handleSearchChange = useCallback(e => setValue(e.detail.value), []); const handleClickCityMenu = useCallback(() => { navigateTo(PageUrl.CitySearch, { city: cityCode, source: OpenSource.JobSearch }); }, [cityCode]); const handleClickTypeMenu = useCallback(() => { setShowMenu(!showMenu); }, [showMenu]); const handleHideMenu = useCallback(() => setShowMenu(false), []); const handleCityChange = useCallback(data => { log('handleCityChange', data); const { openSource, cityCode: code } = data; if (openSource !== OpenSource.JobSearch) { return; } setCityCode(code); }, []); const handleTypePickerConfirm = useCallback((newEmployType: EmployType) => { log('picker confirm', newEmployType); setEmployType(newEmployType); setShowMenu(false); }, []); const onTypeChange = useCallback(type => setTabType(type), [setTabType]); useLoad(() => { const query = getPageQuery<{ city: string }>(); const currentCity = query.city; if (!currentCity) { return; } setCityCode(currentCity); }); useLoad(() => { const cacheHistory = Taro.getStorageSync(CacheKey.JOB_SEARCH_HISTORY); log('useLoad', cacheHistory); if (!cacheHistory) { return; } historyRef.current = cacheHistory; }); useEffect(() => { Taro.eventCenter.on(EventName.SELECT_CITY, handleCityChange); return () => { Taro.eventCenter.off(EventName.SELECT_CITY, handleCityChange); }; }, [handleCityChange]); const searchAction = ( ); return (
{CITY_CODE_TO_NAME_MAP.get(cityCode)}
筛选
{showMenu ? : }
{JOB_TABS.map(tab => ( ))}
历史搜索
{historyRef.current.map(historyKeyword => (
handleClickHistoryItem(historyKeyword)} > {historyKeyword}
))}
); }