207 lines
8.4 KiB
JavaScript
207 lines
8.4 KiB
JavaScript
import React, { useEffect, useState, useRef } from 'react';
|
|
import './index.scss';
|
|
import { getProjectsLists } from '../../api'
|
|
import { factoryZoneId } from '../../../constants/factory'
|
|
import KFIcon from '../../../components/KFIcon';
|
|
|
|
import bg1 from '../../../images/factory/resource/project-top-1.webp';
|
|
import bg2 from '../../../images/factory/resource/project-top-2.webp';
|
|
import bg3 from '../../../images/factory/resource/project-top-3.png';
|
|
|
|
import bg4 from '../../../images/factory/resource/project-content-1.webp';
|
|
import bg5 from '../../../images/factory/resource/project-content-2.webp';
|
|
import bg6 from '../../../images/factory/resource/project-content-3.webp';
|
|
import bg7 from '../../../images/factory/resource/project-content-4.webp';
|
|
import contentRight from '../../../images/factory/resource/project-content-right.webp';
|
|
import bg8 from '../../../images/factory/resource/project-bottom-1.webp'
|
|
|
|
import ActionItem from '../components/ActionItem';
|
|
import '../../common.scss'
|
|
import { Link } from 'react-router-dom';
|
|
import InfiniteScroll from 'react-infinite-scroller';
|
|
|
|
|
|
const bgList = [bg1, bg2, bg3]
|
|
const contentBgList = [bg4, bg5, bg6, bg7]
|
|
|
|
function Index(props) {
|
|
|
|
const [topList, setTopList] = useState([]);
|
|
const [contentList, setContentList] = useState([]);
|
|
const [fullList, setFullList] = useState([]);
|
|
const pageSize = 10
|
|
const [pageNum, setPageNum] = useState(1)
|
|
const [hasMore, setHasMore] = useState(true)
|
|
const [loading, setLoading] = useState(false)
|
|
|
|
useEffect(() => {
|
|
getFullList();
|
|
getTopList();
|
|
}, []);
|
|
|
|
const getTopList = () => {
|
|
getProjectsLists(factoryZoneId, { isHomepage: 1 }).then(res => {
|
|
setTopList(res.data.rows.slice(0, 3)); // 获取前三个项目作为 topList
|
|
});
|
|
};
|
|
|
|
const getFullList = (isMore = false) => {
|
|
if (!hasMore) return
|
|
setLoading(true)
|
|
getProjectsLists(factoryZoneId, { isHomepage: 0, pageSize, pageNum: isMore || pageNum }).then(res => {
|
|
const rows = res.data.rows
|
|
setLoading(false)
|
|
|
|
if (isMore) {
|
|
setPageNum(isMore)
|
|
setFullList([...fullList, ...rows])
|
|
} else {
|
|
// 前面四个项目作为 contentList
|
|
setContentList(res.data.rows.slice(0, 4));
|
|
// 后面项目作为 fullList
|
|
setFullList(res.data.rows.slice(4));
|
|
}
|
|
setHasMore(res.data.total > (isMore ? 4 + fullList.length + rows.length : rows.length))
|
|
// setTotal(res.data.total)
|
|
});
|
|
};
|
|
|
|
return (
|
|
<div className="project">
|
|
<div className="project-top">
|
|
{
|
|
topList.map((item, index) => {
|
|
const project = item.projectProperties
|
|
// project.praisesCount = Math.floor(Math.random(0, 1) * 50)
|
|
// project.forkedCount = Math.floor(Math.random(0, 1) * 50)
|
|
return (
|
|
<Link to={`/${project.fullName}`}><div className="project-top-item" key={index}>
|
|
<img src={bgList[index]} alt="" className="item-bg" />
|
|
<img src={project.authorImageUrl} alt="" className="item-img"></img>
|
|
<div className="item-info">
|
|
<h5 className="item-title">{project.name.split('/')[1]}</h5>
|
|
<p className="item-desc">{project.description}</p>
|
|
<div className="item-bottom">
|
|
<div className="item-bottom-tags">
|
|
{
|
|
project.topics && project.topics.split(',').splice(0, 3).map((topic, index) => {
|
|
return (
|
|
<span key={index} className="item-tag">{topic}</span>
|
|
)
|
|
})
|
|
}
|
|
</div>
|
|
<div className="item-bottom-data">
|
|
<span><i className="iconfont icon-guanzhu mr5 font-12" />{project.forkedCount}</span>
|
|
<span><i className="iconfont icon-dianzan mr5 font-12" />{project.praisesCount}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</Link>
|
|
)
|
|
})
|
|
}
|
|
</div>
|
|
<div className="project-content">
|
|
|
|
<h2>全部软件项目</h2>
|
|
<div className="project-content-top">
|
|
<div className="project-content-top-left">
|
|
<p>xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</p>
|
|
<div className="content-top-list">
|
|
{
|
|
contentList.map((item, index) => {
|
|
const project = item.projectProperties
|
|
// project.praisesCount = Math.floor(Math.random(0, 1) * 50)
|
|
// project.forkedCount = Math.floor(Math.random(0, 1) * 50)
|
|
return <Link to={`/${project.fullName}`} className="content-top-item"><div key={index}>
|
|
<img className="item-bg" src={contentBgList[index]} alt="" />
|
|
<div className="item-top">
|
|
<img src={project.authorImageUrl} alt="" className="item-img"></img>
|
|
<h5 className="item-title">{project.name.split('/')[1]}</h5>
|
|
</div>
|
|
<div className="item-tags">
|
|
{
|
|
project.topics && project.topics.split(',').splice(0, 3).map((topic, index) => {
|
|
return (
|
|
<span key={index} className="item-tag">{topic}</span>
|
|
)
|
|
})
|
|
}
|
|
</div>
|
|
<div className="item-desc">
|
|
{project.description}
|
|
</div>
|
|
<div className="item-data">
|
|
<span><i className="iconfont icon-guanzhu mr5 font-12" />{project.forkedCount}</span>
|
|
<span><i className="iconfont icon-dianzan mr5 font-12" />{project.praisesCount}</span>
|
|
</div>
|
|
</div></Link>
|
|
})
|
|
}
|
|
</div>
|
|
</div>
|
|
<img className="project-content-top-right" src={contentRight} alt="" />
|
|
</div>
|
|
<InfiniteScroll
|
|
threshold={10}
|
|
initialLoad={false}
|
|
pageStart={1}
|
|
loadMore={(e) => { getFullList(e) }}
|
|
hasMore={!loading && hasMore}
|
|
>
|
|
<div className="project-content-bottom">
|
|
{
|
|
fullList.map((item, index) => {
|
|
const project = item.projectProperties
|
|
// project.praisesCount = Math.floor(Math.random(0, 1) * 50)
|
|
// project.forkedCount = Math.floor(Math.random(0, 1) * 50)
|
|
return <ActionItem className="content-bottom-wrapper" key={index} backgroundColor="rgba(19, 53, 91, 0.11)" padding="1px" borderRadius="16px">
|
|
<div className="content-bottom-item">
|
|
{
|
|
index % 2 === 0 && <img className="item-bg" src={bg8} alt="" />
|
|
}
|
|
|
|
<div className="item-top">
|
|
<img src={project.authorImageUrl} alt="" className="item-img"></img>
|
|
<h5 className="item-title">{project.name.split('/')[1]}</h5>
|
|
</div>
|
|
{
|
|
project.description && <div className="item-desc">
|
|
{project.description}
|
|
</div>
|
|
}
|
|
|
|
<div className="item-tags">
|
|
{
|
|
project.topics && project.topics.split(',').splice(0, 3).map((topic, index) => {
|
|
return (
|
|
<span key={index} className="item-tag">{topic}</span>
|
|
)
|
|
})
|
|
}
|
|
</div>
|
|
|
|
<div className="item-data">
|
|
<span><i className="iconfont icon-guanzhu mr5 font-12" />{project.forkedCount}</span>
|
|
<span><i className="iconfont icon-dianzan mr5 font-12" />{project.praisesCount}</span>
|
|
</div>
|
|
</div>
|
|
<div className="content-bottom-btn">
|
|
<Link to={`/${project.fullName}`}><button className="shiny-button">查看详情</button></Link>
|
|
</div>
|
|
</ActionItem>
|
|
})
|
|
}
|
|
</div>
|
|
</InfiniteScroll>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
export default Index
|
|
|
|
|
|
|