123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- import { useCallback, useEffect, useState } from "react";
- import { FC } from "@tarojs/taro";
- import { AtFloatLayout, AtInput, AtTabs, AtTabsPane } from "taro-ui";
- import { AtFloatLayoutProps } from "taro-ui/types/float-layout";
- import { View } from "@tarojs/components";
- import { CITY_LIST, SIGHT_LIST } from "../../constants";
- import { debounce } from "../../../../utils";
- import { getSignListApi } from "../../../../api";
- import "./index.scss";
- export interface SearchLayoutProps extends AtFloatLayoutProps {
- openDetail(id: (typeof SIGHT_LIST)[0]): void;
- }
- export const SearchLayout: FC<SearchLayoutProps> = (props) => {
- const [curTab, setCurTab] = useState(0);
- const [keyword, setKeyword] = useState("");
- const [input, setInput] = useState("");
- const [list, setList] = useState<any>({});
- const [loading, setLoading] = useState(false);
- useEffect(() => {
- if (props.isOpened) {
- getSignList();
- }
- }, [props.isOpened]);
- const getSignList = async (idx?: number) => {
- const _idx = idx ?? curTab;
- if (list[_idx]) return;
- try {
- setLoading(true);
- const data = await getSignListApi({
- region: _idx === 0 ? "" : CITY_LIST[_idx].title,
- type: "scene",
- });
- setList({
- ...list,
- [_idx]: data,
- });
- } finally {
- setLoading(false);
- }
- };
- const handleTabClick = (idx: number) => {
- setCurTab(idx);
- getSignList(idx);
- };
- const debounceSearch = useCallback(
- debounce((v: string) => {
- setKeyword(v);
- }, 1000),
- []
- );
- const fakeSearch = (v: string) => {
- return v.match(keyword) !== null;
- };
- return (
- <AtFloatLayout className="search-layout" {...props}>
- {props.isOpened && (
- <>
- <View className="search-input">
- <AtInput
- clear
- className="search-input__input"
- name="keyword"
- value={input}
- confirm-type="search"
- placeholder="请输入要搜索的内容..."
- onChange={(v) => {
- setInput(v as string);
- debounceSearch(v as string);
- }}
- />
- <View className="search-input__cancel" onClick={props.onClose}>
- 取消
- </View>
- </View>
- <AtTabs
- current={curTab}
- scroll
- className="search-tab"
- tabList={CITY_LIST}
- onClick={handleTabClick}
- >
- {CITY_LIST.map((item, idx) => {
- const _list = (list[idx] || []).filter((i) =>
- keyword ? fakeSearch(i.name) : true
- );
- return (
- <AtTabsPane current={curTab} index={item.id}>
- {_list.length
- ? _list.map((subItem) => (
- <View
- key={subItem.id}
- className="search-tab__item"
- onClick={props.openDetail.bind(undefined, subItem)}
- >
- <View className="search-tab__item-inner">
- <View className="search-tab__item-inner__label">
- {subItem.name}
- </View>
- <View className="limit-line">
- {subItem.description.slice(0, 50)}
- </View>
- </View>
- <View className="search-tab__item__more" />
- </View>
- ))
- : !loading && (
- <View className="search-tab__nomore">暂无内容</View>
- )}
- </AtTabsPane>
- );
- })}
- </AtTabs>
- </>
- )}
- </AtFloatLayout>
- );
- };
|