This commit is contained in:
龚云瀚 2023-09-17 10:56:51 +08:00
parent 9b547bc1e6
commit 33be5f5a97
9 changed files with 637 additions and 61 deletions

View File

@ -8,7 +8,7 @@ import { CNotificationHOC } from "../../modules/courses/common/CNotificationHOC"
import { TPMIndexHOC } from "../../modules/tpm/TPMIndexHOC";
import Loadable from "react-loadable";
import Loading from "../../Loading";
import { Box , Gap , LongWidth } from '../Component/layout';
import { Box, Gap, LongWidth } from '../Component/layout';
import { getImageUrl } from 'educoder';
import { Link } from 'react-router-dom';
import Avatar from '../users/Avatar/Index';
@ -16,6 +16,8 @@ import Avatar from '../users/Avatar/Index';
import './Index.scss';
import { useEffect } from "react";
import axios from "axios";
const MyNoticeIndex = Loadable({
loader: () => import("./notice/myNotice/Index"),
loading: Loading,
@ -70,51 +72,57 @@ const Mysite = Loadable({
loader: () => import("./website/mySiteList"),
loading: Loading,
});
const Createsite = Loadable({
loader: () => import("./website/new"),
loading: Loading,
});
function Index(props){
const { current_user,mygetHelmetapi , checkIfLogin } = props;
function Index(props) {
const { current_user, mygetHelmetapi, checkIfLogin } = props;
const { pathname } = props.location;
const notice_url = mygetHelmetapi && mygetHelmetapi.common && mygetHelmetapi.common.notice;
const [ avatarVisible , setAvatarVisible ] = useState(false);
const [avatarVisible, setAvatarVisible] = useState(false);
const [active, setActive] = useState(1);
console.log('active', active);
useEffect(()=>{
if(checkIfLogin() === false){
useEffect(() => {
if (checkIfLogin() === false) {
props.history.push('/login');
}
},[])
}, [])
useEffect(()=>{
useEffect(() => {
console.log('pathname', pathname, ["/settings/profile"].indexOf(pathname));
if(["/settings/profile"].indexOf(pathname) !== -1){
if (["/settings/profile"].indexOf(pathname) !== -1) {
setActive(1);
}else if(["/settings/emails", "/settings/phone", "/settings/password", "/settings/cancel"].indexOf(pathname) !== -1){
} else if (["/settings/emails", "/settings/phone", "/settings/password", "/settings/cancel"].indexOf(pathname) !== -1) {
setActive(2);
}else if(["/settings/notice/config"].indexOf(pathname) !== -1){
} else if (["/settings/notice/config"].indexOf(pathname) !== -1) {
setActive(4);
}else if(["/settings/notice"].indexOf(pathname) !== -1){
} else if (["/settings/notice"].indexOf(pathname) !== -1) {
setActive(3);
}else if(["/settings/SSH"].indexOf(pathname) !== -1){
} else if (["/settings/SSH"].indexOf(pathname) !== -1) {
setActive(5);
}else if(["/settings/CLA"].indexOf(pathname) !== -1){
} else if (["/settings/CLA"].indexOf(pathname) !== -1) {
setActive(6);
}else if(["/settings/mybot"].indexOf(pathname) !== -1){
} else if (["/settings/mybot"].indexOf(pathname) !== -1) {
setActive(7);
}else if(["/settings/installbot"].indexOf(pathname) !== -1){
} else if (["/settings/installbot"].indexOf(pathname) !== -1) {
setActive(8);
}else if(["/settings/mysite"].indexOf(pathname) !== -1){
} else if (["/settings/mysite"].indexOf(pathname) !== -1) {
setActive(9);
}
}, [pathname])
function onCancelAvatar(){
function onCancelAvatar() {
setAvatarVisible(false);
const { resetUserInfo } = props;
resetUserInfo && resetUserInfo();
}
return(
return (
<div className="newMain clearfix whiteBack">
{
avatarVisible &&
@ -129,34 +137,34 @@ function Index(props){
<div className="shortW">
<div className="userDetail">
<div className="userHeadPhoto">
<img src={getImageUrl(`/${current_user && current_user.image_url}`)} alt=""/>
<span className="userUpdateBox"onClick={()=>setAvatarVisible(true)}>修改头像</span>
<img src={getImageUrl(`/${current_user && current_user.image_url}`)} alt="" />
<span className="userUpdateBox" onClick={() => setAvatarVisible(true)}>修改头像</span>
</div>
<span>{current_user && current_user.username}</span>
</div>
<ul className="securityUl ul-border-buttom">
<li>个人信息</li>
<li className={active === 1 ?"active":""}><Link to={`/settings/profile`}><i className="iconfont icon-gerenziliao mr5 font-14"></i><span className="text-shodow-bold">基本资料</span></Link></li>
<li className={active === 2 ?"active":""}><Link to={`/settings/phone`}><i className="iconfont icon-xuanzhonganquanshezhi_icon mr5 font-14"></i><span className="text-shodow-bold">账号管理</span></Link></li>
<li className={active === 1 ? "active" : ""}><Link to={`/settings/profile`}><i className="iconfont icon-gerenziliao mr5 font-14"></i><span className="text-shodow-bold">基本资料</span></Link></li>
<li className={active === 2 ? "active" : ""}><Link to={`/settings/phone`}><i className="iconfont icon-xuanzhonganquanshezhi_icon mr5 font-14"></i><span className="text-shodow-bold">账号管理</span></Link></li>
</ul>
{notice_url && <ul className="securityUl ul-border-buttom">
<li>消息通知</li>
<li className={active === 3 ?"active":""}><Link to={"/settings/notice"}><i className="iconfont icon-wodetongzhi font-14"></i><span className="text-shodow-bold">我的通知</span></Link></li>
<li className={active === 4 ?"active":""}><Link to={'/settings/notice/config'}><i className="iconfont icon-tongzhiguanli font-14"></i><span className="text-shodow-bold">通知管理</span></Link></li>
<li className={active === 3 ? "active" : ""}><Link to={"/settings/notice"}><i className="iconfont icon-wodetongzhi font-14"></i><span className="text-shodow-bold">我的通知</span></Link></li>
<li className={active === 4 ? "active" : ""}><Link to={'/settings/notice/config'}><i className="iconfont icon-tongzhiguanli font-14"></i><span className="text-shodow-bold">通知管理</span></Link></li>
</ul>}
<ul className="securityUl ul-border-buttom">
<li>安全设置</li>
<li className={active === 5 ?"active":""}><Link to={`/settings/SSH`}><i className="iconfont icon-xuanzhongssh_icon mr5 font-14"></i><span className="text-shodow-bold">SSH密钥</span></Link></li>
<li className={active === 6 ?"active":""}><Link to={`/settings/CLA`}><i className="iconfont icon-a-zu2044 mr5 font-13"></i><span className="text-shodow-bold">我的CLA</span></Link></li>
<li className={active === 5 ? "active" : ""}><Link to={`/settings/SSH`}><i className="iconfont icon-xuanzhongssh_icon mr5 font-14"></i><span className="text-shodow-bold">SSH密钥</span></Link></li>
<li className={active === 6 ? "active" : ""}><Link to={`/settings/CLA`}><i className="iconfont icon-a-zu2044 mr5 font-13"></i><span className="text-shodow-bold">我的CLA</span></Link></li>
</ul>
<ul className="securityUl ul-border-buttom">
<li>Bot开发</li>
<li className={active === 7 ?"active":""}><Link to={`/settings/mybot`}><i className="iconfont icon-kaifabot mr5 font-18"></i><span className="text-shodow-bold">我的Bot</span></Link></li>
<li className={active === 8 ?"active":""}><Link to={`/settings/installbot`}><i className="iconfont icon-BOTpeizhi mr5 font-17"></i><span className="text-shodow-bold">Bot安装</span></Link></li>
<li className={active === 7 ? "active" : ""}><Link to={`/settings/mybot`}><i className="iconfont icon-kaifabot mr5 font-18"></i><span className="text-shodow-bold">我的Bot</span></Link></li>
<li className={active === 8 ? "active" : ""}><Link to={`/settings/installbot`}><i className="iconfont icon-BOTpeizhi mr5 font-17"></i><span className="text-shodow-bold">Bot安装</span></Link></li>
</ul>
<ul className="securityUl">
<li>个人建站</li>
<li className={active === 9 ?"active":""}><Link to={`/settings/mysite`}><i className="iconfont icon-liebiaoicon mr5 font-15"></i><span className="text-shodow-bold">我的站点</span></Link></li>
<li className={active === 9 ? "active" : ""}><Link to={`/settings/mysite`} onClick={window.scrollTo(0, 0)} ><i className="iconfont icon-liebiaoicon mr5 font-15"></i><span className="text-shodow-bold">我的站点</span></Link></li>
</ul>
</div>
<LongWidth>
@ -165,108 +173,117 @@ function Index(props){
<Route
path="/settings/notice/config"
render={(p) => (
<NoticeManager {...props} {...p}/>
<NoticeManager {...props} {...p} />
)}
></Route>
<Route
path="/settings/notice/privateLetter"
render={(p)=>(
<PrivateLetter{...props} {...p}/>
render={(p) => (
<PrivateLetter{...props} {...p} />
)}
></Route>
<Route
path="/settings/CLA"
render={(p) => (
<CLAList {...props} {...p}/>
<CLAList {...props} {...p} />
)}
></Route>
<Route
path="/settings/notice"
render={(p) => (
<MyNoticeIndex {...props} {...p}/>
<MyNoticeIndex {...props} {...p} />
)}
></Route>
<Route
path="/settings/SSH/new"
render={(p) => (
<SSHNew {...props} {...p}/>
<SSHNew {...props} {...p} />
)}
></Route>
<Route
path="/settings/profile"
render={(p) => (
<Profile {...props} {...p}/>
<Profile {...props} {...p} />
)}
></Route>
<Route
path="/settings/emails"
render={(p) => (
<Password {...props} {...p}/>
<Password {...props} {...p} />
)}
></Route>
<Route
path="/settings/password"
render={(p) => (
<Password {...props} {...p}/>
<Password {...props} {...p} />
)}
></Route>
<Route
path="/settings/cancel"
render={(p) => (
<Password {...props} {...p}/>
<Password {...props} {...p} />
)}
></Route>
<Route
path="/settings/phone"
render={(p) => (
<Password {...props} {...p}/>
<Password {...props} {...p} />
)}
></Route>
<Route
path="/settings/verification"
render={(p) => (
<Password {...props} {...p}/>
<Password {...props} {...p} />
)}
></Route>
<Route
path="/settings/SSH"
render={(p) => (
<SSHIndex {...props} {...p}/>
<SSHIndex {...props} {...p} />
)}
></Route>
{/* 创建一个新的bot */}
<Route
path="/settings/mybot/new"
render={(p) => (
<CreateBot {...props} {...p}/>
<CreateBot {...props} {...p} />
)}
></Route>
{/* 开发bot */}
<Route
path="/settings/mybot"
render={(p) => (
<ExploitBot {...props} {...p}/>
<ExploitBot {...props} {...p} />
)}
></Route>
{/* bot配置页面 */}
<Route
path="/settings/installbot/:id"
render={(p) => (
<DispositionDetail {...props} {...p}/>
<DispositionDetail {...props} {...p} />
)}
></Route>
{/* bot配置 */}
<Route
path="/settings/installbot"
render={(p) => (
<Disposition {...props} {...p}/>
<Disposition {...props} {...p} />
)}
></Route>
{/* 新建站点 */}
<Route
path="/settings/mysite/create"
render={(p) => (
<Createsite {...props} {...p} />
)}
></Route>
{/* 个人建站 */}
<Route
path="/settings/mysite"
render={(p) => (
<Mysite {...props} {...p}/>
<Mysite {...props} {...p} />
)}
></Route>
</Switch>

View File

@ -1,8 +1,32 @@
.default_head{
.default_head {
height: 65px;
line-height: 64px;
border-bottom: 1px solid rgba(224, 230, 245, 1);
color:#151d40;
font-size:17px;
padding-bottom:20px;
color: #151d40;
font-size: 17px;
padding-bottom: 20px;
Button {
float: right;
width: 100px;
height: 36px;
margin-top: 8px;
color: #fff;
background-color: #466aff;
border-color: #466aff;
}
}
.bushu {
border-radius: 4px;
background-color: rgba(164, 173, 179, 1);
color: rgba(255, 255, 255, 1);
font-size: 20px;
text-align: center;
float: right;
top:-40px;
}
.form{
border: 1px solid rgba(164, 173, 179, 1);
padding: 10px;
border-radius: 4px;
}

View File

@ -1,16 +1,44 @@
import React, { useState, useEffect, Fragment } from "react";
import { Button, Icon, message, Modal } from "antd";
import { Button, Icon, message, Modal, Form, Drawer } from "antd";
import './index.scss';
import axios from "axios";
function MySiteList(props){
const {current_user} = props;
function MySiteList(props) {
const { form, current_user } = props;
const [sitelist, setSitelist] = useState(undefined);
useEffect(()=>{
document.title='我的站点';
useEffect(() => {
document.title = '我的站点';
axios.get('/site_pages.json').then(result => {
if (result) {
setSitelist(result.data.pages);
}
})
}, [])
return <Fragment>
<div className="default_head">我的站点</div>
</Fragment>
return (
<div className="mysite">
<div className="default_head">
<span>我的站点</span>
<Button onClick={() => { window.location.href = `/settings/mysite/create` }}>新建站点</Button>
</div>
<div className="default_body">
{
sitelist && sitelist.length > 0 &&
sitelist.map((i, k) => {
return (
<div className="form mb20">
<span style={{display:"flex",fontWeight:"bold"}} className="font-15">站点名称: {i.site_name}<p className="ml30 font-15">建站工具: {i.language_frame}</p></span>
<span style={{display:"flex"}} className="font-12">建站时间: {i.created_at}<p className= "font-12 ml30">上次部署时间: {i.last_build_at}</p></span>
<Button onClick={()=>{window.location.href=`/${i.owner}/${i.repo}`}} className="primary">前往仓库</Button>
</div>
)
})
}
</div>
</div>
)
}
export default MySiteList;

View File

@ -0,0 +1,148 @@
import React, { Fragment, forwardRef, useEffect, useState } from "react";
import { Form, Input, Select, Space, Button, message, Radio } from "antd";
import axios from "axios";
import "./index.scss"
import { Link } from "react-router-dom";
function createSite(props) {
const { form, current_user } = props;
const [content, setContent] = useState(undefined);
const [addr, setAddr] = useState(undefined);
const [tag, setTag] = useState("");
const [proname, setProname] = useState("");
const [protag, setProtag] = useState("");
const [themename, setThemename] = useState([""]);
const { TextArea } = Input;
const { getFieldDecorator, validateFields } = props && props.form;
const [pagetheme, setPagetheme] = useState(undefined);
useEffect(() => {
document.title = '注册新的站点';
axios.get('/site_pages/themes.json').then(res => {
if (res) {
setPagetheme(res.data.themes);
}
})
}, [])
function onContentChange(value) {
setContent(value);
};
function ChangeAddr(e) {
setTag(e.target.value);
}
function checkAddr(rule, value, callback) {
let reg = /^[0-9a-zA-Z]+$/;
if (!value) {
callback();
}
if (!reg.test(value)) {
callback("请输入有效的名称");
}
setAddr(value);
callback();
}
function submit(e) {
e.preventDefault();
validateFields((err, fieldsValue) => {
if (err) {
console.log("error");
return;
}
const { site_name, identifier, theme, name, repository_name, clone_addr } = fieldsValue;
const prame = { site_name, identifier, language_frame: "hugo", theme:themename[0], user_id: current_user.user_id, name, repository_name, clone_addr:themename[1] };
axios.post(`/projects/page_migrate.json`, prame).then(response => {
if (response && response.status === 200) {
message.success("创建成功");
props.history.push(`/settings/mysite`)
} else {
message.error("创建失败");
}
})
})
}
console.log(themename);
return (
<div className="Create">
<div className="back">
<Link to={`/settings/mysite`}>我的站点</Link><span className="ceTitle font-18"><i className="iconfont icon-youjiantou ml5 mr5 font-12"></i>创建新的站点</span>
</div>
<div className="Create-title">
<p className="font-15 lh26">新建站点</p>
</div>
<div className="Create-Form">
<Form form={form} name="register" className="Form" scrollToFirstError layout="horizontal" labelCol={{ span: 4 }} wrapperCol={{ span: 18 }} onSubmit={submit} >
<Form.Item name="站点名称" label="站点名称" >
{getFieldDecorator("site_name", {
rules: [{ required: true, message: "请输入站点名称" }, { validator: checkAddr }]
})
(<Input placeholder="请输入站点名称" />)}
</Form.Item>
<Form.Item name="站点标识" label="站点标识" className="Create-Form-biaoshi">
{getFieldDecorator("identifier", {
rules: [{ required: true, message: "请输入站点标识" }]
})
(<Input onChange={ChangeAddr} placeholder="请输入站点标识" />)}
<span>http://{current_user.login}.kingchan.cn/{tag}</span>
</Form.Item>
<Form.Item name="建站工具" label="建站工具:">
<Select style={{ width: 100 }} defaultValue="hugo" disabled />
</Form.Item>
<Form.Item name="主题选择" label="主题选择">
<div className="zhuti">
<ul className="zhutikuai">
{
pagetheme && pagetheme.length > 0 &&
<Radio.Group style={{ height: "100%" }}>
{
pagetheme.map((i, k) => {
return (
<Radio.Button value={k} className="choicebutton" onClick={(e) => { e.target.checked ? setThemename([i.name, i.clone_url]) : setThemename(undefined) }} >
<img src={i.imgage_url} />{i.name}
</Radio.Button>
)
})
}
</Radio.Group>
}
</ul>
</div>
</Form.Item>
<Form.Item>
<Form style={{ display: "flex", left: "80px", position: "relative" }}>
<Form.Item name="拥有者" label="拥有者" style={{ width: "40%" }}>
<Input placeholder={current_user.username} style={{ textAlign: "center" }} disabled />
</Form.Item>
<Form.Item name="项目名称" label="项目名称" style={{ marginLeft: "100px", width: "70%" }}>
{getFieldDecorator("name", {
rules: [{ required: true, message: "请输入项目名称" }]
})
(<Input onChange={(e) => { setProname(e.target.value) }} placeholder="请输入项目名称" />)}
</Form.Item>
</Form>
</Form.Item>
<Form.Item name="项目标识" label="项目标识">
{getFieldDecorator("repository_name", {
rules: [{ required: true, message: "请输入项目标识" }]
})
(<Input onChange={(e) => { setProtag(e.target.value) }} placeholder="请输入项目标识" />)}
</Form.Item>
<Form.Item name="项目简介" label="项目简介">
<TextArea rows={4} onChange={onContentChange} initValue={content} />
</Form.Item>
<div className="submit">
<Button className={addr && tag && proname && protag && themename ? "createbutton mr10" : "mr10"} type="primary" htmlType="submit" disabled={!(addr && tag && proname && protag && themename)} >创建站点</Button>
<Button onClick={() => { window.location.href = '/settings/mysite' }}>取消</Button>
</div>
</Form>
</div>
</div>
)
}
export default Form.create()(forwardRef(createSite));

View File

@ -0,0 +1,88 @@
.Create {
border: 1px solid rgba(79, 108, 188, 0.21);
padding: 30px;
.back {
border-bottom: 1px solid #e0e6f5;
.ceTitle {
font-weight: 700;
color: #151d40;
}
}
.Create-title {
margin-top: 10px;
text-align: center;
p {
position: relative;
font-weight: bold;
color: #151d40;
}
}
.Form {
label {
font-size: 15px;
font-weight: bold;
}
}
.Create-Form {
margin-top: 20px;
Button {
width: 100px;
height: 40px;
}
}
.zhuti {
border: 1px solid rgba(79, 108, 188, 0.21);
display: flex;
flex-wrap: wrap;
padding: 10px;
}
.zhutikuai {
text-align: center;
li {
margin: 9px;
float: left;
}
img {
width: 147px;
height: 92px;
display: flex;
}
p {
margin-bottom: -10px !important;
}
}
.createbutton {
color: #fff;
background-color: #466aff;
border-color: #466aff;
text-align: center;
}
.submit {
position: relative;
left: 40%;
}
.choicebutton {
height: auto;
padding: 0px;
margin-right: 10px;
margin-bottom: 10px;
float: left;
left: 25px;
top:13px;
}
}

View File

@ -1,8 +1,9 @@
import React from 'react';
import React,{useEffect, useState} from 'react';
import { Route, Switch } from 'react-router-dom';
import "./index.scss";
import Loadable from 'react-loadable';
import Loading from '../../Loading';
import axios from 'axios';
const List = Loadable({
@ -18,7 +19,25 @@ const Reposyncer = Loadable({
loader: () => import('./reposyncer'),
loading: Loading,
})
const Site = Loadable({
loader: () => import('./sitedetail'),
loading: Loading,
})
const Sitecreate = Loadable({
loader: ()=> import('./sitecreate'),
loading: Loading,
})
function ServerIndex(props){
const [page,setPage] = useState(undefined);
const { owner , projectsId } = props.match.params;
useEffect(() => {
axios.get(`/site_pages/x.json?owner=${owner}&repo=${projectsId}`).then((res) => {
if (res) {
setPage(res.data.data)
}
})
}, [])
return(
<div className="panels">
<Switch {...props}>
@ -32,6 +51,22 @@ function ServerIndex(props){
() => (<Data {...props}/>)
}
></Route>
{
page?
<Route
path="/:owner/:projectsId/service/site"
render={
()=>(<Site {...props} />)
}
></Route>
:
<Route
path="/:owner/:projectsId/service/new"
render={
()=>(<Sitecreate {...props} />)
}
></Route>
}
<Route path="/:owner/:projectsId/service"
render={
() => (<List {...props}/>)

View File

@ -9,6 +9,16 @@ function Main(props){
const { current_user , resetUserInfo, projectDetail, showNotification } = props;
const [name,setName] = useState(undefined);
const [desc,setDesc] = useState(null);
useEffect(()=>{
if(projectDetail){
setName(projectDetail.name)
setDesc(projectDetail.description)
}
})
useEffect(()=>{
//
if(projectDetail){
@ -54,6 +64,16 @@ function Main(props){
<a onClick={openDetail} className="btnhover">查看详情</a>
</span>
</li>
<li>
<span className="servername">
<img src={require('./img/logo.png')} alt=""/>
<a onClick={()=>{window.location.href=`/${owner}/${projectsId}/service/site`}}>{name?name:""}</a>
</span>
<p className="task-hide-2 serverdesc">{desc?desc:""}</p>
<span className="serverbtn">
<a onClick={()=>{window.location.href=`/${owner}/${projectsId}/service/site`}} className="btnhover">查看详情</a>
</span>
</li>
{/* <li>
<div className="servername" style={{marginBottom: '8px'}}>
// <img src={require('./img/logo.png')} alt=""/>

View File

@ -0,0 +1,146 @@
import React, { Fragment, forwardRef, useEffect, useState } from "react";
import { Form, Input, Select, Space, Button, message, Radio } from "antd";
import axios from "axios";
import { Link } from "react-router-dom";
function createSite(props) {
const { form, current_user } = props;
const [content, setContent] = useState(undefined);
const [addr, setAddr] = useState(undefined);
const [tag, setTag] = useState("");
const [proname, setProname] = useState("");
const [protag, setProtag] = useState("");
const [themename, setThemename] = useState([""]);
const { TextArea } = Input;
const { getFieldDecorator, validateFields } = props && props.form;
const [pagetheme, setPagetheme] = useState(undefined);
useEffect(() => {
document.title = '注册新的站点';
axios.get('/site_pages/themes.json').then(res => {
if (res) {
setPagetheme(res.data.themes);
}
})
}, [])
function onContentChange(value) {
setContent(value);
};
function ChangeAddr(e) {
setTag(e.target.value);
}
function checkAddr(rule, value, callback) {
let reg = /[^\a-\z\A-\Z]/;
if (!value) {
callback();
}
if (!reg.test(value)) {
callback("请输入有效的名称");
}
setAddr(value);
callback();
}
function submit(e) {
e.preventDefault();
validateFields((err, fieldsValue) => {
if (err) {
console.log("error");
return;
}
const { site_name, identifier, theme, name, repository_name, clone_addr } = fieldsValue;
const prame = { site_name, identifier, language_frame: "hugo", theme:themename[0], user_id: current_user.user_id, name, repository_name, clone_addr:themename[1] };
axios.post(`/projects/page_migrate.json`, prame).then(response => {
if (response && response.status === 200) {
message.success("创建成功");
} else {
message.error("创建失败");
}
})
})
}
console.log(themename);
return (
<div className="Create">
<div className="back">
<Link to={`/settings/mysite`}>我的站点</Link><span className="ceTitle font-18"><i className="iconfont icon-youjiantou ml5 mr5 font-12"></i>创建新的站点</span>
</div>
<div className="Create-title">
<p className="font-15 lh26">新建站点</p>
</div>
<div className="Create-Form">
<Form form={form} name="register" className="Form" scrollToFirstError layout="horizontal" labelCol={{ span: 4 }} wrapperCol={{ span: 18 }} onSubmit={submit} >
<Form.Item name="站点名称" label="站点名称" >
{getFieldDecorator("site_name", {
rules: [{ required: true, message: "请输入站点名称" }, { validator: checkAddr }]
})
(<Input placeholder="请输入站点名称" />)}
</Form.Item>
<Form.Item name="站点标识" label="站点标识" className="Create-Form-biaoshi">
{getFieldDecorator("identifier", {
rules: [{ required: true, message: "请输入站点标识" }]
})
(<Input onChange={ChangeAddr} placeholder="请输入站点标识" />)}
<span>http://{current_user.login}.kingchan.cn/{tag}</span>
</Form.Item>
<Form.Item name="建站工具" label="建站工具:">
<Select style={{ width: 100 }} defaultValue="hugo" disabled />
</Form.Item>
<Form.Item name="主题选择" label="主题选择">
<div className="zhuti">
<ul className="zhutikuai">
{
pagetheme && pagetheme.length > 0 &&
<Radio.Group style={{ height: "100%" }}>
{
pagetheme.map((i, k) => {
return (
<Radio.Button value={k} className="choicebutton" onClick={(e) => { e.target.checked ? setThemename([i.name, i.clone_url]) : setThemename(undefined) }} >
<img src={i.imgage_url} />{i.name}
</Radio.Button>
)
})
}
</Radio.Group>
}
</ul>
</div>
</Form.Item>
<Form.Item>
<Form style={{ display: "flex", left: "80px", position: "relative" }}>
<Form.Item name="拥有者" label="拥有者" style={{ width: "40%" }}>
<Input placeholder={current_user.username} style={{ textAlign: "center" }} disabled />
</Form.Item>
<Form.Item name="项目名称" label="项目名称" style={{ marginLeft: "100px", width: "70%" }}>
{getFieldDecorator("name", {
rules: [{ required: true, message: "请输入项目名称" }]
})
(<Input onChange={(e) => { setProname(e.target.value) }} placeholder="请输入项目名称" />)}
</Form.Item>
</Form>
</Form.Item>
<Form.Item name="项目标识" label="项目标识">
{getFieldDecorator("repository_name", {
rules: [{ required: true, message: "请输入项目标识" }]
})
(<Input onChange={(e) => { setProtag(e.target.value) }} placeholder="请输入项目标识" />)}
</Form.Item>
<Form.Item name="项目简介" label="项目简介">
<TextArea rows={4} onChange={onContentChange} initValue={content} />
</Form.Item>
<div className="submit">
<Button className={addr && tag && proname && protag && themename ? "createbutton mr10" : "mr10"} type="primary" htmlType="submit" disabled={!(addr && tag && proname && protag && themename)} >创建站点</Button>
<Button onClick={() => { window.location.href = '/settings/mysite' }}>取消</Button>
</div>
</Form>
</div>
</div>
)
}
export default Form.create()(forwardRef(createSite));

View File

@ -0,0 +1,70 @@
import React, { useEffect, useState } from "react";
import { Button, Select, message, Card } from "antd";
import axios from "axios";
function sitelist(props) {
const [page, setPage] = useState(undefined);
const [branch, setBranch] = useState("");
const [branchlist, setBranchlist] = useState(undefined);
const Url = window.location.href;
const params = Url.split('/');
const owner = params[3];
const repo = params[4];
const { current_user, resetUserInfo, projectDetail, showNotification } = props;
const { Option } = Select;
useEffect(() => {
axios.get(`/site_pages/x.json?owner=${owner}&repo=${repo}`).then((res) => {
if (res) {
setPage(res.data.data)
}
})
}, [])
useEffect(() => {
axios.get(`/v1/${owner}/${repo}/branches/all.json`).then((res) => {
if (res) {
setBranchlist(res.data);
}
})
}, [])
function handleClick() {
const params = { branch, owner, repo }
if (page) {
axios.post(`/site_pages/${page.id}/build.json`, params).then((res) => {
if (res && res.status === 200) {
message.success("部署成功");
} else {
message.error("部署失败");
}
})
}
}
function handlechange(value) {
let u = value;
setBranch(u);
}
return (
<div style={{width:"50%"}}>
<Card title={page ? page.site_name : ""}>
<p>建站工具 {page ? page.language_frame : ""}</p>
<p>绑定仓库 {page ? page.owner + "/" + page.repo : ""}</p>
<p style={{ display: "flex" }}>上次部署时间 {page ? page.last_build_at : ""}<p className="ml30">创建时间 {page ? page.created_at : ""}</p></p>
<div style={{display:"flex"}}>
<Select onChange={handlechange} style={{ width: "100px"}} >
{
branchlist && branchlist.length > 0 &&
branchlist.map((i, k) => {
return (
<Option value={i.name} className="task-hide" >{i.name}</Option>
)
})
}
</Select>
<p className="mt5 ml20">分支数:{projectDetail ? projectDetail.branches_count : ""}</p>
<Button onClick={handleClick} style={{right:"-320px"}} >部署</Button>
</div>
</Card>
</div>
)
}
export default sitelist