rtgk-screen-web/components/screen/InfoCardList/index.js

362 lines
11 KiB
JavaScript
Raw Permalink Normal View History

2024-06-20 11:26:44 +08:00
import React, {
useState,
useImperativeHandle,
useRef,
useCallback,
useEffect,
useMemo,
} from "react";
import InfoCard from "./InfoCard";
import Row from "../Row";
const gutter = 20;
const cardBottom = 20;
const InfoCardList = React.forwardRef((props, ref) => {
const {
mainKey,
speed = 50,
span = 4,
withClassify = false,
autoNext = true,
classifyKey = { name: "name", children: "children" },
pageFinished,
type = "move",
extraColumnsOpt,
...otherProps
} = props;
const sizeRef = useRef();
const infoCardListRef = useRef();
const pageBoxRef = useRef();
const pageRef = useRef(1);
const [data, setData] = useState([]);
const [energy, setEnergy] = useState([]);
const [autoScroll, setAutoScroll] = useState([0, 0]);
const classifyRef = useRef([]);
const classifyBoxRef = useRef();
const pageSize = useMemo(() => Math.floor(24 / span), [span]);
const totalPage = useMemo(() => {
if (withClassify) {
let { children } = classifyKey;
let size = 0;
classifyRef.current = [];
data.forEach((item) => {
let itemPageSize = Math.ceil((item[children].length || 0) / pageSize);
size += itemPageSize;
classifyRef.current.push(size);
});
return size;
} else return Math.ceil(data.length / pageSize);
}, [data, pageSize, withClassify, classifyKey]);
const [pageHeight, setPageHeight] = useState(0);
const setActiveClassify = useCallback(
(page) => {
if (!classifyBoxRef.current) return;
let classifyIndex =
classifyRef.current.findIndex((maxPageSize) => page <= maxPageSize) ||
0;
let { name } = classifyKey;
let oprationname = data?.[classifyIndex]?.[name].split("】")[1];
let text = oprationname === undefined ? "" : "- " + oprationname;
if (text) {
classifyBoxRef.current.style.display = "block";
classifyBoxRef.current.innerText = text;
} else classifyBoxRef.current.style.display = "none";
},
[data]
);
const setPageBoxCss = useCallback(
(page) => {
pageRef.current = page;
setActiveClassify(page);
pageBoxRef.current.style.transition =
page === 1 ? "none" : "transform 0.3s";
pageBoxRef.current.style.transform = `translateY(${
-(page - 1) * (pageHeight + cardBottom)
}px)`;
},
[pageHeight, setActiveClassify]
);
const nextPage = useCallback(() => {
// console.log();
let page = pageRef.current;
if (page + 1 > totalPage) {
if (autoNext) {
setPageBoxCss(1);
} else {
pageFinished && pageFinished();
}
} else {
setPageBoxCss(page + 1);
}
}, [totalPage]);
const moveChecking = useCallback(() => {
let { offsetWidth, scrollWidth } = infoCardListRef.current;
setAutoScroll([offsetWidth, scrollWidth]);
}, [data]);
const pageChecking = useCallback(() => {
let { scrollHeight, offsetHeight } = sizeRef.current;
setPageHeight(scrollHeight);
}, []);
useEffect(() => {
if (type === "move") {
let innerWindow = sizeRef.current.contentDocument.defaultView;
innerWindow.addEventListener("resize", moveChecking);
moveChecking();
return () => {
innerWindow.removeEventListener("resize", moveChecking);
};
}
}, [moveChecking]);
useEffect(() => {
if (type === "page") {
let innerWindow = sizeRef.current.contentDocument.defaultView;
innerWindow.addEventListener("resize", pageChecking);
pageChecking();
return () => {
innerWindow.removeEventListener("resize", pageChecking);
};
}
}, [pageChecking]);
useEffect(() => {
setPageBoxCss(1);
}, [data, setPageBoxCss]);
useImperativeHandle(
ref,
() => ({
setData: (data) => {
setData(data);
setPageBoxCss(1);
},
setEnergy:(data)=>{
setEnergy(data);
},
nextPage,
}),
[nextPage]
);
return (
<div className="infoCardList" ref={infoCardListRef}>
{type === "move" && (
<div className="box move">
{data.map((item) => {
return (
<div key={item[mainKey]} className="item">
<InfoCard {...otherProps} data={item} />
</div>
);
})}
</div>
)}
{type === "page" && (
<div className="page-content">
{withClassify === true && (
<div className="classify" ref={classifyBoxRef}></div>
)}
<div className="classifycenter -mt-14 w-full text-center ">
<label className="bg-[#1890ff] p-1 pt-0.5 pb-0.5">能源信息</label>
</div>
<div className="classifycenterval grid grid-cols-2 gap-1 place-items-start -mt-7 w-full">
{console.log("ernergy",energy)}
{/* {props.energy ?? `日期:${props.energy[0]} 水: ${props.energy[0].water} 电: ${1} 气: ${1}`} */}
{
energy.map(x=>{
return (
<span className={ energy.indexOf(x)===0?`flex-1 mr-20 justify-self-end`:`flex-1 ml-20 justify-self-start`}> 日期{x.time} &nbsp; {x.water} &nbsp; {x.electricity} &nbsp; {x.gas}</span>
)
})}
</div>
<div className="page-box">
<object
ref={sizeRef}
tabIndex="-1"
type="text/html"
aria-hidden="true"
data="about:blank"
style={{
display: "block",
position: "absolute",
top: 0,
left: 0,
width: "100%",
height: "100%",
border: "none",
padding: 0,
margin: 0,
opacity: 0,
zIndex: -1000,
pointerEvents: "none",
}}
></object>
<div className="page" ref={pageBoxRef}>
{withClassify === false && (
<Row className="height-100" gutter={20}>
{data.map((item) => {
let extraColumns = [];
if (extraColumnsOpt) {
let { key, name, val, max } = extraColumnsOpt;
let extraData = item[key];
extraData.forEach((i, index) => {
if (index < max)
extraColumns.push({ title: i[name], text: i[val] });
});
}
return (
<Row.Col span={span} key={item[mainKey]}>
<div className="item height-100">
<InfoCard
{...otherProps}
extraColumns={extraColumns}
data={item}
cardWidth={false}
/>
</div>
</Row.Col>
);
})}
</Row>
)}
{withClassify === true &&
data.map((item) => {
let { name, children } = classifyKey;
return (
<Row gutter={20} key={item[name]}>
{item[children].map((item) => {
let extraColumns = [];
if (extraColumnsOpt) {
let { key, name, val, max } = extraColumnsOpt;
let extraData = item[key];
extraData.forEach((i, index) => {
if (index < max)
extraColumns.push({
title: i[name],
text: i[val],
});
});
}
return (
<Row.Col span={span} key={item[mainKey]}>
<div className="item">
<InfoCard
{...otherProps}
extraColumns={extraColumns}
data={item}
cardWidth={false}
/>
</div>
</Row.Col>
);
})}
</Row>
);
})}
</div>
</div>
</div>
)}
<style jsx>{`
.infoCardList {
height: 100%;
overflow: hidden;
position: relative;
}
.infoCardList > .box {
height: 100%;
display: flex;
justify-content: flex-start;
}
.infoCardList > .box > .item {
height: 100%;
padding-right: ${gutter}px;
}
.infoCardList > .box.move {
animation: move ${autoScroll[1] / speed}s linear infinite;
animation-fill-mode: forwards;
transform: translateX(0px);
}
@keyframes move {
from {
transform: translateX(${autoScroll[0]}px);
}
to {
transform: translateX(${-autoScroll[1]}px);
}
}
.infoCardList .page {
height: 100%;
}
.infoCardList .page :global(.col) {
margin-bottom: ${cardBottom}px;
}
.infoCardList .page .item {
height: ${pageHeight}px;
}
.infoCardList .page-content {
height: 100%;
padding-top: 55px;
padding-bottom: 15px;
position: relative;
}
.infoCardList .classify {
position: absolute;
z-index: 100;
font-weight: 600;
font-size: 1.125rem;
left: 100px;
top: 0px;
// background: #15579f;
// border-radius: 3px;
// transition: all .3s;
}
.infoCardList .classifycenter label {
font-weight: 600;
font-size: 1.125rem;
}
.infoCardList .classifycenter {
position: absolute;
z-index: 100;
// left: 48.5%;
// padding: 2px 5px;
// top: -3px;
// background: #1890ff;
// border-radius: 3px;
// transition: all .3s;
}
.infoCardList .classifycenterval {
position: absolute;
z-index: 100;
font-weight: 600;
font-size: 1.125rem;
// left: 19%;
// top: 20px;
// padding: 2px 5px;
// border-radius: 3px;
// transition: all .3s;
}
.infoCardList .page-box {
height: 100%;
overflow: hidden;
position: relative;
}
`}</style>
</div>
);
});
export default InfoCardList;