This commit is contained in:
sylor_huang@126.com 2020-06-12 18:00:13 +08:00
commit c9cfd7925c
30 changed files with 1047 additions and 377 deletions

View File

@ -538,10 +538,6 @@ a:hover.leftnav-box-inner .btn-cir {
/*右侧头部*/
/*右侧内容*/
.content {
min-width: 1000px;
}
/* tab */

View File

@ -12,7 +12,6 @@ import LoginDialog from './modules/login/LoginDialog';
import Notcompletedysl from './modules/user/Notcompletedysl';
import Trialapplicationysl from './modules/login/Trialapplicationysl';
import Trialapplicationreview from './modules/user/Trialapplicationreview';
import Addcourses from "./modules/courses/coursesPublic/Addcourses";
import AccountProfile from "./modules/user/AccountProfile";
import Accountnewprofile from './modules/user/Accountnewprofile';
import Certifiedprofessional from './modules/modals/Certifiedprofessional';
@ -20,8 +19,7 @@ import Certifiedprofessional from './modules/modals/Certifiedprofessional';
import Loading from './Loading'
import Loadable from 'react-loadable';
import marked from './common/marked'
import marked from './common/marked';
import moment from 'moment'
import { MuiThemeProvider, createMuiTheme } from 'material-ui/styles';
@ -48,14 +46,11 @@ const Projects = Loadable({
loader: () => import('./forge/Index'),
loading: Loading,
})
//403页面
const Shixunauthority = Loadable({
loader: () => import('./modules/403/Shixunauthority'),
loading: Loading,
})
//404页面
const Shixunnopage = Loadable({
loader: () => import('./modules/404/Shixunnopage'),
@ -67,11 +62,6 @@ const http500 = Loadable({
loader: () => import('./modules/500/http500'),
loading: Loading,
})
// 个人主页
// const InfosIndex = Loadable({
// loader: () => import('./modules/user/usersInfo/InfosIndex'),
// loading: Loading,
// })
const InfosIndex = Loadable({
loader: () => import('./forge/users/Infos'),
loading: Loading,
@ -84,7 +74,7 @@ const OrganizeIndex = Loadable({
class App extends Component {
constructor(props) {
super(props)
super(props);
this.state = {
Addcoursestype: false,
Addcoursestypes: false,
@ -92,8 +82,8 @@ class App extends Component {
occupation: 0,
mygetHelmetapi: null,
}
}
HideAddcoursestypess = (i) => {
this.setState({
Addcoursestype: false,
@ -156,7 +146,7 @@ class App extends Component {
this.setState({
mygetHelmetapi: undefined
});
document.title = "EduCoder";
document.title = "Forge";
var link = document.createElement('link'),
oldLink = document.getElementById('dynamic-favicon');
link.id = 'dynamic-favicon';
@ -185,8 +175,6 @@ class App extends Component {
getAppdata = () => {
let url = "/setting.json";
axios.get(url).then((response) => {
// console.log("app.js开始请求/setting.json");
// console.log("获取当前定制信息");
if (response) {
if (response.data) {
this.setState({
@ -204,27 +192,18 @@ class App extends Component {
} catch (e) {
this.gettablogourlnull();
}
} else {
this.gettablogourlnull();
}
} else {
this.gettablogourlnull();
}
}).catch((error) => {
this.gettablogourlnull();
});
};
render() {
let { mygetHelmetapi } = this.state;
return (
<Provider store={store}>
<ConfigProvider locale={zhCN}>
@ -234,7 +213,6 @@ class App extends Component {
<Notcompletedysl {...this.props} {...this.state}></Notcompletedysl>
<Trialapplicationysl {...this.props} {...this.state}></Trialapplicationysl>
<Trialapplicationreview {...this.props} {...this.state}></Trialapplicationreview>
<Addcourses {...this.props} {...this.state} HideAddcoursestypess={(i) => this.HideAddcoursestypess(i)} />
<AccountProfile {...this.props} {...this.state} />
<Certifiedprofessional {...this.props} {...this.state} ModalCancelsy={this.ModalCancelsy} ModalshowCancelsy={this.ModalshowCancelsy} />
<Router>
@ -252,8 +230,7 @@ class App extends Component {
<Route path="/403" component={Shixunauthority} />
<Route path="/500" component={http500} />
<Route
path={"/organize"}
<Route path={"/organize"}
render={
(props) => {
return (<OrganizeIndex {...this.props} {...props} {...this.state} />)
@ -263,20 +240,20 @@ class App extends Component {
{/*404*/}
<Route path="/nopage" component={Shixunnopage} />
{/* 个人主页 */}
<Route path="/users/:username"
<Route path="/users/:username"
render={
(props) => {
return (<InfosIndex {...this.props} {...props} {...this.state} />)
}
}></Route>
}></Route>
<Route exact path="/"
render={
(props) => (<Projects {...this.props} {...props} {...this.state}></Projects>)
(props) => (
<Projects {...this.props} {...props} {...this.state}></Projects>
)
}
/>
<Route component={Shixunnopage} />
</Switch>
</Router>
</MuiThemeProvider>

View File

@ -0,0 +1,19 @@
import React from 'react';
import './Component.scss';
export default (({img , title, desc , rightBtn})=>{
return(
<div className="cards">
<div className="img"><img src={img} alt=""/></div>
<div className="content">
<p className="titles">
<span>{title}</span>
{rightBtn}
</p>
<div className="desc">
{desc}
</div>
</div>
</div>
)
})

View File

@ -1,10 +1,66 @@
ul.ant-menu{
border-right: none;
ul.ant-menu{
border-right: none;
}
ul.ant-menu li:last-child{
border-bottom: none;
}
li.ant-menu-item{
margin:0px!important;
border-bottom: 1px solid #eee;
}
// Cards
.cards{
display: flex;
align-items: center;
padding:20px 34px;
background-color: #fff;
margin:18px 0px;
.img{
margin-right: 20px;
width: 190px;
height: 90px;
border:1px solid rgba(238,238,238,1);
display: flex;
justify-content: center;
align-items: center;
img{
max-width: 100%;
}
}
ul.ant-menu li:last-child{
border-bottom: none;
.content{
flex:1;
width: 0;
.titles{
display: flex;
justify-content: space-between;
margin-bottom: 10px!important;
align-items: center;
&>span{
font-size:18px ;
color: #333;
}
}
.desc{
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
}
li.ant-menu-item{
margin:0px!important;
border-bottom: 1px solid #eee;
}
}
// Tabs
.tabsStyle{
.ant-tabs-bar.ant-tabs-top-bar{
padding-left: 35px;
margin-bottom: 0px;
}
.ant-tabs-nav .ant-tabs-tab{
padding:19px 0px;
margin-right: 40px;
}
.ant-tabs-ink-bar{
width:25px!important;
bottom: 10px;
}
}

View File

@ -0,0 +1,41 @@
import React from 'react';
import styled from 'styled-components';
export default (({fork,parise})=>{
const DivStyle = styled.div`{
display:flex;
align-item:center;
}`;
const SpanStylefork = styled.span`{
display:flex;
align-item:center;
margin-left:30px;
padding:0px 12px;
border-radius:13px;
background-color:#EBF4FE;
height:24px;
line-height:24px;
font-size:12px;
}`;
const SpanStyleparise = styled.span`{
display:flex;
align-item:center;
margin-left:30px;
padding:0px 12px;
border-radius:13px;
background-color:#FFF3DC;
height:24px;
line-height:24px;
font-size:12px;
}`;
return(
<DivStyle>
{
fork || fork ===0 ? <SpanStylefork><i className="iconfont icon-fork font-15 mr3" style={{color:"#1B8FFF"}}></i>fork({fork})</SpanStylefork>:""
}
{
parise || parise ===0?<SpanStyleparise><i className="iconfont icon-guanzhu font-14 mr3" style={{color:"#FFA802"}}></i>点赞({parise})</SpanStyleparise>:""
}
</DivStyle>
)
})

View File

@ -0,0 +1,74 @@
import React from 'react';
import './Component.scss';
import styled from 'styled-components';
const Img = styled.img`{
border-radius:50%;
width:50px;
height:50px;
margin-right:14px;
}`
const Name = styled.div`{
color:#5091FF;
font-size:16px;
height:22px;
line-height:22px;
margin-bottom:7px;
}`
const Time = styled.div`{
color:#888;
font-size:12px;
height:16px;
line-height:16px;
margin-bottom:9px;
display:flex;
align-item:center;
}`
const I = styled.i`{
font-size:13px!important;
color:#60B25E;
margin-right:2px;
}`
const FocusBtn = styled.a`{
display:inline-block;
height:30px;
line-height:26px;
padding:0px 12px;
background-color:#fafafa;
border:1px solid #eee;
border-radius:2px;
color:#888!important;
}`
const Ifocused = styled.i`{
font-size:16px!important;
color:#FFA802;
margin-right:4px;
}`
const Ifocus = styled.i`{
font-size:16px!important;
color:#BBBBBB;
margin-right:4px;
}`
const Div = styled.div`{
margin-bottom: 18px;
padding:20px 16px;
display: flex;
align-items: center;
border:1px solid #eee;
}`
export default (({img,name,time, focusStatus})=>{
return(
<Div>
<Img src={img}/>
<div className="m-infos">
<Name>{name}</Name>
<Time><I className="iconfont icon-shijian"></I>加入时间:{time}</Time>
{
focusStatus ?
<FocusBtn><Ifocused className="iconfont icon-shixing"></Ifocused>已关注</FocusBtn> :
<FocusBtn><Ifocus className="iconfont icon-kongxing"></Ifocus>关注</FocusBtn>
}
</div>
</Div>
)
})

View File

@ -0,0 +1,20 @@
import React from 'react';
import { Tabs } from 'antd';
import './Component.scss';
const { TabPane } = Tabs;
export default (({ nav, index , onChange , children })=>{
return(
nav && nav.length > 0 ?
<Tabs className="tabsStyle" animated={false} activeKey={index} onChange={onChange}>
{
nav.map((item,key)=>{
return(
<TabPane tab={item} key={`${key}`}>{children}</TabPane>
)
})
}
</Tabs>:""
)
})

View File

@ -0,0 +1,44 @@
import styled from 'styled-components';
export const Banner = styled.div`{
padding:20px 25px;
color:#333;
font-size:18px;
border-bottom:1px solid #eee;
background-color:#fff;
border-radius:5px 5px 0px 0px;
}`
export const AlignCenterBetween = styled.div`{
display:flex;
align-items: center;
padding: 14px 14px 14px 20px;
justify-content: space-between;
border-bottom:1px solid #eee;
}`
export const AlignCenter = styled.div`{
display:flex;
align-items: center;
}`
//
export const Box = styled.div`{
display:flex;
align-item:flex-start;
}`
export const Long = styled.div`{
width:72%;
border-radius:5px;
margin-bottom:30px;
}`
export const Short = styled.div`{
width:28%;
border-radius:5px;
margin-bottom:30px;
}`
export const Gap = styled.div`{
padding-left:20px;
box-sizing:border-box;
}`
export const WhiteBack = styled.div`{
background-color:#fff;
border-radius:5px;
}`

View File

@ -27,7 +27,6 @@ const ProjectDetail = Loadable({
loading: Loading,
});
class Index extends Component {
render() {
return (
@ -52,15 +51,12 @@ class Index extends Component {
<ProjectIndex {...this.props} {...props} {...this.state} />
)}
></Route>
<Route
exact
path="/"
render={(props) => (
<ProjectIndex>
{...this.props}
{...props}
{...this.state}
</ProjectIndex>
<Route exact path="/" render={(props) => (
<ProjectIndex
{...this.props}
{...props}
{...this.state}
></ProjectIndex>
)}
/>
</Switch>

View File

@ -90,6 +90,9 @@ class CoderRootDirectory extends Component {
// 页面地址返回到主目录
returnMain = (branch) => {
const { projectsId } = this.props.match.params;
this.setState({
readOnly:true
})
this.props.history.push(`/projects/${projectsId}/coders`);
this.getProjectRoot(branch);
};
@ -138,6 +141,7 @@ class CoderRootDirectory extends Component {
this.props.history.push(`/projects/${projectsId}/coders?url=${arr.path}`);
this.setState({
readOnly: readOnly,
chooseType:"file"
});
};
@ -299,6 +303,7 @@ class CoderRootDirectory extends Component {
this.setState({
branch: value,
isSpin: true,
readOnly:true
});
let { search } = this.props.history.location;
if (search && search.indexOf("?url=") > -1) {
@ -315,11 +320,18 @@ class CoderRootDirectory extends Component {
// 子目录路径返回链接
returnUlr=(url)=>{
this.setState({
chooseType:"dir"
chooseType:"dir",
readOnly:true
})
const { projectsId } = this.props.match.params;
this.props.history.push(`/projects/${projectsId}/coders?url=${url}`);
}
onEdit=(readOnly)=>{
this.setState({
readOnly
})
}
render(){
const { branchLastCommit , lastCommitAuthor , rootList , branch ,filePath , fileDetail , subFileType , readMeContent, isSpin , zip_url , tar_url} = this.state;
const { isManager , isDeveloper , projectDetail } = this.props;
@ -505,6 +517,7 @@ class CoderRootDirectory extends Component {
{...this.props}
{...this.state}
readOnly={this.state.readOnly}
onEdit={this.onEdit}
></CoderRootFileDetail>
)}
{/* readme.txt (isManager || isDeveloper)*/}

View File

@ -15,18 +15,16 @@ class CoderRootFileDetail extends Component {
constructor(props) {
super(props);
this.state = {
readOnly: true,
value: undefined,
language: undefined
};
}
componentDidMount = () => {
const { detail, readOnly } = this.props;
const { detail } = this.props;
this.setState({
value: detail.content,
readOnly: readOnly,
});
};
select_language = (e) => {
@ -34,16 +32,14 @@ class CoderRootFileDetail extends Component {
language: e,
});
};
EditFile = () => {
this.setState({
readOnly: false,
});
};
CancelEdit = () => {
this.setState({
readOnly: true,
});
EditFile = (flag) => {
const { onEdit } = this.props;
onEdit && onEdit(flag);
// this.setState({
// readOnly: false,
// });
};
// 编辑文件
@ -85,8 +81,8 @@ class CoderRootFileDetail extends Component {
};
render() {
const { detail, current_user, isManager, isDeveloper } = this.props;
const { readOnly, language } = this.state;
const { readOnly , detail, current_user, isManager, isDeveloper } = this.props;
const { language } = this.state;
let flag = current_user && current_user.login && (isManager || isDeveloper);
const Option = Select.Option;
const languages = [
@ -151,7 +147,7 @@ class CoderRootFileDetail extends Component {
{flag && (
<div>
{readOnly ? (
<a onClick={this.EditFile} className="ml20">
<a onClick={()=>this.EditFile(false)} className="ml20">
<i className="iconfont icon-bianji1 font-15 color-grey-6"></i>
</a>
) : (
@ -171,7 +167,7 @@ class CoderRootFileDetail extends Component {
<button
type="button"
className="ant-btn ant-btn-sm ml20"
onClick={this.CancelEdit}
onClick={()=>this.EditFile(true)}
>
<span> </span>
</button>

View File

@ -1,6 +1,6 @@
import React, { Component } from 'react';
import { Spin, Tooltip } from 'antd';
import { Link, Route, Switch, withRouter } from 'react-router-dom';
import { Link, Route, Switch } from 'react-router-dom';
import '../css/index.css'
import './list.css';
@ -610,4 +610,4 @@ class Detail extends Component {
}
}
export default withRouter(Detail);
export default Detail;

View File

@ -18,7 +18,7 @@ class OrderItem extends Component {
return (
issue_tags.map((item, key) => {
return (
<Tag color={item.color} className="mlr10" key={key}>{item.name}</Tag>
<span className="mr10">{item.name}</span>
)
})
)

23
src/forge/Team/Box.jsx Normal file
View File

@ -0,0 +1,23 @@
import React from 'react';
export default (({ name , count , bottom , children })=>{
return(
<div className="box">
<div className="head">
<span>{name}</span>
<span>{count}<i className="iconfont icon-youjiantou font-12 ml3"></i></span>
</div>
<div className="content">
{children}
</div>
{
bottom ?
<div className="foot">
{bottom}
</div>
:""
}
</div>
)
})

33
src/forge/Team/Detail.jsx Normal file
View File

@ -0,0 +1,33 @@
import React , { useEffect , useState } from 'react';
import { Route, Switch } from "react-router-dom";
import Loadable from "react-loadable";
import Loading from "../../Loading";
import Cards from '../Component/Cards';
import './Index.scss';
const DetailIndex = Loadable({
loader: () => import("./List"),
loading: Loading,
});
export default ((props)=>{
return(
<div className="teamDetail">
<Cards
title="组织名称"
desc="组织名称组织名称组织名称组织名称组织名称"
rightBtn={<a className="color-blue">设置<i className="iconfont icon-shezhi2 ml3"></i></a>}
img={`https://dss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=4193840146,2109186388&fm=26&gp=0.jpg`}
/>
<Switch {...props}>
<Route
path="/organize/:organizeId"
render={(props) => {
return <DetailIndex {...props} />
}}
></Route>
</Switch>
</div>
)
})

View File

@ -0,0 +1,35 @@
import React from 'react';
import Cards from '../Component/MemberCards';
export default (()=>{
return(
<div>
<div className="MemberBoxThree">
<Cards
img="https://dss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=3331079987,1190181307&fm=111&gp=0.jpg"
name="陈教授"
time="2020-04-29"
focusStatus={true}
/>
<Cards
img="https://dss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=3331079987,1190181307&fm=111&gp=0.jpg"
name="陈教授"
time="2020-04-29"
focusStatus={true}
/>
<Cards
img="https://dss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=3331079987,1190181307&fm=111&gp=0.jpg"
name="陈教授"
time="2020-04-29"
focusStatus={true}
/>
<Cards
img="https://dss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=3331079987,1190181307&fm=111&gp=0.jpg"
name="陈教授"
time="2020-04-29"
focusStatus={true}
/>
</div>
</div>
)
})

View File

@ -0,0 +1,35 @@
import React from 'react';
import styled from 'styled-components';
import { Link } from 'react-router-dom';
const Box=styled.div`{
padding:0px 38px;
}`
const Div = styled.div`{
display:flex;
align-items: center;
margin-left:10px;
padding:25px 0px;
border-bottom:1px solid #eee;
}`
const Imgs = styled.img`{
width:30px;
height:30px;
margin-right:12px;
border-radius:50%;
}`
export default (()=>{
return(
<Box>
<Div>
<Imgs src="https://dss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=3025493530,1989042357&fm=26&gp=0.jpg"/>
<Link to={""}>ajdfwkerijwirjklsf</Link>
</Div>
<Div>
<Imgs src="https://dss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=3025493530,1989042357&fm=26&gp=0.jpg"/>
<Link to={""}>ajdfwkerijwirjklsf</Link>
</Div>
</Box>
)
})

View File

@ -0,0 +1,50 @@
import React , {useState} from 'react';
import { Button } from 'antd';
import styled from 'styled-components';
import { Box , Short , Long , Gap , WhiteBack , AlignCenterBetween } from '../Component/layout';
import Tabs from '../Component/Tabs';
import Memberlist from './GroupDetailMember';
import Grouplist from './GroupDetailProject';
const Leave = styled.a`{
display:block;
border-radius:5px;
border:1px solid rgba(40,189,108,1);
color:rgba(40,189,108,1);
padding:0px 14px;
height:30px;
line-height:30px;
}`
export default ((props)=>{
const [ nav , setNav ] = useState('0');
return(
<Box className="GroupSubLevel">
<Short className="g-sub-left">
<AlignCenterBetween>
<span className="color-grey-3">Owndsknamename</span>
<Leave>离开团队</Leave>
</AlignCenterBetween>
<div className="g-desc">该团队暂无描述</div>
<div className="g-tip">
<p>管理员团队对 <span>所有仓库</span> 具有操作权限且对组织具有 <span>管理员权限</span> </p>
<p>此外该团队拥有了 <span>创建仓库</span> 的权限成员可以在组织中创建新的仓库 </p>
<Button type="primary">团队设置</Button>
</div>
</Short>
<Long>
<Gap>
<WhiteBack>
<Tabs nav={['团队成员','团队项目']} index={nav} onChange={setNav}>
{
nav === "0" ?
<Memberlist />:<Grouplist />
}
</Tabs>
</WhiteBack>
</Gap>
</Long>
</Box>
)
})

View File

@ -1,13 +1,13 @@
import React from 'react';
import { Route, Switch } from "react-router-dom";
import Loadable from "react-loadable";
import Loading from "../../Loading";
import { SnackbarHOC } from "educoder";
import { CNotificationHOC } from "../../modules/courses/common/CNotificationHOC";
import { TPMIndexHOC } from "../../modules/tpm/TPMIndexHOC";
import Loadable from "react-loadable";
import Loading from "../../Loading";
import '../css/index.css';
@ -15,17 +15,39 @@ const New = Loadable({
loader: () => import("./New"),
loading: Loading,
});
const DetailIndex = Loadable({
loader: () => import("./Detail"),
loading: Loading,
});
const SubDetail = Loadable({
loader: () => import("./SubDetail"),
loading: Loading,
});
export default CNotificationHOC()(SnackbarHOC()(TPMIndexHOC(
((props)=>{
return (
<Switch {...props}>
<Route
path="/organize/new"
render={(props) => {
return <New {...props} />;
}}
></Route>
</Switch>
<div className="newMain">
<Switch {...props}>
<Route
path="/organize/:organizeId/member"
render={(props) => {
return <SubDetail {...props} />
}}
></Route>
<Route
path="/organize/new"
render={(props) => {
return <New {...props} />
}}
></Route>
<Route
path="/organize/:organizeId"
render={(props) => {
return <DetailIndex {...props} />
}}
></Route>
</Switch>
</div>
)
})
)))

View File

@ -12,13 +12,14 @@
font-size: 18px;
}
.teamBox-form{
padding:24px 40px;
padding:24px 40px 0px 40px;
}
.lables{
position: relative;
color:#333;
margin-bottom: 5px;
display: block;
font-size: 16px;
}
.lables.must::before{
content: "*";
@ -28,4 +29,247 @@
left: -15px;
height: 100%;
}
}
}
.ant-btn.grey{
background: #bbb;
color: #fff;
border: 1px solid #bbb;
}
.teamDetail{
width: 1200px;
margin:0px auto;
}
.list{
display: flex;
align-items: flex-start;
.list-l{
background-color: #fff;
max-width: 860px;
width: 72%;
.head{
padding:16px 32px;
border-bottom: 1px solid #eee;
display: flex;
justify-content: space-between;
align-items: center;
.addBtn{
display: inline-block;
border-radius: 5px;
border:1px solid #5091FF;
color: #5091FF;
height: 30px;
line-height: 30px;
padding:0px 10px;
}
}
.team{
padding:0px 32px;
.team_project{
padding:22px 0px;
border-bottom: 1px solid #eee;
.t_p_title{
display: flex;
align-items: center;
justify-content: space-between;
.name{
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
font-size: 18px;
max-width: 500px;
float: left;
}
}
.desc{
color: #333;
margin-top: 6px;
margin-bottom: 3px;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
&:last-child{
border-bottom: none;;
}
}
}
}
.list-r{
width: 28%;
max-width: 340px;
padding-left: 20px;
box-sizing: border-box;
}
.box{
background:rgba(255,255,255,1);
border-radius:5px;
margin-bottom: 20px;
.head{
padding:25px 20px;
display: flex;
border-bottom: 1px solid #eee;
justify-content: space-between;
color: #333;
}
.content{
padding:13px 0px;
.teammembers{
display: flex;
align-items: center;
padding:13px 20px;
.m-img{
border-radius: 50%;
width:45px;
height: 45px;
margin-right: 12px;
}
}
}
.foot{
padding:15px 20px;
border-top: 1px solid #eee;
}
}
}
.subNavs{
display: flex;
a{
display: block;
margin-left: 14px;
height: 40px;
padding:0px 22px;
border-radius: 2px;
border:1px solid #eee;
background-color: #fafafa;
color:#333;
display: flex;
align-items: center;
font-size: 14px;
span{
display: block;
height: 18px;
line-height: 18px;
}
lable{
display: block;
padding:0px 7px;
background-color:#eee;
height: 18px;
line-height: 18px;
font-size: 12px;
border-radius: 10px;
margin-left: 5px;
}
&.active{
border:1px solid #5091FF;
color: #5091FF;
lable{
background-color: #F1F8FF;
color: #5091FF;
}
}
}
}
// 组织团队
.groupBox{
display: flex;
flex-wrap: wrap;
align-items: flex-start;
background-color: #fff;
padding:30px 35px;
margin-bottom: 30px;
&>div{
border:1px solid #eee;
background-color: #fff;
width: 48.5%;
margin-right: 3%;
margin-bottom: 30px;
.g-head,.g-foot{
display: flex;
justify-content: space-between;
background-color: #F1F8FF;
padding:10px 10px 10px 25px;
align-items: center;
}
.g-foot{
background-color: #fafafa;
justify-content: left;
}
.g-body{
padding:15px 25px;
}
}
&>div:nth-child(2n){
margin-right: 0px;
}
}
// 组织成员-一行四个
.memberBox{
display: flex;
align-items: flex-start;
flex-wrap: wrap;
background-color: #fff;
padding:24px 35px;
margin-bottom: 30px;
min-height: 400px;
align-content: flex-start;
&>div{
width:22.75% ;
margin-right: 3%;
.m-infos{
flex:1;
}
}
&>div:nth-child(4n){
margin-right: 0px;
}
}
// 团队成员-一行三个
.MemberBoxThree{
display: flex;
align-items: flex-start;
flex-wrap: wrap;
background-color: #fff;
padding:24px 35px;
margin-bottom: 30px;
min-height: 400px;
align-content: flex-start;
&>div{
width:31% ;
margin-right: 3.5%;
.m-infos{
flex:1;
}
}
&>div:nth-child(3n){
margin-right: 0px;
}
}
// 团队详情成员项目
.GroupSubLevel{
display: flex;
align-items: flex-start;
.g-sub-left{
background-color: #fff;
.g-desc{
padding:18px 20px;
color:#333;
min-height: 100px;
}
.g-tip{
padding:28px 20px;
border-top: 1px solid #eee;
&>p{
margin-bottom: 10px!important;
}
&>p>span{
color:#333;
}
&>button{
margin-top: 10px;
}
}
}
}

124
src/forge/Team/List.jsx Normal file
View File

@ -0,0 +1,124 @@
import React from 'react';
import { Button } from 'antd';
import Search from '../Component/Search';
import Sort from '../Component/Sort';
import ListCount from '../Component/ListCount';
import Box from './Box';
import './Index.scss';
import styled from 'styled-components';
import { Menu } from 'antd';
const Span = styled.span`{
color:#888;
font-size:12px;
margin-right:10px;
}`
const Align = styled.div`{
display:flex;
aligin:center;
}`
const ListName = styled.div`{
font-size:14px;
color:#333;
margin-bottom:8px;
height:18px;
line-height:18px;
}`;
const ColorListName = styled.div`{
color:#5091FF;
font-size:14px;
margin-bottom:8px;
height:18px;
line-height:18px;
}`
const Img = styled.img`{
border-radius:50%;
width:45px;
height:45px;
margin-right:12px;
}`
export default (()=>{
function onSearch(value){
}
const menu=(
<Menu>
<Menu.Item key="updated_on">更新时间排序</Menu.Item>
<Menu.Item key="created_on">项目数排序</Menu.Item>
</Menu>
)
const menu_new=(
<Menu>
<Menu.Item key="updated_on">新建托管项目</Menu.Item>
<Menu.Item key="created_on">新建镜像项目</Menu.Item>
</Menu>
)
const leftList = (
<div className="team_project">
<p className="t_p_title">
<span className="flex1">
<span className="name">react项目react项目react项目react项目</span>
<i className="iconfont icon-banbenku font-20 color-green" />
<i className="iconfont icon-jingxiang font-18 color-green" />
<i className="iconfont icon-fork font-18 color-orange" />
</span>
<ListCount fork={1} parise={0}/>
</p>
<div className="desc">
用于构建用户界面的 JavaScript
</div>
<div className="infos">
<span className="font-12 color-grey-8">更新于1天前</span>
</div>
</div>
)
return(
<div className="list">
<div className="list-l">
<div className="head">
<div style={{width:"370px"}}>
<Search placeholder="输入仓库名称进行搜索" onSearch={onSearch}/>
</div>
<p>
<Sort menu={menu_new}>
<a className="addBtn mr30">+&nbsp;新建项目</a>
</Sort>
<Sort menu={menu}>
<a className="color-blue">排序<i className="iconfont icon-sanjiaoxing-down ml3 font-14"></i></a>
</Sort>
</p>
</div>
<div className="team">
{leftList}
</div>
</div>
<div className="list-r">
<Box name="组织成员" count={8}>
<div className="teammembers">
<Img src="https://dss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=1990625098,3468619056&fm=111&gp=0.jpg" alt="" className="m-img"/>
<div>
<ListName>陈Professer</ListName>
<Align><i className="iconfont icon-shijian color-green mr3 font-13"></i><Span>加入时间2020-04-28</Span></Align>
</div>
</div>
</Box>
<Box
name="组织团队"
count={3}
bottom={<Button type={'primary'} to={``}>新建团队</Button>}
>
<div className="teammembers">
<div>
<ColorListName>陈Professer</ColorListName>
<Align>
<Span>2名成员</Span>
<Span>1个仓库</Span>
</Align>
</div>
</div>
</Box>
</div>
</div>
)
})

View File

@ -1,13 +1,17 @@
import React,{ forwardRef , useCallback } from 'react';
import './Index.scss';
import { Form , Input , Cascader , Checkbox , Upload } from "antd";
import { Form , Input , Cascader , Radio , Checkbox , Upload , Button } from "antd";
import { locData } from "../Utils/locData";
export default Form.create()(
forwardRef(({form})=>{
const { getFieldDecorator, validateFields, setFieldsValue } = form;
const radioStyle = {
display: 'block',
height: '30px',
lineHeight: '30px',
}
const helper = useCallback(
(label, name, rules, widget, isRequired = true) => (
<React.Fragment>
@ -52,11 +56,11 @@ export default Form.create()(
'可见性',
"exposure",
[{ required: true, message: "请选择可见性" }],
<Checkbox.Group>
<Checkbox value="1" key={1}>公开</Checkbox>
<Checkbox value="2" key={2}>受限<span className="color-grey-8">仅对登录用户可见</span></Checkbox>
<Checkbox value="3" key={3}>公开<span className="color-grey-8">仅对组织成员可见</span></Checkbox>
</Checkbox.Group>
<Radio.Group name="exposure">
<Radio style={radioStyle} value="1" key={1}>公开</Radio>
<Radio style={radioStyle} value="2" key={2}>受限<span className="color-grey-8">仅对登录用户可见</span></Radio>
<Radio style={radioStyle} value="3" key={3}>公开<span className="color-grey-8">仅对组织成员可见</span></Radio>
</Radio.Group>
)}
{helper(
'选择头像',
@ -72,6 +76,10 @@ export default Form.create()(
)}
</Form>
</div>
<p className="mt20">
<Button type="primary" className="mr30">创建组织</Button>
<Button className="grey">取消</Button>
</p>
</div>
</div>
)

View File

@ -0,0 +1,57 @@
import React from 'react';
import { Route, Switch , Link } from "react-router-dom";
import Loadable from "react-loadable";
import Loading from "../../Loading";
import './Index.scss';
import Cards from '../Component/Cards';
const Group = Loadable({
loader: () => import("./TeamGroup"),
loading: Loading,
});
const Member = Loadable({
loader: () => import("./TeamMember"),
loading: Loading,
});
const GroupDetails = Loadable({
loader: () => import("./GroupDetails"),
loading: Loading,
});
export default ((props)=>{
return(
<div className="teamDetail">
<Cards
title="组织名称"
rightBtn={
<span className="subNavs">
<Link to={``} className="active"><span>组织成员</span><lable>13</lable></Link>
<Link to={``}><span>组织团队</span><lable>13</lable></Link>
</span>
}
img={`https://dss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=4193840146,2109186388&fm=26&gp=0.jpg`}
/>
<Switch {...props}>
<Route
path="/organize/:organizeId/member/:memberId"
render={(props) => {
return <GroupDetails {...props} />
}}
></Route>
<Route
path="/organize/:organizeId/member"
render={(props) => {
return <Member {...props} />
}}
></Route>
<Route
path="/organize/:organizeId/group"
render={(props) => {
return <Group {...props} />
}}
></Route>
</Switch>
</div>
)
})

View File

@ -0,0 +1,49 @@
import React from 'react';
import { Banner } from '../Component/layout';
import styled from 'styled-components';
const SpanName = styled.span`{
font-size:16px;
color:#333;
}`
const SpanFoot = styled.span`{
margin-right:5px;
color:#333
}`
const ALink = styled.a`{
border:1px solid #F73030;
color:#F73030!important;
height:30px;
line-height:30px;
padding:0px 15px;
border-radius:5px;
}`
const ImgContent = styled.img`{
height:44px;
width:44px;
border-radius:50%;
margin:5px 20px 5px 0px;
}`
export default (()=>{
return(
<div>
<Banner>组织团队</Banner>
<div className="groupBox">
<div>
<p className="g-head">
<SpanName>oweners</SpanName>
<ALink>离开团队</ALink>
</p>
<div className="g-body">
<ImgContent src="https://dss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=3331079987,1190181307&fm=111&gp=0.jpg"/>
<ImgContent src="https://dss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=3331079987,1190181307&fm=111&gp=0.jpg"/>
</div>
<p className="g-foot">
<SpanFoot>2&nbsp;名成员</SpanFoot>
<SpanFoot>1&nbsp;个项目</SpanFoot>
</p>
</div>
</div>
</div>
)
})

View File

@ -0,0 +1,25 @@
import React from 'react';
import { Banner } from '../Component/layout';
import Cards from '../Component/MemberCards';
export default (()=>{
return(
<div>
<Banner>组织成员</Banner>
<div className="memberBox">
<Cards
img="https://dss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=3331079987,1190181307&fm=111&gp=0.jpg"
name="陈教授"
time="2020-04-29"
focusStatus={true}
/>
<Cards
img="https://dss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=3331079987,1190181307&fm=111&gp=0.jpg"
name="陈教授"
time="2020-04-29"
focusStatus={false}
/>
</div>
</div>
)
})

View File

@ -100,7 +100,7 @@ class Index extends Component {
return (
<Dragger {...upload} className={this.props.className}>
{ icon || <Icon type="inbox" />}
<p className="ant-upload-text">拖动文件或<span className="color-blue">点击此处上传</span></p>
<p className="ant-upload-text font-14">拖动文件或<span className="color-blue">点击此处上传</span></p>
</Dragger>
)
}

View File

@ -26,6 +26,9 @@ export default Form.create()(
const [attachment, setAttachment] = useState(undefined);
const [options , setOptions] = useState(undefined);
const repo_id = projectDetail && projectDetail.repo_id;
const { projectsId, versionId } = match.params;
useEffect(()=>{
getBranchs(projectsId);
},[projectsId])
@ -41,9 +44,6 @@ export default Form.create()(
line-height: 35px;
`;
const repo_id = projectDetail && projectDetail.repo_id;
const { projectsId, versionId } = match.params;
useEffect(() => {
if (versionId) {

View File

@ -1338,15 +1338,6 @@ samp {
padding: 16px 0px;
}
/* FORM START */
.ant-form label {
/* 为了覆盖antd的样式这里使用了importantTODO */
font-size: 16px !important;
}
.ant-form label.font-18 {
font-size: 18px !important;
}
.ant-form label.font-14 {
font-size: 14px !important;

View File

@ -7,7 +7,6 @@ import { CenterBtnGrp, SaveBtn, CancelBtn } from "../util/GeneralButton";
import { useLoaded } from "../util/hooks";
import { updateResume } from "../data/updateResume";
import { getResume } from "../data/getResume";
import Nav from "../util/Nav";
const Backgroud = styled(FullScreen)`
background: rgba(245, 246, 249, 1);

View File

@ -8,13 +8,13 @@ import './TPMIndex.css';
import LoginDialog from '../login/LoginDialog';
import AccountProfile from '../user/AccountProfile';
import AccountPhoneemail from '../user/AccountPhoneemail';
const $ = window.$;
import cookies from 'react-cookies';
export function TPMIndexHOC(WrappedComponent) {
// 这里如果extends WrappedComponent 会出现 WrappedComponent mount twice的问题
return class II extends React.Component {
constructor(props) {
super(props)
console.log("cook ",cookies.load("autologin_trustie"));
super(props);
window.$('#root').css('position', 'relative')
this.state = {
@ -43,47 +43,8 @@ export function TPMIndexHOC(WrappedComponent) {
current_user: newUser
})
}
showShixun = () => {
const { shixunId } = this.props.match.params
const url = `/api/v1/shixuns/${shixunId}/show_shixun`
this.setState({ tpmLoading: true })
axios.get(url,
{
withCredentials: true
}
).then((response) => {
if (response.data && response.data.shixun) {
this.initCommonState(response.data.current_user)
response.data.tpmLoading = false;
this.setState(response.data);
}
}).catch((error) => {
console.log(error)
})
}
aboutFocus = () => {
const { creator, watched } = this.state
/*http://localhost:3000/api/v1/users/155/watch?object_id=156&object_type=user*/
const focusUrl = `/api/v1/users/${creator.owner_id}/${watched ? 'unwatch' : 'watch'}?object_id=${creator.owner_id}&object_type=user`
axios.get(focusUrl, {
})
.then((response) => {
const status = response.data.status;
if (status == 1) {
const new_author_info = Object.assign({}, creator)
this.setState({
watched: !watched
})
}
}).catch((error) => {
console.log(error)
})
}
keyupListener = (e) => {
if (e.key === "Escape") {
this.setState({ globalLoading: false })
@ -92,10 +53,11 @@ export function TPMIndexHOC(WrappedComponent) {
componentWillUnmount() {
window.removeEventListener('keyup', this.keyupListener)
}
componentWillMount(){
this.fetchUsers();
}
componentDidMount() {
// console.log("TPMIndexHOC========");
// console.log(this.props);
window.addEventListener('keyup', this.keyupListener)
if (this.props.match.path === "/") {
@ -112,99 +74,9 @@ export function TPMIndexHOC(WrappedComponent) {
document.title = "教学课堂";
}
$.ajaxSetup({
cache: true
});
//帮助后台传参数
const query = this.props.location.search;
var dataqueryss = {}
try {
var foqus = this.foo(query);
if (JSON.stringify(foqus) === "{}") {
this.setState({
dataquerys: {},
});
} else {
this.setState({
dataquerys: foqus,
});
dataqueryss = foqus;
}
} catch (e) {
this.setState({
dataquerys: {},
})
}
this.fetchUsers(dataqueryss);
///请求定制化的信息
this.getAppdata();
}
/**
课堂权限相关方法暂时写这里了 ----------------------------------------START
ADMIN = 0 # 超级管理员
CREATOR = 1 # 课程创建者
PROFESSOR = 2 # 课程老师
ASSISTANT_PROFESSOR = 3 # 课程助教
STUDENT = 4 # 学生
NORMAL = 5 # 普通用户
v2
# 课程权限判断
ADMIN = 0 # 超级管理员
BUSINESS = 1 # 运营人员
CREATOR = 2 # 课程创建者 课堂管理员
PROFESSOR = 3 # 课程老师
ASSISTANT_PROFESSOR = 4 # 课程助教
STUDENT = 5 # 学生
NORMAL = 6 # 普通用户
Anonymous = 7 # 普未登录
*/
//超管0
isSuperAdmin = () => {
// return false
return this.state.coursedata && this.state.coursedata.course_identity === 0
}
isCourseAdmin = () => {
return this.state.coursedata && this.state.coursedata.course_identity === 2
}
//超管、运维0-1
isClassManagement = () => {
return this.state.coursedata && this.state.coursedata.course_identity < 2
}
//超管、运维、课堂管理0-2
isAdminOrCreator = () => {
return this.state.coursedata && this.state.coursedata.course_identity < 3
}
//超管、运维、课堂管理、老师0-3
isAdminOrTeacher = () => {
return this.state.coursedata && this.state.coursedata.course_identity < 4
}
// 助教===4
isAssistant = () => {
return this.state.coursedata && this.state.coursedata.course_identity === 4
}
// 超管、运维、课堂管理、老师、助教0-4
isAdmin = () => {
return this.state.coursedata && this.state.coursedata.course_identity < 5
}
// 学生5
isStudent = () => {
return this.state.coursedata && this.state.coursedata.course_identity === 5
}
// 超管、运维、课堂管理、老师、助教、学生0-5
isAdminOrStudent = () => {
return this.state.coursedata && this.state.coursedata.course_identity <= 5
}
// 游客未登录/非课堂成员6>
isNotMember = () => {
return this.state.coursedata && this.state.coursedata.course_identity >= 6
}
//课堂是否已结束
isCourseEnd = () => {
return this.state.current_user ? this.state.current_user.course_is_end : false
}
//获取数据为空的时候
@ -254,7 +126,6 @@ export function TPMIndexHOC(WrappedComponent) {
console.log("hoc获取游览器配置失败 重新请求开始读取配置");
this.getAppdatausr();
}
};
getAppdatausr = () => {
let url = "/setting.json";
@ -275,131 +146,26 @@ export function TPMIndexHOC(WrappedComponent) {
} catch (e) {
this.gettablogourlnull();
}
} else {
this.gettablogourlnull();
}
} else {
this.gettablogourlnull();
}
}).catch((error) => {
this.gettablogourlnull();
});
}
fetchUser = () => {
console.log("`111111");
let url = `/users/get_user_info.json`
let courseId;
let query = this.props.location.pathname;
const type = query.split('/');
if (type[1] == 'classrooms' && type[2]) {
courseId = parseInt(type[2])
}
var datay = {};
if (JSON.stringify(this.state.dataquerys) === "{}") {
datay = {
course_id: isNaN(courseId) ? undefined : courseId,
school: 1
}
} else {
datay = {
course_id: isNaN(courseId) ? undefined : courseId,
school: 1,
chinaoocTimestamp: this.state.dataquerys.chinaoocTimestamp,
websiteName: this.state.dataquerys.websiteName,
chinaoocKey: this.state.dataquerys.chinaoocKey,
}
}
axios.get(url, {
params: datay
}).then((response) => {
fetchUsers = () => {
let url = `/users/get_user_info.json`;
axios.get(url).then((response) => {
if (response && response.data) {
console.log("`111111",response.data);
this.initCommonState(response.data);
this.setState({
tpmLoading: false,
coursedata: {
course_identity: response.data.course_identity >= 0 ? response.data.course_identity : undefined,
course_public: response.data.course_public,
name: response.data.course_name,
userid: response.data.user_id
}
})
}
}).catch((error) => {
console.log(error)
})
};
fetchUsers = (yslurlobject) => {
let url = `/users/get_user_info.json`
let courseId;
let query = this.props.location.pathname;
const type = query.split('/');
if (type[1] == 'classrooms' && type[2]) {
courseId = parseInt(type[2])
// url += `?course_id=${courseId}`
}
var datay = {};
if (JSON.stringify(yslurlobject) === "{}") {
datay = {
course_id: isNaN(courseId) ? undefined : courseId,
school: 1
}
} else {
datay = {
course_id: isNaN(courseId) ? undefined : courseId,
school: 1,
chinaoocTimestamp: yslurlobject.chinaoocTimestamp,
websiteName: yslurlobject.websiteName,
chinaoocKey: yslurlobject.chinaoocKey,
}
}
axios.get(url, {
params:
datay
},
{
// withCredentials: true
}
).then((response) => {
/*
{
"username": "黄井泉",
"login": "Hjqreturn",
"user_id": 12,
"image_url": "avatar/User/12",
"admin": true,
"is_teacher": false,
"tidding_count": 0
}
*/
if (response === undefined) {
return
}
if (response.data) {
this.initCommonState(response.data)
this.setState({
tpmLoading: false,
coursedata: {
course_identity: response.data.course_identity >= 0 ? response.data.course_identity : undefined,
course_public: response.data.course_public,
name: response.data.course_name,
userid: response.data.user_id
},
tpmLoading: false
})
}
}).catch((error) => {
console.log(error)
})
@ -411,12 +177,9 @@ export function TPMIndexHOC(WrappedComponent) {
var arr;
do {
arr = regExp.exec(url);
// console.log(arr); // arr = [完整的字符串, key, 等号或'', value或'']
if (arr) {
var key = arr[1];
var value = arr[3];
// arr[2] === ''时, value = undefined
if (!arr[2])
value = undefined;
@ -581,23 +344,8 @@ export function TPMIndexHOC(WrappedComponent) {
}
render() {
let { Headertop, Footerdown, isRender, AccountProfiletype, AccountPhoneemailtype, current_user } = this.state;
let { Footerdown, isRender, AccountProfiletype, AccountPhoneemailtype, current_user } = this.state;
const common = {
isSuperAdmin: this.isSuperAdmin,
isAdminOrCreator: this.isAdminOrCreator,
isClassManagement: this.isClassManagement,
isCourseAdmin: this.isCourseAdmin,
isAdmin: this.isAdmin,
isAdminOrTeacher: this.isAdminOrTeacher,
isAssistant: this.isAssistant,
isStudent: this.isStudent,
isAdminOrStudent: this.isAdminOrStudent,
isNotMember: this.isNotMember,
isCourseEnd: this.isCourseEnd,
isUserid: this.state.coursedata && this.state.coursedata.userid,
fetchUser: this.fetchUser,
showLoginDialog: this.showLoginDialog,
checkIfLogin: this.checkIfLogin,
@ -619,9 +367,7 @@ export function TPMIndexHOC(WrappedComponent) {
yslslowCheckresultsNo: this.yslslowCheckresultsNo,
MdifHasAnchorJustScorll: this.MdifHasAnchorJustScorll,
scrollToAnchor: this.scrollToAnchor
};
var mypath = this.props && this.props.match && this.props.match.path;
return (
<div className="indexHOC">
{isRender === true ? <LoginDialog
@ -643,7 +389,6 @@ export function TPMIndexHOC(WrappedComponent) {
{...this.state}
{...this.dialogObj}
/> : ""}
<NewHeader {...this.state} {...this.props}></NewHeader>
<Spin spinning={this.state.globalLoading} delay={0} className="globalSpin"
size="large"
@ -652,7 +397,6 @@ export function TPMIndexHOC(WrappedComponent) {
<div className="newContainer newContainers">
<WrappedComponent initCommonState={(user) => this.initCommonState(user)}
{...this.props} {...this.state}
showShixun={this.showShixun} aboutFocus={this.aboutFocus}
{...common}
>
</WrappedComponent>
@ -662,7 +406,6 @@ export function TPMIndexHOC(WrappedComponent) {
{...this.state} {...this.props}
Footerdown={Footerdown}
/>
</div>
);
}