forked from Gitlink/forgeplus-react
407 lines
14 KiB
JavaScript
407 lines
14 KiB
JavaScript
import React, { Component } from 'react';
|
||
import { Link } from 'react-router-dom';
|
||
import { Menu, Input, Spin, Pagination, Popover, Select, Button, Tabs } from 'antd';
|
||
import { getImageUrl } from 'educoder';
|
||
import '../css/index.scss'
|
||
import './list.css';
|
||
import './Index.scss';
|
||
import ListItem from './IndexItem'
|
||
import axios from 'axios';
|
||
import img_new from '../Images/new.png';
|
||
import img_array from '../Images/array.png';
|
||
import banner from '../Images/banner.png';
|
||
import AddProjectModal from '../Head/AddProjectModal';
|
||
const Search = Input.Search;
|
||
|
||
class Index extends Component {
|
||
constructor(props) {
|
||
super(props);
|
||
this.state = {
|
||
projectsList: undefined,
|
||
page: 1,
|
||
limit: 15,
|
||
search: undefined,
|
||
sort: undefined,
|
||
total: 0,
|
||
isSpin: true,
|
||
project_type: undefined,
|
||
category_id: undefined,
|
||
|
||
typeList: undefined,
|
||
categoryList: undefined,
|
||
recommendList: undefined,
|
||
|
||
languageList: undefined,
|
||
languageId: undefined,
|
||
filter: undefined,
|
||
}
|
||
|
||
}
|
||
|
||
componentDidMount = () => {
|
||
const { page, limit, search, sort, project_type, category_id, languageId, filter } = this.state;
|
||
this.getListData(page, limit, search, sort, project_type, category_id, languageId, filter);
|
||
|
||
this.getType();
|
||
|
||
this.getCategory();
|
||
|
||
this.getRecommand();
|
||
|
||
this.getLanguage();
|
||
}
|
||
|
||
// 获取语言列表
|
||
getLanguage = () => {
|
||
const url = '/project_languages.json';
|
||
axios.get(url).then(result => {
|
||
if (result) {
|
||
this.setState({
|
||
languageList: result.data.project_languages
|
||
})
|
||
}
|
||
}).catch(error => { })
|
||
}
|
||
// 获取推荐列表
|
||
getRecommand = () => {
|
||
const url = `/projects/recommend.json`;
|
||
axios.get(url).then(result => {
|
||
if (result) {
|
||
this.setState({
|
||
recommendList: result.data
|
||
})
|
||
}
|
||
}).catch(error => { })
|
||
}
|
||
|
||
// 获取列表
|
||
getListData = (page, limit, search, sort, project_type, category_id, languageId, filter) => {
|
||
const { current_user } = this.props;
|
||
const url = `/projects.json`;
|
||
axios.get(url, {
|
||
params: {
|
||
user_id: current_user && current_user.user_id,
|
||
page,
|
||
limit,
|
||
search,
|
||
sort_by: sort,
|
||
project_type,
|
||
category_id,
|
||
language_id: languageId,
|
||
filter
|
||
}
|
||
}).then((result) => {
|
||
if (result) {
|
||
this.setState({
|
||
projectsList: result.data.projects,
|
||
total: result.data.total_count,
|
||
isSpin: false
|
||
})
|
||
}
|
||
}).catch((error) => { })
|
||
}
|
||
|
||
// 获取类型
|
||
getType = () => {
|
||
const url = `/projects/group_type_list.json`;
|
||
axios.get(url).then((result) => {
|
||
if (result && result.data) {
|
||
this.setTypeList(result.data, undefined)
|
||
}
|
||
}).catch((error) => { })
|
||
}
|
||
|
||
setTypeList = (list, active_type) => {
|
||
this.setState({
|
||
typeList: list.map((item, key) => {
|
||
const acitve = active_type && active_type === item.project_type
|
||
return (
|
||
<li key={key} className={`cursor-pointer px-12px py-4px rounded-2px `}
|
||
style={{ background: acitve ? "#F6F7F9" : "", color: acitve ? "#165DFF" : "" }}
|
||
onClick={() => this.changeType(`${item.project_type}`, list)}>
|
||
{item.name}({item.projects_count})
|
||
</li>
|
||
)
|
||
})
|
||
})
|
||
}
|
||
|
||
// 切换类型
|
||
changeType = (type, list) => {
|
||
this.setState({
|
||
isSpin: true,
|
||
project_type: type,
|
||
search: undefined
|
||
})
|
||
this.setTypeList(list, type)
|
||
const { page, limit, sort, category_id, languageId, filter } = this.state;
|
||
this.getListData(page, limit, undefined, sort, type, category_id, languageId, filter);
|
||
}
|
||
|
||
// 获取类型
|
||
getCategory = () => {
|
||
const url = `/project_categories/group_list.json`;
|
||
|
||
axios.get(url).then((result) => {
|
||
if (result && result.data) {
|
||
this.setCategoryList(result.data, undefined);
|
||
}
|
||
}).catch((error) => { })
|
||
}
|
||
|
||
setCategoryList = (list, active_id) => {
|
||
this.setState({
|
||
categoryList: list.map((item, key) => {
|
||
const acitve = active_id && parseInt(active_id) === item.id
|
||
return (
|
||
<li key={key} className={`cursor-pointer px-12px py-4px rounded-2px`}
|
||
style={{ background: acitve ? "#F6F7F9" : "", color: acitve ? "#165DFF" : "" }}
|
||
onClick={() => this.changeCategory(`${item.id}`, list)}>
|
||
{item.name}({item.projects_count})
|
||
</li>
|
||
)
|
||
})
|
||
})
|
||
}
|
||
|
||
changeCategory = (id, list) => {
|
||
this.setState({
|
||
category_id: id,
|
||
page: 1
|
||
});
|
||
this.setCategoryList(list, id)
|
||
const { limit, sort, project_type, languageId, filter } = this.state;
|
||
this.getListData(1, limit, undefined, sort, project_type, id, languageId, filter);
|
||
}
|
||
|
||
// 排序
|
||
ChangeSoryBy = (e) => {
|
||
this.setState({
|
||
sort_by: e.key,
|
||
page: 1,
|
||
search: undefined,
|
||
isSpin: true
|
||
})
|
||
const { limit, project_type, category_id, languageId, filter } = this.state;
|
||
this.getListData(1, limit, undefined, e.key, project_type, category_id, languageId, filter);
|
||
}
|
||
|
||
// 搜索
|
||
searchFun = (value) => {
|
||
this.setState({
|
||
page: 1,
|
||
search: value,
|
||
isSpin: true,
|
||
project_type: undefined,
|
||
sort: "updated_on"
|
||
})
|
||
const { limit, sort, category_id, languageId, filter } = this.state;
|
||
this.getListData(1, limit, value, sort, undefined, category_id, languageId, filter);
|
||
}
|
||
changeSearchValue = (e) => {
|
||
this.setState({
|
||
search: e.target.value
|
||
})
|
||
}
|
||
// 翻页
|
||
ChangePage = (page) => {
|
||
this.setState({
|
||
page
|
||
})
|
||
const { limit, search, sort, project_type, category_id, languageId, filter } = this.state;
|
||
this.getListData(page, limit, search, sort, project_type, category_id, languageId, filter);
|
||
}
|
||
|
||
getoDetail = (login, identifier) => {
|
||
this.props.history.push(`/projects/${login}/${identifier}`);
|
||
}
|
||
|
||
// 选择语言类别
|
||
changeLanguage = (e) => {
|
||
this.setState({
|
||
isSpin: true,
|
||
languageId: e === 0 ? undefined : e
|
||
})
|
||
const { page, limit, sort, project_type, category_id, filter } = this.state;
|
||
this.getListData(page, limit, undefined, sort, project_type, category_id, e === 0 ? undefined : e, filter);
|
||
}
|
||
|
||
changeFilter = (e) => {
|
||
this.setState({
|
||
isSpin: true,
|
||
filter: e
|
||
})
|
||
const { page, limit, search, sort, project_type, category_id, languageId } = this.state;
|
||
this.getListData(page, limit, search, sort, project_type, category_id, languageId, e);
|
||
}
|
||
|
||
menu = () => {
|
||
return (
|
||
<Menu onClick={this.ChangeSoryBy}>
|
||
<Menu.Item key="updated_on">更新时间排序</Menu.Item>
|
||
<Menu.Item key="created_on">创建时间排序</Menu.Item>
|
||
<Menu.Item key="forked_count">fork数据排序</Menu.Item>
|
||
<Menu.Item key="praises_count">点赞数量排序</Menu.Item>
|
||
</Menu>
|
||
)
|
||
}
|
||
|
||
newItem = () => {
|
||
return (
|
||
<Menu>
|
||
<Menu.Item key="created_mirror"><Link to={`/projects/mirror/new`}>新建镜像项目</Link></Menu.Item>
|
||
<Menu.Item key="created_deposit"><Link to={`/projects/deposit/new`}>新建托管项目</Link></Menu.Item>
|
||
</Menu>
|
||
)
|
||
}
|
||
|
||
pagination = (total, limit, page) => {
|
||
return (
|
||
total && total > limit ?
|
||
<div className="edu-txt-center pt30 mb30 border-top-grey">
|
||
<Pagination simple defaultCurrent={page} total={total} pageSize={limit} onChange={this.ChangePage}></Pagination>
|
||
</div> : ""
|
||
)
|
||
}
|
||
|
||
render() {
|
||
const { current_user } = this.props;
|
||
|
||
const { projectsList, recommendList, languageList, languageId,
|
||
isSpin, total, search, limit, page, typeList, categoryList, filter } = this.state;
|
||
|
||
|
||
return (
|
||
<div className='pt-20px' style={{ background: "#EEF5FE", lineHeight: "normal" }}>
|
||
{/* <div className="subjectBanner">
|
||
<img src={banner} alt="" />
|
||
<div className="bannerBox">
|
||
<div class="subjectleft">
|
||
<span>开源社区</span>
|
||
<span>面向高校的教学开源</span>
|
||
</div>
|
||
<Button type={"primary"} size={"large"}>
|
||
<Link to={`/projects/deposit/new`}>新建项目</Link>
|
||
</Button>
|
||
<Button type={"primary"} size={"large"}>
|
||
<AddProjectModal showNotification={this.props.showNotification} />
|
||
</Button>
|
||
<Button type={"primary"} size={"large"} style={{backgroundColor:"rgb(47, 163, 79)",borderColor:"rgb(47, 163, 79)"}}>
|
||
<a href={`https://data.educoder.net/api/attachments/1955244?disposition=inline`} target="_blank">新手指引</a>
|
||
</Button>
|
||
</div>
|
||
</div> */}
|
||
{
|
||
recommendList && recommendList.length > 0 &&
|
||
<div className="recommandProjects">
|
||
{/* {
|
||
recommendList.map((item,key)=>{
|
||
return(
|
||
<div onClick={()=>this.getoDetail(item.author && item.author.login,item.identifier)}>
|
||
<div className="mainInfo">
|
||
<img src={getImageUrl(`/${item.author && item.author.image_url}`)} alt=""/>
|
||
<p className="school">{item.name}</p>
|
||
<p className="name">{item.author && item.author.name}</p>
|
||
</div>
|
||
<div className="baseInfo">
|
||
<span className="look"><i className="iconfont icon-dianjiliang font-12"></i>{item.visits}</span>
|
||
<span className="type">{item.category && item.category.name}</span>
|
||
</div>
|
||
</div>
|
||
)
|
||
})
|
||
} */}
|
||
</div>
|
||
}
|
||
<div className="w-1200px ml-auto mr-auto">
|
||
<div className="bg-white rounded-8px py-16px px-20px flex flex-col gap-30px">
|
||
<ul className="flex flex-wrap gap-20px">
|
||
<li style={{ color: "#9096A3" }} className='py-4px rounded-2px'>项目类型</li>
|
||
{typeList}
|
||
</ul>
|
||
<ul className="flex flex-wrap gap-20px">
|
||
<li style={{ color: "#9096A3" }} className='py-4px rounded-2px'>项目类别</li>
|
||
{categoryList}
|
||
</ul>
|
||
</div>
|
||
<div className="mt-16px bg-white rounded-8px px-20px">
|
||
<Spin spinning={isSpin}>
|
||
<div className='flex gap-20px py-12px mb-20px' style={{ borderBottom: "1px solid #DBDCE0" }}>
|
||
<div className='flex flex-1 gap-40px mr-auto'>
|
||
{[
|
||
{ label: "全部", key: "undefined" },
|
||
{ label: "我管理的", key: "manage" },
|
||
{ label: "我学习的", key: "study" },
|
||
].map((item) => (<div key={item.key} className={`h-full flex item-center relative cursor-pointer ${(filter || "undefined") == item.key ? "font-medium" : ""}`}
|
||
style={{ color: (filter || "undefined") == item.key ? "#232B40" : "#5F6368" }}
|
||
onClick={() => { this.changeFilter(item.key) }}>
|
||
{item.label}
|
||
{(filter || "undefined") == item.key && <div className='w-full h-2px absolute' style={{ background: "#232B40", left: 0, bottom: "-12px" }}></div>}
|
||
</div>))}
|
||
</div>
|
||
<Button type={"primary"} size={"large"} style={{ background: "#3061D0" }}>
|
||
<Link to={`/projects/deposit/new`}>新建项目</Link>
|
||
</Button>
|
||
<Button type={"primary"} size={"large"} style={{ background: "#3061D0" }}>
|
||
<AddProjectModal showNotification={this.props.showNotification} />
|
||
</Button>
|
||
</div>
|
||
{/* <Button size='large' onClick={()=>{this.changeFilter(undefined)}} type={this.state.filter == undefined ? 'primary':'default'}>全部</Button>
|
||
<Button size='large' onClick={()=>{this.changeFilter('manage')}} type={this.state.filter == 'manage' ? 'primary':'default'} className='ml10 mr10'>我管理的</Button>
|
||
<Button size='large' onClick={()=>{this.changeFilter('study')}} type={this.state.filter == 'study' ? 'primary':'default'}>我学习的</Button> */}
|
||
<div className='flex gap-20px item-center mb-8px'>
|
||
<Select
|
||
showSearch
|
||
placeholder="请选择语言"
|
||
style={{ width: "150px" }}
|
||
size={"large"}
|
||
onChange={this.changeLanguage}
|
||
value={languageId}
|
||
allowClear={true}
|
||
optionFilterProp="children"
|
||
filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0}
|
||
>
|
||
<Select.Option key={0} value={0}>请选择语言</Select.Option>
|
||
{
|
||
languageList && languageList.length > 0 && languageList.map((item, key) => {
|
||
return (
|
||
<Select.Option key={item.id} value={item.id}>
|
||
{item.name}
|
||
</Select.Option>
|
||
)
|
||
})
|
||
}
|
||
</Select>
|
||
<Search
|
||
placeholder="输入项目名称关键字进行搜索"
|
||
enterButton="搜索"
|
||
size="large"
|
||
onSearch={this.searchFun}
|
||
className="list-r-Search mr-auto"
|
||
value={search}
|
||
onChange={this.changeSearchValue}
|
||
/>
|
||
{current_user && current_user.login &&
|
||
<Popover content={this.newItem()} trigger={["click"]} placement='bottom'>
|
||
<a style={{ color: "#3061D0" }}>
|
||
<span className="color-blue font-16"><img src={img_new} alt="" width="13px" /> 新建</span>
|
||
</a>
|
||
</Popover>
|
||
}
|
||
<Popover content={this.menu()} trigger={['click']} placement='bottom'>
|
||
<a style={{ color: "#3061D0" }}>
|
||
<span className="color-blue font-16">排序 <img src={img_array} alt="" width="10px" /></span>
|
||
</a>
|
||
</Popover>
|
||
</div>
|
||
<ListItem {...this.props} {...this.state} projects={projectsList}></ListItem>
|
||
{this.pagination(total, limit, page)}
|
||
</Spin>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|
||
}
|
||
export default Index;
|