forked from Gitlink/forgeplus-react
add project watch/praise/fork users list
This commit is contained in:
parent
fc33fd0a2f
commit
b5dca5a1aa
|
@ -117,6 +117,18 @@ const MilepostDetail = Loadable({
|
|||
loader: () => import('../Order/MilepostDetail'),
|
||||
loading: Loading,
|
||||
})
|
||||
const WatchUsers = Loadable({
|
||||
loader: () => import('../UsersList/watch_users'),
|
||||
loading: Loading,
|
||||
})
|
||||
const PraiseUsers = Loadable({
|
||||
loader: () => import('../UsersList/praise_users'),
|
||||
loading: Loading,
|
||||
})
|
||||
const ForkUsers = Loadable({
|
||||
loader: () => import('../UsersList/fork_users'),
|
||||
loading: Loading,
|
||||
})
|
||||
|
||||
|
||||
const TrendsIndex = Loadable({
|
||||
|
@ -200,9 +212,14 @@ class Detail extends Component{
|
|||
// 关注和取消关注
|
||||
focusFunc =(flag)=>{
|
||||
const { project_id } = this.state;
|
||||
|
||||
axios({
|
||||
method: flag? 'delete' : 'post',
|
||||
url: `/projects/${project_id}/watchers/${flag? 'unfollow' : 'follow'}.json`
|
||||
url: `/watchers/${flag? 'unfollow' : 'follow'}.json`,
|
||||
params: {
|
||||
target_type: "project",
|
||||
id: project_id
|
||||
}
|
||||
})
|
||||
.then(result => {
|
||||
if(result && result.data.status === 0){
|
||||
|
@ -363,19 +380,28 @@ class Detail extends Component{
|
|||
<img src={watched ? img_focused : img_focus} alt="" width="14px"/>
|
||||
{watched ? '取消关注':'关注'}
|
||||
</a>
|
||||
<span className="detail_tag_btn_count">{watchers_count}</span>
|
||||
<Link className="detail_tag_btn_count" to={{pathname:`/projects/${projectsId}/watch_users`, state}}>
|
||||
{watchers_count}
|
||||
</Link>
|
||||
{/* <span className="detail_tag_btn_count">{watchers_count}</span> */}
|
||||
</span>
|
||||
<span className="detail_tag_btn">
|
||||
<a className="detail_tag_btn_name" onClick={()=>this.pariseFunc(praised)}>
|
||||
<img src={praised ? img_parised : img_parise} width="13px" alt=""/>
|
||||
{praised ? '取消点赞':'点赞'}
|
||||
</a>
|
||||
<span className="detail_tag_btn_count">{praises_count}</span>
|
||||
<Link className="detail_tag_btn_count" to={{pathname:`/projects/${projectsId}/praise_users`,state}}>
|
||||
{praises_count}
|
||||
</Link>
|
||||
{/* <span className="detail_tag_btn_count">{praises_count}</span> */}
|
||||
</span>
|
||||
<span className="detail_tag_btn">
|
||||
<a className="detail_tag_btn_name" onClick={this.forkFunc}>
|
||||
<img src={img_fork} alt="" width="10px"/>Fork</a>
|
||||
<span className="detail_tag_btn_count">{forked_count}</span>
|
||||
<Link className="detail_tag_btn_count" to={{pathname:`/projects/${projectsId}/fork_users`,state}}>
|
||||
{forked_count}
|
||||
</Link>
|
||||
{/* <span className="detail_tag_btn_count">{forked_count}</span> */}
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
|
@ -539,6 +565,21 @@ class Detail extends Component{
|
|||
(props) => (<CoderRootIndex {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:projectsId/watch_users"
|
||||
render={
|
||||
(props) => (<WatchUsers {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:projectsId/praise_users"
|
||||
render={
|
||||
(props) => (<PraiseUsers {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:projectsId/fork_users"
|
||||
render={
|
||||
(props) => (<ForkUsers {...this.props} {...props} {...this.state}/>)
|
||||
}
|
||||
></Route>
|
||||
<Route path="/projects/:projectsId"
|
||||
render={
|
||||
(props) => (<CoderRootIndex {...this.props} {...props} {...this.state}/>)
|
||||
|
|
|
@ -308,10 +308,14 @@
|
|||
}
|
||||
.detail_tag_btn_count{
|
||||
padding:0px 10px;
|
||||
color: #fff;
|
||||
color: #fff !important;
|
||||
background: #1C91FF;
|
||||
border-radius: 0px 4px 4px 0px;
|
||||
}
|
||||
.detail_tag_btn_count:hover{
|
||||
color: #1C91FF !important;
|
||||
background: #fff;
|
||||
}
|
||||
/* 详情-代码 */
|
||||
.branch-wrapper{
|
||||
border:1px solid #eee;
|
||||
|
|
|
@ -0,0 +1,147 @@
|
|||
import React, { Component } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import axios from "axios";
|
||||
import { getImageUrl } from "educoder";
|
||||
import { Spin, Pagination } from "antd";
|
||||
import "./list.css";
|
||||
import NoneData from "../Nodata";
|
||||
import FocusButton from "./focus_button";
|
||||
class CommonUsers extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
user_type: this.props.user_type,
|
||||
type_title: this.props.type_title,
|
||||
project_id: this.props.project_id,
|
||||
users: null,
|
||||
count: 0,
|
||||
limit: 20,
|
||||
page: 1,
|
||||
isSpin: false,
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount = () => {
|
||||
this.getUsersList();
|
||||
};
|
||||
|
||||
getUsersList = (page, limit) => {
|
||||
this.setState({
|
||||
isSpin: true,
|
||||
});
|
||||
const { user_type, project_id } = this.state;
|
||||
|
||||
const url = `/projects/${project_id}/${user_type}.json`;
|
||||
axios
|
||||
.get(url, {
|
||||
params: {
|
||||
page,
|
||||
limit,
|
||||
},
|
||||
})
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
this.setState({
|
||||
count: result.data.count,
|
||||
users: result.data.users,
|
||||
isSpin: false,
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
};
|
||||
|
||||
// 翻页
|
||||
ChangePage = (page) => {
|
||||
this.setState({
|
||||
page,
|
||||
isSpin: true,
|
||||
});
|
||||
const { limit } = this.state;
|
||||
this.getUsersList(page, limit);
|
||||
};
|
||||
|
||||
render() {
|
||||
const { users, count, page, limit, isSpin, type_title } = this.state;
|
||||
const Paginations = (
|
||||
<React.Fragment>
|
||||
{count > limit ? (
|
||||
<div className="mt50 mb30 edu-txt-center">
|
||||
<Pagination
|
||||
simple
|
||||
defaultCurrent={page}
|
||||
total={count}
|
||||
pageSize={limit}
|
||||
onChange={this.ChangePage}
|
||||
></Pagination>
|
||||
</div>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</React.Fragment>
|
||||
);
|
||||
|
||||
const renderList = () => {
|
||||
if (users && users.length > 0) {
|
||||
return users.map((item, key) => {
|
||||
return (
|
||||
<div className="w-25 pull-left" key={key}>
|
||||
<div className="pbt25 grid-item mlr10 border-b-line">
|
||||
<div>
|
||||
<Link
|
||||
to={`/users/${item.login}/projects`}
|
||||
className="show-user-link"
|
||||
>
|
||||
<img
|
||||
className="avatar-60"
|
||||
src={getImageUrl(`images/${item.image_url}`)}
|
||||
alt=""
|
||||
/>
|
||||
</Link>
|
||||
</div>
|
||||
<div className="ml12">
|
||||
<div>
|
||||
<Link
|
||||
to={`/users/${item.login}/projects`}
|
||||
className="font-16 text-primary hide-1 task-hide max-w-200"
|
||||
>
|
||||
{item.name}
|
||||
</Link>
|
||||
</div>
|
||||
<div className="font-12 text-gray grid-item pb5">
|
||||
<i className="iconfont icon-shijian user-join-time"></i>
|
||||
<span className="ml4">加入时间:{item.format_time}</span>
|
||||
</div>
|
||||
<FocusButton is_watch={item.is_watch} id={item.login} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
}
|
||||
};
|
||||
return (
|
||||
<div className="background-g pbt15">
|
||||
<div className="main background-f">
|
||||
<div className="plr-20 user-list-items">
|
||||
<div className="font-18 pb-10 border-b-line">{type_title}</div>
|
||||
<Spin spinning={isSpin}>
|
||||
<div className="w-100 inline-block">
|
||||
{count === 0 ? (
|
||||
<NoneData _html="暂时还没有相关数据哦!" />
|
||||
) : (
|
||||
renderList()
|
||||
)}
|
||||
</div>
|
||||
</Spin>
|
||||
{Paginations}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default CommonUsers;
|
|
@ -0,0 +1,73 @@
|
|||
import React, { Component } from "react";
|
||||
import axios from "axios";
|
||||
import { Spin, Button } from "antd";
|
||||
import "./list.css";
|
||||
|
||||
class FocusButton extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
is_watch: false,
|
||||
id: "",
|
||||
isSpin: false,
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount = () => {
|
||||
this.set_watch();
|
||||
};
|
||||
|
||||
set_watch = () => {
|
||||
this.setState({
|
||||
is_watch: this.props.is_watch,
|
||||
id: this.props.id,
|
||||
isSpin: false,
|
||||
});
|
||||
};
|
||||
|
||||
// 关注和取消关注
|
||||
focusFunc = (flag) => {
|
||||
const { id } = this.state;
|
||||
this.setState({ isSpin: true });
|
||||
axios({
|
||||
method: flag ? "delete" : "post",
|
||||
url: `/watchers/${flag ? "unfollow" : "follow"}.json`,
|
||||
params: {
|
||||
target_type: "user",
|
||||
id: id,
|
||||
},
|
||||
})
|
||||
.then((result) => {
|
||||
if (result && result.data.status === 0) {
|
||||
this.setState({
|
||||
is_watch: result.data.watched,
|
||||
isSpin: false,
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
const { is_watch, isSpin } = this.state;
|
||||
return (
|
||||
<Button loading={isSpin} onClick={() => this.focusFunc(is_watch)}>
|
||||
{is_watch ? (
|
||||
<span className="">
|
||||
<i className="iconfont icon-shixing font-15 text-yellow mr-4"></i>
|
||||
<span className="font-12">已关注</span>
|
||||
</span>
|
||||
) : (
|
||||
<span className="">
|
||||
<i className="iconfont icon-kongxing font-15"></i>
|
||||
<span className="font-12">关注</span>
|
||||
</span>
|
||||
)}
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default FocusButton;
|
|
@ -0,0 +1,144 @@
|
|||
import React, { Component } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import axios from "axios";
|
||||
import { getImageUrl } from "educoder";
|
||||
import { Spin, Pagination } from "antd";
|
||||
import "./list.css";
|
||||
import NoneData from "../Nodata";
|
||||
// import FocusButton from "./focus_button";
|
||||
class ForkUsers extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
users: null,
|
||||
count: 0,
|
||||
limit: 20,
|
||||
page: 1,
|
||||
isSpin: false,
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount = () => {
|
||||
this.getUsersList();
|
||||
};
|
||||
|
||||
getUsersList = (page, limit) => {
|
||||
this.setState({
|
||||
isSpin: true,
|
||||
});
|
||||
const { projectsId } = this.props.match.params;
|
||||
|
||||
const url = `/projects/${projectsId}/fork_users.json`;
|
||||
axios
|
||||
.get(url, {
|
||||
params: {
|
||||
page,
|
||||
limit,
|
||||
},
|
||||
})
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
this.setState({
|
||||
count: result.data.count,
|
||||
users: result.data.users,
|
||||
isSpin: false,
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
};
|
||||
|
||||
// 翻页
|
||||
ChangePage = (page) => {
|
||||
this.setState({
|
||||
page,
|
||||
isSpin: true,
|
||||
});
|
||||
const { limit } = this.state;
|
||||
this.getUsersList(page, limit);
|
||||
};
|
||||
|
||||
render() {
|
||||
const { users, count, page, limit, isSpin } = this.state;
|
||||
const Paginations = (
|
||||
<React.Fragment>
|
||||
{count > limit ? (
|
||||
<div className="mt50 mb30 edu-txt-center">
|
||||
<Pagination
|
||||
simple
|
||||
defaultCurrent={page}
|
||||
total={count}
|
||||
pageSize={limit}
|
||||
onChange={this.ChangePage}
|
||||
></Pagination>
|
||||
</div>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</React.Fragment>
|
||||
);
|
||||
|
||||
const renderList = () => {
|
||||
if (users && users.length > 0) {
|
||||
return users.map((item, key) => {
|
||||
return (
|
||||
<div className="w-25 pull-left" key={key}>
|
||||
<div className="pbt25 grid-item mlr10 border-b-line">
|
||||
<div>
|
||||
<Link
|
||||
to={`/users/${item.login}/projects`}
|
||||
className="show-user-link"
|
||||
>
|
||||
<img
|
||||
className="avatar-60"
|
||||
src={getImageUrl(`images/${item.image_url}`)}
|
||||
alt=""
|
||||
/>
|
||||
</Link>
|
||||
</div>
|
||||
<div className="ml12">
|
||||
<div>
|
||||
<Link
|
||||
to={`/users/${item.login}/projects`}
|
||||
className="font-16 text-primary hide-1 task-hide max-w-200"
|
||||
>
|
||||
{item.name}
|
||||
</Link>
|
||||
</div>
|
||||
<div className="font-12 text-gray grid-item pb5">
|
||||
<i className="iconfont icon-shijian user-join-time"></i>
|
||||
<span className="ml4">fork时间:{item.format_time}</span>
|
||||
</div>
|
||||
{/* <FocusButton is_watch={item.is_watch} id={item.login} /> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
}
|
||||
};
|
||||
return (
|
||||
<div className="background-g pbt15">
|
||||
<div className="main background-f">
|
||||
<div className="plr-20 user-list-items">
|
||||
<div className="font-18 pb-10 border-b-line">Fork列表</div>
|
||||
<Spin spinning={isSpin}>
|
||||
<div className="w-100 inline-block">
|
||||
{count === 0 ? (
|
||||
<NoneData _html="暂时还没有相关数据哦!" />
|
||||
) : (
|
||||
renderList()
|
||||
)}
|
||||
</div>
|
||||
</Spin>
|
||||
{Paginations}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default ForkUsers;
|
|
@ -0,0 +1,100 @@
|
|||
.background-f {
|
||||
background: #fff;
|
||||
}
|
||||
.background-g {
|
||||
background: rgb(234, 235, 236);
|
||||
}
|
||||
.pt-15 {
|
||||
padding-top: 15px;
|
||||
}
|
||||
.mr-4{margin-right: 4px;}
|
||||
.pb-10 {
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
.plr-20 {
|
||||
padding: 0 20px;
|
||||
}
|
||||
.font-18 {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.font-12 {
|
||||
font-size: 12px;
|
||||
}
|
||||
.font-15 {
|
||||
font-size: 15px;
|
||||
}
|
||||
.border-b-line {
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
.list-item {
|
||||
width: 100%;
|
||||
}
|
||||
.w-100 {
|
||||
width: 100%;
|
||||
}
|
||||
.w-25 {
|
||||
width: 25%;
|
||||
}
|
||||
.p-10 {
|
||||
padding: 10px;
|
||||
}
|
||||
.pd-105 {
|
||||
padding: 15px 10px;
|
||||
}
|
||||
.grid-item {
|
||||
display: grid !important;
|
||||
align-items: center;
|
||||
grid-template-columns: max-content 1fr;
|
||||
}
|
||||
.avatar-60 {
|
||||
height: 60px;
|
||||
width: 60px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.text-primary {
|
||||
color: #5091ff !important;
|
||||
}
|
||||
.text-primary:hover {
|
||||
color: #2878ff !important;
|
||||
}
|
||||
.text-yellow{
|
||||
color: #FFA802 !important
|
||||
}
|
||||
.text-gray {
|
||||
color: #888888;
|
||||
}
|
||||
.ml12 {
|
||||
margin-left: 12px;
|
||||
}
|
||||
.user-join-time {
|
||||
font-size: 14px !important;
|
||||
color: #60b25e;
|
||||
}
|
||||
.btn-cir-grey {
|
||||
background: rgba(250, 250, 250, 1);
|
||||
color: #888888;
|
||||
font-weight: normal;
|
||||
border: 1px solid rgba(238, 238, 238, 1);
|
||||
border-radius: 2px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.wd-75 {
|
||||
width: 75px;
|
||||
}
|
||||
.pbt15 {
|
||||
padding: 15px 0;
|
||||
}
|
||||
.pbt25 {
|
||||
padding: 25px 0;
|
||||
}
|
||||
.mlr10 {
|
||||
margin: 0 15px;
|
||||
}
|
||||
.user-list-items {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
}
|
||||
.max-w-200{max-width: 200px;}
|
||||
.inline-block{display: inline-block;}
|
|
@ -0,0 +1,32 @@
|
|||
import React, { Component } from "react";
|
||||
import CommonUsers from "./common_users"
|
||||
class PraiseUsers extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
projectId: null
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount = () => {
|
||||
this.get_projectId();
|
||||
};
|
||||
|
||||
get_projectId = () => {
|
||||
this.setState({
|
||||
projectId: this.props.match.params.projectsId
|
||||
})
|
||||
};
|
||||
|
||||
render() {
|
||||
const { projectId } = this.state;
|
||||
return (
|
||||
<div>
|
||||
{projectId && <CommonUsers user_type="praise_users" type_title="点赞列表" project_id={projectId} />}
|
||||
</div>
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default PraiseUsers;
|
|
@ -0,0 +1,32 @@
|
|||
import React, { Component } from "react";
|
||||
import CommonUsers from "./common_users"
|
||||
class WatchUsers extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
projectId: null
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount = () => {
|
||||
this.get_projectId();
|
||||
};
|
||||
|
||||
get_projectId = () => {
|
||||
this.setState({
|
||||
projectId: this.props.match.params.projectsId
|
||||
})
|
||||
};
|
||||
|
||||
render() {
|
||||
const { projectId } = this.state;
|
||||
return (
|
||||
<div>
|
||||
{projectId && <CommonUsers user_type="watch_users" type_title="关注列表" project_id={projectId} />}
|
||||
</div>
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default WatchUsers;
|
|
@ -921,6 +921,9 @@ class NewHeader extends Component {
|
|||
</img>
|
||||
</a>
|
||||
<ul className="edu-menu-list" style={{ top: '46px', 'textAlign': 'center' }}>
|
||||
<li className="bor-bottom-greyE">
|
||||
<a href="javascript:void(0)" className="fs12 hide-1 task-hide edu-txt-w80">{user.username}</a>
|
||||
</li>
|
||||
{
|
||||
mygetHelmetapi2 && mygetHelmetapi2.new_course && mygetHelmetapi2.new_course.edit_account &&
|
||||
<li><a href={`${mygetHelmetapi2.new_course.edit_account}`} target="_blank">修改资料</a></li>
|
||||
|
|
Loading…
Reference in New Issue