You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
260 lines
8.4 KiB
260 lines
8.4 KiB
import React, { useState, useEffect, useContext } from "react";
|
|
import { ListView } from "antd-mobile";
|
|
import Modal from "react-modal";
|
|
import "./Malls.scss";
|
|
import search from "./search.png";
|
|
import pos from "./pos.png";
|
|
import close_white from "./close_white.png";
|
|
import up from "./up.png";
|
|
import {
|
|
Mall,
|
|
cityMallsGetter,
|
|
CityMall,
|
|
} from "../../js/helpers/data-helper.js";
|
|
import { MallCode } from "../../pages/Index/Index";
|
|
|
|
const getSectionData = (dataBlob, sectionID) => dataBlob[sectionID];
|
|
const getRowData = (dataBlob, sectionID, rowID) => dataBlob[rowID];
|
|
|
|
function genData(ds, cityMalls) {
|
|
const dataBlob = {};
|
|
const sectionIDs = [];
|
|
const rowIDs = [];
|
|
const groupByIndex = (list) =>
|
|
list.reduce((acc, nxt) => {
|
|
acc[nxt.index] = acc[nxt.index] ? [...acc[nxt.index], nxt] : [nxt];
|
|
return acc;
|
|
}, {});
|
|
const data = groupByIndex(cityMalls);
|
|
Object.keys(data).forEach((item, index) => {
|
|
sectionIDs.push(item);
|
|
dataBlob[item] = item;
|
|
rowIDs[index] = [];
|
|
|
|
data[item].forEach((city) => {
|
|
rowIDs[index].push(city.name);
|
|
dataBlob[city.name] = city;
|
|
});
|
|
});
|
|
return ds.cloneWithRowsAndSections(dataBlob, sectionIDs, rowIDs);
|
|
}
|
|
|
|
const Malls = ({ isOpen, onRequestClose, setMallCode }) => {
|
|
const [q, setQ] = useState("");
|
|
const [showList, setShowList] = useState(false);
|
|
const [cities, setCities] = useState([]);
|
|
const [currentMall, setCurrentMall] = useState(null);
|
|
const [currentCity, setCurrentCity] = useState(null);
|
|
const [currentMalls, setCurrentMalls] = useState([]);
|
|
const [isMallExpand, setIsMallExpand] = useState(false);
|
|
const [dataSource, setDataSource] = useState(
|
|
new ListView.DataSource({
|
|
getRowData,
|
|
getSectionHeaderData: getSectionData,
|
|
rowHasChanged: (row1, row2) => row1 !== row2,
|
|
sectionHeaderHasChanged: (s1, s2) => s1 !== s2,
|
|
})
|
|
);
|
|
const mallCode = useContext(MallCode);
|
|
const setDefaultCityMall = (list) => {
|
|
setCurrentCity(list[0]);
|
|
setCurrentMall(list[0].malls[0]);
|
|
setCurrentMalls(list[0].malls);
|
|
};
|
|
|
|
useEffect(() => {
|
|
document.title = "城市商场选择";
|
|
cityMallsGetter().then((cityMalls) => {
|
|
setCities(cityMalls);
|
|
setDataSource(genData(dataSource, cityMalls));
|
|
|
|
if (cityMalls.length) {
|
|
const city = cityMalls.find(({ malls }) =>
|
|
malls.find(({ code }) => mallCode === code)
|
|
);
|
|
if (city) {
|
|
setCurrentCity(city);
|
|
const mall = city.malls.find(({ code }) => mallCode === code);
|
|
if (mall) setCurrentMall(mall);
|
|
setCurrentMalls(city.malls);
|
|
} else setDefaultCityMall(cityMalls);
|
|
}
|
|
});
|
|
}, [mallCode]);
|
|
|
|
return (
|
|
<Modal
|
|
isOpen={isOpen}
|
|
style={{ overlay: { zIndex: 10000, background: "#fff" } }}
|
|
ariaHideApp={false}
|
|
className="malls"
|
|
onRequestClose={() => onRequestClose()}
|
|
>
|
|
<div className="malls" onClick={() => setIsMallExpand(false)}>
|
|
<div className="input-wrapper">
|
|
<input
|
|
value={q}
|
|
className="input"
|
|
placeholder="输入城市进行搜索"
|
|
onChange={(e) => setQ(e.target.value)}
|
|
onFocus={() => setShowList(true)}
|
|
onBlur={() => !q && setShowList(false)}
|
|
></input>
|
|
</div>
|
|
<img className="search-icon" src={search}></img>
|
|
{q && (
|
|
<img className="close" src={close_white} onClick={() => setQ("")} />
|
|
)}
|
|
{showList && (
|
|
<div className="list">
|
|
{cities
|
|
.filter(({ name }) => name.includes(q))
|
|
.map((city) => (
|
|
<div
|
|
className="item"
|
|
key={city.name}
|
|
onClick={() => {
|
|
setCurrentCity(city);
|
|
setCurrentMall(city.malls[0]);
|
|
setCurrentMalls(city.malls);
|
|
setShowList(false);
|
|
}}
|
|
>
|
|
{city.name}
|
|
</div>
|
|
))}
|
|
</div>
|
|
)}
|
|
{!showList && (
|
|
<div className="main">
|
|
<div className="r1">
|
|
<div className="left">
|
|
<img className="pos" src={pos}></img>
|
|
{currentCity && <span>{currentCity.name}</span>}
|
|
|
|
{currentMall && <span>{currentMall.name}</span>}
|
|
<img className="up" src={up}></img>
|
|
</div>
|
|
<span className="right">当前定位城市</span>
|
|
</div>
|
|
<div className="r2">切换商场</div>
|
|
<div
|
|
className="malls-wrapper"
|
|
onClick={() => {
|
|
setIsMallExpand(false);
|
|
}}
|
|
>
|
|
<div
|
|
className={"malls1" + (isMallExpand ? " expand" : "")}
|
|
onClick={(e) => {
|
|
e.stopPropagation();
|
|
}}
|
|
>
|
|
{currentMalls.map((mall) => (
|
|
<span
|
|
key={mall.code}
|
|
className="tag"
|
|
onClick={() => {
|
|
console.log("setMallCode", mall.code);
|
|
setCurrentMall(mall);
|
|
setIsMallExpand(false);
|
|
setMallCode(mall.code);
|
|
onRequestClose();
|
|
// Taro.reLaunch({
|
|
// url: `/pages/index/index?mallId=${mall.id}`
|
|
// });
|
|
}}
|
|
>
|
|
{mall.name}
|
|
</span>
|
|
))}
|
|
{!isMallExpand && (
|
|
<div
|
|
className="more"
|
|
onClick={(e) => {
|
|
e.stopPropagation();
|
|
setIsMallExpand(true);
|
|
}}
|
|
>
|
|
更多
|
|
</div>
|
|
)}
|
|
{isMallExpand && (
|
|
<img
|
|
className="fold"
|
|
src={up}
|
|
onClick={(e) => {
|
|
e.stopPropagation();
|
|
setIsMallExpand(false);
|
|
}}
|
|
></img>
|
|
)}
|
|
</div>
|
|
<ListView.IndexedList
|
|
dataSource={dataSource}
|
|
className="am-list sticky-list"
|
|
useBodyScroll
|
|
renderSectionHeader={(sectionData) => (
|
|
<div>
|
|
<div
|
|
className="sticky"
|
|
style={{
|
|
zIndex: 3,
|
|
}}
|
|
>
|
|
{sectionData}
|
|
</div>
|
|
</div>
|
|
)}
|
|
renderHeader={() => (
|
|
<div>
|
|
<div className="meta">切换城市</div>
|
|
<div className="city-buttons">
|
|
{cities.map((city) => (
|
|
<div
|
|
key={city.name}
|
|
className="city-button"
|
|
onClick={() => {
|
|
setCurrentCity(city);
|
|
setCurrentMall(city.malls[0]);
|
|
setCurrentMalls(city.malls);
|
|
}}
|
|
>
|
|
{city.name}
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
)}
|
|
renderRow={(rowData) => (
|
|
<div
|
|
key={rowData.name}
|
|
className="city-button"
|
|
onClick={() => {
|
|
setCurrentCity(rowData);
|
|
setCurrentMalls(rowData.malls);
|
|
setCurrentMall(rowData.malls[0]);
|
|
}}
|
|
>
|
|
{rowData.name}
|
|
</div>
|
|
)}
|
|
quickSearchBarStyle={{
|
|
position: "absolute",
|
|
top: 25,
|
|
}}
|
|
delayTime={10}
|
|
delayActivityIndicator={
|
|
<div style={{ padding: 25, textAlign: "center" }}>
|
|
rendering...
|
|
</div>
|
|
}
|
|
/>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</Modal>
|
|
);
|
|
};
|
|
export default Malls;
|
|
|