Merge branch 'develop_new' into develop_educoder

# Conflicts:
#	src/modules/tpm/NewHeader.js
This commit is contained in:
caishi 2021-03-23 16:13:36 +08:00
commit 68b1296652
16 changed files with 1031 additions and 65 deletions

View File

@ -20,6 +20,7 @@ li.ant-menu-item{
background-color: #fff;
margin-bottom:18px;
min-height: 130px;
border:1px solid #eee;
.img{
margin-right: 20px;
width: 190px;
@ -61,6 +62,7 @@ li.ant-menu-item{
}
// Tabs
.tabsStyle{
border:1px solid #eee;
.ant-tabs-bar.ant-tabs-top-bar{
padding-left: 35px;
margin-bottom: 0px;

897
src/forge/Head/Header.js Normal file
View File

@ -0,0 +1,897 @@
import React, { Component } from 'react';
import AccountProfile from "../../modules/user/AccountProfile";
import { getImageUrl } from 'educoder'
import axios from 'axios';
import { Modal, Input, message, notification , Dropdown , Menu ,Divider } from 'antd';
import LoginDialog from '../../modules/login/LoginDialog';
import GotoQQgroup from '../../modal/GotoQQgroup'
// import 'antd/lib/modal/style/index.css';
// import 'antd/lib/checkbox/style/index.css';
// import 'antd/lib/radio/style/index.css';
// import 'antd/lib/input/style/index.css';
import '../../modules/tpm/TPMIndex.css';
import logo from '../../modules/tpm/images/logo.png';
import './header.scss';
const $ = window.$
// TODO 这部分脚本从公共脚本中直接调用
const { Search } = Input;
let old_url;
window._header_componentHandler = null;
// 非trustie链接则新开页跳转
const str = ['www.trustie.net','forgeplus.trustie.net','forum.trustie.net','testforgeplus.trustie.net']
class NewHeader extends Component {
constructor(props) {
super(props)
this.state = {
Addcoursestypes: false,
tojoinitemtype: false,
tojoinclasstitle: undefined,
rolearr: ["", ""],
Checkboxteacherchecked: false,
Checkboxstudentchecked: false,
Checkboxteachingchecked: false,
Checkboxteachertype: false,
Checkboxteachingtype: false,
code_notice: false,
checked_notice: false,
RadioGroupvalue: undefined,
submitapplications: false,
isRender: false,
showSearchOpentype: false,
showTrial: false,
setevaluatinghides: false,
occupation: 0,
mydisplay: false,
headtypesonClickbool: false,
headtypess: "/",
settings: null,
goshowqqgtounp: false,
visiblemyss: false,
openSearch:false,
}
}
componentDidMount() {
// this.getAppdata();
this.geturlsdata();
window._header_componentHandler = this;
//下拉框的显示隐藏
var hoverTimeout;
var hoveredPanel;
$(".edu-menu-panel").hover(function () {
if (hoverTimeout) { // 一次只显示一个panel
if (hoveredPanel && hoveredPanel !== this) {
$(hoveredPanel).find(".edu-menu-list").hide()
}
clearTimeout(hoverTimeout);
hoverTimeout = null;
}
hoveredPanel = this;
$(this).find(".edu-menu-list").show();
}, function () {
var that = this;
// 延迟hide
hoverTimeout = setTimeout(function () {
$(that).find(".edu-menu-list").hide();
}, 800)
});
//获取游览器地址
try {
window.sessionStorage.setItem("yslgeturls", JSON.stringify(window.location.href))
} catch (e) {}
}
SearchInput = (open,item)=>{
if(open){
return(
<div
onBlur={() => {
setTimeout(() => {
this.setState({
openSearch:false
})
}, 300)
}}
>
<Search placeholder="实践课程/教学课堂/实践项目/交流问答"
className={`search-input mr20`}
onSearch={(value)=>this.onGlobalSearch(value,item)}
autoFocus={true}
/>
</div>
)
}else{
return <i className="iconfont icon-sousuo font-18 color-white ml30" onClick={() => {
this.setState({openSearch:true})
}} />
}
}
onGlobalSearch=(value,item)=>{
window.location.href=`${item && item.url}?value=` + value;
}
openNotification = (messge) => {
notification.open({
message: "提示",
description:
messge,
});
};
componentWillReceiveProps(newProps, oldProps) {
this.setState({
user: newProps.user
})
if (newProps.Headertop !== undefined) {
old_url = newProps.Headertop.old_url
}
}
getCookie = (key) => {
var arr, reg = RegExp('(^| )' + key + '=([^;]+)(;|$)');
if (arr === document.cookie.match(reg))
return decodeURIComponent(arr[2]);
else
return null;
}
delCookie = (name) => {
var exp = new Date();
exp.setTime(exp.getTime() - 1);
var cval = this.getCookie(name);
if (cval != null) {
document.cookie = name + "=" + cval + ";expires=" + exp.toGMTString();
}
}
onLogout = () => {
const url = `/accounts/logout.json`
this.delCookie("autologin_trustie")
axios.get(url, {
}).then((response) => {
if (response.data.status === 1) {
this.setState({
user: undefined
})
window.location.href = "/login"
message.success('退出成功');
}
});
}
tojoinclass = () => {
let { user } = this.state;
if (user === undefined) {
this.setState({
isRender: true
})
return
}
if (user && user.login === "") {
this.setState({
isRender: true
})
return;
}
if (user && user.profile_completed === false) {
this.setState({
AccountProfiletype: true
})
return;
}
this.setState({
Addcoursestypes: true,
})
}
tojoinitem = () => {
if (this.props.user && this.props.user.email === undefined || this.props.user && this.props.user.email === null || this.props.user && this.props.user.email === "") {
this.openNotification("请先绑定邮箱,谢谢");
return
}
let { user } = this.state;
if (user === undefined) {
this.setState({
isRender: true
})
return
}
if (user && user.login === "") {
this.setState({
isRender: true
})
return;
}
if (user && user.profile_completed === false) {
this.setState({
AccountProfiletype: true
})
return;
}
this.setState({
tojoinitemtype: true
})
}
submitstatevalue = (sum, value, data) => {
this.setState({
Addcoursestypes: false,
tojoinitemtype: false,
tojoinclasstitle: undefined,
rolearr: ["", ""],
Checkboxteacherchecked: false,
Checkboxstudentchecked: false,
Checkboxteachingchecked: false,
Checkboxteachertype: false,
Checkboxteachingtype: false,
code_notice: false,
checked_notice: false,
submitapplicationssum: sum,
submitapplications: true,
submitapplicationsvalue: value,
submitapplicationsvaluedata: data,
RadioGroupvalue: undefined
})
}
onChangeRadioGroup = (e) => {
this.setState({
RadioGroupvalue: e.target.value,
});
}
submitsubmitapplications = () => {
let {
submitapplicationssum,
submitapplicationsvaluedata
} = this.state;
this.setState({
submitapplications: false,
RadioGroupvalue: undefined
})
if (submitapplicationssum === 0) {
if (submitapplicationsvaluedata !== undefined) {
window.location.href = "/courses/" + submitapplicationsvaluedata;
}
} else if (submitapplicationssum === 1) {
if (submitapplicationsvaluedata !== undefined) {
window.location.href = "/projects/" + submitapplicationsvaluedata;
}
}
}
hidesubmitapplications = () => {
this.setState({
Addcoursestypes: false,
tojoinitemtype: false,
tojoinclasstitle: undefined,
rolearr: ["", ""],
Checkboxteacherchecked: false,
Checkboxstudentchecked: false,
Checkboxteachingchecked: false,
Checkboxteachertype: false,
Checkboxteachingtype: false,
code_notice: false,
checked_notice: false,
submitapplications: false,
RadioGroupvalue: undefined
})
}
educoderlogin = () => {
//登录账号
this.setState({
isRender: true
})
}
educoderloginysl = () => {
//退出账号
var url = `/accounts/logout.json`;
axios.get((url)).then((result) => {
if (result !== undefined) {
window.location.href = "/";
}
}).catch((error) => {
console.log(error);
})
}
hideAddcoursestypes = () => {
this.setState({
Addcoursestypes: false
})
};
HideAddcoursestypess = (i) => {
console.log("调用了");
this.setState({
Addcoursestypes: false,
mydisplay: true,
occupation: i,
})
};
ModalCancelsy = () => {
this.setState({
mydisplay: false,
})
};
hidetojoinclass = () => {
this.setState({
tojoinclasstype: false,
tojoinitemtype: false,
tojoinclasstitle: undefined,
rolearr: ["", ""],
Checkboxteacherchecked: false,
Checkboxstudentchecked: false,
Checkboxteachingchecked: false,
Checkboxteachertype: false,
Checkboxteachingtype: false,
code_notice: false,
checked_notice: false,
RadioGroupvalue: undefined
})
}
submittojoinclass = (value) => {
let { tojoinclasstitle, rolearr, RadioGroupvalue } = this.state;
if (tojoinclasstitle === undefined) {
this.setState({
code_notice: true
})
return
}
let newrolearr = rolearr;
if (tojoinclasstitle.length < 6) {
this.setState({
code_notice: true
})
return
}
if (tojoinclasstitle === "" || tojoinclasstitle === undefined) {
this.setState({
code_notice: true
})
return
} else {
this.setState({
code_notice: false
})
}
let pamst = [];
let num = 0;
for (var i = 0; i < newrolearr.length; i++) {
if (newrolearr[i] !== "") {
pamst.push(newrolearr[i])
} else {
num = num + 1
}
}
if (num === 2 && value === 0) {
this.setState({
checked_notice: true
})
return
}
if (value === 1 && RadioGroupvalue === undefined) {
this.setState({
checked_notice: true
})
return
}
if (value === 1) {
let url = "/project_applies.json";
axios.post(url, {
code: tojoinclasstitle,
role: RadioGroupvalue
}
).then((response) => {
if (response.data.status === 1) {
this.submitstatevalue(1, "您输入的邀请码错误")
} else if (response.data.status === 2) {
this.submitstatevalue(1, "您已经是该项目成员", response.data.project)
} else if (response.data.status === 3) {
this.submitstatevalue(1, "请选择一个角色")
} else if (response.data.status === 4) {
this.submitstatevalue(1, "您的申请已提交,请等待项目管理员审批")
} else if (response.data.status === 5) {
this.submitstatevalue(1, "您已经申请加入该项目了,请耐心等待")
} else if (response.data.status === 6) {
this.submitstatevalue(1, "您已成功加入项目", response.data.project)
} else if (response.data.status === 0) {
if (RadioGroupvalue === "reporter") {
this.openNotification("您加入项目成功!");
window.location.href = `/projects/${response.data.project_id}`;
} else {
this.openNotification("您的申请已提交,请等待项目管理员审批!");
}
}
})
}
this.hidetojoinclass()
}
// 关闭
cancelModulationModels = () => {
this.setState({ isRenders: false })
}
inputjoinclassvalue = (e) => {
if (e.target.value.length >= 7) {
this.openNotification("请输入6位项目邀请码!");
return
}
this.setState({
tojoinclasstitle: e.target.value
})
}
showSearchOpen = (e) => {
this.setState({
showSearchOpentype: true
})
}
hideshowSearchOpen = (e) => {
let { setevaluatinghides } = this.state;
if (setevaluatinghides === true) {
this.setState({
showSearchOpentype: false,
setevaluatinghides: false
})
}
}
onKeywordSearchKeyDown = (value) => {
let url = `/search?value=${value}`;
this.props.history.push(url)
}
onKeywordSearchKeyDowns = () => {
this.setState({
setevaluatinghides: false
})
}
setevaluatinghides = () => {
this.setState({
setevaluatinghides: true
})
}
//头部获取是否已经登录了
getUser = (url, type) => {
if (type === "projects") {
if (this.props.user && this.props.user.email === undefined || this.props.user && this.props.user.email === null || this.props.user && this.props.user.email === "") {
this.openNotification("请先绑定邮箱,谢谢");
return
}
}
let { user } = this.state;
if (user === undefined) {
this.setState({
isRender: true
})
return
}
if (user && user.login === "") {
this.setState({
isRender: true
})
return;
}
if (user && user.profile_completed === false) {
this.setState({
AccountProfiletype: true
})
return;
}
if (type === "newshixuns") {
if (this.props && this.props.current_user && this.props.current_user.is_shixun_marker === false) {
this.setgoshowqqgtounp(true);
return;
}
}
if (url !== undefined || url !== "") {
window.location.href = url;
}
}
//修改登录方法
Modifyloginvalue = () => {
this.setState({
isRender: false,
})
}
hideAccountProfile = () => {
this.setState({
AccountProfiletype: false
})
};
headtypesonClick = (url, bool) => {
this.setState({
headtypess: url,
headtypesonClickbool: bool,
})
}
//获取数据为空的时候
gettablogourlnull = () => {
this.setState({
settings: undefined
});
var link = document.createElement('link'),
oldLink = document.getElementById('dynamic-favicon');
link.id = 'dynamic-favicon';
link.rel = 'shortcut icon';
link.href = "/react/build/./favicon.ico";
if (oldLink) {
document.head.removeChild(oldLink);
}
document.head.appendChild(link);
};
//获取数据的时候
gettablogourldata = (response) => {
document.title = response.data.setting.name;
var link = document.createElement('link'),
oldLink = document.getElementById('dynamic-favicon');
link.id = 'dynamic-favicon';
link.rel = 'shortcut icon';
link.href = '/' + response.data.setting.tab_logo_url;
if (oldLink) {
document.head.removeChild(oldLink);
}
document.head.appendChild(link);
}
handleVisibleChanges = (boll) => {
this.setState({
visiblemyss: boll,
})
}
getAppdata = () => {
try {
var chromesettingArray = JSON.parse(localStorage.getItem('chromesetting'));
var chromesettingresponseArray = JSON.parse(localStorage.getItem('chromesettingresponse'));
this.setState({
settings: chromesettingArray
});
if (chromesettingArray.tab_logo_url) {
this.gettablogourldata(chromesettingresponseArray);
} else {
this.gettablogourlnull();
}
} catch (e) {
this.geturlsdata();
}
};
geturlsdata = () => {
let url = "/setting.json";
axios.get(url).then((response) => {
if (response && response.data) {
this.setState({ settings: response.data.setting });
// localStorage.setItem('chromesetting', JSON.stringify(response.data.setting));
// localStorage.setItem('chromesettingresponse', JSON.stringify(response));
try {
if (response.data.setting.tab_logo_url) {
this.gettablogourldata(response);
} else {
this.gettablogourlnull();
}
} catch (e) {
this.gettablogourlnull();
}
} else {
this.gettablogourlnull();
}
}).catch((error) => {
this.gettablogourlnull();
});
}
matchpaths = (url) => {
const { match } = this.props;
if(url){
if (match.path.indexOf(url) > -1) {
return true
}else {
return false
}
}
}
// 处理弹框
setgoshowqqgtounp = (bool) => {
this.setState({
goshowqqgtounp: bool
})
}
addMenu=(list)=>{
return(
list && list.length >0 &&
<div className="dropdownFlex">
<Menu>
{
list.map((item,key)=>{
return(
(item.name !=="加入课堂" && item.name !=="加入开发项目") && <Menu.Item><a href={item.url}>{item.name}</a></Menu.Item>
)
})
}
</Menu>
</div>
)
}
render() {
const { match } = this.props;
let { Addcoursestypes,
tojoinitemtype,
tojoinclasstitle,
code_notice,
checked_notice,
AccountProfiletype,
submitapplications,
submitapplicationsvalue,
user,
isRender,
showSearchOpentype,
headtypesonClickbool,
headtypess,
settings,
goshowqqgtounp,
openSearch,
} = this.state;
/*用户名称 用户头像url*/
let activeIndex = false;
let activeForums = false;
let activeShixuns = false;
let activePaths = false;
let coursestype = false;
let activePackages = false;
let activeMoopCases = false;
let activeCompetitions = false;
if (match.path === '/forums') {
activeForums = true;
} else if (match.path.startsWith('/shixuns')) {
activeShixuns = true;
} else if (match.path.startsWith('/paths')) {
activePaths = true;
} else if (match.path.startsWith('/courses')) {
coursestype = true;
} else if (match.path.startsWith('/crowdsourcing')) {
activePackages = true;
} else if (match.path.startsWith('/moop_cases')) {
activeMoopCases = true;
} else if (match.path.startsWith('/competitions')) {
activeCompetitions = true;
} else {
activeIndex = true;
}
let headtypes = '/';
if (settings) {
if (settings.navbar) {
if (settings.navbar.length > 0) {
if (match.path === '/') {
if (headtypesonClickbool === false) {
headtypes = undefined;
} else {
headtypes = headtypess;
}
} else {
for (var i = 0; i < settings.navbar.length; i++) {
if (match.path === settings.navbar[i].link) {
headtypes = settings.navbar[i].link;
break;
}
}
}
}
}
}
let shixuntype = false;
let pathstype = false;
let coursestypes = false;
if (this.props && this.props.mygetHelmetapi != null) {
let shixun = "/shixuns";
let paths = "/paths";
let courses = "/courses";
this.props.mygetHelmetapi.navbar.map((item, key) => {
var reg = RegExp(item.link);
if (shixun.match(reg)) {
if (item.hidden === true) {
shixuntype = true
}
}
if (paths.match(reg)) {
if (item.hidden === true) {
pathstype = true
}
}
if (courses.match(reg)) {
if (item.hidden === true) {
coursestypes = true
}
}
})
}
let search_url = settings && settings.common && settings.common.length> 0 && settings.common.filter(item=>item.name==="搜索");
let notice_url = settings && settings.common && settings.common.length> 0 && settings.common.filter(item=>item.name==="通知");
return (
<div className="newHeaders" id="nHeader">
<div className="headerContent">
{isRender === true ?
<LoginDialog
{...this.props}
{...this.state}
Modifyloginvalue={() => this.Modifyloginvalue()}
/> : ""}
{AccountProfiletype === true ?
<AccountProfile
hideAccountProfile={() => this.hideAccountProfile()}
{...this.props}
{...this.state}
/> : ""}
{
goshowqqgtounp === true ?
<GotoQQgroup {...this.state} {...this.props} setgoshowqqgtounp={(bool) => this.setgoshowqqgtounp(bool)}></GotoQQgroup>
:""
}
<a href={settings && settings.new_course.default_url} className={"fl mr30"} style={{minWidth:"45px"}}>
{
settings && settings.nav_logo_url ?
<img alt="可控开源社区" className="logoimg" style={{ heigth: "40px" }} src={getImageUrl(settings.nav_logo_url)}></img>
:
<img alt="可控开源社区" className="logoimg" style={{ heigth: "40px" }} src={logo}></img>
}
</a>
<div className="head-nav pr" id={"head-navpre1"}>
{
settings && settings.navbar && settings.navbar.length > 0 ?
<ul id="header-nav">
{
settings.navbar && settings.navbar.map((item, key) => {
var new_link = item.link;
var user_login = this.props.user && this.props.user.login;
var is_hidden = item.hidden
if (new_link && (new_link.indexOf("courses") > -1 || new_link.indexOf("contests") > -1)) {
if (user_login) {
if (new_link.indexOf("courses") > -1) {
new_link = new_link.replace(/courses/g, "users/" + user_login + "/courses")
} else if (new_link.indexOf("contests") > -1) {
new_link = new_link.replace(/contests/g, "users/" + user_login + "/contests")
}
} else {
is_hidden = true
}
}
if (user_login && (new_link && new_link.indexOf("homes") > -1)) {
new_link = new_link.replace(/homes/g, "users/" + user_login + "/user_activities")
}
var waiLian = (new_link && str.filter(item=>new_link.indexOf(item)>-1) );
var wl = waiLian && waiLian.length>0;
return (
<li key={key} onClick={() => this.headtypesonClick(item.link, true)} className={`${this.matchpaths(item.link) === true ? 'pr active' : 'pr'}`} style={!is_hidden ? { display: 'flex' } : { display: 'none' }}>
<a href={new_link} target={wl ? "_self":"_blank"}>{item.name}</a>
</li>
)
})
}
</ul>
: ""
}
</div>
<div className="head-right">
{search_url && search_url.length>0 ? this.SearchInput(openSearch,search_url[0]):""}
{
(coursestypes === true && this.props.user.main_site === false && (settings && !settings.add && (settings.add && settings.add.length === 0))) ? "" :
<Dropdown overlay={this.addMenu(settings && settings.add)} placement="bottomRight">
<i className="iconfont icon-tianjiafangda color-white ml30"></i>
</Dropdown>
}
{this.props.user && this.props.user.login && (notice_url && notice_url.length>0) ?
<div className="ml30 edu-menu-panel">
{user && user.login &&
<a href={`${notice_url[0].url}`} style={{ position: 'relative' }}>
<i className="iconfont icon-xiaoxilingdang color-white"></i>
<span className="newslight" style={{ display: this.props.Headertop === undefined ? "none" : this.props.Headertop.new_message === true ? "block" : "none" }}>
</span>
</a>
}
</div>:""
}
<Modal
keyboard={false}
title="提示"
visible={submitapplications}
closable={false}
footer={null}
>
<div className="task_popup_con ml30">
<div className="mr15">
<ul>
<div className="task-popup-content">
<p className="task-popup-text-center font-16">
{submitapplicationsvalue}
</p>
</div>
<li className="clearfix mt10 edu-txt-center">
<a className="task-btn mr10"
onClick={this.hidesubmitapplications}>取消</a>
<a
className="task-btn task-btn-orange ml20"
onClick={this.submitsubmitapplications}>确定</a>
</li>
</ul>
</div>
</div>
</Modal>
</div>
{user === undefined ?
<span className="font-15">
<a onClick={() => this.educoderlogin()} className="mr5 color-white">登录</a>
{
settings && settings.new_course && settings.new_course.register_url &&
<span><em className="vertical-line"></em><a className="ml5 color-white" href={`${settings.new_course.register_url}`} target="_blank"></a></span>
}
</span>
: user.login === "" ?
<span className="font-15">
<a onClick={() => this.educoderlogin()} className="mr5 color-white">登录</a>
{
settings && settings.new_course && settings.new_course.register_url &&
<span><em className="vertical-line"></em><a className="color-white ml5" href={`${settings.new_course.register_url}`} target="_blank"></a></span>
}
</span>
:
<div className="ml30 edu-menu-panel" style={{ height: "70px", lineHeight: "70px" }}>
<a href={`/users/${this.props.current_user === undefined ? "" : this.props.current_user.login}/courses`}>
<img alt="头像" className="radius" height="34" id="nh_user_logo" name="avatar_image"
src={getImageUrl(`images/` + user.image_url)} width="34">
</img>
</a>
<ul className="edu-menu-list" style={{ top: '60px', textAlign: 'center' }}>
<li className="bor-bottom-greyE" style={{cursor:"default",background:"#fff"}}>{this.props.current_user.username}</li>
{
settings && settings.personal && settings.personal.length > 0 && settings.personal.map((item,key)=>{
return(
<li key={key}><a href={item.url} target="_blank">{item.name}</a></li>
)
})
}
<li className="bor-top-greyE">
<a onClick={() => this.educoderloginysl()}>退出</a>
</li>
</ul>
</div>
}
</div>
</div>
);
}
}
export default NewHeader;

View File

@ -0,0 +1,10 @@
.dropdownFlex{
display:flex;
padding:5px;
background:#fff;
border-radius: 3px;
.ant-menu-vertical > .ant-menu-item{
border:none
}
}

View File

@ -48,7 +48,7 @@ export default (props)=>{
</Short>
<Long>
<Gap>
<WhiteBack>
<WhiteBack style={{border:'1px solid #eee'}}>
<Switch>
<Route
path="/organize/:OIdentifier/group/:groupId/setting/project"

View File

@ -139,7 +139,7 @@ export default Form.create()(
}
return (
<Spin spinning={isSpin}>
<WhiteBack className="mb30">
<WhiteBack className="mb30" style={{border:"1px solid #eee"}}>
<Banner>{groupId ? "基本设置" : "新建团队"}</Banner>
<Div>
<Form>

View File

@ -48,6 +48,7 @@
max-width: 860px;
width: 72%;
margin-bottom: 30px;
border:1px solid #eee;
.head{
padding:16px 32px;
border-bottom: 1px solid #eee;
@ -109,6 +110,9 @@
padding-left: 20px;
box-sizing: border-box;
margin-bottom: 30px;
& > div{
border:1px solid #eee;
}
}
.box{
background:rgba(255,255,255,1);
@ -273,6 +277,9 @@
display: flex;
align-items: flex-start;
.g-sub-left{
&>div{
border:1px solid #eee;
}
background-color: #fff;
.g-desc{
padding:18px 20px;

View File

@ -55,6 +55,7 @@ export default (( props )=>{
</Short>
<Long>
<Gap >
<div style={{border:"1px solid #eee"}}>
<Switch>
<Route
path="/organize/:OIdentifier/setting/hooks"
@ -81,6 +82,7 @@ export default (( props )=>{
)}
></Route>
</Switch>
</div>
</Gap>
</Long>
</Box>

View File

@ -5,7 +5,7 @@ import GroupItems from './TeamGroupItems';
const limit = 14;
function TeamGroup({organizeDetail,history}){
return(
<div style={{background:"#fff",marginBottom:"30px"}}>
<div style={{background:"#fff",marginBottom:"30px",border:'1px solid #eee'}}>
<Banner>组织团队</Banner>
<GroupItems limit={limit} organizeDetail={organizeDetail} count={7} history={history}/>
</div>

View File

@ -33,7 +33,7 @@ function TeamMember({organizeDetail,current_user}){
}
return(
<WhiteBack style={{marginBottom:"30px"}}>
<WhiteBack style={{marginBottom:"30px",border:'1px solid #eee'}}>
<Banner>组织成员</Banner>
<Spin spinning={isSpin}>
<div style={{minHeight:"400px"}}>

View File

@ -31,12 +31,20 @@ $flex:flex;
display: $flex;
align-items: flex-start;
padding:20px 25px;
background-color:rgba(250,250,250,1)
}
& > div img{
background-color:rgba(250,250,250,1);
.imgBox{
width: 190px;
height: 90px;
margin-right: 20px
display: flex;
align-items: center;
justify-content: center;
margin-right: 20px;
background-color: #fff;
img{
max-width: 90%;
max-height: 90%;
}
}
}
.item-news{
display: $flex;

View File

@ -4,7 +4,7 @@ import { getImageUrl } from 'educoder';
function TeamItem({item,history}){
return(
<div onClick={()=>{history.push(`/organize/${item.name}`)}} style={{cursor:"pointer"}}>
<img alt="" src={getImageUrl(`images/${item.avatar_url}`)}/>
<div className="imgBox"><img alt="" src={getImageUrl(`images/${item.avatar_url}`)}/></div>
<div style={{flex:'1'}}>
<span className="mb5 font-18 color-grey-3 task-hide">{item.name}</span>
<div className="task-hide-2">

View File

@ -22,6 +22,7 @@
width:74%;
background: #fff;
padding:0px !important;
border:1px solid #eee;
}
.text-center{text-align: center;}

View File

@ -1,5 +1,4 @@
import React, { Component } from 'react';
import { Link } from "react-router-dom";
import AccountProfile from "../user/AccountProfile";
import { getImageUrl } from 'educoder'
import axios from 'axios';
@ -7,10 +6,10 @@ import { Modal, Input, message, notification } from 'antd';
import LoginDialog from '../login/LoginDialog';
import GotoQQgroup from '../../modal/GotoQQgroup'
import 'antd/lib/modal/style/index.css';
import 'antd/lib/checkbox/style/index.css';
import 'antd/lib/radio/style/index.css';
import 'antd/lib/input/style/index.css';
// import 'antd/lib/modal/style/index.css';
// import 'antd/lib/checkbox/style/index.css';
// import 'antd/lib/radio/style/index.css';
// import 'antd/lib/input/style/index.css';
import './TPMIndex.css';
import logo from './images/logo.png';
@ -47,9 +46,10 @@ class NewHeader extends Component {
mydisplay: false,
headtypesonClickbool: false,
headtypess: "/",
mygetHelmetapi2: null,
settings: null,
goshowqqgtounp: false,
visiblemyss: false,
openSearch:false
}
}
componentDidMount() {
@ -84,6 +84,36 @@ class NewHeader extends Component {
} catch (e) {}
}
SearchInput = (open,url)=>{
if(open){
return(
<div
onBlur={() => {
setTimeout(() => {
this.setState({
openSearch:false
})
}, 300)
}}
>
<Search placeholder="实践课程/教学课堂/实践项目/交流问答"
className={`search-input mr20`}
onSearch={(value)=>this.onGlobalSearch(value,url)}
autoFocus={true}
/>
</div>
)
}else{
return <i className="iconfont icon-sousuo font-18 color-white ml30" onClick={() => {
this.setState({openSearch:true})
}} />
}
}
onGlobalSearch=(value,url)=>{
this.props.history.push(`${url}/search?value=` + value);
}
openNotification = (messge) => {
notification.open({
message: "提示",
@ -92,6 +122,8 @@ class NewHeader extends Component {
});
};
componentWillReceiveProps(newProps, oldProps) {
this.setState({
user: newProps.user
@ -99,7 +131,6 @@ class NewHeader extends Component {
if (newProps.Headertop !== undefined) {
old_url = newProps.Headertop.old_url
}
}
getCookie = (key) => {
var arr, reg = RegExp('(^| )' + key + '=([^;]+)(;|$)');
@ -497,7 +528,7 @@ class NewHeader extends Component {
//获取数据为空的时候
gettablogourlnull = () => {
this.setState({
mygetHelmetapi2: undefined
settings: undefined
});
var link = document.createElement('link'),
oldLink = document.getElementById('dynamic-favicon');
@ -535,7 +566,7 @@ class NewHeader extends Component {
var chromesettingArray = JSON.parse(localStorage.getItem('chromesetting'));
var chromesettingresponseArray = JSON.parse(localStorage.getItem('chromesettingresponse'));
this.setState({
mygetHelmetapi2: chromesettingArray
settings: chromesettingArray
});
if (chromesettingArray.tab_logo_url) {
this.gettablogourldata(chromesettingresponseArray);
@ -551,7 +582,7 @@ class NewHeader extends Component {
let url = "/setting.json";
axios.get(url).then((response) => {
if (response && response.data) {
this.setState({ mygetHelmetapi2: response.data.setting });
this.setState({ settings: response.data.setting });
// localStorage.setItem('chromesetting', JSON.stringify(response.data.setting));
// localStorage.setItem('chromesettingresponse', JSON.stringify(response));
try {
@ -574,11 +605,7 @@ class NewHeader extends Component {
matchpaths = (url) => {
const { match } = this.props;
if(url){
if (url.indexOf('forums') > -1 && match.path.indexOf('forums') > -1) {
return true
} else if (url.indexOf('projects') > -1 && match.path.indexOf('projects') > -1) {
return true
} else if (url.indexOf('users') > -1 && match.path.indexOf('users') > -1) {
if (match.path.indexOf(url) > -1) {
return true
}else {
return false
@ -609,8 +636,9 @@ class NewHeader extends Component {
showSearchOpentype,
headtypesonClickbool,
headtypess,
mygetHelmetapi2,
settings,
goshowqqgtounp,
openSearch
} = this.state;
/*用户名称 用户头像url*/
let activeIndex = false;
@ -641,9 +669,9 @@ class NewHeader extends Component {
}
let headtypes = '/';
if (mygetHelmetapi2) {
if (mygetHelmetapi2.navbar) {
if (mygetHelmetapi2.navbar.length > 0) {
if (settings) {
if (settings.navbar) {
if (settings.navbar.length > 0) {
if (match.path === '/') {
if (headtypesonClickbool === false) {
headtypes = undefined;
@ -651,9 +679,9 @@ class NewHeader extends Component {
headtypes = headtypess;
}
} else {
for (var i = 0; i < mygetHelmetapi2.navbar.length; i++) {
if (match.path === mygetHelmetapi2.navbar[i].link) {
headtypes = mygetHelmetapi2.navbar[i].link;
for (var i = 0; i < settings.navbar.length; i++) {
if (match.path === settings.navbar[i].link) {
headtypes = settings.navbar[i].link;
break;
}
}
@ -708,20 +736,20 @@ class NewHeader extends Component {
<GotoQQgroup {...this.state} {...this.props} setgoshowqqgtounp={(bool) => this.setgoshowqqgtounp(bool)}></GotoQQgroup>
:""
}
<a href={mygetHelmetapi2 && mygetHelmetapi2.new_course.default_url} className={"fl mr30"} style={{minWidth:"45px"}}>
<a href={settings && settings.new_course.default_url} className={"fl mr30"} style={{minWidth:"45px"}}>
{
mygetHelmetapi2 && mygetHelmetapi2.nav_logo_url ?
<img alt="可控开源社区" className="logoimg" style={{ heigth: "40px" }} src={getImageUrl(mygetHelmetapi2.nav_logo_url)}></img>
settings && settings.nav_logo_url ?
<img alt="可控开源社区" className="logoimg" style={{ heigth: "40px" }} src={getImageUrl(settings.nav_logo_url)}></img>
:
<img alt="可控开源社区" className="logoimg" style={{ heigth: "40px" }} src={logo}></img>
}
</a>
<div className="head-nav pr" id={"head-navpre1"}>
{
mygetHelmetapi2 && mygetHelmetapi2.navbar && mygetHelmetapi2.navbar.length > 0 ?
settings && settings.navbar && settings.navbar.length > 0 ?
<ul id="header-nav">
{
mygetHelmetapi2.navbar && mygetHelmetapi2.navbar.map((item, key) => {
settings.navbar && settings.navbar.map((item, key) => {
var new_link = item.link;
var user_login = this.props.user && this.props.user.login;
var is_hidden = item.hidden
@ -754,32 +782,37 @@ class NewHeader extends Component {
}
</div>
<div className="head-right">
{settings && settings.search_url ? this.SearchInput(openSearch,settings.search_url):""}
{this.props.user && this.props.user.login &&
<div className="edu-menu-panel">
<div className="edu-menu-panel ml30">
<i className="iconfont icon-tianjiafangda color-white"></i>
<div className="edu-menu-list" style={{ top: '48px' }}>
<div className="overPart"></div>
{
coursestypes === true && this.props.user && this.props.user.main_site === false ? "" :
(coursestypes === true && this.props.user.main_site === false && (settings && !settings.add && (settings.add && settings.add.length === 0))) ? "" :
<ul className="edu-txt-center">
<li><Link to={"/projects/mirror/new"}>新建镜像项目</Link></li>
<li><Link to={"/projects/deposit/new"}>新建托管项目</Link></li>
<li><Link to={"/organize/new"}>新建组织</Link></li>
{
settings && settings.add && settings.add.map((item,key)=>{
return(
<li><a href={item.url}>{item.name}</a></li>
)
})
}
</ul>
}
</div>
</div>
}
{this.props.user && this.props.user.login &&
{this.props.user && this.props.user.login && ( settings && settings.notice_url) ?
<div className="ml30 edu-menu-panel">
{user && user.login &&
<a href={`${mygetHelmetapi2 && mygetHelmetapi2.new_course && mygetHelmetapi2.new_course.tiding_url}`} style={{ position: 'relative' }} target="_blank">
<a href={`${settings && settings.notice_url}`} style={{ position: 'relative' }}>
<i className="iconfont icon-xiaoxilingdang color-white"></i>
<span className="newslight" style={{ display: this.props.Headertop === undefined ? "none" : this.props.Headertop.new_message === true ? "block" : "none" }}>
</span>
</a>
}
</div>
</div>:""
}
<Modal
keyboard={false}
@ -812,16 +845,16 @@ class NewHeader extends Component {
<span className="font-15">
<a onClick={() => this.educoderlogin()} className="mr5 color-white">登录</a>
{
mygetHelmetapi2 && mygetHelmetapi2.new_course && mygetHelmetapi2.new_course.register_url &&
<span><em className="vertical-line"></em><a className="ml5 color-white" href={`${mygetHelmetapi2.new_course.register_url}`} target="_blank"></a></span>
settings && settings.new_course && settings.new_course.register_url &&
<span><em className="vertical-line"></em><a className="ml5 color-white" href={`${settings.new_course.register_url}`} target="_blank"></a></span>
}
</span>
: user.login === "" ?
<span className="font-15">
<a onClick={() => this.educoderlogin()} className="mr5 color-white">登录</a>
{
mygetHelmetapi2 && mygetHelmetapi2.new_course && mygetHelmetapi2.new_course.register_url &&
<span><em className="vertical-line"></em><a className="color-white ml5" href={`${mygetHelmetapi2.new_course.register_url}`} target="_blank"></a></span>
settings && settings.new_course && settings.new_course.register_url &&
<span><em className="vertical-line"></em><a className="color-white ml5" href={`${settings.new_course.register_url}`} target="_blank"></a></span>
}
</span>
:
@ -833,16 +866,12 @@ class NewHeader extends Component {
</a>
<ul className="edu-menu-list" style={{ top: '60px', textAlign: 'center' }}>
<li className="bor-bottom-greyE" style={{cursor:"default",background:"#fff"}}>{this.props.current_user.username}</li>
<li>
<Link to={`/users/${this.props.current_user.login}`}>个人中心</Link>
</li>
{
mygetHelmetapi2 && mygetHelmetapi2.new_course && mygetHelmetapi2.new_course.my_courses &&
<li><a href={`${mygetHelmetapi2.new_course.my_courses}`} target="_blank">我的课程</a></li>
}
{
mygetHelmetapi2 && mygetHelmetapi2.new_course && mygetHelmetapi2.new_course.my_organ &&
<li><a href={`/users/${this.props.current_user.login}/organizes`} target="_blank">我的组织</a></li>
settings && settings.personal && settings.personal.length > 0 && settings.personal.map((item,key)=>{
return(
<li key={key}><a href={item.url} target="_blank">{item.name}</a></li>
)
})
}
<li className="bor-top-greyE">
<a onClick={() => this.educoderloginysl()}>退出</a>

View File

@ -28,9 +28,19 @@ body>.-task-title {
width: 100%;
height:70px;
min-width: 1200px;
z-index: 10000;
z-index: 1000;
background:#242424;
position: fixed;
box-shadow: 0px 0px 14px rgb(0 0 0 / 10%);
}
.search-input {
width: 300px;
background: #373e3f !important;
border: 1px solid #373e3f !important;
}
.search-input .ant-input {
background: #373e3f !important;
color: #fff;
}
.headerContent{
padding:0px 25px;

View File

@ -1,5 +1,5 @@
import React from 'react';
import NewHeader from './NewHeader'
import NewHeader from '../../forge/Head/Header'
import NewFooter from './NewFooter'
import { downloadFile } from 'educoder'
import axios from 'axios';