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

138 lines
4.1 KiB
JavaScript

import React, {useRef, useEffect, useCallback, useLayoutEffect} from 'react';
import _ from 'lodash'
import {imgUrl as url} from '../../../utils/requests'
let defaultUrl = "/img/noImg.png";
const fetchImg = fileCode => {
// console.log("fetchImg")
return new Promise((resolve, reject) => {
let ajax = new XMLHttpRequest();
ajax.open("GET", `${url}${fileCode}`, true);
ajax.responseType = "blob";
ajax.setRequestHeader("Cache-Control", "max-age=3600")
ajax.setRequestHeader("Authorization", window.localStorage.getItem("token"))
ajax.onload = function () {
if (ajax.status == 200) {
ajax.response.text().then(res => {
// console.log("res", JSON.parse(res))
try{
res = JSON.parse(res);
}catch(e){
console.log(e)
}
if (res.error) {
resolve(defaultUrl)
} else {
let blob = ajax.response;
let oFileReader = new FileReader();
oFileReader.onloadend = function (e) {
console.log("e", e)
let base64 = e.target.result;
resolve(base64)
};
oFileReader.readAsDataURL(blob);
}
})
}
}
ajax.send();
})
}
function InfoCard(props) {
const imgBox = useRef();
const {imgKey, status = {}, columns = [],extraColumns = [], data = {}, cardWidth = 256, contentHeight} = props;
const {key = '', value, color} = status;
const setImg = useCallback(async () => {
let url = defaultUrl;
if (imgKey && data[imgKey]) {
url = await fetchImg(data[imgKey]);
}
imgBox.current && (imgBox.current.style.backgroundImage = `url('${url}')`)
}, [data[imgKey]])
useLayoutEffect(() => {
let observer = new IntersectionObserver((entries, observer) => {
if(entries[0].intersectionRatio > 0) setImg();
}, {});
observer && observer.observe(imgBox.current);
return () => {
observer && observer.unobserve(imgBox.current);
}
}, [setImg])
return (
<div className='infoCard'>
<div className="img" ref={imgBox}/>
{data[key] && (
<div className="status" style={{backgroundColor: color? color(data[key]) : "unset" }}>
{value? value(data[key]) : data[key]}
</div>
)}
<div className="contentBox">
{columns.concat(extraColumns).map(({title, code, text}) => {
return (
<div key={title} className="info-item">
<span className='label'>{title}</span>
<span className='value'>{text || data[code]}</span>
</div>
)
})}
</div>
<style jsx>{`
.infoCard{
height: 100%;
width: ${cardWidth? cardWidth + 'px' : '100%'};
min-width: ${cardWidth? cardWidth + 'px' : '100%'};
position: relative;
display: flex;
flex-direction: column;
}
.infoCard > .img{
background-size: cover;
background-position: center center;
background-repeat: no-repeat;
background-color: rgba(0,0,0,0.2);
flex: 1;
}
.infoCard > .status{
position: absolute;
top:0;
left:0;
font-size: 16px;
color: #FFFFFF;
font-weight: 600;
line-height: 28px;
padding: 0 8px;
}
.infoCard > .contentBox{
background: rgba(6,45,141,0.80);
border: 1px solid rgba(255,255,255,0.16);
padding: 5px 10px;
height: ${contentHeight? contentHeight + 'px' : 'unset'};
}
.infoCard .info-item{
display: flex;
justify-content: space-between;
line-height: 28px;
font-size: 12px;
white-space: nowrap;
}
.infoCard .info-item .label,
.infoCard .info-item .value{
text-overflow: ellipsis;
overflow: hidden;
}
.infoCard .info-item .value{
font-size: 14px;
color: #28EAFF;
font-weight: 500;
}
`}</style>
</div>
);
}
export default InfoCard;