error page

This commit is contained in:
zuiidea
2016-10-16 23:05:18 +08:00
parent 0255f197f4
commit 23b32b332e
18 changed files with 30 additions and 641 deletions
+8 -16
View File
@@ -1,25 +1,17 @@
import React, { PropTypes } from 'react'
import { Menu, Icon } from 'antd'
import { Link } from 'dva/router'
import React, {PropTypes} from 'react'
import {Menu, Icon} from 'antd'
import {Link} from 'dva/router'
import styles from './main.less'
const SubMenu = Menu.SubMenu
function getMenuKeyFromUrl(pathname) {
let key = ''
try {
key = pathname.match(/\/([^\/]*)/i)[1]
/* eslint no-empty:0 */
} catch (e) {}
return key
}
function Header({ location }) {
console.log(getMenuKeyFromUrl(location.pathname),location.pathname);
function Header({location}) {
return (
<div className={styles.header}>
<Menu className="header-menu" mode="horizontal">
<SubMenu style={{float:'right'}} title={<span><Icon type="user" />吴彦祖</span>}>
<SubMenu style={{
float: 'right'
}} title={< span > <Icon type="user"/>吴彦祖 < /span>}>
<Menu.Item key="signOut">
<a>注销</a>
</Menu.Item>
@@ -30,7 +22,7 @@ function Header({ location }) {
}
Header.propTypes = {
location: PropTypes.object,
location: PropTypes.object
}
export default Header
+3 -11
View File
@@ -2,16 +2,8 @@ import React, {PropTypes} from 'react'
import styles from './main.less'
import {config} from '../../utils'
function Footer({location}) {
return (
<div className={styles.footer}>
{config.footerText}
</div>
)
}
Footer.propTypes = {
location: PropTypes.object
}
const Footer = () => <div className={styles.footer}>
{config.footerText}
</div>
export default Footer
+2 -2
View File
@@ -1,7 +1,7 @@
import React from 'react'
import { Router, Route , IndexRedirect , hashHistory} from 'dva/router'
import App from './components/layout/main'
import NotFound from './routes/NotFound'
import Error from './routes/error'
import Dashboard from './routes/dashboard'
import Users from './routes/users'
@@ -12,7 +12,7 @@ export default function ({ history }) {
<IndexRedirect to="/dashboard" />
<Route path="dashboard" component={Dashboard}/>
<Route path="/users" component={ Users } />
<Route path="*" component={ NotFound } />
<Route path="*" component={ Error } />
</Route>
</Router>
)
-14
View File
@@ -1,14 +0,0 @@
import React from 'react';
import { Button } from 'antd';
import styles from './NotFound.less';
const NotFound = () =>
<div className={styles.normal}>
<div className={styles.container}>
<h1 className={styles.title}>404</h1>
<p className={styles.desc}>未找到该页面</p>
<a href="/"><Button type="primary" style={{ marginTop: 5 }}>返回首页</Button></a>
</div>
</div>;
export default NotFound;
-25
View File
@@ -1,25 +0,0 @@
.normal {
width: 100%;
height: 100%;
min-height: 100vh;
padding-top: 120px;
}
.container {
padding: 0;
margin: 0 auto;
width: 620px;
height: 300px;
text-align: center;
}
.title {
font-size: 80px;
color: #666;
margin-top: 20px;
margin-bottom: 10px;
}
.desc {
font-size: 14px;
}
+1 -4
View File
@@ -79,14 +79,11 @@ function Users({ location, dispatch, users }) {
},
}
// 解决 Form.create initialValue 的问题
// 每次创建一个全新的组件, 而不做diff
// 如果你使用了redux, 请移步 http://react-component.github.io/form/examples/redux.html
const UserModalGen = () =>
<UserModal {...userModalProps} />
return (
<div className={styles.normal}>
<div>
<UserSearch {...userSearchProps} />
<UserList {...userListProps} />
<UserModalGen />
-4
View File
@@ -1,4 +0,0 @@
.normal {
width: 800px;
margin: 20px auto;
}
+10
View File
@@ -0,0 +1,10 @@
import React from 'react'
import {Icon} from 'antd'
import styles from './error.less'
const Error = () => <div className={styles.error}>
<Icon type="frown-o"/>
<h1>404 Not Found</h1>
</div>
export default Error
@@ -1,4 +1,4 @@
.not-found {
.error {
color: black;
text-align: center;
position: absolute;
@@ -7,9 +7,11 @@
left: 50%;
margin-left: -100px;
width: 200px;
height: 100px;
:global .anticon{
font-size: 48px;
margin-bottom: 16px;
}
h1 {
font-family: "PingFang SC",;
font-family: cursive;
}
}
-16
View File
@@ -1,16 +0,0 @@
import React from 'react'
import { Icon } from 'antd'
import './error.less'
const Error = React.createClass({
render() {
return (
<div className="not-found">
<div style={{ fontSize:32 }}><Icon type="frown"/></div>
<h1>{this.props.errorMsg || '404 Not Found'}</h1>
</div>
);
}
})
module.exports = Error
-140
View File
@@ -1,140 +0,0 @@
import React from 'react'
import ReactDOM from 'react-dom'
import { ajax, config, Logger } from '../../utils/lib'
import { Icon, message, Table, Button, Row, Col, Dropdown, Menu } from 'antd'
import './list.less'
const logger = Logger.getLogger('List')
let List = React.createClass({
getInitialState() {
logger.info()
const tableName = this.props.routes.pop().tableName
return {
tableName,
pager:{
showSizeChanger: true,
showQuickJumper: true,
showTotal: total => `共 ${total} 条`
},
data:[],
params:{},
loading: false,
};
},
componentDidMount() {
this.fetch()
},
handleTableChange(pagination, filters, sorter) {
let pager = this.state.pager
pager.current = pagination.current
this.state.pager = pager
this.state.params = {
results: pagination.pageSize,
page: pagination.current,
sortField: sorter.field,
sortOrder: sorter.order,
...filters
}
this.fetch()
},
fetch() {
const _this = this
this.setState({loading: true})
ajax({
url: 'https://randomuser.me/api/',
data: {
results:10,
..._this.state.params
},
success: function (result) {
const pager = _this.state.pager
const params = _this.state.params
pager.total = 200
_this.setState({
loading: false,
data: result.results,
pager,
params})
}
})
},
render() {
const columns = [
{
title: '头像',
dataIndex: 'picture',
width:64,
className:'avatar-col',
render: text => <img width='24' src={text.thumbnail} />,
},{
title: '姓名',
dataIndex: 'name',
sorter: true,
render: text => `${text.first} ${text.last}`,
}, {
title: '性别',
dataIndex: 'gender',
filters: [
{ text: 'Male', value: 'male' },
{ text: 'Female', value: 'female' },
],
}, {
title: '座机',
dataIndex: 'cell',
}, {
title: '国家',
dataIndex: 'nat',
}, {
title: '城市',
dataIndex: 'location',
render: text => text.city,
},{
title: '手机',
dataIndex: 'phone',
},{
title: '邮箱',
dataIndex: 'email',
},{
title: '时间',
dataIndex: 'dob',
render: text => new Date(text).format("yyyy-MM-dd hh:mm:ss"),
},{
title: '操作',
dataIndex: 'login',
render: (text,it) => {
const menu = (
<Menu>
<Menu.Item>
<a href='javascript:;'>编辑</a>
</Menu.Item>
<Menu.Item>
<a href='javascript:;'>删除</a>
</Menu.Item>
</Menu>
)
return <Dropdown overlay={menu}>
<a className="ant-dropdown-link" href="javascript:;">
操作 <Icon type="down" />
</a>
</Dropdown>
},
}]
return (
<div>
<Table
bordered
columns={columns}
rowKey={record => record.registered}
dataSource={this.state.data}
pagination={this.state.pager}
loading={this.state.loading}
onChange={this.handleTableChange}
className="list-table"
size="small" />
</div>
)
},
})
module.exports = List
-9
View File
@@ -1,9 +0,0 @@
.list-table{
.avatar-col{
line-height: 1;
}
td{
height: 39px;
}
}
-92
View File
@@ -1,92 +0,0 @@
import React from 'react'
import ReactDOM from 'react-dom'
import Header from '../components/Header'
import Footer from '../components/Footer'
import Sidebar from '../components/Sidebar'
import SignIn from './user/SignIn'
import Breadcrumb from '../components/Breadcrumb'
import './index.less'
import { ajax, config, Logger } from '../utils/lib.js'
import { Spin, message, Icon } from 'antd'
const logger = Logger.getLogger('App')
const App = React.createClass({
getInitialState() {
let loading=false,
login=true
if (config.needLogin){
loading=true
login=false
}
return {
loading,
login,
userName: '未登录',
collapse: false,
}
},
componentDidMount() {
const _this = this
if(localStorage.getItem("username")&&localStorage.getItem("username")=="guest"&&
localStorage.getItem("password")&&localStorage.getItem("password")=='guest'){
_this.loginSuccess("guest")
return
}
if (!this.state.login) {
const loading = message.loading('正在获取用户信息...', 0)
ajax({
url: config.user.info,
success: function (result) {
if (result.isSuccess) {
loading()
_this.loginSuccess(result.userName)
} else {
loading()
_this.setState({loading: false})
}
}
})
}
},
loginSuccess(name) {
logger.debug('callback logingSuccess, name = %s', name)
this.setState({
loading: false,
login: true,
userName: name,
})
},
render() {
if (this.state.loading) {
return (<Spin spinning={this.state.loading} size="large">
<SignIn loginSuccess= {this.loginSuccess} />
</Spin>)
} else if (!this.state.login) {
return <SignIn loginSuccess={this.loginSuccess} />
}
const collapse = this.state.collapse
return (
<div className={collapse ? "ant-layout-aside ant-layout-aside-collapse" : "ant-layout-aside"}>
<aside className="ant-layout-sider">
<Sidebar />
<div className="ant-aside-action" onClick={this.onCollapseChange}>
{collapse ? <Icon type="right" /> : <Icon type="left" />}
</div>
</aside>
<div className="ant-layout-main">
<Header userName={this.state.userName} />
<Breadcrumb {...this.props} />
<div className="ant-layout-container">
<div className="ant-layout-content">
{this.props.children}
</div>
</div>
<Footer />
</div>
</div>
)
},
})
module.exports = App
-165
View File
@@ -1,165 +0,0 @@
body {
height: 100%;
overflow-y: hidden;
background-color: #f8f8f8;
}
.ant-layout-aside {
position: relative;
min-height: 100%;
.ant-layout-header {
.ant-menu {
line-height: 47px;
}
.ant-menu-horizontal {
border: none;
}
box-shadow: 0 0 20px rgba(0, 0, 0, 0.05);
}
.ant-layout-sider {
width: 224px;
background: #404040;
position: absolute;
overflow: visible;
padding-bottom: 24px;
height: 100%;
transition: all 0.3s ease;
& > .ant-menu {
margin-bottom: 20px;
& > .anticon {
transition: font-size 0.3s;
}
& > .ant-menu-item {
margin: 16px 0;
&.nav-text {
vertical-align: baseline;
display: inline-block;
}
}
}
.ant-layout-logo {
text-align: center;
height: 40px;
line-height: 40px;
cursor: pointer;
img {
width: 40px;
margin-right: 8px;
}
span {
vertical-align: text-bottom;
font-size: 16px;
text-transform: uppercase;
display: inline-block;
}
}
}
.ant-layout-breadcrumb {
height: 48px;
line-height: 48px;
padding: 0 16px;
margin-bottom: -24px;
}
.ant-layout-main {
margin-left: 224px;
transition: all 0.3s ease;
}
.ant-aside-action {
height: 42px;
width: 224px;
position: fixed;
bottom: 0;
background: #474747;
color: #fff;
text-align: center;
line-height: 42px;
cursor: pointer;
transition: all 0.3s ease;
}
.ant-layout-container {
margin: 24px 16px;
.ant-layout-content {
background: #fff;
padding: 24px;
min-height: e("calc(100vh - 168px)");
position: relative;
}
}
.ant-layout-footer {
height: 48px;
line-height: 48px;
text-align: center;
font-size: 12px;
color: #999;
background: #fff;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.05);
width: 100%;
}
&.ant-layout-aside-collapse {
.ant-aside-action {
width: 64px;
transition: all 0.3s ease;
}
.ant-layout-main {
margin-left: 64px;
transition: all 0.3s ease;
}
.ant-layout-sider {
width: 64px;
transition: all 0.3s ease;
& > .ant-menu {
& > .ant-menu-item {
transition: all 0s ease;
&:hover {
background: #2db7f5;
color: #fff;
transition: all 0s ease;
.nav-text {
display: inline-block;
vertical-align: top;
background: #2db7f5;
color: #fff;
padding-right: 16px;
border-radius: 0 5px 5px 0;
}
}
.nav-text {
display: none;
}
& > .anticon {
font-size: 16px;
display: inline-block;
}
}
}
}
}
}
.ant-layout-main{
height: 100vh;
overflow-y:auto;
}
-15
View File
@@ -1,15 +0,0 @@
import React from 'react'
import { ajax, config, Logger } from '../../utils/lib'
import { Icon, message, Button, Row, Col, Form, Input, Select } from 'antd'
import './dashboard.less'
const logger = Logger.getLogger('Dashboard')
const Dashboard = React.createClass({
render(){
return(
<div>hello</div>
)
}
})
module.exports = Dashboard
View File
-88
View File
@@ -1,88 +0,0 @@
import React from 'react'
import ReactDOM from 'react-dom'
import { ajax, config, Logger } from '../../utils/lib'
import { Icon, message, Button, Row, Col, Form, Input, Select } from 'antd'
import './signIn.less'
const FormItem = Form.Item
const logger = Logger.getLogger('SignIn')
let SignIn = React.createClass({
getInitialState() {
return {
loading: false,
}
},
handleSubmit(e) {
const _this = this
e.preventDefault()
this.props.form.validateFieldsAndScroll((errors, values) => {
if (!!errors) {
return
}
_this.setState({ loading: true })
ajax({
url:config.user.signIn,
data:values,
success:function(result){
if(result.isSuccess){
_this.props.loginSuccess(result.userName, true)
}else {
message.error(`登录失败: ${result.message}, 请联系管理员`)
}
},
complete:function(){
_this.setState({ loading: false })
}
})
})
},
render() {
const { getFieldProps } = this.props.form
const username = getFieldProps('username', {
rules: [
{
required: true,
message: '不能为空',
},
],
})
const password = getFieldProps('password', {
rules: [
{
required: true,
message: '不能为空',
},
],
})
return (
<div className="signIn-from">
<div className="logo mb">
<img src="https://t.alipayobjects.com/images/rmsweb/T1B9hfXcdvXXXXXXXX.svg" />
<span>Ant Design</span>
</div>
<form horizontal onSubmit={this.handleSubmit} form={this.props.form}>
<FormItem hasFeedback>
<Input {...username} size="large" placeholder="账户" />
</FormItem>
<FormItem hasFeedback>
<Input {...password} size="large" type="password" placeholder="密码" />
</FormItem>
<Row className="self-modal-footer">
<Button type="primary" size="large" onClick={this.handleSubmit} loading={this.state.loading}>
登录
</Button>
</Row>
<p style={{color:'#ccc',textAlign:'center'}} className='m-y-sm'>
<span className='mr'>账号:guest</span>
<span>密码:guest</span>
</p>
</form>
</div>
)
},
})
SignIn = Form.create()(SignIn)
module.exports = SignIn
-36
View File
@@ -1,36 +0,0 @@
.signIn-from {
position: absolute;
top: 50%;
left: 50%;
margin: -160px 0 0 -160px;
width: 320px;
height: 320px;
padding: 36px;
box-shadow: 0 0 100px rgba(0,0,0,.08);
button {
width: 100%;
}
}
.logo {
text-align: center;
height: 40px;
line-height: 40px;
cursor: pointer;
img {
width: 40px;
margin-right: 8px;
}
span {
vertical-align: text-bottom;
font-size: 16px;
text-transform: uppercase;
display: inline-block;
}
}
.ant-spin-container,.ant-spin-nested-loading{
height: 100%;
}