├── .env
├── src
├── style
│ ├── button.less
│ ├── utils-border.less
│ ├── imgs
│ │ ├── b1.jpg
│ │ ├── 404.png
│ │ ├── beauty.jpg
│ │ └── mobile.gif
│ ├── theme
│ │ ├── theme-danger.json
│ │ ├── theme-grey.json
│ │ ├── theme-info.json
│ │ ├── theme-warn.json
│ │ └── index.js
│ ├── scroll.less
│ ├── img.less
│ ├── table.less
│ ├── icons.less
│ ├── modal.less
│ ├── utils-spacing.less
│ ├── login.less
│ ├── utils-color.less
│ ├── utils-text.less
│ ├── utils-size.less
│ ├── card.less
│ ├── global.less
│ ├── index.less
│ ├── variables.less
│ ├── menu.less
│ └── banner.less
├── index.css
├── action
│ ├── type.js
│ └── index.js
├── App.test.js
├── components
│ ├── Page.jsx
│ ├── widget
│ │ └── AuthWidget.js
│ ├── pages
│ │ ├── NotFound.jsx
│ │ └── Login.jsx
│ ├── ui
│ │ ├── emoji
│ │ │ └── index.jsx
│ │ ├── banners
│ │ │ ├── index.jsx
│ │ │ ├── AutoPlay.jsx
│ │ │ ├── Basic.jsx
│ │ │ └── Custom.jsx
│ │ ├── Spins.jsx
│ │ ├── Icons.jsx
│ │ ├── Draggable.jsx
│ │ ├── Notifications.jsx
│ │ ├── Buttons.jsx
│ │ └── Wysiwyg.jsx
│ ├── auth
│ │ ├── RouterEnter.js
│ │ └── Basic.js
│ ├── tables
│ │ ├── ExpandedTable.jsx
│ │ ├── BasicTable.jsx
│ │ ├── FixedTable.jsx
│ │ ├── AdvancedTables.jsx
│ │ ├── BasicTables.jsx
│ │ ├── SelectTable.jsx
│ │ ├── AsynchronousTable.jsx
│ │ ├── SortTable.jsx
│ │ ├── SearchTable.jsx
│ │ └── EditableTable.jsx
│ ├── charts
│ │ ├── RechartsRadialBarChart.jsx
│ │ ├── RechartsBarChart.jsx
│ │ ├── RechartsRadarChart.jsx
│ │ ├── RechartsSimpleLineChart.jsx
│ │ ├── Echarts.jsx
│ │ ├── Recharts.jsx
│ │ ├── EchartsPie.jsx
│ │ ├── EchartsGraphnpm.jsx
│ │ ├── EchartsArea.jsx
│ │ ├── EchartsScatter.jsx
│ │ └── EchartsForce.js
│ ├── forms
│ │ ├── LoginForm.jsx
│ │ ├── HorizontalForm.jsx
│ │ └── ModalForm.jsx
│ ├── dashboard
│ │ ├── EchartsProjects.jsx
│ │ └── EchartsViews.jsx
│ ├── animation
│ │ ├── BasicAnimations.jsx
│ │ └── ExampleAnimations.jsx
│ ├── BreadcrumbCustom.jsx
│ ├── HeaderCustom.jsx
│ └── SiderCustom.jsx
├── axios
│ ├── config.js
│ ├── tools.js
│ └── index.js
├── App.css
├── index.js
├── utils
│ └── index.jsx
├── reducer
│ └── index.js
├── logo.svg
├── App.js
├── registerServiceWorker.js
└── routes
│ └── index.js
├── public
├── favicon.ico
└── index.html
├── config
├── vendor.config.js
├── jest
│ ├── fileTransform.js
│ └── cssTransform.js
├── polyfills.js
├── paths.js
├── env.js
└── webpackDevServer.config.js
├── .gitignore
├── .eslintrc
├── scripts
├── test.js
├── start.js
└── build.js
└── package.json
/.env:
--------------------------------------------------------------------------------
1 | PORT=3006
--------------------------------------------------------------------------------
/src/style/button.less:
--------------------------------------------------------------------------------
1 | .ant-btn+.ant-btn {
2 | margin-left: 10px;
3 | }
--------------------------------------------------------------------------------
/src/style/utils-border.less:
--------------------------------------------------------------------------------
1 | .b-a {
2 | border: 1px solid @border-color;
3 | }
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gytai/react-admin/master/public/favicon.ico
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | padding: 0;
4 | font-family: sans-serif;
5 | }
6 |
--------------------------------------------------------------------------------
/src/style/imgs/b1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gytai/react-admin/master/src/style/imgs/b1.jpg
--------------------------------------------------------------------------------
/src/style/theme/theme-danger.json:
--------------------------------------------------------------------------------
1 | {
2 | "header": {
3 | "background": "#f44455"
4 | }
5 | }
--------------------------------------------------------------------------------
/src/style/theme/theme-grey.json:
--------------------------------------------------------------------------------
1 | {
2 | "header": {
3 | "background": "#424242"
4 | }
5 | }
--------------------------------------------------------------------------------
/src/style/theme/theme-info.json:
--------------------------------------------------------------------------------
1 | {
2 | "header": {
3 | "background": "#6887ff"
4 | }
5 | }
--------------------------------------------------------------------------------
/src/style/theme/theme-warn.json:
--------------------------------------------------------------------------------
1 | {
2 | "header": {
3 | "background": "#fcc100"
4 | }
5 | }
--------------------------------------------------------------------------------
/src/style/imgs/404.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gytai/react-admin/master/src/style/imgs/404.png
--------------------------------------------------------------------------------
/src/style/imgs/beauty.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gytai/react-admin/master/src/style/imgs/beauty.jpg
--------------------------------------------------------------------------------
/src/style/imgs/mobile.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gytai/react-admin/master/src/style/imgs/mobile.gif
--------------------------------------------------------------------------------
/src/action/type.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by 叶子 on 2017/7/30.
3 | */
4 | export const REQUEST_DATA = 'REQUEST_DATA';
5 |
6 | export const RECEIVE_DATA = 'RECEIVE_DATA';
7 |
--------------------------------------------------------------------------------
/src/style/scroll.less:
--------------------------------------------------------------------------------
1 | //美化webkit内核滚动条
2 | ::-webkit-scrollbar {
3 | width: 8px;
4 | height: 8px;
5 | }
6 | ::-webkit-scrollbar-thumb {
7 | background-color: #777;
8 | }
--------------------------------------------------------------------------------
/src/style/img.less:
--------------------------------------------------------------------------------
1 | img {
2 | vertical-align: middle;
3 | }
4 | .img-responsive{
5 | width: 100%;
6 | height: auto;
7 | }
8 | .img-circle {
9 | border-radius: 50%;
10 | }
--------------------------------------------------------------------------------
/config/vendor.config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by 叶子 on 2017/9/24.
3 | */
4 | module.exports = {
5 | entry: {
6 | vendor: ['antd'], // 需要分离的库
7 | charts: ['echarts-for-react']
8 | }
9 | };
--------------------------------------------------------------------------------
/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import App from './App';
4 |
5 | it('renders without crashing', () => {
6 | const div = document.createElement('div');
7 | ReactDOM.render(, div);
8 | });
9 |
--------------------------------------------------------------------------------
/src/style/table.less:
--------------------------------------------------------------------------------
1 | .table-operations {
2 | margin-bottom: 16px;
3 | > button {
4 | margin-right: 8px;
5 | }
6 | }
7 |
8 | .editable-row-text {
9 | padding: 5px;
10 | }
11 |
12 | .editable-row-operations a {
13 | margin-right: 8px;
14 | }
--------------------------------------------------------------------------------
/src/style/theme/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by hao.cheng on 2017/5/6.
3 | */
4 | import themeinfo from './theme-info.json';
5 | import themegrey from './theme-grey.json';
6 | import themedanger from './theme-danger.json';
7 | import themewarn from './theme-warn.json';
8 |
9 | export default { themeinfo, themegrey, themedanger, themewarn};
--------------------------------------------------------------------------------
/src/components/Page.jsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by hao.cheng on 2017/4/16.
3 | */
4 | import React from 'react';
5 |
6 | class Page extends React.Component {
7 | render() {
8 | return (
9 |
10 | {this.props.children}
11 |
12 | )
13 |
14 | }
15 | }
16 |
17 | export default Page;
--------------------------------------------------------------------------------
/config/jest/fileTransform.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const path = require('path');
4 |
5 | // This is a custom Jest transformer turning file imports into filenames.
6 | // http://facebook.github.io/jest/docs/tutorial-webpack.html
7 |
8 | module.exports = {
9 | process(src, filename) {
10 | return `module.exports = ${JSON.stringify(path.basename(filename))};`;
11 | },
12 | };
13 |
--------------------------------------------------------------------------------
/config/jest/cssTransform.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // This is a custom Jest transformer turning style imports into empty objects.
4 | // http://facebook.github.io/jest/docs/tutorial-webpack.html
5 |
6 | module.exports = {
7 | process() {
8 | return 'module.exports = {};';
9 | },
10 | getCacheKey() {
11 | // The output is always the same.
12 | return 'cssTransform';
13 | },
14 | };
15 |
--------------------------------------------------------------------------------
/src/axios/config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by 叶子 on 2017/7/30.
3 | * 接口地址配置文件
4 | */
5 |
6 | //easy-mock模拟数据接口地址
7 | const EASY_MOCK = 'https://www.easy-mock.com/mock';
8 | const MOCK_AUTH = EASY_MOCK + '/597b5ed9a1d30433d8411456/auth'; // 权限接口地址
9 | export const MOCK_AUTH_ADMIN = MOCK_AUTH + '/admin'; // 管理员权限接口
10 | export const MOCK_AUTH_VISITOR = MOCK_AUTH + '/visitor'; // 访问权限接口
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | animation: App-logo-spin infinite 20s linear;
7 | height: 80px;
8 | }
9 |
10 | .App-header {
11 | background-color: #222;
12 | height: 150px;
13 | padding: 20px;
14 | color: white;
15 | }
16 |
17 | .App-intro {
18 | font-size: large;
19 | }
20 |
21 | @keyframes App-logo-spin {
22 | from { transform: rotate(0deg); }
23 | to { transform: rotate(360deg); }
24 | }
25 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | */node_modules
6 | client/node_modules
7 | server/node_modules
8 | mqtt/node_modules
9 |
10 | # testing
11 | /coverage
12 |
13 | # production
14 | /build
15 |
16 | # misc
17 | .DS_Store
18 | .env.local
19 | .env.development.local
20 | .env.test.local
21 | .env.production.local
22 |
23 | npm-debug.log*
24 | yarn-debug.log*
25 | yarn-error.log*
26 |
27 | .idea
28 |
--------------------------------------------------------------------------------
/src/components/widget/AuthWidget.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by 叶子 on 2017/7/31.
3 | */
4 | import { Component } from 'react';
5 | import { connect } from 'react-redux';
6 |
7 | class AuthWidget extends Component {
8 | render() {
9 | return this.props.children(this.props.auth.data || {});
10 | }
11 | }
12 |
13 | const mapStateToProps = state => {
14 | const { auth = {data: {}} } = state.httpData;
15 | return { auth };
16 | };
17 |
18 | export default connect(mapStateToProps)(AuthWidget);
--------------------------------------------------------------------------------
/src/style/icons.less:
--------------------------------------------------------------------------------
1 | ul.icons-list{
2 | list-style: none;
3 | overflow: hidden;
4 | li{
5 | float: left;
6 | width: 10%;
7 | text-align: center;
8 | list-style: none;
9 | cursor: pointer;
10 | height: 100px;
11 | transition: all .3s;
12 | background-color: #fff;
13 | &:hover{
14 | background-color: #cccccc;
15 | color: #fff;
16 | }
17 | i{
18 | margin: 16px 0 10px;
19 | }
20 | span{
21 | display: block;
22 | text-align: center;
23 | }
24 | }
25 | }
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "react-app",
3 | "rules": {
4 | "no-multi-spaces": 1,
5 | "react/jsx-tag-spacing": 1, // 总是在自动关闭的标签前加一个空格,正常情况下也不需要换行
6 | "jsx-quotes": 1,
7 | "react/jsx-closing-bracket-location": 1, // 遵循JSX语法缩进/格式
8 | "react/jsx-boolean-value": 1, // 如果属性值为 true, 可以直接省略
9 | "react/no-string-refs": 1, // 总是在Refs里使用回调函数
10 | "react/self-closing-comp": 1, // 对于没有子元素的标签来说总是自己关闭标签
11 | "react/sort-comp": 1, // 按照具体规范的React.createClass 的生命周期函数书写代码
12 | "react/jsx-pascal-case": 1 // React模块名使用帕斯卡命名,实例使用骆驼式命名
13 | }
14 | }
--------------------------------------------------------------------------------
/src/style/modal.less:
--------------------------------------------------------------------------------
1 | .vertical-center-modal {
2 | text-align: center;
3 | white-space: nowrap;
4 | &:before {
5 | content: '';
6 | display: inline-block;
7 | height: 100%;
8 | vertical-align: middle;
9 | width: 0;
10 | }
11 | .ant-modal {
12 | display: inline-block;
13 | vertical-align: middle;
14 | top: 0;
15 | text-align: left;
16 | }
17 | }
18 | /*
19 | // Use flex which not working in IE
20 | .vertical-center-modal {
21 | display: flex;
22 | align-items: center;
23 | justify-content: center;
24 | }
25 |
26 | .vertical-center-modal .ant-modal {
27 | top: 0;
28 | }
29 | */
--------------------------------------------------------------------------------
/src/style/utils-spacing.less:
--------------------------------------------------------------------------------
1 | .pb-s { padding-bottom: @spacer * 0.5 !important; }
2 | .pb-m { padding-bottom: @spacer * 1 !important; }
3 | .pb-l { padding-bottom: @spacer * 2 !important; }
4 | .pa-s { padding: @spacer * 0.5 !important; }
5 | .pa-m { padding: @spacer * 1 !important; }
6 | .pa-l { padding: @spacer * 2 !important; }
7 |
8 | .mr-s { margin-right: @spacer * 0.5 !important; }
9 | .mr-m { margin-right: @spacer * 1 !important; }
10 | .mr-l { margin-right: @spacer * 2 !important; }
11 | .mb-s { margin-bottom: @spacer * 0.5 !important; }
12 | .mb-m { margin-bottom: @spacer * 1 !important; }
13 | .mb-l { margin-bottom: @spacer * 2 !important; }
14 |
--------------------------------------------------------------------------------
/src/style/login.less:
--------------------------------------------------------------------------------
1 | .login{
2 | display: flex;
3 | justify-content: center;
4 | align-items: center;
5 | height: 100%;
6 | background: #f3f3f3;
7 | .login-form{
8 | width: 320px;
9 | height: 340px;
10 | padding: 36px;
11 | box-shadow: 0 0 100px rgba(0,0,0,.08);
12 | background: #fff;
13 | .login-logo{
14 | text-align: center;
15 | height: 40px;
16 | line-height: 40px;
17 | cursor: pointer;
18 | margin-bottom: 24px;
19 | span {
20 | vertical-align: text-bottom;
21 | font-size: 16px;
22 | text-transform: uppercase;
23 | display: inline-block;
24 | }
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/config/polyfills.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | if (typeof Promise === 'undefined') {
4 | // Rejection tracking prevents a common issue where React gets into an
5 | // inconsistent state due to an error, but it gets swallowed by a Promise,
6 | // and the user has no idea what causes React's erratic future behavior.
7 | require('promise/lib/rejection-tracking').enable();
8 | window.Promise = require('promise/lib/es6-extensions.js');
9 | }
10 |
11 | // fetch() polyfill for making API calls.
12 | require('whatwg-fetch');
13 |
14 | // Object.assign() is commonly used with React.
15 | // It will use the native implementation if it's present and isn't buggy.
16 | Object.assign = require('object-assign');
17 |
--------------------------------------------------------------------------------
/src/components/pages/NotFound.jsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by hao.cheng on 2017/5/7.
3 | */
4 | import React from 'react';
5 | import img from '../../style/imgs/404.png';
6 |
7 |
8 | class NotFound extends React.Component {
9 | state = {
10 | animated: ''
11 | };
12 | enter = () => {
13 | this.setState({animated: 'hinge'})
14 | };
15 | render() {
16 | return (
17 |
18 |

19 |
20 | )
21 | }
22 | }
23 |
24 | export default NotFound;
--------------------------------------------------------------------------------
/src/style/utils-color.less:
--------------------------------------------------------------------------------
1 | .color-variant(@bg, @color) {
2 | color: @color;
3 | background-color: @bg;
4 | }
5 | .dark-white {
6 | color: @dark;
7 | background-color: @white;
8 | }
9 | .min-black {
10 | .color-variant(@min-black, @black-color)
11 | }
12 | .black {
13 | .color-variant(@black, @black-color);
14 | }
15 |
16 | .dark {
17 | .color-variant(@dark, @dark-color);
18 | }
19 |
20 | .grey {
21 | .color-variant(@grey, @grey-color);
22 | }
23 |
24 | .primary {
25 | .color-variant(@primary, @primary-color);
26 | }
27 |
28 | .info {
29 | .color-variant(@info, @info-color);
30 | }
31 | .warn {
32 | .color-variant(@warn, @warn-color);
33 | }
34 | .danger {
35 | .color-variant(@danger, @danger-color)
36 | }
--------------------------------------------------------------------------------
/src/action/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by 叶子 on 2017/7/30.
3 | */
4 | import * as type from './type';
5 | import * as http from '../axios/index';
6 |
7 | const requestData = category => ({
8 | type: type.REQUEST_DATA,
9 | category
10 | });
11 | export const receiveData = (data, category) => ({
12 | type: type.RECEIVE_DATA,
13 | data,
14 | category
15 | });
16 | /**
17 | * 请求数据调用方法
18 | * @param funcName 请求接口的函数名
19 | * @param params 请求接口的参数
20 | */
21 | export const fetchData = ({funcName, params, stateName}) => dispatch => {
22 | !stateName && (stateName = funcName);
23 | dispatch(requestData(stateName));
24 | return http[funcName](params).then(res => dispatch(receiveData(res, stateName)));
25 | };
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import './style/lib/animate.css';
5 | import registerServiceWorker from './registerServiceWorker';
6 | import { Provider } from 'react-redux';
7 | import thunk from 'redux-thunk';
8 | import { createStore, applyMiddleware } from 'redux';
9 | import reducer from './reducer';
10 |
11 | import CRouter from './routes';
12 |
13 |
14 | // redux 注入操作
15 | const middleware = [thunk];
16 | const store = createStore(reducer, applyMiddleware(...middleware));
17 | console.log(store.getState());
18 |
19 | ReactDOM.render(
20 |
21 |
22 |
23 | ,
24 | document.getElementById('root')
25 | );
26 | registerServiceWorker();
--------------------------------------------------------------------------------
/src/style/utils-text.less:
--------------------------------------------------------------------------------
1 | .text{
2 | font-size: 1rem;
3 | }
4 | .text-2x{
5 | font-size: 2rem;
6 | }
7 | .text-3x{
8 | font-size: 3rem;
9 | }
10 | .text-4x{
11 | font-size: 4rem;
12 | }
13 |
14 | .text-center {
15 | text-align: center;
16 | }
17 |
18 | .text-left {
19 | text-align: left;
20 | }
21 |
22 | .text-right {
23 | text-align: right;
24 | }
25 |
26 | .text-danger,
27 | .text-danger-hover a:hover {
28 | color: #f44455 !important;
29 | }
30 | .text-dark,
31 | .text-dark-hover a:hover {
32 | color: #2e3e4e !important;
33 | }
34 | .text-info,
35 | .text-info-hover a:hover {
36 | color: #6887ff !important;
37 | }
38 | .text-success,
39 | .text-success-hover a:hover {
40 | color: #6cc788 !important;
41 | }
42 | .text-blue,
43 | .text-blue-hover a:hover {
44 | color: #2196f3 !important; }
45 |
--------------------------------------------------------------------------------
/src/utils/index.jsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by hao.cheng on 2017/4/28.
3 | */
4 | // 获取url的参数
5 | export const queryString = () => {
6 | let _queryString = {};
7 | const _query = window.location.search.substr(1);
8 | const _vars = _query.split('&');
9 | _vars.forEach((v, i) => {
10 | const _pair = v.split('=');
11 | if (!_queryString.hasOwnProperty(_pair[0])) {
12 | _queryString[_pair[0]] = decodeURIComponent(_pair[1]);
13 | } else if (typeof _queryString[_pair[0]] === 'string') {
14 | const _arr = [ _queryString[_pair[0]], decodeURIComponent(_pair[1])];
15 | _queryString[_pair[0]] = _arr;
16 | } else {
17 | _queryString[_pair[0]].push(decodeURIComponent(_pair[1]));
18 | }
19 | });
20 | return _queryString;
21 | };
--------------------------------------------------------------------------------
/scripts/test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // Do this as the first thing so that any code reading it knows the right env.
4 | process.env.BABEL_ENV = 'test';
5 | process.env.NODE_ENV = 'test';
6 | process.env.PUBLIC_URL = '';
7 |
8 | // Makes the script crash on unhandled rejections instead of silently
9 | // ignoring them. In the future, promise rejections that are not handled will
10 | // terminate the Node.js process with a non-zero exit code.
11 | process.on('unhandledRejection', err => {
12 | throw err;
13 | });
14 |
15 | // Ensure environment variables are read.
16 | require('../config/env');
17 |
18 | const jest = require('jest');
19 | const argv = process.argv.slice(2);
20 |
21 | // Watch unless on CI or in coverage mode
22 | if (!process.env.CI && argv.indexOf('--coverage') < 0) {
23 | argv.push('--watch');
24 | }
25 |
26 |
27 | jest.run(argv);
28 |
--------------------------------------------------------------------------------
/src/axios/tools.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by 叶子 on 2017/7/30.
3 | * http通用工具函数
4 | */
5 | import axios from 'axios';
6 | import { message } from 'antd';
7 |
8 | /**
9 | * 公用get请求
10 | * @param url 接口地址
11 | * @param msg 接口异常提示
12 | * @param headers 接口所需header配置
13 | */
14 | export const get = ({url, msg = '接口异常', headers}) =>
15 | axios.get(url, headers).then(res => res.data).catch(err => {
16 | console.log(err);
17 | message.warn(msg);
18 | });
19 |
20 | /**
21 | * 公用post请求
22 | * @param url 接口地址
23 | * @param data 接口参数
24 | * @param msg 接口异常提示
25 | * @param headers 接口所需header配置
26 | */
27 | export const post = ({url, data, msg = '接口异常', headers}) =>
28 | axios.post(url, data, headers).then(res => res.data).catch(err => {
29 | console.log(err);
30 | message.warn(msg);
31 | });
32 |
--------------------------------------------------------------------------------
/src/style/utils-size.less:
--------------------------------------------------------------------------------
1 | .w-8{
2 | width: 8px;
3 | height: 8px;
4 | display: inline-block;
5 | }
6 | .w-16{
7 | width: 16px;
8 | height: 16px;
9 | display: inline-block;
10 | }
11 | .w-20{
12 | width: 20px;
13 | height: 20px;
14 | display: inline-block;
15 | }
16 | .w-24{
17 | width: 24px;
18 | height: 24px;
19 | display: inline-block;
20 | text-align: center;
21 | }
22 | .w-32{
23 | width: 32px;
24 | height: 32px;
25 | line-height: 32px;
26 | display: inline-block;
27 | text-align: center;
28 | }
29 | .w-40{
30 | width: 40px;
31 | height: 40px;
32 | line-height: 40px;
33 | display: inline-block;
34 | text-align: center;
35 | }
36 | .w-48{
37 | width: 48px;
38 | height: 48px;
39 | line-height: 48px;
40 | display: inline-block;
41 | text-align: center;
42 | }
43 | .w-56{
44 | width: 56px;
45 | height: 56px;
46 | line-height: 56px;
47 | display: inline-block;
48 | text-align: center;
49 | }
--------------------------------------------------------------------------------
/src/style/card.less:
--------------------------------------------------------------------------------
1 | .react-draggable, .cursor-move{
2 | cursor: move;
3 | strong {
4 | background: #ddd;
5 | border: 1px solid #999;
6 | border-radius: 3px;
7 | display: block;
8 | margin-bottom: 10px;
9 | padding: 3px 5px;
10 | text-align: center;
11 | }
12 | }
13 | .no-cursor {
14 | cursor: auto;
15 | }
16 | .card-tool {
17 | position: absolute;
18 | right: 24px;
19 | top: 24px;
20 | }
21 |
22 | .list-group {
23 | .list-group-item {
24 | position: relative;
25 | display: block;
26 | margin-bottom: -1px;
27 | padding: 12px 16px;
28 | background: transparent;
29 | border: 1px solid #ddd;
30 | border-color: rgba(120, 130, 140, 0.065);
31 | border-width: 1px 0;
32 | &:first-child {
33 | border-top-width: 0;
34 | }
35 | &:last-child {
36 | border-bottom-width: 0;
37 | }
38 | }
39 | }
40 | .no-padding {
41 | .ant-card-body {
42 | padding: 0 !important;
43 | }
44 | }
--------------------------------------------------------------------------------
/src/components/ui/emoji/index.jsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by hao.cheng on 2017/4/22.
3 | */
4 | import React from 'react';
5 | import PropTypes from 'prop-types';
6 | import './iconfont';
7 |
8 | const Emoji = ({type}) => {
9 | const useTag = ``;
10 | return (
11 |
12 |
13 |
26 |
27 |
28 | );
29 | };
30 |
31 | Emoji.propTypes = {
32 | type: PropTypes.string.isRequired
33 | };
34 |
35 | export default Emoji;
--------------------------------------------------------------------------------
/src/reducer/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by 叶子 on 2017/7/30.
3 | */
4 | import { combineReducers } from 'redux';
5 | import * as type from '../action/type';
6 |
7 | const handleData = (state = {isFetching: true, data: {}}, action) => {
8 | switch (action.type) {
9 | case type.REQUEST_DATA:
10 | return {...state, isFetching: true};
11 | case type.RECEIVE_DATA:
12 | return {...state, isFetching: false, data: action.data};
13 | default:
14 | return {...state};
15 | }
16 | };
17 | const httpData = (state = {}, action) => {
18 | switch (action.type) {
19 | case type.RECEIVE_DATA:
20 | case type.REQUEST_DATA:
21 | return {
22 | ...state,
23 | [action.category]: handleData(state[action.category], action)
24 | };
25 | default:
26 | return {...state};
27 | }
28 | };
29 |
30 | export default combineReducers({
31 | httpData
32 | });
33 |
--------------------------------------------------------------------------------
/src/style/global.less:
--------------------------------------------------------------------------------
1 | small {
2 | opacity: .6;
3 | }
4 | .text-muted{
5 | opacity: .6;
6 | }
7 | .clear{
8 | display: block;
9 | overflow: hidden;
10 | }
11 | .center {
12 | display: flex;
13 | justify-content: center;
14 | align-items: center;
15 | }
16 | .y-center{
17 | display: flex;
18 | align-items: center;
19 | }
20 | .block{
21 | display: block;
22 | }
23 | .inline {
24 | display: inline;
25 | }
26 | .none{
27 | display: none;
28 | }
29 | .b-white {
30 | border-color: #ffffff;
31 | }
32 | .w-full {
33 | width: 100%;
34 | }
35 |
36 | .w-auto {
37 | width: auto;
38 | }
39 |
40 | .h-auto {
41 | height: auto;
42 | }
43 |
44 | .h-full {
45 | height: 100%;
46 | }
47 |
48 | .h-v {
49 | height: 100vh;
50 | }
51 |
52 | .h-v-5 {
53 | height: 50vh;
54 | }
55 |
56 |
57 | .pull-left {
58 | float: left;
59 | }
60 |
61 | .pull-right {
62 | float: right;
63 | }
64 |
65 | .w-40 {
66 | width: 40px;
67 | height: 40px;
68 | line-height: 40px;
69 | display: inline-block;
70 | text-align: center;
71 | }
--------------------------------------------------------------------------------
/src/components/auth/RouterEnter.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by 叶子 on 2017/8/1.
3 | */
4 | /**
5 | * Created by 叶子 on 2017/7/31.
6 | */
7 | import React, { Component } from 'react';
8 | import { Row, Col, Card } from 'antd';
9 | import BreadcrumbCustom from '@/components/BreadcrumbCustom';
10 | import AuthWidget from '@/components/widget/AuthWidget';
11 |
12 | class RouterEnter extends Component {
13 | render() {
14 | return (
15 |
16 |
17 |
(
19 |
20 |
21 |
22 | 只有管理员登录才能看到该页面,否则跳转到404页面
23 |
24 |
25 |
26 | )}
27 | />
28 |
29 | )
30 | }
31 | }
32 |
33 | export default RouterEnter;
--------------------------------------------------------------------------------
/src/style/index.less:
--------------------------------------------------------------------------------
1 | @import "variables";
2 | @import "global";
3 | @import "scroll";
4 | @import "table";
5 | @import "login";
6 | @import "icons";
7 | @import "button";
8 | @import "modal";
9 | @import "menu";
10 | @import "banner";
11 | @import "card";
12 | @import "img";
13 | @import "utils-text";
14 | @import "utils-color";
15 | @import "utils-size";
16 | @import "utils-border";
17 | @import "utils-spacing";
18 | #root{
19 | height: 100%;
20 | }
21 | .ant-layout{
22 | height: 100%;
23 | .logo{
24 | height: 32px;
25 | background: #333;
26 | border-radius: 6px;
27 | margin: 16px;
28 | }
29 | .ant-layout-sider-collapsed{
30 | .anticon{
31 | font-size: 16px;
32 | margin-left: 8px;
33 | }
34 | .nav-text{
35 | display: none;
36 | }
37 | .ant-menu-submenu-vertical > .ant-menu-submenu-title:after{
38 | display: none;
39 | }
40 | }
41 | p {
42 | margin: 10px 0 10px 0;
43 | }
44 | }
45 | .gutter-example{
46 | .ant-row{
47 | //margin-left: 0 !important;
48 | //margin-right: 0 !important;
49 | >div{
50 | background: transparent;
51 | border: 0;
52 | }
53 | }
54 | }
55 | .gutter-box {
56 | padding: 5px 0;
57 | }
--------------------------------------------------------------------------------
/src/style/variables.less:
--------------------------------------------------------------------------------
1 | @full-black: rgba(0, 0, 0, 1);
2 | @dark-black: rgba(0, 0, 0, 0.87);
3 | @light-black: rgba(0, 0, 0, 0.54);
4 | @min-black: rgba(0, 0, 0, 0.065);
5 |
6 | @full-white: rgba(255, 255, 255, 1);
7 | @dark-white: rgba(255, 255, 255, 0.87);
8 | @light-white: rgba(255, 255, 255, 0.54);
9 | @min-white: rgba(255, 255, 255, 0.1);
10 |
11 | @primary: #0cc2aa;
12 | @accent: #a88add;
13 | @warn: #fcc100;
14 |
15 | @info: #6887ff;
16 | @success: #6cc788;
17 | @warning: #f77a99;
18 | @danger: #f44455;
19 |
20 | @light: #f8f8f8;
21 | @grey: #424242;
22 | @dark: #2e3e4e;
23 | @black: #2a2b3c;
24 | @white: #ffffff;
25 |
26 | @primary-color: @dark-white;
27 | @accent-color: @dark-white;
28 | @warn-color: @dark-white;
29 | @success-color: @dark-white;
30 | @info-color: @dark-white;
31 | @warning-color: @dark-white;
32 | @danger-color: @dark-white;
33 | @light-color: @dark-black;
34 | @grey-color: @dark-white;
35 | @dark-color: @dark-white;
36 | @black-color: @dark-white;
37 |
38 | @border-color: rgba(120, 130, 140, 0.13);
39 |
40 | @spacer: 1rem;
--------------------------------------------------------------------------------
/src/components/tables/ExpandedTable.jsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by hao.cheng on 2017/4/16.
3 | */
4 | import React from 'react';
5 | import { Table } from 'antd';
6 |
7 | const columns = [
8 | { title: 'Name', dataIndex: 'name', key: 'name' },
9 | { title: 'Age', dataIndex: 'age', key: 'age' },
10 | { title: 'Address', dataIndex: 'address', key: 'address' },
11 | { title: 'Action', dataIndex: '', key: 'x', render: () => Delete },
12 | ];
13 |
14 | const data = [
15 | { key: 1, name: 'John Brown', age: 32, address: 'New York No. 1 Lake Park', description: 'My name is John Brown, I am 32 years old, living in New York No. 1 Lake Park.' },
16 | { key: 2, name: 'Jim Green', age: 42, address: 'London No. 1 Lake Park', description: 'My name is Jim Green, I am 42 years old, living in London No. 1 Lake Park.' },
17 | { key: 3, name: 'Joe Black', age: 32, address: 'Sidney No. 1 Lake Park', description: 'My name is Joe Black, I am 32 years old, living in Sidney No. 1 Lake Park.' },
18 | ];
19 |
20 | const ExpandedTable = () => (
21 | {record.description}
}
24 | dataSource={data}
25 | />
26 | );
27 |
28 | export default ExpandedTable;
--------------------------------------------------------------------------------
/src/components/charts/RechartsRadialBarChart.jsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by hao.cheng on 2017/4/22.
3 | */
4 | import React from 'react';
5 | import { RadialBarChart, RadialBar, Legend, Tooltip, ResponsiveContainer } from 'recharts';
6 |
7 | const data = [
8 | {name: '18-24', uv: 31.47, pv: 2400, fill: '#8884d8'},
9 | {name: '25-29', uv: 26.69, pv: 4567, fill: '#83a6ed'},
10 | {name: '30-34', uv: 15.69, pv: 1398, fill: '#8dd1e1'},
11 | {name: '35-39', uv: 8.22, pv: 9800, fill: '#82ca9d'},
12 | {name: '40-49', uv: 8.63, pv: 3908, fill: '#a4de6c'},
13 | {name: '50+', uv: 2.63, pv: 4800, fill: '#d0ed57'},
14 | {name: 'unknow', uv: 6.67, pv: 4800, fill: '#ffc658'}
15 | ];
16 |
17 | const RechartsRadialBarChart = () => (
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | );
26 |
27 | export default RechartsRadialBarChart;
--------------------------------------------------------------------------------
/src/components/charts/RechartsBarChart.jsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by hao.cheng on 2017/4/21.
3 | */
4 | import React from 'react';
5 | import {BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer} from 'recharts';
6 |
7 | const data = [
8 | {name: 'Page A', uv: 4000, pv: 2400, amt: 2400},
9 | {name: 'Page B', uv: 3000, pv: 1398, amt: 2210},
10 | {name: 'Page C', uv: 2000, pv: 9800, amt: 2290},
11 | {name: 'Page D', uv: 2780, pv: 3908, amt: 2000},
12 | {name: 'Page E', uv: 1890, pv: 4800, amt: 2181},
13 | {name: 'Page F', uv: 2390, pv: 3800, amt: 2500},
14 | {name: 'Page G', uv: 3490, pv: 4300, amt: 2100},
15 | ];
16 |
17 | const RechartsBarChart = () => (
18 |
19 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 | );
33 |
34 | export default RechartsBarChart;
--------------------------------------------------------------------------------
/src/components/charts/RechartsRadarChart.jsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by hao.cheng on 2017/4/22.
3 | */
4 | import React from 'react';
5 | import {Radar, RadarChart, PolarGrid, Legend,
6 | PolarAngleAxis, PolarRadiusAxis, ResponsiveContainer} from 'recharts';
7 |
8 | const data = [
9 | { subject: 'Math', A: 120, B: 110, fullMark: 150 },
10 | { subject: 'Chinese', A: 98, B: 130, fullMark: 150 },
11 | { subject: 'English', A: 86, B: 130, fullMark: 150 },
12 | { subject: 'Geography', A: 99, B: 100, fullMark: 150 },
13 | { subject: 'Physics', A: 85, B: 90, fullMark: 150 },
14 | { subject: 'History', A: 65, B: 85, fullMark: 150 },
15 | ];
16 |
17 | const RechartsRadarChart = () => (
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | );
29 |
30 | export default RechartsRadarChart;
--------------------------------------------------------------------------------
/src/components/charts/RechartsSimpleLineChart.jsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by hao.cheng on 2017/4/21.
3 | */
4 | import React from 'react';
5 | import {LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer} from 'recharts';
6 |
7 |
8 | const data = [
9 | {name: 'Page A', uv: 4000, pv: 2400, amt: 2400},
10 | {name: 'Page B', uv: 3000, pv: 1398, amt: 2210},
11 | {name: 'Page C', uv: 2000, pv: 9800, amt: 2290},
12 | {name: 'Page D', uv: 2780, pv: 3908, amt: 2000},
13 | {name: 'Page E', uv: 1890, pv: 4800, amt: 2181},
14 | {name: 'Page F', uv: 2390, pv: 3800, amt: 2500},
15 | {name: 'Page G', uv: 3490, pv: 4300, amt: 2100},
16 | ];
17 |
18 | const RechartsSimpleLineChart = () => (
19 |
20 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | );
35 |
36 | export default RechartsSimpleLineChart;
--------------------------------------------------------------------------------
/src/components/tables/BasicTable.jsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by hao.cheng on 2017/4/15.
3 | */
4 | import React from 'react';
5 | import { Table, Icon } from 'antd';
6 |
7 | const columns = [{
8 | title: 'Name',
9 | dataIndex: 'name',
10 | key: 'name',
11 | render: text => {text},
12 | }, {
13 | title: 'Age',
14 | dataIndex: 'age',
15 | key: 'age',
16 | }, {
17 | title: 'Address',
18 | dataIndex: 'address',
19 | key: 'address',
20 | }, {
21 | title: 'Action',
22 | key: 'action',
23 | render: (text, record) => (
24 |
25 | Action 一 {record.name}
26 |
27 | Delete
28 |
29 |
30 | More actions
31 |
32 |
33 | ),
34 | }];
35 |
36 | const data = [{
37 | key: '1',
38 | name: 'John Brown',
39 | age: 32,
40 | address: 'New York No. 1 Lake Park',
41 | }, {
42 | key: '2',
43 | name: 'Jim Green',
44 | age: 42,
45 | address: 'London No. 1 Lake Park',
46 | }, {
47 | key: '3',
48 | name: 'Joe Black',
49 | age: 32,
50 | address: 'Sidney No. 1 Lake Park',
51 | }];
52 |
53 | const BasicTable = () => (
54 |
55 | );
56 |
57 | export default BasicTable;
--------------------------------------------------------------------------------
/src/components/tables/FixedTable.jsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by hao.cheng on 2017/4/16.
3 | */
4 | import React from 'react';
5 | import { Table } from 'antd';
6 |
7 | const columns = [
8 | { title: 'Full Name', width: 100, dataIndex: 'name', key: 'name', fixed: 'left' },
9 | { title: 'Age', width: 100, dataIndex: 'age', key: 'age', fixed: 'left' },
10 | { title: 'Column 1', dataIndex: 'address', key: '1' },
11 | { title: 'Column 2', dataIndex: 'address', key: '2' },
12 | { title: 'Column 3', dataIndex: 'address', key: '3' },
13 | { title: 'Column 4', dataIndex: 'address', key: '4' },
14 | { title: 'Column 5', dataIndex: 'address', key: '5' },
15 | { title: 'Column 6', dataIndex: 'address', key: '6' },
16 | { title: 'Column 7', dataIndex: 'address', key: '7' },
17 | { title: 'Column 8', dataIndex: 'address', key: '8' },
18 | {
19 | title: 'Action',
20 | key: 'operation',
21 | fixed: 'right',
22 | width: 100,
23 | render: () => action,
24 | },
25 | ];
26 |
27 | const data = [{
28 | key: '1',
29 | name: 'John Brown',
30 | age: 32,
31 | address: 'New York Park',
32 | }, {
33 | key: '2',
34 | name: 'Jim Green',
35 | age: 40,
36 | address: 'London Park',
37 | }];
38 |
39 | const FixedTable = () => (
40 |
41 | );
42 |
43 | export default FixedTable;
--------------------------------------------------------------------------------
/src/style/menu.less:
--------------------------------------------------------------------------------
1 | .ant-menu-dark {
2 | &.ant-menu-inline {
3 | .ant-menu-item-selected {
4 | background-color: #5f5f5f !important;
5 | }
6 | }
7 | }
8 | .custom-trigger {
9 | font-size: 18px;
10 | line-height: 64px;
11 | padding: 0 16px;
12 | cursor: pointer;
13 | transition: color .3s;
14 | }
15 | .ant-layout-sider-collapsed {
16 | overflow-y: initial !important;
17 | }
18 | .avatar {
19 | position: relative;
20 | display: inline-block;
21 | width: 40px;
22 | line-height: 1;
23 | border-radius: 500px;
24 | white-space: nowrap;
25 | font-weight: bold;
26 | i {
27 | position: absolute;
28 | left: 0;
29 | top: 0;
30 | width: 10px;
31 | height: 10px;
32 | margin: 1px;
33 | border-width: 2px;
34 | border-style: solid;
35 | border-radius: 100%;
36 | &.bottom {
37 | left: auto;
38 | top: auto;
39 | bottom: 0;
40 | right: 0;
41 | }
42 | &.on {
43 | background-color: #6cc788;
44 | }
45 | }
46 | img {
47 | border-radius: 500px;
48 | width: 100%;
49 | }
50 | }
51 | .switcher {
52 | z-index: 1050;
53 | position: fixed;
54 | top: 78px;
55 | right: -240px;
56 | width: 240px;
57 | transition: right 0.2s ease;
58 | border: 1px solid rgba(120, 120, 120, 0.1);
59 | background-clip: padding-box;
60 | &.active {
61 | right: -2px;
62 | }
63 | .sw-btn {
64 | position: absolute;
65 | left: -43px;
66 | top: -1px;
67 | padding: 10px 15px;
68 | z-index: 1045;
69 | border: 1px solid rgba(120, 120, 120, 0.1);
70 | border-right-width: 0;
71 | background-clip: padding-box;
72 | }
73 | }
--------------------------------------------------------------------------------
/src/components/ui/banners/index.jsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by hao.cheng on 2017/4/26.
3 | */
4 | import React from 'react';
5 | import { Row, Col, Card } from 'antd';
6 | import BreadcrumbCustom from '../../BreadcrumbCustom';
7 | import Basic from './Basic';
8 | import AutoPlay from './AutoPlay';
9 | import Custom from './Custom';
10 |
11 | class Banners extends React.Component {
12 | render() {
13 | return (
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | )
41 | }
42 | }
43 |
44 | export default Banners;
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
11 |
12 |
13 |
22 | React App
23 |
24 |
25 |
28 |
29 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/src/axios/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by hao.cheng on 2017/4/16.
3 | */
4 | import axios from 'axios';
5 | import { get } from './tools';
6 | import * as config from './config';
7 |
8 | export const getPros = () => axios.post('http://api.xitu.io/resources/github', {
9 | category: "trending",
10 | period: "day",
11 | lang: "javascript",
12 | offset: 0,
13 | limit: 30
14 | }).then(function (response) {
15 | return response.data;
16 | }).catch(function (error) {
17 | console.log(error);
18 | });
19 |
20 | export const npmDependencies = () => axios.get('./npm.json').then(res => res.data).catch(err => console.log(err));
21 |
22 | export const weibo = () => axios.get('./weibo.json').then(res => res.data).catch(err => console.log(err));
23 |
24 | const GIT_OAUTH = 'https://github.com/login/oauth';
25 | export const gitOauthLogin = () => axios.get(`${GIT_OAUTH}/authorize?client_id=792cdcd244e98dcd2dee&redirect_uri=http://localhost:3006/&scope=user&state=reactAdmin`);
26 | export const gitOauthToken = code => axios.post('https://cors-anywhere.herokuapp.com/' + GIT_OAUTH + '/access_token', {...{client_id: '792cdcd244e98dcd2dee',
27 | client_secret: '81c4ff9df390d482b7c8b214a55cf24bf1f53059', redirect_uri: 'http://localhost:3006/', state: 'reactAdmin'}, code: code}, {headers: {Accept: 'application/json'}})
28 | .then(res => res.data).catch(err => console.log(err));
29 | export const gitOauthInfo = access_token => axios({
30 | method: 'get',
31 | url: 'https://api.github.com/user?access_token=' + access_token,
32 | }).then(res => res.data).catch(err => console.log(err));
33 |
34 | // easy-mock数据交互
35 | // 管理员权限获取
36 | export const admin = () => get({url: config.MOCK_AUTH_ADMIN});
37 |
38 | // 访问权限获取
39 | export const guest = () => get({url: config.MOCK_AUTH_VISITOR});
--------------------------------------------------------------------------------
/src/components/tables/AdvancedTables.jsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by hao.cheng on 2017/4/16.
3 | */
4 | import React from 'react';
5 | import { Row, Col, Card } from 'antd';
6 | import FixedTable from './FixedTable';
7 | import ExpandedTable from './ExpandedTable';
8 | import EditableTable from './EditableTable';
9 | import BreadcrumbCustom from '../BreadcrumbCustom';
10 |
11 | class AdvancedTables extends React.Component {
12 | render() {
13 | return (
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 | );
43 | }
44 | }
45 |
46 | export default AdvancedTables;
--------------------------------------------------------------------------------
/src/components/tables/BasicTables.jsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by hao.cheng on 2017/4/15.
3 | */
4 | import React from 'react';
5 | import { Row, Col, Card } from 'antd';
6 | import BasicTable from './BasicTable';
7 | import SelectTable from './SelectTable';
8 | import SortTable from './SortTable';
9 | import SearchTable from './SearchTable';
10 | import BreadcrumbCustom from '../BreadcrumbCustom';
11 |
12 | const BasicTables = () => (
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | {/**/}
25 | {/**/}
26 | {/**/}
27 | {/**/}
28 | {/*
*/}
29 | {/**/}
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | );
58 |
59 | export default BasicTables;
--------------------------------------------------------------------------------
/src/components/auth/Basic.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by 叶子 on 2017/7/31.
3 | */
4 | import React, { Component } from 'react';
5 | import { Row, Col, Card } from 'antd';
6 | import BreadcrumbCustom from '@/components/BreadcrumbCustom';
7 | import AuthWidget from '@/components/widget/AuthWidget';
8 | import beauty from '@/style/imgs/beauty.jpg';
9 |
10 | class Basic extends Component {
11 | render() {
12 | return (
13 |
14 |
15 |
(
17 |
18 |
19 |
20 | {!auth.uid && 登录之后你将看到一张美女图
}
21 | {
22 | auth.permissions && auth.permissions.includes('auth/authPage/visit') &&
23 |
24 |

25 | {(auth.permissions.includes('auth/authPage/edit') &&
26 |
27 |
看啥子美女,看点美景就行啦~😄😄
28 |
管理员身份登录才能看到这两段话
29 |
) ||
30 |
33 | }
34 |
35 |
36 | }
37 |
38 |
39 |
40 | )}
41 | />
42 |
43 |
44 | )
45 | }
46 | }
47 |
48 | export default Basic;
--------------------------------------------------------------------------------
/src/components/charts/Echarts.jsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by hao.cheng on 2017/4/17.
3 | */
4 | import React from 'react';
5 | import { Row, Col, Card } from 'antd';
6 | import EchartsArea from './EchartsArea';
7 | import EchartsPie from './EchartsPie';
8 | import EchartsEffectScatter from './EchartsEffectScatter';
9 | import EchartsForce from './EchartsForce';
10 |
11 | class Echarts extends React.Component {
12 | render() {
13 | return (
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | {/**/}
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 | )
52 | }
53 | }
54 |
55 | export default Echarts;
--------------------------------------------------------------------------------
/src/components/charts/Recharts.jsx:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by hao.cheng on 2017/4/21.
3 | */
4 | import React from 'react';
5 | import { Row, Col, Card } from 'antd';
6 | import RechartsSimpleLineChart from './RechartsSimpleLineChart';
7 | import RechartsBarChart from './RechartsBarChart';
8 | import RechartsRadialBarChart from './RechartsRadialBarChart';
9 | import RechartsRadarChart from './RechartsRadarChart';
10 |
11 | class Recharts extends React.Component {
12 | render() {
13 | return (
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | )
51 | }
52 | }
53 |
54 | export default Recharts;
--------------------------------------------------------------------------------
/config/paths.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const path = require('path');
4 | const fs = require('fs');
5 | const url = require('url');
6 |
7 | // Make sure any symlinks in the project folder are resolved:
8 | // https://github.com/facebookincubator/create-react-app/issues/637
9 | const appDirectory = fs.realpathSync(process.cwd());
10 | const resolveApp = relativePath => path.resolve(appDirectory, relativePath);
11 |
12 | const envPublicUrl = process.env.PUBLIC_URL;
13 |
14 | function ensureSlash(path, needsSlash) {
15 | const hasSlash = path.endsWith('/');
16 | if (hasSlash && !needsSlash) {
17 | return path.substr(path, path.length - 1);
18 | } else if (!hasSlash && needsSlash) {
19 | return `${path}/`;
20 | } else {
21 | return path;
22 | }
23 | }
24 |
25 | const getPublicUrl = appPackageJson =>
26 | envPublicUrl || require(appPackageJson).homepage;
27 |
28 | // We use `PUBLIC_URL` environment variable or "homepage" field to infer
29 | // "public path" at which the app is served.
30 | // Webpack needs to know it to put the right