@ -1,211 +0,0 @@ |
|||||
import "./style.scss"; |
|
||||
import React, { useState, useEffect } from "react"; |
|
||||
|
|
||||
import search from "./search.png"; |
|
||||
import close from "./close.png"; |
|
||||
import go from "./go.png"; |
|
||||
import arrow from "./arrow.png"; |
|
||||
import ShopsWithFilter from "../ShopsWithFilter/ShopsWithFilter"; |
|
||||
const STATES = { |
|
||||
init: 0, |
|
||||
moreFac: 1, |
|
||||
facList: 2, |
|
||||
}; |
|
||||
export const DefaultPopupStates = STATES; |
|
||||
const initMarginBottom = 47; |
|
||||
const DefaultPopup = ({ |
|
||||
state, |
|
||||
setState, |
|
||||
onSearch, |
|
||||
facilities, |
|
||||
onClickFac, |
|
||||
mall, |
|
||||
onClick, |
|
||||
setEnd, |
|
||||
hasTab, |
|
||||
blurMap = () => {}, |
|
||||
}) => { |
|
||||
const marginBottomStateMap = { |
|
||||
0: 47, |
|
||||
1: hasTab |
|
||||
? window.innerHeight - 52 - 179 - 98 |
|
||||
: window.innerHeight - 52 - 179, |
|
||||
}; |
|
||||
const baseMarginBottom = marginBottomStateMap[state]; |
|
||||
const [facList, setFacList] = useState(null); |
|
||||
const [focused, setFocused] = useState(null); |
|
||||
const [start, setStart] = useState(null); |
|
||||
const [marginBottom, setMarginBottom] = useState(null); |
|
||||
const [doTransition, setdoTransition] = useState(false); |
|
||||
useEffect(() => { |
|
||||
setdoTransition(true); |
|
||||
setMarginBottom(baseMarginBottom); |
|
||||
setTimeout(() => { |
|
||||
setdoTransition(false); |
|
||||
}, 500); |
|
||||
}, [state]); |
|
||||
const handleTouchStart = (e) => { |
|
||||
if (start) return; |
|
||||
setStart({ |
|
||||
identifier: e.changedTouches[0].identifier, |
|
||||
y: e.changedTouches[0].clientY, |
|
||||
}); |
|
||||
}; |
|
||||
const handleTouchMove = (e) => { |
|
||||
if (!start) return; |
|
||||
const touch = Array.from(e.changedTouches).find( |
|
||||
({ identifier }) => identifier === start.identifier |
|
||||
); |
|
||||
if (!touch) return; |
|
||||
const delta = touch.clientY - start.y; |
|
||||
setMarginBottom(baseMarginBottom - delta); |
|
||||
}; |
|
||||
const handleTouchEnd = (e) => { |
|
||||
if (!start) return; |
|
||||
const touch = Array.from(e.changedTouches).find( |
|
||||
({ identifier }) => identifier === start.identifier |
|
||||
); |
|
||||
if (!touch) return; |
|
||||
setStart(null); |
|
||||
const delta = touch.clientY - start.y; |
|
||||
const newState = |
|
||||
state === STATES.init && delta < -100 |
|
||||
? STATES.moreFac |
|
||||
: state === STATES.moreFac && delta > 100 |
|
||||
? STATES.init |
|
||||
: state; |
|
||||
|
|
||||
if (state === newState) { |
|
||||
setdoTransition(true); |
|
||||
setMarginBottom(baseMarginBottom); |
|
||||
setTimeout(() => { |
|
||||
setdoTransition(false); |
|
||||
}, 500); |
|
||||
} else setState(newState); |
|
||||
}; |
|
||||
|
|
||||
return ( |
|
||||
<> |
|
||||
{state === STATES.init || state === STATES.moreFac ? ( |
|
||||
<div |
|
||||
className={"dp" + (state === STATES.moreFac ? " more-fac" : "")} |
|
||||
style={{ |
|
||||
marginBottom: marginBottom + "px", |
|
||||
transition: !doTransition ? "none" : "margin-bottom 0.5s ease", |
|
||||
}} |
|
||||
onTouchStart={handleTouchStart} |
|
||||
onTouchMove={handleTouchMove} |
|
||||
onTouchCancel={handleTouchEnd} |
|
||||
onTouchEnd={handleTouchEnd} |
|
||||
> |
|
||||
<div |
|
||||
className="ts" |
|
||||
onClick={() => |
|
||||
setState(state === STATES.moreFac ? STATES.init : STATES.moreFac) |
|
||||
} |
|
||||
> |
|
||||
<img className="t1" src={arrow} /> |
|
||||
</div> |
|
||||
|
|
||||
<div className="search" onClick={onSearch}> |
|
||||
<img className="icon" src={search}></img> |
|
||||
<div className="sep"></div> |
|
||||
搜索店铺 |
|
||||
</div> |
|
||||
<div className="facs"> |
|
||||
{Object.entries(facilities).map(([name, list]) => ( |
|
||||
<div |
|
||||
className="fac" |
|
||||
key={name} |
|
||||
onClick={() => { |
|
||||
list.sort((a, b) => a.floorOrder - b.floorOrder); |
|
||||
setFacList(list); |
|
||||
setState(STATES.facList); |
|
||||
}} |
|
||||
> |
|
||||
<img src={list[0].url}></img> |
|
||||
{name} |
|
||||
</div> |
|
||||
))} |
|
||||
</div> |
|
||||
</div> |
|
||||
) : ( |
|
||||
<> |
|
||||
<img |
|
||||
src={close} |
|
||||
className="close" |
|
||||
onClick={(e) => { |
|
||||
e.preventDefault(); |
|
||||
e.stopPropagation(); |
|
||||
setState(STATES.init); |
|
||||
setFacList(null); |
|
||||
blurMap(); |
|
||||
}} |
|
||||
></img> |
|
||||
<div className="dp1"> |
|
||||
{facList && |
|
||||
facList.map((fac, i) => { |
|
||||
const showRow1 = |
|
||||
i === 0 || fac.floorName !== facList[i - 1].floorName; |
|
||||
const isActive = focused === fac.id; |
|
||||
return ( |
|
||||
<div key={fac.id}> |
|
||||
{showRow1 && ( |
|
||||
<div className={"row1" + (i === 0 ? "" : " has-border")}> |
|
||||
{fac.floorName} |
|
||||
</div> |
|
||||
)} |
|
||||
<div |
|
||||
className={[ |
|
||||
"row2", |
|
||||
isActive ? "active" : "", |
|
||||
!showRow1 ? "has-margin" : "", |
|
||||
].join(" ")} |
|
||||
onClick={() => { |
|
||||
setFocused(fac.id); |
|
||||
onClickFac(fac.id); |
|
||||
}} |
|
||||
> |
|
||||
{fac.name} |
|
||||
<span className="meta">{fac.floorName}</span> |
|
||||
{isActive && ( |
|
||||
<div |
|
||||
className="go" |
|
||||
src={go} |
|
||||
onClick={(e) => { |
|
||||
e.stopPropagation(); |
|
||||
setState(STATES.init); |
|
||||
onClickFac(fac.id); |
|
||||
}} |
|
||||
> |
|
||||
GO |
|
||||
</div> |
|
||||
)} |
|
||||
</div> |
|
||||
</div> |
|
||||
); |
|
||||
})} |
|
||||
</div> |
|
||||
</> |
|
||||
)} |
|
||||
{state !== STATES.facList && ( |
|
||||
<div |
|
||||
className="sf" |
|
||||
onClick={() => { |
|
||||
setState(STATES.moreFac); |
|
||||
}} |
|
||||
> |
|
||||
<ShopsWithFilter |
|
||||
mall={mall} |
|
||||
onClick={(e) => { |
|
||||
setState(STATES.init); |
|
||||
onClick(e); |
|
||||
}} |
|
||||
wingHeight="calc(100vh - 310px)" |
|
||||
></ShopsWithFilter> |
|
||||
</div> |
|
||||
)} |
|
||||
</> |
|
||||
); |
|
||||
}; |
|
||||
export default DefaultPopup; |
|
||||
|
Before Width: | Height: | Size: 526 B |
|
Before Width: | Height: | Size: 596 B |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 1.5 KiB |
@ -1,231 +0,0 @@ |
|||||
.dp { |
|
||||
position: relative; |
|
||||
width: calc(100vw - 20px); |
|
||||
margin-left: 10px; |
|
||||
height: 179px; |
|
||||
border-top-left-radius: 24px; |
|
||||
border-top-right-radius: 24px; |
|
||||
text-align: center; |
|
||||
position: relative; |
|
||||
padding: 14px 0 0 0; |
|
||||
background: #ffffff; |
|
||||
box-shadow: 0px 12px 16px rgba(104, 110, 127, 0.08); |
|
||||
border-radius: 18px; |
|
||||
&::before { |
|
||||
position: absolute; |
|
||||
content: ""; |
|
||||
top: 0; |
|
||||
left: -10px; |
|
||||
right: -10px; |
|
||||
height: 236px; |
|
||||
background: linear-gradient( |
|
||||
180deg, |
|
||||
rgba(243, 244, 248, 0) 0%, |
|
||||
#f3f4f8 41.53%, |
|
||||
#f3f4f8 100% |
|
||||
); |
|
||||
z-index: -1; |
|
||||
} |
|
||||
&::after { |
|
||||
position: absolute; |
|
||||
content: ""; |
|
||||
left: -10px; |
|
||||
right: -10px; |
|
||||
top: 236px; |
|
||||
height: calc(100vh - 52px - 236px); |
|
||||
background: #f3f4f8; |
|
||||
z-index: -1; |
|
||||
} |
|
||||
&.more-fac { |
|
||||
.t1, |
|
||||
.t2 { |
|
||||
transform: rotate(180deg); |
|
||||
} |
|
||||
.facs { |
|
||||
max-height: 333px; |
|
||||
overflow-y: scroll; |
|
||||
} |
|
||||
} |
|
||||
.ts { |
|
||||
position: absolute; |
|
||||
margin: auto; |
|
||||
left: 0; |
|
||||
right: 0; |
|
||||
top: 0; |
|
||||
width: 24px; |
|
||||
height: 24px; |
|
||||
.t1 { |
|
||||
position: absolute; |
|
||||
margin: auto; |
|
||||
left: 0; |
|
||||
right: 0; |
|
||||
top: 3px; |
|
||||
width: 33px; |
|
||||
height: 7px; |
|
||||
border-radius: 5px; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.search { |
|
||||
position: relative; |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
margin: 0 14px; |
|
||||
height: 60px; |
|
||||
font-family: PingFang SC; |
|
||||
font-style: normal; |
|
||||
font-weight: 500; |
|
||||
font-size: 16px; |
|
||||
color: #323337; |
|
||||
text-align: left; |
|
||||
background: #f3f4f8; |
|
||||
border: 1px solid #edeff3; |
|
||||
box-sizing: border-box; |
|
||||
border-radius: 10px; |
|
||||
padding-left: 14px; |
|
||||
.icon { |
|
||||
width: 24px; |
|
||||
height: 24px; |
|
||||
} |
|
||||
.sep { |
|
||||
width: 1px; |
|
||||
height: 16px; |
|
||||
background: #c9cbd1; |
|
||||
margin: 0 14px; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.facs { |
|
||||
display: inline-flex; |
|
||||
align-items: flex-start; |
|
||||
overflow-x: auto; |
|
||||
overflow-y: hidden; |
|
||||
width: 100%; |
|
||||
white-space: nowrap; |
|
||||
margin-top: 20px; |
|
||||
padding-left: 20px; |
|
||||
height: 75px; |
|
||||
.fac { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
justify-content: space-between; |
|
||||
height: 65px; |
|
||||
margin-right: 20px; |
|
||||
font-family: PingFang SC; |
|
||||
font-style: normal; |
|
||||
font-weight: 500; |
|
||||
font-size: 11px; |
|
||||
line-height: 15px; |
|
||||
text-align: center; |
|
||||
color: #474a56; |
|
||||
align-items: center; |
|
||||
img { |
|
||||
display: block; |
|
||||
width: 44px; |
|
||||
height: 44px; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
.close { |
|
||||
position: absolute; |
|
||||
top: 16px; |
|
||||
right: 26px; |
|
||||
width: 24px; |
|
||||
height: 24px; |
|
||||
z-index: 10; |
|
||||
} |
|
||||
.dp1 { |
|
||||
position: relative; |
|
||||
margin: 0 10px 26px 10px; |
|
||||
height: 326px; |
|
||||
border-radius: 18px; |
|
||||
background: #ffffff; |
|
||||
box-shadow: 0px 12px 16px rgba(104, 110, 127, 0.08); |
|
||||
text-align: center; |
|
||||
padding: 14px; |
|
||||
overflow-x: hidden; |
|
||||
overflow-y: auto; |
|
||||
.row1, |
|
||||
.row2 { |
|
||||
text-align: left; |
|
||||
line-height: 48px; |
|
||||
height: 48px; |
|
||||
} |
|
||||
.row1 { |
|
||||
font-family: DINPro; |
|
||||
font-style: normal; |
|
||||
font-weight: bold; |
|
||||
font-size: 24px; |
|
||||
line-height: 48px; |
|
||||
height: 48px; |
|
||||
color: #323337; |
|
||||
padding: 0 16px; |
|
||||
&.has-border { |
|
||||
position: relative; |
|
||||
padding-top: 24px; |
|
||||
height: 72px; |
|
||||
&::after { |
|
||||
position: absolute; |
|
||||
content: ""; |
|
||||
top: 12px; |
|
||||
left: 0; |
|
||||
right: 0; |
|
||||
border-top: 1px dashed #edeff3; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
.row2 { |
|
||||
display: flex; |
|
||||
position: relative; |
|
||||
padding-left: 16px; |
|
||||
font-family: PingFang SC; |
|
||||
font-style: normal; |
|
||||
font-weight: 500; |
|
||||
font-size: 16px; |
|
||||
color: #323337; |
|
||||
background: #f9f9fb; |
|
||||
border-radius: 12px; |
|
||||
&.has-margin { |
|
||||
margin-top: 4px; |
|
||||
} |
|
||||
&.active { |
|
||||
background: linear-gradient(180deg, #508af7 0%, #5ea5f9 100%); |
|
||||
color: #ffffff; |
|
||||
border-radius: 12px; |
|
||||
.meta { |
|
||||
color: #ffffff; |
|
||||
} |
|
||||
} |
|
||||
.meta { |
|
||||
margin-left: 16px; |
|
||||
font-family: DINPro; |
|
||||
font-style: normal; |
|
||||
font-weight: normal; |
|
||||
font-size: 17px; |
|
||||
color: #a1a5b3; |
|
||||
} |
|
||||
.go { |
|
||||
position: absolute; |
|
||||
top: 8px; |
|
||||
right: 8px; |
|
||||
width: 96px; |
|
||||
height: 32px; |
|
||||
background: #ffffff; |
|
||||
box-shadow: 0px 2px 6px rgba(93, 172, 249, 0.2); |
|
||||
border-radius: 8px; |
|
||||
font-family: PingFang SC; |
|
||||
font-style: normal; |
|
||||
font-weight: 600; |
|
||||
font-size: 16px; |
|
||||
line-height: 32px; |
|
||||
text-align: center; |
|
||||
color: #437af7; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
.sf { |
|
||||
position: absolute; |
|
||||
top: 177px; |
|
||||
left: 0; |
|
||||
} |
|
||||
@ -1,184 +0,0 @@ |
|||||
import React, { useState, useEffect } from "react"; |
|
||||
import ShopList from "../ShopList/ShopList.js"; |
|
||||
import "./HeadBar.scss"; |
|
||||
import { searchTypes } from "../Options/Options"; |
|
||||
import backpng from './back.png' |
|
||||
|
|
||||
const HeadBar = ({ |
|
||||
mall, |
|
||||
exit, |
|
||||
start, |
|
||||
end, |
|
||||
floors, |
|
||||
onSwap, |
|
||||
shop, |
|
||||
onSetStart, |
|
||||
onSetEnd, |
|
||||
isPick, |
|
||||
setIsPick, |
|
||||
blurMap, |
|
||||
showSearchType, |
|
||||
onClickSearchType, |
|
||||
searchType, |
|
||||
onIsTypingChange |
|
||||
}) => { |
|
||||
const [isTypingStart, setIsTypingStart] = useState(false); |
|
||||
const [isTypingEnd, setIsTypingEnd] = useState(false); |
|
||||
const isTyping = isTypingStart || isTypingEnd; |
|
||||
const [q, setQ] = useState(null); |
|
||||
const onlyShowStart = isTypingStart || (!start && isPick); |
|
||||
const onlyShowEnd = isTypingEnd || (!end && isPick); |
|
||||
const showStart = !onlyShowEnd; |
|
||||
const showEnd = !onlyShowStart; |
|
||||
const showBoth = !(isPick || isTyping); |
|
||||
const hasBoth = start && end; |
|
||||
const startValue = |
|
||||
q !== null ? q : isPick ? (shop ? shop.name : "") : start ? start.name : ""; |
|
||||
const endValue = |
|
||||
q !== null ? q : isPick ? (shop ? shop.name : "") : end ? end.name : ""; |
|
||||
|
|
||||
useEffect(() => { onIsTypingChange(isTyping) }, [isTyping]) |
|
||||
return ( |
|
||||
<div |
|
||||
className={"head-bar" + (showBoth ? " double" : "")} |
|
||||
onClick={() => blurMap()} |
|
||||
> |
|
||||
<div |
|
||||
className="back" |
|
||||
onClick={() => { |
|
||||
if (isPick) setIsPick(false); |
|
||||
else if (isTypingStart) { |
|
||||
setQ(null); |
|
||||
setIsTypingStart(false); |
|
||||
} else if (isTypingEnd) { |
|
||||
setQ(null); |
|
||||
setIsTypingEnd(false); |
|
||||
} else exit(); |
|
||||
}} |
|
||||
> |
|
||||
<img src={backpng}></img> |
|
||||
</div> |
|
||||
<div className="content"> |
|
||||
{showBoth && <div className="dots"></div>} |
|
||||
{showStart && ( |
|
||||
<div className={"row start" + (onlyShowStart ? " single" : "")}> |
|
||||
<div className="text"> |
|
||||
<input |
|
||||
value={startValue} |
|
||||
onFocus={() => setIsTypingStart(true)} |
|
||||
onChange={(e) => setQ(e.target.value)} |
|
||||
readOnly={isPick} |
|
||||
disabled={isPick} |
|
||||
placeholder={isPick ? "请点击地图选择起点" : "请输入起点"} |
|
||||
></input> |
|
||||
{(start || (isPick && shop)) && ( |
|
||||
<span className="label"> |
|
||||
{floors[(start ? start : shop).floorOrder][1]} |
|
||||
</span> |
|
||||
)} |
|
||||
<div style={{ flex: 1 }}></div> |
|
||||
{start === null && isPick && ( |
|
||||
<div |
|
||||
className='right' |
|
||||
onClick={() => { |
|
||||
setIsPick(false); |
|
||||
onSetStart(shop); |
|
||||
}} |
|
||||
> |
|
||||
开始导航 |
|
||||
</div> |
|
||||
)} |
|
||||
{start === null && !isPick && !isTypingStart && ( |
|
||||
<div |
|
||||
className="right" |
|
||||
onClick={() => { |
|
||||
setQ(null); |
|
||||
setIsPick(true); |
|
||||
setIsTypingStart(false); |
|
||||
setIsTypingEnd(false); |
|
||||
}} |
|
||||
> |
|
||||
地图选点 |
|
||||
</div> |
|
||||
)} |
|
||||
</div> |
|
||||
</div> |
|
||||
)} |
|
||||
{showEnd && ( |
|
||||
<div className={"row end" + (isPick ? " single" : "")}> |
|
||||
<div className={"text " + (isTypingEnd ? '' : 'has-border')}> |
|
||||
<input |
|
||||
value={endValue} |
|
||||
onFocus={() => setIsTypingEnd(true)} |
|
||||
onChange={(e) => setQ(e.target.value)} |
|
||||
readOnly={isPick} |
|
||||
disabled={isPick} |
|
||||
placeholder={isPick ? "请点击地图选择终点" : "请输入终点"} |
|
||||
></input> |
|
||||
{((isPick && shop) || end) && ( |
|
||||
<span className="label"> |
|
||||
{floors[(end ? end : shop).floorOrder][1]} |
|
||||
</span> |
|
||||
)} |
|
||||
<div style={{ flex: 1 }}></div> |
|
||||
{end === null && isPick && ( |
|
||||
<div |
|
||||
className={shop ? "right green" : "right grey"} |
|
||||
onClick={() => { |
|
||||
setIsPick(false); |
|
||||
onSetEnd(shop); |
|
||||
}} |
|
||||
> |
|
||||
开始导航 |
|
||||
</div> |
|
||||
)} |
|
||||
{end === null && !isPick && !isTypingEnd && ( |
|
||||
<div |
|
||||
className="right" |
|
||||
onClick={() => { |
|
||||
setQ(null); |
|
||||
setIsPick(true); |
|
||||
setIsTypingEnd(false); |
|
||||
}} |
|
||||
> |
|
||||
地图选点 |
|
||||
</div> |
|
||||
)} |
|
||||
</div> |
|
||||
</div> |
|
||||
)} |
|
||||
|
|
||||
{showBoth && <div className="switch" onClick={() => onSwap()}></div>} |
|
||||
</div> |
|
||||
{showBoth && !hasBoth && ( |
|
||||
<div className={"banner " + (start === null ? "start" : "end")}> |
|
||||
请在顶部选择{!start ? "起" : "终"}点 |
|
||||
</div> |
|
||||
)} |
|
||||
{isTyping && q && ( |
|
||||
<div className="shop-list-wrapper"> |
|
||||
<ShopList |
|
||||
mall={mall} |
|
||||
q={q} |
|
||||
onClick={(shop) => { |
|
||||
if (isTypingStart) { |
|
||||
onSetStart(shop); |
|
||||
setQ(null); |
|
||||
setIsTypingStart(false); |
|
||||
} |
|
||||
if (isTypingEnd) { |
|
||||
onSetEnd(shop); |
|
||||
setQ(null); |
|
||||
setIsTypingEnd(false); |
|
||||
} |
|
||||
}} |
|
||||
top={"70px"} |
|
||||
isRow={true} |
|
||||
></ShopList> |
|
||||
</div> |
|
||||
)} |
|
||||
</div> |
|
||||
); |
|
||||
}; |
|
||||
|
|
||||
export default HeadBar; |
|
||||
@ -1,271 +0,0 @@ |
|||||
.head-bar { |
|
||||
display: flex; |
|
||||
box-sizing: border-box; |
|
||||
width: calc(100vw - 20px); |
|
||||
margin-left: 10px; |
|
||||
margin-top: 10px; |
|
||||
font-size: 16px; |
|
||||
line-height: 44px; |
|
||||
position: relative; |
|
||||
z-index: 1; |
|
||||
height: 64px; |
|
||||
position: relative; |
|
||||
border-radius: 12px; |
|
||||
align-items: center; |
|
||||
pointer-events: auto; |
|
||||
&.double { |
|
||||
height: 114px; |
|
||||
.back { |
|
||||
height: 114px; |
|
||||
} |
|
||||
.content { |
|
||||
height: 114px; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.back { |
|
||||
display: flex; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
position: relative; |
|
||||
background: #ffffff; |
|
||||
flex: 0 0 50px; |
|
||||
margin-right: 8px; |
|
||||
height: 64px; |
|
||||
border-radius: 12px; |
|
||||
img { |
|
||||
width: 32px; |
|
||||
height: 32px; |
|
||||
} |
|
||||
} |
|
||||
.content { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
justify-content: center; |
|
||||
background: #ffffff; |
|
||||
height: 64px; |
|
||||
z-index: 2; |
|
||||
flex: 1; |
|
||||
position: relative; |
|
||||
border-radius: 12px; |
|
||||
.dots { |
|
||||
position: absolute; |
|
||||
top: 0; |
|
||||
bottom: 0; |
|
||||
left: 23px; |
|
||||
width: 2px; |
|
||||
height: 2px; |
|
||||
border-radius: 50%; |
|
||||
background: #c9cbd1; |
|
||||
margin: auto 0; |
|
||||
&::before { |
|
||||
content: ""; |
|
||||
display: block; |
|
||||
position: absolute; |
|
||||
top: -6px; |
|
||||
width: 2px; |
|
||||
height: 2px; |
|
||||
border-radius: 50%; |
|
||||
background: #c9cbd1; |
|
||||
left: 0; |
|
||||
right: 0; |
|
||||
margin: 0 auto; |
|
||||
} |
|
||||
&::after { |
|
||||
content: ""; |
|
||||
display: block; |
|
||||
position: absolute; |
|
||||
bottom: -6px; |
|
||||
width: 2px; |
|
||||
height: 2px; |
|
||||
border-radius: 50%; |
|
||||
background: #c9cbd1; |
|
||||
left: 0; |
|
||||
right: 0; |
|
||||
margin: 0 auto; |
|
||||
} |
|
||||
} |
|
||||
.row { |
|
||||
position: relative; |
|
||||
line-height: 57px; |
|
||||
height: 57px; |
|
||||
padding-left: 48px; |
|
||||
padding-right: 49px; |
|
||||
&.start { |
|
||||
background: 16px center/16px 16px no-repeat url("./start.png"); |
|
||||
} |
|
||||
&.end { |
|
||||
background: 16px center/16px 16px no-repeat url("./end.png"); |
|
||||
} |
|
||||
&.single { |
|
||||
padding-right: 10px; |
|
||||
} |
|
||||
.text { |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
input { |
|
||||
border: none; |
|
||||
background: transparent; |
|
||||
display: inline-block; |
|
||||
line-height: 57px; |
|
||||
outline: none; |
|
||||
width: 100%; |
|
||||
font-family: PingFang SC; |
|
||||
font-style: normal; |
|
||||
font-weight: 600; |
|
||||
font-size: 18px; |
|
||||
color: #323337; |
|
||||
} |
|
||||
::placeholder { |
|
||||
font-size: 16px; |
|
||||
font-weight: 400; |
|
||||
color: #c9cbd1; |
|
||||
} |
|
||||
&.has-border { |
|
||||
border-top: 1px solid rgba(238, 238, 238, 0.7); |
|
||||
} |
|
||||
|
|
||||
.label { |
|
||||
display: inline-block; |
|
||||
flex: 0 0 30px; |
|
||||
text-align: right; |
|
||||
margin-left: 8px; |
|
||||
font-style: normal; |
|
||||
font-weight: bold; |
|
||||
font-size: 12px; |
|
||||
color: #b3aea7; |
|
||||
} |
|
||||
.right { |
|
||||
background: #f3f4f8; |
|
||||
border: 1px solid #edeff3; |
|
||||
box-sizing: border-box; |
|
||||
border-radius: 8px; |
|
||||
font-family: PingFang SC; |
|
||||
font-style: normal; |
|
||||
font-weight: 600; |
|
||||
font-size: 12px; |
|
||||
line-height: 33px; |
|
||||
color: #437af7; |
|
||||
flex: 0 0 80px; |
|
||||
text-align: center; |
|
||||
display: inline-block; |
|
||||
white-space: nowrap; |
|
||||
margin-left: 8px; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
.switch { |
|
||||
position: absolute; |
|
||||
width: 49px; |
|
||||
height: 32px; |
|
||||
background-image: url("./switch.png"); |
|
||||
background-size: contain; |
|
||||
background-repeat: no-repeat; |
|
||||
background-position: center; |
|
||||
top: 0; |
|
||||
bottom: 0; |
|
||||
right: 0; |
|
||||
margin: auto 0; |
|
||||
} |
|
||||
} |
|
||||
.banner { |
|
||||
position: absolute; |
|
||||
display: flex; |
|
||||
background: rgba(0, 0, 0, 0.6); |
|
||||
width: 237px; |
|
||||
line-height: 40px; |
|
||||
height: 40px; |
|
||||
text-align: center; |
|
||||
bottom: -48px; |
|
||||
left: 0; |
|
||||
right: 0; |
|
||||
margin: auto; |
|
||||
font-family: PingFang SC; |
|
||||
font-style: normal; |
|
||||
font-weight: normal; |
|
||||
font-size: 14px; |
|
||||
color: #ffffff; |
|
||||
border-radius: 20px; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
&.start::before { |
|
||||
content: ""; |
|
||||
display: inline-block; |
|
||||
width: 16px; |
|
||||
height: 16px; |
|
||||
margin-right: 8px; |
|
||||
vertical-align: middle; |
|
||||
background-image: url("./start.png"); |
|
||||
background-size: contain; |
|
||||
} |
|
||||
&.end::before { |
|
||||
content: ""; |
|
||||
display: inline-block; |
|
||||
width: 16px; |
|
||||
height: 16px; |
|
||||
margin-right: 8px; |
|
||||
vertical-align: middle; |
|
||||
background-image: url("./end.png"); |
|
||||
background-size: contain; |
|
||||
} |
|
||||
&::after { |
|
||||
content: ""; |
|
||||
display: inline-block; |
|
||||
margin-left: 8px; |
|
||||
width: 16px; |
|
||||
height: 16px; |
|
||||
vertical-align: middle; |
|
||||
background-image: url("./arrow.png"); |
|
||||
background-size: contain; |
|
||||
} |
|
||||
} |
|
||||
.shop-list-wrapper { |
|
||||
position: absolute; |
|
||||
top: 64px; |
|
||||
left: -10px; |
|
||||
width: 100vw; |
|
||||
height: calc(100vh - 74px); |
|
||||
overflow-x: hidden; |
|
||||
overflow-y: auto; |
|
||||
} |
|
||||
.search-type { |
|
||||
position: absolute; |
|
||||
top: 100px; |
|
||||
width: 100vw; |
|
||||
height: 40px; |
|
||||
line-height: 40px; |
|
||||
background: #fff; |
|
||||
display: flex; |
|
||||
color: #404040; |
|
||||
left: 0; |
|
||||
font-size: 12px; |
|
||||
.el { |
|
||||
flex: 1 1 33%; |
|
||||
text-align: center; |
|
||||
span { |
|
||||
position: relative; |
|
||||
display: inline-block; |
|
||||
img { |
|
||||
width: 18px; |
|
||||
height: 18px; |
|
||||
vertical-align: middle; |
|
||||
margin-right: 8px; |
|
||||
} |
|
||||
&.active { |
|
||||
color: #0074ed; |
|
||||
} |
|
||||
&.active { |
|
||||
&::after { |
|
||||
content: ""; |
|
||||
position: absolute; |
|
||||
width: 100%; |
|
||||
height: 4px; |
|
||||
background: #0074ed; |
|
||||
bottom: 0; |
|
||||
left: 0; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
Before Width: | Height: | Size: 316 B |
|
Before Width: | Height: | Size: 841 B |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 791 B |
@ -1,260 +0,0 @@ |
|||||
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; |
|
||||
@ -1,242 +0,0 @@ |
|||||
/*postcss-pxtransform disable*/ |
|
||||
.malls { |
|
||||
position: relative; |
|
||||
width: 100vw; |
|
||||
height: 100vh; |
|
||||
box-sizing: border-box; |
|
||||
color: #5a5a5a; |
|
||||
font-family: SourceHanSansCN-Medium, SourceHanSansCN; |
|
||||
background: #fff; |
|
||||
box-sizing: border-box; |
|
||||
.search-icon { |
|
||||
position: absolute; |
|
||||
width: 13px; |
|
||||
height: 13px; |
|
||||
top: 21px; |
|
||||
left: 26px; |
|
||||
z-index: 1; |
|
||||
} |
|
||||
.close { |
|
||||
position: absolute; |
|
||||
border-radius: 50%; |
|
||||
background: #8d8d8d; |
|
||||
width: 20px; |
|
||||
height: 20px; |
|
||||
top: 17px; |
|
||||
right: 19px; |
|
||||
} |
|
||||
.input-wrapper { |
|
||||
padding: 12px 14px 0 14px; |
|
||||
.input { |
|
||||
padding: 5px 30px; |
|
||||
background: #ececec; |
|
||||
border-radius: 100px; |
|
||||
height: 30px; |
|
||||
line-height: 20px; |
|
||||
font-size: 11px; |
|
||||
box-sizing: border-box; |
|
||||
border: none; |
|
||||
width: 100%; |
|
||||
outline: none; |
|
||||
} |
|
||||
::placeholder { |
|
||||
color: #a9a9a9; |
|
||||
} |
|
||||
} |
|
||||
.list { |
|
||||
padding: 0 50px 0 15px; |
|
||||
line-height: 36px; |
|
||||
height: calc(100vh - 42px); |
|
||||
font-size: 12px; |
|
||||
overflow: scroll; |
|
||||
.item { |
|
||||
border-bottom: 1px solid #f4f4f4; |
|
||||
} |
|
||||
} |
|
||||
.main { |
|
||||
.r1 { |
|
||||
padding: 18px 15px; |
|
||||
line-height: 30px; |
|
||||
.left { |
|
||||
position: relative; |
|
||||
display: inline-block; |
|
||||
font-size: 14px; |
|
||||
background: rgba(244, 244, 244, 1); |
|
||||
border-radius: 8px; |
|
||||
border: 1px solid rgba(236, 236, 236, 1); |
|
||||
padding: 0 30px; |
|
||||
.pos { |
|
||||
position: absolute; |
|
||||
width: 14px; |
|
||||
height: 16px; |
|
||||
top: 7px; |
|
||||
left: 9px; |
|
||||
} |
|
||||
.up { |
|
||||
position: absolute; |
|
||||
right: 7.5px; |
|
||||
top: 12.5px; |
|
||||
width: 8px; |
|
||||
height: 5px; |
|
||||
transform-origin: center; |
|
||||
transform: rotate(90deg); |
|
||||
} |
|
||||
|
|
||||
Text + Text { |
|
||||
margin-left: 22px; |
|
||||
} |
|
||||
} |
|
||||
.right { |
|
||||
margin-left: 15px; |
|
||||
font-size: 11px; |
|
||||
font-weight: 400; |
|
||||
color: rgba(169, 169, 169, 1); |
|
||||
} |
|
||||
} |
|
||||
.r2 { |
|
||||
padding-left: 15px; |
|
||||
color: #a9a9a9; |
|
||||
font-size: 11px; |
|
||||
line-height: 11px; |
|
||||
font-weight: 400; |
|
||||
} |
|
||||
.malls-wrapper { |
|
||||
height: calc(100vh - 119px); |
|
||||
.malls1 { |
|
||||
position: relative; |
|
||||
margin-top: 11px; |
|
||||
padding-left: 15px; |
|
||||
padding-right: 60px; |
|
||||
height: 32px; |
|
||||
overflow: hidden; |
|
||||
background: #fff; |
|
||||
z-index: 10; |
|
||||
.more { |
|
||||
position: absolute; |
|
||||
line-height: 30px; |
|
||||
color: #a9a9a9; |
|
||||
right: 14px; |
|
||||
font-size: 11px; |
|
||||
top: 0; |
|
||||
} |
|
||||
&.expand { |
|
||||
box-shadow: 0px 15px 12px 0px rgba(0, 0, 0, 0.22); |
|
||||
padding-right: 15px; |
|
||||
padding-bottom: 17px; |
|
||||
overflow: auto; |
|
||||
height: auto; |
|
||||
} |
|
||||
.tag { |
|
||||
color: #878787; |
|
||||
font-size: 12px; |
|
||||
padding: 0 11px; |
|
||||
border-radius: 15px; |
|
||||
border: 1px solid rgba(236, 236, 236, 1); |
|
||||
line-height: 30px; |
|
||||
display: inline-block; |
|
||||
margin-bottom: 12px; |
|
||||
margin-right: 10px; |
|
||||
} |
|
||||
.fold { |
|
||||
position: absolute; |
|
||||
bottom: 0; |
|
||||
width: 8px; |
|
||||
height: 5px; |
|
||||
padding: 8px 6.5px; |
|
||||
left: 0; |
|
||||
right: 0; |
|
||||
margin: auto; |
|
||||
} |
|
||||
.fold::after { |
|
||||
content: ""; |
|
||||
position: absolute; |
|
||||
left: -5px; |
|
||||
right: -5px; |
|
||||
top: -5px; |
|
||||
bottom: -5px; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
.am-indexed-list-container { |
|
||||
position: absolute; |
|
||||
top: 178px; |
|
||||
border-top: 1px solid #f4f4f4; |
|
||||
padding: 0 50px 0 15px; |
|
||||
height: calc(100vh - 178px); |
|
||||
width: 100vw; |
|
||||
box-sizing: border-box; |
|
||||
.am-indexed-list-quick-search-bar :first-child { |
|
||||
display: none !important; |
|
||||
} |
|
||||
.am-indexed-list-quick-search-bar { |
|
||||
top: 204px; |
|
||||
font-size: 11px; |
|
||||
transform: none; |
|
||||
right: 15px; |
|
||||
z-index: 1; |
|
||||
text-align: center; |
|
||||
li { |
|
||||
display: block; |
|
||||
padding: 0; |
|
||||
font-size: 11px; |
|
||||
color: #a9a9a9; |
|
||||
line-height: 15px; |
|
||||
height: 15px; |
|
||||
width: 15px; |
|
||||
} |
|
||||
li:active { |
|
||||
background: #0091ff; |
|
||||
|
|
||||
color: white; |
|
||||
border-radius: 50%; |
|
||||
} |
|
||||
} |
|
||||
.at-list::after { |
|
||||
content: none; |
|
||||
} |
|
||||
.am-indexed-list-section-body { |
|
||||
line-height: 36px; |
|
||||
color: #878787; |
|
||||
font-size: 12px; |
|
||||
font-weight: 400; |
|
||||
border-bottom: 1px solid #f4f4f4; |
|
||||
background: none; |
|
||||
padding: 0; |
|
||||
} |
|
||||
.am-indexed-list-section-header { |
|
||||
font-size: 12px; |
|
||||
font-weight: 400; |
|
||||
border-bottom: 1px solid #f4f4f4; |
|
||||
padding: 0; |
|
||||
} |
|
||||
.am-list-body { |
|
||||
color: #5a5a5a; |
|
||||
line-height: 36px; |
|
||||
} |
|
||||
} |
|
||||
.meta { |
|
||||
font-size: 11px; |
|
||||
font-weight: 400; |
|
||||
margin-top: 7px; |
|
||||
padding: 11px 0; |
|
||||
color: #a9a9a9; |
|
||||
} |
|
||||
.city-buttons { |
|
||||
display: grid; |
|
||||
grid-column-gap: 10px; |
|
||||
grid-row-gap: 11px; |
|
||||
grid-auto-rows: 30px; |
|
||||
grid-auto-columns: 70px; |
|
||||
grid-template-columns: 1fr 1fr 1fr 1fr; |
|
||||
.city-button { |
|
||||
display: inline-block; |
|
||||
color: #878787; |
|
||||
font-size: 12px; |
|
||||
line-height: 30px; |
|
||||
background: rgba(244, 244, 244, 1); |
|
||||
border-radius: 4px; |
|
||||
text-align: center; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
Before Width: | Height: | Size: 833 B |
|
Before Width: | Height: | Size: 998 B |
|
Before Width: | Height: | Size: 936 B |
|
Before Width: | Height: | Size: 464 B |
|
Before Width: | Height: | Size: 870 B |
|
Before Width: | Height: | Size: 1.3 KiB |
@ -1,53 +0,0 @@ |
|||||
import React from "react"; |
|
||||
import { searchTypes, audioOptions } from "../Options/Options"; |
|
||||
import "./More.scss"; |
|
||||
import flat from "./2d.png"; |
|
||||
import thrD from "./3d.png"; |
|
||||
|
|
||||
const displayModes = [ |
|
||||
{ |
|
||||
id: 0, |
|
||||
name: "2D", |
|
||||
bg: flat, |
|
||||
}, |
|
||||
{ |
|
||||
id: 1, |
|
||||
name: "3D", |
|
||||
bg: thrD, |
|
||||
}, |
|
||||
]; |
|
||||
const More = ({ |
|
||||
showHeadBar, |
|
||||
displayMode, |
|
||||
searchType, |
|
||||
onClickDisplayMode, |
|
||||
onClickSearchType, |
|
||||
}) => { |
|
||||
return ( |
|
||||
<div className={"more " + (showHeadBar ? "has-header-top" : "")}> |
|
||||
<div className="types"> |
|
||||
{searchTypes.map(({ id, name, bg, bgb }) => ( |
|
||||
<div |
|
||||
key={id} |
|
||||
className={"btn " + (searchType === id ? "active" : "")} |
|
||||
onClick={() => { |
|
||||
onClickSearchType(id); |
|
||||
}} |
|
||||
> |
|
||||
<img src={searchType === id ? bgb : bg} /> |
|
||||
<div>{name}</div> |
|
||||
</div> |
|
||||
))} |
|
||||
</div> |
|
||||
|
|
||||
<div |
|
||||
className="btn big" |
|
||||
onClick={() => onClickDisplayMode(displayMode == 0 ? 1 : 0)} |
|
||||
> |
|
||||
<img src={displayMode == 0 ? flat : thrD}></img> |
|
||||
{displayMode == 0 ? "2D" : "3D"} |
|
||||
</div> |
|
||||
</div> |
|
||||
); |
|
||||
}; |
|
||||
export default More; |
|
||||
@ -1,53 +0,0 @@ |
|||||
.more { |
|
||||
position: absolute; |
|
||||
top: 10px; |
|
||||
right: 10px; |
|
||||
display: inline-flex; |
|
||||
flex-direction: column; |
|
||||
pointer-events: auto; |
|
||||
&.has-header-top { |
|
||||
top: 138px; |
|
||||
} |
|
||||
.types { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
width: 40px; |
|
||||
height: 160px; |
|
||||
background: #ffffff; |
|
||||
box-shadow: 0px 8px 8px rgba(104, 110, 127, 0.04); |
|
||||
border-radius: 12px; |
|
||||
justify-content: space-evenly; |
|
||||
align-items: center; |
|
||||
} |
|
||||
.btn { |
|
||||
display: inline-flex; |
|
||||
flex-direction: column; |
|
||||
width: 32px; |
|
||||
height: 48px; |
|
||||
font-family: PingFang SC; |
|
||||
font-style: normal; |
|
||||
font-weight: 500; |
|
||||
font-size: 10px; |
|
||||
line-height: 14px; |
|
||||
text-align: center; |
|
||||
color: #474a56; |
|
||||
background: #ffffff; |
|
||||
border-radius: 12px; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
img { |
|
||||
width: 24px; |
|
||||
height: 24px; |
|
||||
} |
|
||||
&.active { |
|
||||
background: linear-gradient(180deg, #508af7 0%, #5ea5f9 100%); |
|
||||
color: #fff; |
|
||||
} |
|
||||
&.big { |
|
||||
width: 40px; |
|
||||
height: 56px; |
|
||||
margin-top: 8px; |
|
||||
box-shadow: 0px 8px 8px rgba(104, 110, 127, 0.04); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
Before Width: | Height: | Size: 596 B After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 1.8 KiB |
@ -1,137 +0,0 @@ |
|||||
import React from "react"; |
|
||||
import Modal from "react-modal"; |
|
||||
import flat from "./2d.png"; |
|
||||
import thrD from "./3d.png"; |
|
||||
import on from "./on.png"; |
|
||||
import mute from "./mute.png"; |
|
||||
import ft from "./ft.png"; |
|
||||
import ftb from "./ftb.png"; |
|
||||
import ztb from "./ztb.png"; |
|
||||
import zt from "./zt.png"; |
|
||||
import shortest from "./shortest.png"; |
|
||||
import shortestb from "./shortestb.png"; |
|
||||
import ft1 from "./ft1.png"; |
|
||||
import ftb1 from "./ftb1.png"; |
|
||||
import ztb1 from "./ztb1.png"; |
|
||||
import zt1 from "./zt1.png"; |
|
||||
import shortest1 from "./shortest1.png"; |
|
||||
import shortestb1 from "./shortestb1.png"; |
|
||||
import "antd-mobile/lib/switch/style/css"; |
|
||||
import "./Options.scss"; |
|
||||
|
|
||||
export const displayModes = [ |
|
||||
{ |
|
||||
id: 0, |
|
||||
name: "2D", |
|
||||
bg: flat, |
|
||||
}, |
|
||||
{ |
|
||||
id: 1, |
|
||||
name: "3D", |
|
||||
bg: thrD, |
|
||||
}, |
|
||||
]; |
|
||||
export const searchTypes = [ |
|
||||
{ |
|
||||
id: 0, |
|
||||
name: "最佳", |
|
||||
bg: shortest, |
|
||||
bgb: shortestb, |
|
||||
bg1: shortest1, |
|
||||
bgb1: shortestb1, |
|
||||
}, |
|
||||
{ |
|
||||
id: 1, |
|
||||
name: "扶梯", |
|
||||
bg: ft, |
|
||||
bgb: ftb, |
|
||||
bg1: ft1, |
|
||||
bgb1: ftb1, |
|
||||
}, |
|
||||
{ |
|
||||
id: 2, |
|
||||
name: "直梯", |
|
||||
bg: zt, |
|
||||
bgb: ztb, |
|
||||
bg1: zt1, |
|
||||
bgb1: ztb1, |
|
||||
}, |
|
||||
]; |
|
||||
export const audioOptions = [ |
|
||||
{ |
|
||||
id: 0, |
|
||||
name: "语音", |
|
||||
bg: on, |
|
||||
}, |
|
||||
{ |
|
||||
id: 1, |
|
||||
name: "语音", |
|
||||
bg: mute, |
|
||||
}, |
|
||||
]; |
|
||||
|
|
||||
const Options = ({ |
|
||||
show, |
|
||||
hide, |
|
||||
onClickDisplayMode, |
|
||||
onClickSearchType, |
|
||||
onClickPlayAudioMode, |
|
||||
showHeadBar, |
|
||||
}) => ( |
|
||||
<Modal |
|
||||
isOpen={show} |
|
||||
style={{ |
|
||||
overlay: { |
|
||||
zIndex: 10000, |
|
||||
background: "rgba(0,0,0,0)", |
|
||||
}, |
|
||||
}} |
|
||||
ariaHideApp={false} |
|
||||
className={"modal" + (showHeadBar ? " has-header-bar" : "")} |
|
||||
onRequestClose={() => hide()} |
|
||||
> |
|
||||
<div className="row"> |
|
||||
{displayModes.map(({ id, name, bg }) => ( |
|
||||
<div |
|
||||
key={id} |
|
||||
className={"col"} |
|
||||
onClick={() => { |
|
||||
onClickDisplayMode(id); |
|
||||
hide(); |
|
||||
}} |
|
||||
> |
|
||||
<div |
|
||||
className="up" |
|
||||
style={{ |
|
||||
background: `center/22px 22px no-repeat url(${bg})`, |
|
||||
}} |
|
||||
></div> |
|
||||
<div className="down">{name}</div> |
|
||||
</div> |
|
||||
))} |
|
||||
|
|
||||
<div className="col"></div> |
|
||||
</div> |
|
||||
<div className="row"> |
|
||||
{searchTypes.map(({ id, name, bg }) => ( |
|
||||
<div |
|
||||
key={id} |
|
||||
className="col" |
|
||||
onClick={() => { |
|
||||
onClickSearchType(id); |
|
||||
hide(); |
|
||||
}} |
|
||||
> |
|
||||
<div |
|
||||
className="up" |
|
||||
style={{ |
|
||||
background: `center/22px 22px no-repeat url(${bg})`, |
|
||||
}} |
|
||||
></div> |
|
||||
<div className="down">{name}</div> |
|
||||
</div> |
|
||||
))} |
|
||||
</div> |
|
||||
</Modal> |
|
||||
); |
|
||||
export default Options; |
|
||||
@ -1,106 +0,0 @@ |
|||||
.modal { |
|
||||
position: absolute; |
|
||||
width: 168px; |
|
||||
height: 136px; |
|
||||
background: #ffffff; |
|
||||
border-radius: 8px; |
|
||||
box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, 0.08); |
|
||||
outline: none; |
|
||||
right: 59px; |
|
||||
top: 12px; |
|
||||
overflow: hidden; |
|
||||
padding-top: 16px; |
|
||||
&.has-header-bar { |
|
||||
top: 112px; |
|
||||
} |
|
||||
.title { |
|
||||
background: #f4f4f4; |
|
||||
padding: 0 19px; |
|
||||
color: #878787; |
|
||||
font-family: SourceHanSansCN-Regular, SourceHanSansCN; |
|
||||
font-weight: 400; |
|
||||
line-height: 40px; |
|
||||
font-size: 11px; |
|
||||
} |
|
||||
.row { |
|
||||
display: flex; |
|
||||
flex: 1; |
|
||||
flex-direction: row; |
|
||||
margin-bottom: 18px; |
|
||||
.col { |
|
||||
flex: 1; |
|
||||
text-align: center; |
|
||||
.up { |
|
||||
width: 22px; |
|
||||
height: 22px; |
|
||||
margin: auto; |
|
||||
} |
|
||||
.down { |
|
||||
font-size: 12px; |
|
||||
font-family: SourceHanSansCN, SourceHanSansCN-Regular; |
|
||||
font-weight: 400; |
|
||||
text-align: center; |
|
||||
color: #696969; |
|
||||
line-height: 20px; |
|
||||
} |
|
||||
&.active { |
|
||||
.down { |
|
||||
color: #0074ed; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
.bottom { |
|
||||
position: absolute; |
|
||||
bottom: 0; |
|
||||
width: 100%; |
|
||||
line-height: 52px; |
|
||||
padding: 0 20px; |
|
||||
background: #f4f4f4; |
|
||||
color: #404040; |
|
||||
font-size: 12px; |
|
||||
font-family: SourceHanSansCN-Regular, SourceHanSansCN; |
|
||||
font-weight: 400; |
|
||||
.am-switch { |
|
||||
position: absolute; |
|
||||
top: 16px; |
|
||||
right: 20px; |
|
||||
input[type="checkbox"]:checked + .checkbox:after { |
|
||||
transform: translateX(22px); |
|
||||
} |
|
||||
.checkbox { |
|
||||
width: 42px; |
|
||||
height: 20px; |
|
||||
border-radius: 20px; |
|
||||
&:before { |
|
||||
content: " "; |
|
||||
position: absolute; |
|
||||
left: 1.5px; |
|
||||
top: 1.5px; |
|
||||
width: 39px; |
|
||||
height: 17px; |
|
||||
border-radius: 17px; |
|
||||
box-sizing: border-box; |
|
||||
background: #fff; |
|
||||
z-index: 1; |
|
||||
transition: all 200ms; |
|
||||
transform: scale(1); |
|
||||
} |
|
||||
&:after { |
|
||||
content: " "; |
|
||||
height: 17px; |
|
||||
width: 17px; |
|
||||
border-radius: 17px; |
|
||||
background: #fff; |
|
||||
position: absolute; |
|
||||
z-index: 2; |
|
||||
left: 1.5px; |
|
||||
top: 1.5px; |
|
||||
transform: translateX(0); |
|
||||
transition: all 200ms; |
|
||||
box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.21); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
Before Width: | Height: | Size: 720 B |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 452 B |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 905 B |
|
Before Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 565 B |
|
Before Width: | Height: | Size: 585 B |
|
Before Width: | Height: | Size: 466 B |
|
Before Width: | Height: | Size: 590 B |
@ -1,64 +1,100 @@ |
|||||
import React from "react"; |
|
||||
import desc from "./desc.png"; |
|
||||
import closeButton from "./close.png"; |
|
||||
|
import React, { useState, useEffect } from "react"; |
||||
import "./Popup.scss"; |
import "./Popup.scss"; |
||||
import navpng from "./nav.png"; |
|
||||
import arpng from "./ar.png"; |
|
||||
import couponTop from "./couponTop.png"; |
|
||||
const Popup = ({ |
|
||||
showPopup, |
|
||||
defaultPopup, |
|
||||
floors, |
|
||||
closePopup, |
|
||||
shop, |
|
||||
showDetail, |
|
||||
setEnd, |
|
||||
handleAR, |
|
||||
onClickCoupon, |
|
||||
}) => ( |
|
||||
<div className={["popup-wrapper", showPopup ? "" : "noshow"].join(" ")}> |
|
||||
{floors} |
|
||||
{defaultPopup} |
|
||||
{showPopup && ( |
|
||||
<div className="popup"> |
|
||||
{shop.hasCoupon && ( |
|
||||
<img |
|
||||
className="couponTop" |
|
||||
src={couponTop} |
|
||||
onClick={(shop) => onClickCoupon(shop)} |
|
||||
></img> |
|
||||
)} |
|
||||
<img |
|
||||
alt="关闭" |
|
||||
className="close-icon" |
|
||||
src={closeButton} |
|
||||
onClick={() => closePopup()} |
|
||||
></img> |
|
||||
<div className="r1"> |
|
||||
{shop.logoPath && ( |
|
||||
|
import ShopList from "../ShopList/ShopList.js"; |
||||
|
const Popup = ({ mall, sceneIndex, onClick, floors, shop, onClickActive }) => { |
||||
|
const [long, setLong] = useState(false); |
||||
|
const [height, setHeight] = useState(false); |
||||
|
const [start, setStart] = useState(null); |
||||
|
const [doTransition, setdoTransition] = useState(false); |
||||
|
const baseHeight = long ? window.innerHeight : 312; |
||||
|
useEffect(() => { |
||||
|
setdoTransition(true); |
||||
|
setHeight(baseHeight); |
||||
|
setTimeout(() => { |
||||
|
setdoTransition(false); |
||||
|
}, 500); |
||||
|
}, [long]); |
||||
|
const handleTouchStart = (e) => { |
||||
|
if (start) return; |
||||
|
setStart({ |
||||
|
identifier: e.changedTouches[0].identifier, |
||||
|
y: e.changedTouches[0].clientY, |
||||
|
}); |
||||
|
}; |
||||
|
const handleTouchMove = (e) => { |
||||
|
if (!start) return; |
||||
|
const touch = Array.from(e.changedTouches).find( |
||||
|
({ identifier }) => identifier === start.identifier |
||||
|
); |
||||
|
if (!touch) return; |
||||
|
const delta = touch.clientY - start.y; |
||||
|
setHeight(baseHeight - delta); |
||||
|
}; |
||||
|
const handleTouchEnd = (e) => { |
||||
|
if (!start) return; |
||||
|
const touch = Array.from(e.changedTouches).find( |
||||
|
({ identifier }) => identifier === start.identifier |
||||
|
); |
||||
|
if (!touch) return; |
||||
|
setStart(null); |
||||
|
const delta = touch.clientY - start.y; |
||||
|
const nxtLong = |
||||
|
!long && delta < -100 ? true : long && delta > 100 ? false : long; |
||||
|
|
||||
|
if (long === nxtLong) { |
||||
|
setdoTransition(true); |
||||
|
setHeight(baseHeight); |
||||
|
setTimeout(() => { |
||||
|
setdoTransition(false); |
||||
|
}, 500); |
||||
|
} else setLong(nxtLong); |
||||
|
}; |
||||
|
|
||||
|
useEffect(() => { |
||||
|
if (shop) { |
||||
|
if (long) { |
||||
|
setLong(false); |
||||
|
setTimeout(() => { |
||||
|
const domEl = document.getElementById("shop" + shop.houseNum); |
||||
|
if (domEl) |
||||
|
domEl.scrollIntoView({ behavior: "smooth", block: "center" }); |
||||
|
}, 500); |
||||
|
} else { |
||||
|
const domEl = document.getElementById("shop" + shop.houseNum); |
||||
|
if (domEl) |
||||
|
domEl.scrollIntoView({ behavior: "smooth", block: "center" }); |
||||
|
} |
||||
|
} |
||||
|
}, [shop]); |
||||
|
return ( |
||||
<div |
<div |
||||
className="avatar" |
|
||||
|
className={["popup-wrapper", long ? "long" : ""].join(" ")} |
||||
style={{ |
style={{ |
||||
backgroundImage: `url(${shop.logoPath})`, |
|
||||
|
height: height + "px", |
||||
|
transition: !doTransition ? "none" : "margin-bottom 0.5s ease", |
||||
|
backgroundImage: mall.theme.image.backgroundImg |
||||
|
? `url(${mall.theme.image.backgroundImg})` |
||||
|
: "", |
||||
}} |
}} |
||||
></div> |
|
||||
)} |
|
||||
<div style={{ flex: 1 }}> |
|
||||
<div className="popupname">{shop.name}</div> |
|
||||
<div className="popupdesc"> |
|
||||
<span> {shop.shopFormat ? shop.shopFormat : " "}</span> |
|
||||
<span> {shop.floorName}</span> |
|
||||
</div> |
|
||||
</div> |
|
||||
</div> |
|
||||
|
|
||||
<div className="tabs"> |
|
||||
<div className="tab" onClick={() => setEnd()}> |
|
||||
<img src={navpng} /> 导航动画 |
|
||||
</div> |
|
||||
</div> |
|
||||
|
onTouchStart={handleTouchStart} |
||||
|
onTouchMove={handleTouchMove} |
||||
|
onTouchCancel={handleTouchEnd} |
||||
|
onTouchEnd={handleTouchEnd} |
||||
|
> |
||||
|
{floors} |
||||
|
<div className="listWrapper"> |
||||
|
<ShopList |
||||
|
className="flex1" |
||||
|
mall={mall} |
||||
|
isRow={false} |
||||
|
format={null} |
||||
|
floorOrder={sceneIndex} |
||||
|
onClick={onClick} |
||||
|
shop={shop} |
||||
|
onClickActive={onClickActive} |
||||
|
></ShopList> |
||||
</div> |
</div> |
||||
)} |
|
||||
</div> |
</div> |
||||
); |
|
||||
|
); |
||||
|
}; |
||||
export default Popup; |
export default Popup; |
||||
|
|||||
|
Before Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 596 B |
|
Before Width: | Height: | Size: 87 KiB |
|
Before Width: | Height: | Size: 97 B |
|
Before Width: | Height: | Size: 480 B |
@ -1,91 +1,100 @@ |
|||||
/*postcss-pxtransform disable*/ |
/*postcss-pxtransform disable*/ |
||||
.shop { |
.shop { |
||||
|
position: relative; |
||||
font-size: 0; |
font-size: 0; |
||||
line-height: 0; |
line-height: 0; |
||||
overflow: hidden; |
overflow: hidden; |
||||
|
background: var(--brand-background); |
||||
|
border-radius: 6px; |
||||
|
.active { |
||||
|
position: absolute; |
||||
|
top: 0; |
||||
|
left: 0; |
||||
|
right: 0; |
||||
|
bottom: 0; |
||||
|
background: linear-gradient(99.5deg, #f0b92b 0%, #f9d556 100%); |
||||
|
.avatar { |
||||
|
display: block; |
||||
|
width: 100%; |
||||
|
height: calc((100vw - 55px) / 4); |
||||
|
padding: 8px; |
||||
|
background: #ffffff; |
||||
|
box-sizing: border-box; |
||||
|
border-radius: 4px; |
||||
|
} |
||||
|
.r1 { |
||||
|
color: rgba(0, 0, 0, 0.8); |
||||
|
} |
||||
|
} |
||||
&.is-row { |
&.is-row { |
||||
position: relative; |
position: relative; |
||||
height: 66px; |
|
||||
background: #ffffff; |
|
||||
|
height: 80px; |
||||
|
background: rgba(255, 255, 255, 0.6); |
||||
border-radius: 12px; |
border-radius: 12px; |
||||
|
.rowRight { |
||||
|
position: absolute; |
||||
|
right: 12px; |
||||
|
top: 0; |
||||
|
bottom: 0; |
||||
|
margin: auto; |
||||
|
width: 56px; |
||||
|
height: 44px; |
||||
|
background: center / cover no-repeat url(./rowRight.png); |
||||
|
} |
||||
.avatar { |
.avatar { |
||||
position: absolute; |
position: absolute; |
||||
width: 50px; |
|
||||
height: 50px; |
|
||||
|
width: 64px; |
||||
|
height: 64px; |
||||
top: 8px; |
top: 8px; |
||||
left: 8px; |
left: 8px; |
||||
border: 1px solid #e9d7ad; |
|
||||
box-sizing: border-box; |
box-sizing: border-box; |
||||
border-radius: 6px; |
border-radius: 6px; |
||||
padding: 7px; |
|
||||
} |
} |
||||
.name { |
.name { |
||||
position: absolute; |
position: absolute; |
||||
top: 10px; |
|
||||
left: 66px; |
|
||||
font-style: normal; |
|
||||
font-weight: bold; |
|
||||
|
top: 14px; |
||||
|
left: 92px; |
||||
|
font-weight: 600; |
||||
font-size: 16px; |
font-size: 16px; |
||||
line-height: 22px; |
line-height: 22px; |
||||
color: #333333; |
|
||||
} |
|
||||
.houseNum { |
|
||||
position: absolute; |
|
||||
left: 67px; |
|
||||
bottom: 13px; |
|
||||
font-style: normal; |
|
||||
font-weight: 500; |
|
||||
font-size: 10px; |
|
||||
line-height: 13px; |
|
||||
color: #b3aea7; |
|
||||
|
color: rgba(0, 0, 0, 0.8); |
||||
} |
} |
||||
.format { |
|
||||
|
.meta { |
||||
|
display: flex; |
||||
position: absolute; |
position: absolute; |
||||
top: 11px; |
|
||||
right: 16px; |
|
||||
font-style: normal; |
|
||||
font-weight: bold; |
|
||||
|
top: 49px; |
||||
|
left: 92px; |
||||
|
font-weight: 600; |
||||
font-size: 12px; |
font-size: 12px; |
||||
line-height: 17px; |
line-height: 17px; |
||||
color: #b3aea7; |
|
||||
|
color: rgba(0, 0, 0, 0.4); |
||||
|
align-items: center; |
||||
|
.sep { |
||||
|
display: inline-block; |
||||
|
margin: 0 12px; |
||||
|
width: 1px; |
||||
|
height: 10px; |
||||
|
background: rgba(0, 0, 0, 0.1); |
||||
|
} |
||||
} |
} |
||||
} |
} |
||||
.avatar { |
.avatar { |
||||
width: calc((100vw - 96px - 18px - 10px - 11px) / 3); |
|
||||
height: calc((100vw - 96px - 18px - 10px - 11px) / 3); |
|
||||
|
display: block; |
||||
|
width: 100%; |
||||
|
height: calc((100vw - 55px) / 4); |
||||
padding: 8px; |
padding: 8px; |
||||
background: #ffffff; |
background: #ffffff; |
||||
box-sizing: border-box; |
box-sizing: border-box; |
||||
border-radius: 6px; |
|
||||
|
border-radius: 4px; |
||||
} |
} |
||||
.r1 { |
.r1 { |
||||
padding: 0 4px; |
|
||||
margin-top: 4px; |
|
||||
font-family: PingFang SC; |
|
||||
font-style: normal; |
|
||||
font-weight: 500; |
|
||||
|
font-weight: 600; |
||||
font-size: 12px; |
font-size: 12px; |
||||
line-height: 17px; |
|
||||
color: #323337; |
|
||||
|
line-height: 25px; |
||||
|
padding: 0 6px; |
||||
|
color: var(--brand-color, rgba(0, 0, 0, 0.8)); |
||||
overflow: hidden; |
overflow: hidden; |
||||
white-space: nowrap; |
white-space: nowrap; |
||||
text-overflow: ellipsis; |
text-overflow: ellipsis; |
||||
} |
} |
||||
.r2 { |
|
||||
margin-top: 4px; |
|
||||
display: flex; |
|
||||
justify-content: space-between; |
|
||||
font-family: PingFang SC; |
|
||||
font-style: normal; |
|
||||
font-weight: 500; |
|
||||
font-size: 9px; |
|
||||
line-height: 13px; |
|
||||
color: #a1a5b3; |
|
||||
padding: 0 4px; |
|
||||
span { |
|
||||
font-weight: normal; |
|
||||
font-size: 10px; |
|
||||
color: #a1a5b3; |
|
||||
} |
|
||||
} |
|
||||
} |
} |
||||
|
|||||
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 814 B |
@ -1,24 +0,0 @@ |
|||||
import React from "react"; |
|
||||
import "./ShopTabs.scss"; |
|
||||
import floor from "./floor.png"; |
|
||||
import floorActive from "./floor_active.png"; |
|
||||
import format from "./format.png"; |
|
||||
import formatActive from "./format_active.png"; |
|
||||
export default ({ tab, onSetTab }) => ( |
|
||||
<div className="shop-tabs"> |
|
||||
<div |
|
||||
onClick={() => onSetTab("业态")} |
|
||||
className={["tab", tab === "业态" ? "active" : ""].join(" ")} |
|
||||
> |
|
||||
<img src={tab === "业态" ? formatActive : format}></img> |
|
||||
业态 |
|
||||
</div> |
|
||||
<div |
|
||||
onClick={() => onSetTab("楼层")} |
|
||||
className={["tab", tab === "楼层" ? "active" : ""].join(" ")} |
|
||||
> |
|
||||
<img src={tab === "楼层" ? floorActive : floor}></img> |
|
||||
楼层 |
|
||||
</div> |
|
||||
</div> |
|
||||
); |
|
||||
@ -1,32 +0,0 @@ |
|||||
.shop-tabs { |
|
||||
display: flex; |
|
||||
width: calc(100vw - 20px); |
|
||||
height: 56px; |
|
||||
background: #edeff3; |
|
||||
border-radius: 12px; |
|
||||
justify-content: space-around; |
|
||||
align-items: center; |
|
||||
.tab { |
|
||||
display: flex; |
|
||||
width: calc((100vw - 20px - 8px - 3px) / 2); |
|
||||
height: 48px; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
font-family: PingFang SC; |
|
||||
font-style: normal; |
|
||||
font-weight: 500; |
|
||||
font-size: 16px; |
|
||||
line-height: 22px; |
|
||||
color: #7a7e8d; |
|
||||
&.active { |
|
||||
background: #ffffff; |
|
||||
border-radius: 8px; |
|
||||
color: #323337; |
|
||||
} |
|
||||
img { |
|
||||
width: 20px; |
|
||||
height: 20px; |
|
||||
margin-right: 8px; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
Before Width: | Height: | Size: 901 B |
|
Before Width: | Height: | Size: 858 B |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
@ -1,103 +0,0 @@ |
|||||
import React, { useState, useEffect } from "react"; |
|
||||
import ShopList from "../ShopList/ShopList.js"; |
|
||||
import "./ShopsWithFilter.scss"; |
|
||||
import ShopTabs from "../ShopTabs/ShopTabs"; |
|
||||
import SideBar from "../SideBar/SideBar"; |
|
||||
const ShopsWithFilter = ({ |
|
||||
mall, |
|
||||
onClick, |
|
||||
reset, |
|
||||
onReset = () => {}, |
|
||||
wingHeight, |
|
||||
}) => { |
|
||||
const [tab, setTab] = useState("业态"); |
|
||||
const [format, setFormat] = useState(null); |
|
||||
const [floorOrder, setFloorOrder] = useState(null); |
|
||||
useEffect(() => { |
|
||||
if (reset) { |
|
||||
setFormat(null); |
|
||||
setFloorOrder(null); |
|
||||
setTab("业态"); |
|
||||
onReset(); |
|
||||
} |
|
||||
}, [reset]); |
|
||||
const formats = mall |
|
||||
? mall.shopInfo.reduce( |
|
||||
(acc, { shopList }) => |
|
||||
shopList.reduce( |
|
||||
(acc1, nxt) => |
|
||||
acc1.includes(nxt.shopFormat) |
|
||||
? [...acc1] |
|
||||
: [...acc1, nxt.shopFormat], |
|
||||
acc |
|
||||
), |
|
||||
[] |
|
||||
) |
|
||||
: []; |
|
||||
const floors = mall ? mall.floorData : []; |
|
||||
const floorNameOrderMap = floors.reduce( |
|
||||
(acc, nxt) => ({ ...acc, [nxt.name]: nxt.floorOrder }), |
|
||||
{} |
|
||||
); |
|
||||
const floorOrderNameMap = floors.reduce( |
|
||||
(acc, nxt) => ({ ...acc, [nxt.floorOrder]: nxt.name }), |
|
||||
{} |
|
||||
); |
|
||||
return ( |
|
||||
<> |
|
||||
<div style={{ marginTop: "16px", marginLeft: "10px" }}> |
|
||||
<ShopTabs |
|
||||
tab={tab} |
|
||||
onSetTab={(el) => { |
|
||||
setFormat(null); |
|
||||
setFloorOrder(null); |
|
||||
setTab(el); |
|
||||
}} |
|
||||
></ShopTabs> |
|
||||
</div> |
|
||||
|
|
||||
<div className="wings" style={{ height: wingHeight }}> |
|
||||
<div className="left"> |
|
||||
<SideBar |
|
||||
active={ |
|
||||
tab === "业态" && format === null |
|
||||
? "全部业态" |
|
||||
: tab === "楼层" && floorOrder === null |
|
||||
? "全部楼层" |
|
||||
: tab === "业态" |
|
||||
? format |
|
||||
: floorOrderNameMap[floorOrder] |
|
||||
} |
|
||||
onSetActive={(el) => { |
|
||||
if (tab === "业态") { |
|
||||
setFormat(el === "全部业态" ? null : el); |
|
||||
} else { |
|
||||
setFloorOrder(el === "全部楼层" ? null : floorNameOrderMap[el]); |
|
||||
} |
|
||||
}} |
|
||||
list={ |
|
||||
tab === "业态" |
|
||||
? ["全部业态", ...formats] |
|
||||
: [ |
|
||||
"全部楼层", |
|
||||
...floors |
|
||||
.filter(({ url }) => url !== null) |
|
||||
.map(({ name }) => name), |
|
||||
] |
|
||||
} |
|
||||
></SideBar> |
|
||||
</div> |
|
||||
<div className="right"> |
|
||||
<ShopList |
|
||||
mall={mall} |
|
||||
isRow={false} |
|
||||
format={format} |
|
||||
floorOrder={floorOrder} |
|
||||
onClick={onClick} |
|
||||
></ShopList> |
|
||||
</div> |
|
||||
</div> |
|
||||
</> |
|
||||
); |
|
||||
}; |
|
||||
export default ShopsWithFilter; |
|
||||
@ -1,22 +0,0 @@ |
|||||
.wings { |
|
||||
display: flex; |
|
||||
width: 100vw; |
|
||||
height: calc(100vh - 156px); |
|
||||
border-top: 1px solid #edeff3; |
|
||||
margin-top: 8px; |
|
||||
.left { |
|
||||
width: 96px; |
|
||||
flex: 0 0 96px; |
|
||||
height: 100%; |
|
||||
background: #edeff3; |
|
||||
overflow-x: hidden; |
|
||||
overflow-y: auto; |
|
||||
} |
|
||||
.right { |
|
||||
flex: 1; |
|
||||
height: 100%; |
|
||||
background: #f3f4f8; |
|
||||
overflow-x: hidden; |
|
||||
overflow-y: auto; |
|
||||
} |
|
||||
} |
|
||||
@ -1,15 +0,0 @@ |
|||||
import React from "react"; |
|
||||
import "./SideBar.scss"; |
|
||||
export default ({ list, active, onSetActive }) => ( |
|
||||
<div className="side-bar"> |
|
||||
{list.map((el) => ( |
|
||||
<div |
|
||||
key={el} |
|
||||
className={["option", active === el ? "active" : ""].join(" ")} |
|
||||
onClick={() => onSetActive(el)} |
|
||||
> |
|
||||
{el} |
|
||||
</div> |
|
||||
))} |
|
||||
</div> |
|
||||
); |
|
||||
@ -1,20 +0,0 @@ |
|||||
.side-bar { |
|
||||
width: 100%; |
|
||||
.option { |
|
||||
display: flex; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
width: 100%; |
|
||||
height: 48px; |
|
||||
font-family: PingFang SC; |
|
||||
font-style: normal; |
|
||||
font-weight: 500; |
|
||||
font-size: 12px; |
|
||||
color: #474a56; |
|
||||
&.active { |
|
||||
background: #ffffff; |
|
||||
color: #437af7; |
|
||||
font-weight: 600; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,212 +0,0 @@ |
|||||
import React, { useState, useEffect } from "react"; |
|
||||
import car from "./car.png"; |
|
||||
import axios from "axios"; |
|
||||
import "./Car.scss"; |
|
||||
import plus from "./plus.svg"; |
|
||||
import Keyboard from "../Keyboard/Keyboard"; |
|
||||
import platepng from "./plate.png"; |
|
||||
import plateActive from "./plate_active.png"; |
|
||||
import lot from "./lot.png"; |
|
||||
import lotActive from "./lot_active.png"; |
|
||||
|
|
||||
const Car = ({ lots, onLot = () => {}, plate, hasReverse }) => { |
|
||||
const [isPlate, setIsPlate] = useState(hasReverse); |
|
||||
const [qArr, setQArr] = useState(hasReverse ? ["苏", "A"] : []); |
|
||||
const [opened, setOpened] = useState(false); |
|
||||
const [showKeyBoard, setShowKeyBoard] = useState(true); |
|
||||
const [focusedIndex, setFocusedIndex] = useState(hasReverse ? 2 : 0); |
|
||||
const [isNum, setIsNum] = useState(true); |
|
||||
const q = qArr.join(""); |
|
||||
const setQ = (str) => setQArr(str.split("")); |
|
||||
useEffect(() => { |
|
||||
if (!opened) { |
|
||||
setOpened(true); |
|
||||
if (plate) { |
|
||||
setQ(plate); |
|
||||
setFocusedIndex(null); |
|
||||
} |
|
||||
setShowKeyBoard(!plate); |
|
||||
} |
|
||||
}, [opened]); |
|
||||
const toPlate = () => { |
|
||||
if (!hasReverse) |
|
||||
return window.weui.toast("敬请期待", { |
|
||||
className: "toast", |
|
||||
}); |
|
||||
setQ("苏A"); |
|
||||
setIsPlate(true); |
|
||||
setFocusedIndex(2); |
|
||||
setShowKeyBoard(true); |
|
||||
}; |
|
||||
const toLot = () => { |
|
||||
setQ(""); |
|
||||
setFocusedIndex(0); |
|
||||
setIsPlate(false); |
|
||||
setShowKeyBoard(true); |
|
||||
}; |
|
||||
|
|
||||
const handleSubmit = async () => { |
|
||||
if (isPlate) { |
|
||||
if (!q) { |
|
||||
return window.weui.toast("请输入正确车牌号", { |
|
||||
className: "toast", |
|
||||
}); |
|
||||
} |
|
||||
const { |
|
||||
data: { data, code, msg }, |
|
||||
} = { data: { data: null, code: "201", msg: "123" } }; |
|
||||
if (code !== "200") |
|
||||
return window.weui.toast(msg, { |
|
||||
className: "toast", |
|
||||
}); |
|
||||
else { |
|
||||
if (!lots.includes(data.spaceNo)) |
|
||||
return window.weui.toast(`未找到车位号:${data.spaceNo}`, { |
|
||||
className: "toast", |
|
||||
}); |
|
||||
return onLot(data.spaceNo); |
|
||||
} |
|
||||
} |
|
||||
// if (!q || !lots.includes(floor + q.toUpperCase())) {
|
|
||||
if (!q || !lots.includes(q.toUpperCase())) { |
|
||||
return window.weui.toast("请输入正确车位号", { |
|
||||
className: "toast", |
|
||||
}); |
|
||||
} |
|
||||
// onLot(floor + q.toUpperCase());
|
|
||||
onLot(q.toUpperCase()); |
|
||||
}; |
|
||||
return ( |
|
||||
<div className="car"> |
|
||||
<img className="car-img" src={car} /> |
|
||||
<div className="car-modal"> |
|
||||
<div className={"content" + (showKeyBoard ? " has-keyboard" : "")}> |
|
||||
<div className="form"> |
|
||||
<div className="tabs"> |
|
||||
<div |
|
||||
className={`tab ${isPlate ? "active" : ""}`} |
|
||||
onClick={toPlate} |
|
||||
> |
|
||||
<img src={isPlate ? plateActive : platepng}></img> |
|
||||
车牌查找 |
|
||||
</div> |
|
||||
<div |
|
||||
className={`tab ${!isPlate ? "active" : ""}`} |
|
||||
onClick={toLot} |
|
||||
> |
|
||||
<img src={isPlate ? lot : lotActive}></img> |
|
||||
车位查找 |
|
||||
</div> |
|
||||
</div> |
|
||||
{isPlate ? ( |
|
||||
<div className="platenum"> |
|
||||
{new Array(8).fill(0).map((_, i) => ( |
|
||||
<div |
|
||||
className={[ |
|
||||
"box", |
|
||||
focusedIndex === i ? "active" : "", |
|
||||
i === 2 ? "more-margin" : "", |
|
||||
i === 7 ? "sp" : "", |
|
||||
].join(" ")} |
|
||||
key={i} |
|
||||
onClick={() => { |
|
||||
setIsNum(i !== 0); |
|
||||
setFocusedIndex(i); |
|
||||
setShowKeyBoard(true); |
|
||||
}} |
|
||||
> |
|
||||
{i === 7 && !qArr[i] ? ( |
|
||||
<> |
|
||||
<img src={plus} className="plus"></img> |
|
||||
</> |
|
||||
) : ( |
|
||||
qArr[i] |
|
||||
)} |
|
||||
</div> |
|
||||
))} |
|
||||
</div> |
|
||||
) : ( |
|
||||
<div className="lots"> |
|
||||
{new Array(4).fill(0).map((_, i) => ( |
|
||||
<div |
|
||||
className={[ |
|
||||
"box", |
|
||||
"big", |
|
||||
focusedIndex === i ? "active" : "", |
|
||||
].join(" ")} |
|
||||
key={i} |
|
||||
onClick={() => { |
|
||||
setIsNum(true); |
|
||||
setFocusedIndex(i); |
|
||||
setShowKeyBoard(true); |
|
||||
}} |
|
||||
> |
|
||||
{qArr[i]} |
|
||||
</div> |
|
||||
))} |
|
||||
</div> |
|
||||
)} |
|
||||
|
|
||||
{!isPlate && ( |
|
||||
<> |
|
||||
{/* <div className="floor1" onClick={() => setFloor(floor1)}> |
|
||||
{floor1} |
|
||||
</div> |
|
||||
<div className="floor2">{floor}</div> |
|
||||
<div className="floor3" onClick={() => setFloor(floor3)}> |
|
||||
{floor3} |
|
||||
</div> */} |
|
||||
</> |
|
||||
)} |
|
||||
<div className="btn" onClick={handleSubmit}> |
|
||||
寻车 |
|
||||
</div> |
|
||||
</div> |
|
||||
</div> |
|
||||
</div> |
|
||||
{showKeyBoard && ( |
|
||||
<Keyboard |
|
||||
isNum={isNum} |
|
||||
onClose={() => { |
|
||||
setFocusedIndex(null); |
|
||||
setShowKeyBoard(false); |
|
||||
}} |
|
||||
onSetIsNum={(val) => setIsNum(val)} |
|
||||
onInput={(val) => { |
|
||||
qArr[focusedIndex] = val; |
|
||||
setQArr([...qArr]); |
|
||||
if (isPlate) { |
|
||||
switch (focusedIndex) { |
|
||||
case 6: |
|
||||
case 7: |
|
||||
setShowKeyBoard(false); |
|
||||
break; |
|
||||
default: |
|
||||
setIsNum(true); |
|
||||
setFocusedIndex(focusedIndex + 1); |
|
||||
break; |
|
||||
} |
|
||||
} else { |
|
||||
switch (focusedIndex) { |
|
||||
case 3: |
|
||||
setShowKeyBoard(false); |
|
||||
break; |
|
||||
default: |
|
||||
setIsNum(true); |
|
||||
setFocusedIndex(focusedIndex + 1); |
|
||||
break; |
|
||||
} |
|
||||
} |
|
||||
}} |
|
||||
onBackspace={() => { |
|
||||
qArr[focusedIndex] = ""; |
|
||||
setQArr([...qArr]); |
|
||||
setFocusedIndex(Math.max(0, focusedIndex - 1)); |
|
||||
}} |
|
||||
onFinish={handleSubmit} |
|
||||
></Keyboard> |
|
||||
)} |
|
||||
</div> |
|
||||
); |
|
||||
}; |
|
||||
export default Car; |
|
||||
@ -1,255 +0,0 @@ |
|||||
.car { |
|
||||
position: relative; |
|
||||
width: 100vw; |
|
||||
height: calc(100vh - 98px); |
|
||||
background: #f3f4f8; |
|
||||
pointer-events: auto; |
|
||||
.car-img { |
|
||||
position: absolute; |
|
||||
width: 220px; |
|
||||
height: 220px; |
|
||||
left: 0; |
|
||||
right: 0; |
|
||||
bottom: auto; |
|
||||
margin: auto; |
|
||||
top: 16px; |
|
||||
} |
|
||||
.car-modal { |
|
||||
position: absolute; |
|
||||
top: 0; |
|
||||
bottom: 0; |
|
||||
left: 0; |
|
||||
right: 0; |
|
||||
z-index: 10; |
|
||||
} |
|
||||
.content { |
|
||||
position: absolute; |
|
||||
left: 2.6667vw; |
|
||||
right: 2.6667vw; |
|
||||
width: calc(100vw - 4.2667vw); |
|
||||
height: 458px; |
|
||||
bottom: 10px; |
|
||||
padding-top: 34px; |
|
||||
background: #ffffff; |
|
||||
box-shadow: 0px 12px 16px rgba(104, 110, 127, 0.08); |
|
||||
border-radius: 18px; |
|
||||
overflow: hidden; |
|
||||
|
|
||||
.form { |
|
||||
position: absolute; |
|
||||
top: 14px; |
|
||||
left: 3.7333vw; |
|
||||
right: 3.7333vw; |
|
||||
bottom: 14px; |
|
||||
z-index: 3; |
|
||||
text-align: left; |
|
||||
.platenum { |
|
||||
display: flex; |
|
||||
justify-content: center; |
|
||||
position: absolute; |
|
||||
top: 102px; |
|
||||
left: -3.7333vw; |
|
||||
right: -3.7333vw; |
|
||||
text-align: center; |
|
||||
} |
|
||||
.lots { |
|
||||
position: absolute; |
|
||||
top: 95px; |
|
||||
left: 0; |
|
||||
right: 0; |
|
||||
display: inline-flex; |
|
||||
justify-content: center; |
|
||||
} |
|
||||
.box { |
|
||||
width: 9.6vw; |
|
||||
height: 64px; |
|
||||
background: #f3f4f8; |
|
||||
font-family: Noto IKEA Simplified Chinese; |
|
||||
font-style: normal; |
|
||||
font-weight: bold; |
|
||||
font-size: 18px; |
|
||||
text-align: center; |
|
||||
color: #323337; |
|
||||
border-radius: 8px; |
|
||||
display: flex; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
align-content: center; |
|
||||
flex-direction: column; |
|
||||
&.big { |
|
||||
width: 12.8vw; |
|
||||
} |
|
||||
&.active { |
|
||||
border: 2px solid #437af7; |
|
||||
box-shadow: 0px 6px 12px rgba(93, 172, 249, 0.2); |
|
||||
} |
|
||||
&.sp { |
|
||||
background: none; |
|
||||
border: 1px solid #c9cbd1; |
|
||||
&.active { |
|
||||
border: 2px solid #437af7; |
|
||||
box-shadow: 0px 6px 12px rgba(93, 172, 249, 0.2); |
|
||||
} |
|
||||
} |
|
||||
.plus { |
|
||||
position: relative; |
|
||||
width: 6.4vw; |
|
||||
margin: 0; |
|
||||
} |
|
||||
} |
|
||||
.box + .box { |
|
||||
margin-left: 1.0667vw; |
|
||||
} |
|
||||
.box + .box.more-margin { |
|
||||
margin-left: 5.0667vw; |
|
||||
} |
|
||||
.input { |
|
||||
position: absolute; |
|
||||
font-family: Noto IKEA Simplified Chinese; |
|
||||
font-style: normal; |
|
||||
font-weight: bold; |
|
||||
font-size: 16px; |
|
||||
top: 114px; |
|
||||
width: 216px; |
|
||||
left: calc((100vw - 28px - 216px) / 2); |
|
||||
background: transparent; |
|
||||
height: 40px; |
|
||||
line-height: 40px; |
|
||||
color: #474747; |
|
||||
border: none; |
|
||||
outline: none; |
|
||||
text-align: center; |
|
||||
&.right { |
|
||||
text-align: left; |
|
||||
left: calc((100vw - 28px - 216px + 63px) / 2); |
|
||||
} |
|
||||
} |
|
||||
::placeholder { |
|
||||
font-family: Noto IKEA Simplified Chinese; |
|
||||
font-style: normal; |
|
||||
font-weight: normal; |
|
||||
font-size: 14px; |
|
||||
color: #b3aea7; |
|
||||
} |
|
||||
.dec1 { |
|
||||
position: absolute; |
|
||||
top: 154px; |
|
||||
bottom: auto; |
|
||||
right: auto; |
|
||||
width: 223px; |
|
||||
height: 21px; |
|
||||
left: calc((100vw - 28px - 216px) / 2); |
|
||||
&.right { |
|
||||
left: calc((100vw - 28px - 216px + 63px) / 2); |
|
||||
} |
|
||||
} |
|
||||
.dec2 { |
|
||||
position: absolute; |
|
||||
top: 132px; |
|
||||
bottom: auto; |
|
||||
right: auto; |
|
||||
width: 11.7333vw; |
|
||||
height: 21px; |
|
||||
left: calc((100vw - 7.4667vw - 57.6vw - 16.8vw) / 2); |
|
||||
pointer-events: none; |
|
||||
} |
|
||||
.floor1, |
|
||||
.floor2, |
|
||||
.floor3 { |
|
||||
position: absolute; |
|
||||
left: calc((100vw - 7.4667vw - 57.6vw - 16.8vw) / 2); |
|
||||
font-family: Noto IKEA Simplified Chinese; |
|
||||
font-style: normal; |
|
||||
font-weight: bold; |
|
||||
font-size: 4.2667vw; |
|
||||
color: #474747; |
|
||||
width: 9.8667vw; |
|
||||
text-align: center; |
|
||||
} |
|
||||
.floor1, |
|
||||
.floor3 { |
|
||||
color: rgba(113, 112, 110, 0.2); |
|
||||
font-size: 3.2vw; |
|
||||
line-height: 4.8vw; |
|
||||
height: 4.8vw; |
|
||||
} |
|
||||
.floor1 { |
|
||||
top: 77px; |
|
||||
} |
|
||||
.floor2 { |
|
||||
top: 101px; |
|
||||
line-height: 6.4vw; |
|
||||
height: 6.4vw; |
|
||||
} |
|
||||
.floor3 { |
|
||||
top: 134px; |
|
||||
} |
|
||||
.btns { |
|
||||
display: grid; |
|
||||
grid-template-columns: 1fr 1fr; |
|
||||
position: absolute; |
|
||||
top: 129px; |
|
||||
left: 24px; |
|
||||
right: 24px; |
|
||||
gap: 0 16px; |
|
||||
} |
|
||||
.btn { |
|
||||
display: flex; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
position: absolute; |
|
||||
height: 56px; |
|
||||
left: 1.0667vw; |
|
||||
right: 1.0667vw; |
|
||||
margin: auto; |
|
||||
bottom: 14px; |
|
||||
background: linear-gradient(180deg, #508af7 0%, #5ea5f9 100%); |
|
||||
box-shadow: 0px 6px 12px rgba(93, 172, 249, 0.2); |
|
||||
border-radius: 16px; |
|
||||
font-family: PingFang SC; |
|
||||
font-style: normal; |
|
||||
font-weight: bold; |
|
||||
font-size: 16px; |
|
||||
line-height: 22px; |
|
||||
text-align: center; |
|
||||
color: #ffffff; |
|
||||
} |
|
||||
|
|
||||
.tabs { |
|
||||
display: flex; |
|
||||
width: 100%; |
|
||||
padding: 4px; |
|
||||
background: #edeff3; |
|
||||
border-radius: 12px; |
|
||||
} |
|
||||
.tab { |
|
||||
display: flex; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
flex: 1; |
|
||||
height: 48px; |
|
||||
font-family: PingFang SC; |
|
||||
font-style: normal; |
|
||||
font-weight: bold; |
|
||||
font-size: 16px; |
|
||||
line-height: 22px; |
|
||||
color: #7a7e8d; |
|
||||
img { |
|
||||
position: relative; |
|
||||
margin: 0; |
|
||||
margin-right: 8px; |
|
||||
width: 24px; |
|
||||
height: 24px; |
|
||||
} |
|
||||
} |
|
||||
.tab.active { |
|
||||
background: #ffffff; |
|
||||
border-radius: 10px; |
|
||||
color: #323337; |
|
||||
} |
|
||||
.tab + .tab { |
|
||||
margin-left: 4px; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 685 B |
|
Before Width: | Height: | Size: 675 B |
|
Before Width: | Height: | Size: 356 B |
|
Before Width: | Height: | Size: 354 B |
|
Before Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 6.6 KiB |
|
Before Width: | Height: | Size: 3.6 KiB |
@ -1,15 +0,0 @@ |
|||||
import act from "./act.svg"; |
|
||||
import actActive from "./actActive.svg"; |
|
||||
import car from "./car.svg"; |
|
||||
import carActive from "./carActive.svg"; |
|
||||
import map from "./map.svg"; |
|
||||
import mapActive from "./mapActive.svg"; |
|
||||
import my from "./my.svg"; |
|
||||
import myActive from "./myActive.svg"; |
|
||||
const TabMap = { |
|
||||
活动: { logo: act, logoActive: actActive }, |
|
||||
寻车: { logo: car, logoActive: carActive }, |
|
||||
地图: { logo: map, logoActive: mapActive }, |
|
||||
我的: { logo: my, logoActive: myActive }, |
|
||||
}; |
|
||||
export default TabMap; |
|
||||
|
Before Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 971 B |
|
Before Width: | Height: | Size: 1015 B |
|
After Width: | Height: | Size: 5.0 KiB |
@ -1,104 +0,0 @@ |
|||||
import React from "react"; |
|
||||
import "./Keyboard.scss"; |
|
||||
const N1 = "1234567890"; |
|
||||
const N2 = "QWERTYUIOP"; |
|
||||
const N3 = "ASDFGHJKL"; |
|
||||
const N4 = "ZXCVBNM"; |
|
||||
const C1 = "京津渝沪冀晋辽吉黑苏"; |
|
||||
const C2 = "浙皖闽赣鲁豫鄂湘粤琼"; |
|
||||
const C3 = "川贵云陕甘青蒙桂宁新"; |
|
||||
const C4 = "藏使领警学港澳"; |
|
||||
const Keyboard = ({ |
|
||||
isNum, |
|
||||
onInput, |
|
||||
onBackspace, |
|
||||
onSetIsNum, |
|
||||
onClose, |
|
||||
onFinish, |
|
||||
}) => { |
|
||||
return ( |
|
||||
<div className="keyboard"> |
|
||||
<div className="bar"> |
|
||||
<div className="btn1" onClick={onClose}> |
|
||||
取消 |
|
||||
</div> |
|
||||
<div className="btn2" onClick={onFinish}> |
|
||||
完成 |
|
||||
</div> |
|
||||
</div> |
|
||||
{isNum ? ( |
|
||||
<div className="plane"> |
|
||||
<div className="row"> |
|
||||
{N1.split("").map((key) => ( |
|
||||
<div className="key" key={key} onClick={() => onInput(key)}> |
|
||||
{key} |
|
||||
</div> |
|
||||
))} |
|
||||
</div> |
|
||||
<div className="row"> |
|
||||
{N2.split("").map((key) => ( |
|
||||
<div className="key" key={key} onClick={() => onInput(key)}> |
|
||||
{key} |
|
||||
</div> |
|
||||
))} |
|
||||
</div> |
|
||||
<div className="row"> |
|
||||
{N3.split("").map((key) => ( |
|
||||
<div className="key" key={key} onClick={() => onInput(key)}> |
|
||||
{key} |
|
||||
</div> |
|
||||
))} |
|
||||
</div> |
|
||||
<div className="row"> |
|
||||
<div className="key1" onClick={() => onSetIsNum(false)}> |
|
||||
字 |
|
||||
</div> |
|
||||
{N4.split("").map((key) => ( |
|
||||
<div className="key" key={key} onClick={() => onInput(key)}> |
|
||||
{key} |
|
||||
</div> |
|
||||
))} |
|
||||
<div className="key2" onClick={onBackspace}></div> |
|
||||
</div> |
|
||||
</div> |
|
||||
) : ( |
|
||||
<div className="plane"> |
|
||||
<div className="row"> |
|
||||
{C1.split("").map((key) => ( |
|
||||
<div className="key" key={key} onClick={() => onInput(key)}> |
|
||||
{key} |
|
||||
</div> |
|
||||
))} |
|
||||
</div> |
|
||||
<div className="row"> |
|
||||
{C2.split("").map((key) => ( |
|
||||
<div className="key" key={key} onClick={() => onInput(key)}> |
|
||||
{key} |
|
||||
</div> |
|
||||
))} |
|
||||
</div> |
|
||||
<div className="row"> |
|
||||
{C3.split("").map((key) => ( |
|
||||
<div className="key" key={key} onClick={() => onInput(key)}> |
|
||||
{key} |
|
||||
</div> |
|
||||
))} |
|
||||
</div> |
|
||||
<div className="row"> |
|
||||
<div className="key1" onClick={() => onSetIsNum(true)}> |
|
||||
ABC |
|
||||
</div> |
|
||||
{C4.split("").map((key) => ( |
|
||||
<div className="key" key={key} onClick={() => onInput(key)}> |
|
||||
{key} |
|
||||
</div> |
|
||||
))} |
|
||||
<div className="key2" onClick={onBackspace}></div> |
|
||||
</div> |
|
||||
</div> |
|
||||
)} |
|
||||
<div className="safe"></div> |
|
||||
</div> |
|
||||
); |
|
||||
}; |
|
||||
export default Keyboard; |
|
||||
@ -1,128 +0,0 @@ |
|||||
.keyboard { |
|
||||
position: absolute; |
|
||||
bottom: -98px; |
|
||||
left: 0; |
|
||||
right: 0; |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
width: 100vw; |
|
||||
height: 294px; |
|
||||
z-index: 10; |
|
||||
.bar { |
|
||||
display: flex; |
|
||||
flex: 0 0 40px; |
|
||||
justify-content: space-between; |
|
||||
line-height: 40px; |
|
||||
background: #ffffff; |
|
||||
box-shadow: 0px -1px 12px rgba(0, 0, 0, 0.05); |
|
||||
.btn1 { |
|
||||
position: relative; |
|
||||
flex: 0 0 80px; |
|
||||
text-align: center; |
|
||||
font-family: Noto IKEA Simplified Chinese; |
|
||||
font-style: normal; |
|
||||
font-weight: normal; |
|
||||
font-size: 16px; |
|
||||
color: #4f4f4f; |
|
||||
&::after { |
|
||||
content: ""; |
|
||||
position: absolute; |
|
||||
top: 14px; |
|
||||
right: 0; |
|
||||
width: 1px; |
|
||||
height: 14px; |
|
||||
background: #e0e0e0; |
|
||||
} |
|
||||
} |
|
||||
.btn2 { |
|
||||
position: relative; |
|
||||
flex: 0 0 80px; |
|
||||
text-align: center; |
|
||||
font-family: Noto IKEA Simplified Chinese; |
|
||||
font-style: normal; |
|
||||
font-weight: bold; |
|
||||
font-size: 16px; |
|
||||
color: #437af7; |
|
||||
&::after { |
|
||||
content: ""; |
|
||||
position: absolute; |
|
||||
top: 14px; |
|
||||
left: 0; |
|
||||
width: 1px; |
|
||||
height: 14px; |
|
||||
background: #e0e0e0; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
.safe { |
|
||||
flex: 0 0 34px; |
|
||||
background: #d1d5db; |
|
||||
} |
|
||||
.plane { |
|
||||
flex: 1; |
|
||||
background: #d1d5db; |
|
||||
.row { |
|
||||
display: flex; |
|
||||
width: 100vw; |
|
||||
justify-content: center; |
|
||||
padding-top: 12px; |
|
||||
} |
|
||||
.key { |
|
||||
width: 8.5333vw; |
|
||||
height: 40px; |
|
||||
font-family: Noto IKEA Simplified Chinese; |
|
||||
font-style: normal; |
|
||||
font-weight: normal; |
|
||||
font-size: 16px; |
|
||||
line-height: 40px; |
|
||||
text-align: center; |
|
||||
color: #333333; |
|
||||
background: #ffffff; |
|
||||
box-shadow: 0px 1px 0px #898a8d; |
|
||||
border-radius: 4px; |
|
||||
&.bold { |
|
||||
font-weight: bold; |
|
||||
} |
|
||||
&:active { |
|
||||
background: #0166b3; |
|
||||
box-shadow: 0px 2px 1px rgba(0, 0, 0, 0.2); |
|
||||
color: #ffffff; |
|
||||
} |
|
||||
} |
|
||||
.key + .key { |
|
||||
margin-left: 1.0667vw; |
|
||||
} |
|
||||
.key1 { |
|
||||
width: 13.3333vw; |
|
||||
height: 40px; |
|
||||
background: linear-gradient(180deg, #508af7 0%, #5ea5f9 100%); |
|
||||
color: #fff; |
|
||||
box-shadow: 0px 2px 1px rgba(0, 0, 0, 0.2); |
|
||||
border-radius: 4px; |
|
||||
font-family: Noto IKEA Simplified Chinese; |
|
||||
font-style: normal; |
|
||||
font-weight: normal; |
|
||||
font-size: 16px; |
|
||||
line-height: 40px; |
|
||||
text-align: center; |
|
||||
} |
|
||||
.key1 + .key { |
|
||||
margin-left: 1.0667vw; |
|
||||
} |
|
||||
.key2 { |
|
||||
width: 13.3333vw; |
|
||||
height: 40px; |
|
||||
background: #adb3bc; |
|
||||
color: #fff; |
|
||||
box-shadow: 0px 2px 1px rgba(0, 0, 0, 0.2); |
|
||||
border-radius: 4px; |
|
||||
background-image: url(./backspace.png); |
|
||||
background-repeat: no-repeat; |
|
||||
background-size: 20px; |
|
||||
background-position: center; |
|
||||
} |
|
||||
.key + .key2 { |
|
||||
margin-left: 1.0667vw; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
Before Width: | Height: | Size: 502 B |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.1 KiB |