├── .editorconfig ├── .gitignore ├── .gitmodules ├── CHANGELOG.md ├── README.md ├── assets ├── btn-learn-more.png ├── btn-live-preview.png ├── demo-preview.gif └── preview.png ├── package.json ├── public ├── favicon.ico ├── index.html └── manifest.json ├── src ├── App.js ├── App.test.js ├── assets │ ├── quill.css │ └── range-date-picker.css ├── components │ ├── add-new-post │ │ ├── Editor.js │ │ ├── SidebarActions.js │ │ └── SidebarCategories.js │ ├── blog │ │ ├── Discussions.js │ │ ├── NewDraft.js │ │ ├── UsersByDevice.js │ │ └── UsersOverview.js │ ├── common │ │ ├── CountryReports.js │ │ ├── PageTitle.js │ │ ├── RangeDatePicker.js │ │ ├── SmallStats.js │ │ └── TopReferrals.js │ ├── components-overview │ │ ├── ButtonGroups.js │ │ ├── Checkboxes.js │ │ ├── Colors.js │ │ ├── CompleteFormExample.js │ │ ├── CustomFileUpload.js │ │ ├── CustomSelect.js │ │ ├── DropdownInputGroups.js │ │ ├── FormValidation.js │ │ ├── Forms.js │ │ ├── InputGroups.js │ │ ├── NormalButtons.js │ │ ├── NormalOutlineButtons.js │ │ ├── ProgressBars.js │ │ ├── RadioButtons.js │ │ ├── SeamlessInputGroups.js │ │ ├── Sliders.js │ │ ├── SmallButtons.js │ │ ├── SmallOutlineButtons.js │ │ └── ToggleButtons.js │ ├── layout │ │ ├── MainFooter.js │ │ ├── MainNavbar │ │ │ ├── MainNavbar.js │ │ │ ├── NavbarNav │ │ │ │ ├── NavbarNav.js │ │ │ │ ├── Notifications.js │ │ │ │ └── UserActions.js │ │ │ ├── NavbarSearch.js │ │ │ └── NavbarToggle.js │ │ └── MainSidebar │ │ │ ├── MainSidebar.js │ │ │ ├── SidebarMainNavbar.js │ │ │ ├── SidebarNavItem.js │ │ │ ├── SidebarNavItems.js │ │ │ └── SidebarSearch.js │ └── user-profile-lite │ │ ├── UserAccountDetails.js │ │ └── UserDetails.js ├── data │ └── sidebar-nav-items.js ├── flux │ ├── constants.js │ ├── dispatcher.js │ ├── index.js │ └── store.js ├── images │ ├── avatars │ │ ├── 0.jpg │ │ ├── 1.jpg │ │ ├── 2.jpg │ │ └── 3.jpg │ ├── content-management │ │ ├── 1.jpeg │ │ ├── 10.jpeg │ │ ├── 11.jpeg │ │ ├── 12.jpeg │ │ ├── 13.jpeg │ │ ├── 14.jpeg │ │ ├── 15.jpeg │ │ ├── 16.jpeg │ │ ├── 2.jpeg │ │ ├── 3.jpeg │ │ ├── 4.jpeg │ │ ├── 5.jpeg │ │ ├── 6.jpeg │ │ ├── 7.jpeg │ │ ├── 8.jpeg │ │ └── 9.jpeg │ ├── file-manager │ │ └── document-preview-1.jpg │ ├── flags │ │ ├── flag-au.png │ │ ├── flag-jp.png │ │ ├── flag-uk.png │ │ └── flag-us.png │ ├── sales-overview │ │ ├── no-product-image.jpg │ │ ├── product-basics.jpg │ │ ├── product-order-1.jpg │ │ ├── product-order-2.jpg │ │ ├── product-order-3.jpg │ │ ├── product-shoes.jpg │ │ ├── product-sportswear.jpg │ │ └── product-sweaters.jpg │ ├── shards-dashboards-logo-danger.svg │ ├── shards-dashboards-logo-info.svg │ ├── shards-dashboards-logo-java.svg │ ├── shards-dashboards-logo-royal-blue.svg │ ├── shards-dashboards-logo-salmon.svg │ ├── shards-dashboards-logo-secondary.svg │ ├── shards-dashboards-logo-success.svg │ ├── shards-dashboards-logo-warning.svg │ ├── shards-dashboards-logo.svg │ └── user-profile │ │ ├── team-thumb-1.png │ │ ├── team-thumb-2.png │ │ ├── team-thumb-3.png │ │ └── up-user-details-background.jpg ├── index.js ├── layouts │ ├── Default.js │ └── index.js ├── routes.js ├── serviceWorker.js ├── utils │ └── chart.js ├── views │ ├── AddNewPost.js │ ├── BlogOverview.js │ ├── BlogPosts.js │ ├── ComponentsOverview.js │ ├── Errors.js │ ├── Tables.js │ └── UserProfileLite.js └── withTracker.js └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | end_of_line = lf 7 | indent_size = 2 8 | indent_style = space 9 | insert_final_newline = true 10 | max_line_length = 80 11 | trim_trailing_whitespace = true 12 | 13 | [*.md] 14 | max_line_length = 0 15 | trim_trailing_whitespace = false 16 | 17 | [COMMIT_EDITMSG] 18 | max_line_length = 0 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "src/shards-dashboard"] 2 | path = src/shards-dashboard 3 | url = git@github.com:DesignRevision/shards-dashboard.git 4 | branch = master 5 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this project will be documented in this file. 3 | 4 | ## [1.0.0] - 2019-01-07 5 | 6 | - Initial release. 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | 4 | 5 |

6 | 7 |

Shards Dashboard React

8 |

9 | 10 | 11 | 12 | 13 | 14 | 15 |

16 | 17 |

18 | A free React admin dashboard template pack featuring a modern design system
and lots of custom templates and components. 19 |

20 | 21 |

22 | 23 | 24 | 25 | 26 | 27 | 28 |

29 | 30 |
31 | 32 |

33 | 34 | 35 | 36 |

37 | 38 |
39 | 40 | > ✨ **Note:** You can download the Sketch files from the official product page. 41 | 42 |
43 | 44 | ### Quick Start 45 | 46 | * Install dependencies by running `yarn` or `npm install`. 47 | * Run `yarn start` or `npm run start` to start the local development server. 48 | * 😎 **That's it!** You're ready to start building awesome dashboards. 49 | 50 |
51 | 52 | ### Project Structure 53 | 54 | - This project is bootstrapped using [Create React App](https://github.com/facebook/create-react-app). 55 | - **Flux** is used for state management and all Flux specific files are located inside `src/flux`. Transitioning to a more robust solution such as Redux is also fairly simple. 56 | - All primary templates are located inside `src/views`. 57 | - There is only one single layout defined (Default) inside `src/layouts`, however, the current structure provides an easy way of extending the UI kit. 58 | - The `src/components` directory hosts all template-specific subcomponents in their own subdirectory. 59 | - The layout styles inherited from Shards Dashboard are pulled in from the `src/shards-dashboard` submodule inside `src/App.js`. 60 | - Other extra styles specific to the libraries used are located inside `src/assets`. 61 | - The `src/utils` directory contains generic Chart.js utilities. 62 | 63 |
64 | 65 | ### Available Scripts 66 | 67 | ### `npm start` 68 | 69 | Runs the app in the development mode. 70 | 71 | ### `npm test` 72 | 73 | Launches the test runner in the interactive watch mode. 74 | 75 | ### `npm run build` 76 | 77 | Builds the app for production to the `build` folder. 78 | 79 | ### `npm run eject` 80 | 81 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!** 82 | 83 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. 84 | 85 | 86 |
87 | 88 | ### 🌟 Pro Version 89 | 90 | If you're looking for something more, check out [Shards Dashboard Pro React](https://designrevision.com/downloads/shards-dashboard-pro-react/) which features many more custom templates and components. Use the `GITHUB15` coupon code for a **15% discount off the current price**. 91 | 92 |
93 | 94 | ### Built using 95 | 96 | - [Shards React](https://github.com/designrevision/shards-react) 97 | - [Chart.js](https://www.chartjs.org/) 98 | - [Flux](https://facebook.github.io/flux/) 99 | - [No UI Slider](https://refreshless.com/nouislider/) 100 | - [React Datepicker](https://www.npmjs.com/package/react-datepicker) 101 | - [Quill](https://quilljs.com/) 102 | 103 |
104 | 105 | ### Changelog 106 | 107 | Please check out the [CHANGELOG](CHANGELOG.md). 108 | -------------------------------------------------------------------------------- /assets/btn-learn-more.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DesignRevision/shards-dashboard-react/6f8840524e4de2965e5585cfefd2a9b6bb088eb9/assets/btn-learn-more.png -------------------------------------------------------------------------------- /assets/btn-live-preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DesignRevision/shards-dashboard-react/6f8840524e4de2965e5585cfefd2a9b6bb088eb9/assets/btn-live-preview.png -------------------------------------------------------------------------------- /assets/demo-preview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DesignRevision/shards-dashboard-react/6f8840524e4de2965e5585cfefd2a9b6bb088eb9/assets/demo-preview.gif -------------------------------------------------------------------------------- /assets/preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DesignRevision/shards-dashboard-react/6f8840524e4de2965e5585cfefd2a9b6bb088eb9/assets/preview.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "shards-dashboard-lite-react", 3 | "version": "1.0.0", 4 | "private": true, 5 | "homepage": "./", 6 | "dependencies": { 7 | "camelize": "^1.0.0", 8 | "chart.js": "^2.7.3", 9 | "classnames": "^2.2.6", 10 | "cross-env": "^5.2.0", 11 | "dateformat": "^3.0.3", 12 | "flux": "^3.1.3", 13 | "lodash.find": "^4.6.0", 14 | "react": "^16.6.3", 15 | "react-dom": "^16.6.3", 16 | "react-ga": "^2.5.6", 17 | "react-quill": "^1.3.3", 18 | "react-router-dom": "^4.3.1", 19 | "react-scripts": "2.1.1", 20 | "shards-react": "^1.0.0", 21 | "shortid": "^2.2.14" 22 | }, 23 | "scripts": { 24 | "start": "react-scripts start", 25 | "build:prod": "cross-env REACT_APP_BASENAME=/demo/shards-dashboard-lite-react REACT_APP_GAID=UA-115105611-1 npm run build", 26 | "build": "cross-env REACT_APP_BASENAME=/demo/shards-dashboard-lite-react react-scripts build", 27 | "test": "react-scripts test", 28 | "eject": "react-scripts eject" 29 | }, 30 | "eslintConfig": { 31 | "extends": "react-app" 32 | }, 33 | "browserslist": [ 34 | ">0.2%", 35 | "not dead", 36 | "not ie <= 11", 37 | "not op_mini all" 38 | ] 39 | } 40 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DesignRevision/shards-dashboard-react/6f8840524e4de2965e5585cfefd2a9b6bb088eb9/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 14 | 15 | 24 | Shards Dashboard Lite React 25 | 26 | 27 | 30 |
31 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "Shards Dashboard Lite React", 3 | "name": "Shards Dashboard Lite React", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": ".", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { BrowserRouter as Router, Route } from "react-router-dom"; 3 | 4 | import routes from "./routes"; 5 | import withTracker from "./withTracker"; 6 | 7 | import "bootstrap/dist/css/bootstrap.min.css"; 8 | import "./shards-dashboard/styles/shards-dashboards.1.1.0.min.css"; 9 | 10 | export default () => ( 11 | 12 |
13 | {routes.map((route, index) => { 14 | return ( 15 | { 20 | return ( 21 | 22 | 23 | 24 | ); 25 | })} 26 | /> 27 | ); 28 | })} 29 |
30 |
31 | ); 32 | -------------------------------------------------------------------------------- /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 | ReactDOM.unmountComponentAtNode(div); 9 | }); 10 | -------------------------------------------------------------------------------- /src/assets/quill.css: -------------------------------------------------------------------------------- 1 | .add-new-post__editor .ql-container, 2 | .add-new-post__editor .ql-editor { 3 | min-height: 400px; 4 | } 5 | -------------------------------------------------------------------------------- /src/assets/range-date-picker.css: -------------------------------------------------------------------------------- 1 | .date-range .react-datepicker-wrapper { 2 | display: flex; 3 | flex: 1; 4 | max-width: 160px; 5 | } 6 | 7 | .date-range .react-datepicker__input-container { 8 | width: 100%; 9 | } 10 | 11 | @media (max-width: 575px) { 12 | .date-range .react-datepicker-wrapper { 13 | max-width: 100%; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/components/add-new-post/Editor.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactQuill from "react-quill"; 3 | import { Card, CardBody, Form, FormInput } from "shards-react"; 4 | 5 | import "react-quill/dist/quill.snow.css"; 6 | import "../../assets/quill.css"; 7 | 8 | const Editor = () => ( 9 | 10 | 11 |
12 | 13 | 14 | 15 |
16 |
17 | ); 18 | 19 | export default Editor; 20 | -------------------------------------------------------------------------------- /src/components/add-new-post/SidebarActions.js: -------------------------------------------------------------------------------- 1 | /* eslint jsx-a11y/anchor-is-valid: 0 */ 2 | 3 | import React from "react"; 4 | import PropTypes from "prop-types"; 5 | import { 6 | Card, 7 | CardHeader, 8 | CardBody, 9 | ListGroup, 10 | ListGroupItem, 11 | Button 12 | } from "shards-react"; 13 | 14 | const SidebarActions = ({ title }) => ( 15 | 16 | 17 |
{title}
18 |
19 | 20 | 21 | 22 | 23 | 24 | flag 25 | Status: Draft{" "} 26 | 27 | Edit 28 | 29 | 30 | 31 | visibility 32 | Visibility:{" "} 33 | Public{" "} 34 | 35 | Edit 36 | 37 | 38 | 39 | calendar_today 40 | Schedule: Now{" "} 41 | 42 | Edit 43 | 44 | 45 | 46 | score 47 | Readability:{" "} 48 | Ok 49 | 50 | 51 | 52 | 55 | 58 | 59 | 60 | 61 |
62 | ); 63 | 64 | SidebarActions.propTypes = { 65 | /** 66 | * The component's title. 67 | */ 68 | title: PropTypes.string 69 | }; 70 | 71 | SidebarActions.defaultProps = { 72 | title: "Actions" 73 | }; 74 | 75 | export default SidebarActions; 76 | -------------------------------------------------------------------------------- /src/components/add-new-post/SidebarCategories.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import PropTypes from "prop-types"; 3 | import { 4 | Card, 5 | CardHeader, 6 | CardBody, 7 | ListGroup, 8 | ListGroupItem, 9 | Button, 10 | InputGroup, 11 | InputGroupAddon, 12 | FormCheckbox, 13 | FormInput 14 | } from "shards-react"; 15 | 16 | const SidebarCategories = ({ title }) => ( 17 | 18 | 19 |
{title}
20 |
21 | 22 | 23 | 24 | 25 | Uncategorized 26 | 27 | 28 | Design 29 | 30 | 31 | Development 32 | 33 | 34 | Writing 35 | 36 | 37 | Books 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 48 | 49 | 50 | 51 | 52 | 53 |
54 | ); 55 | 56 | SidebarCategories.propTypes = { 57 | /** 58 | * The component's title. 59 | */ 60 | title: PropTypes.string 61 | }; 62 | 63 | SidebarCategories.defaultProps = { 64 | title: "Categories" 65 | }; 66 | 67 | export default SidebarCategories; 68 | -------------------------------------------------------------------------------- /src/components/blog/Discussions.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import PropTypes from "prop-types"; 3 | import { 4 | Card, 5 | CardHeader, 6 | CardBody, 7 | CardFooter, 8 | ButtonGroup, 9 | Button, 10 | Row, 11 | Col 12 | } from "shards-react"; 13 | 14 | const Discussions = ({ title, discussions }) => ( 15 | 16 | 17 |
{title}
18 |
19 | 20 | 21 | {discussions.map((discussion, idx) => ( 22 |
23 | {/* Avatar */} 24 |
25 | {discussion.author.name} 26 |
27 | 28 | {/* Content */} 29 |
30 | {/* Content :: Title */} 31 |
32 | 33 | {discussion.author.name} 34 | {" "} 35 | on{" "} 36 | 37 | {discussion.post.title} 38 | 39 | - {discussion.date} 40 |
41 | 42 | {/* Content :: Body */} 43 |

{discussion.body}

44 | 45 | {/* Content :: Actions */} 46 |
47 | 48 | 54 | 60 | 66 | 67 |
68 |
69 |
70 | ))} 71 |
72 | 73 | 74 | 75 | 76 | 79 | 80 | 81 | 82 |
83 | ); 84 | 85 | Discussions.propTypes = { 86 | /** 87 | * The component's title. 88 | */ 89 | title: PropTypes.string, 90 | /** 91 | * The discussions dataset. 92 | */ 93 | discussions: PropTypes.array 94 | }; 95 | 96 | Discussions.defaultProps = { 97 | title: "Discussions", 98 | discussions: [ 99 | { 100 | id: 1, 101 | date: "3 days ago", 102 | author: { 103 | image: require("../../images/avatars/1.jpg"), 104 | name: "John Doe", 105 | url: "#" 106 | }, 107 | post: { 108 | title: "Hello World!", 109 | url: "#" 110 | }, 111 | body: "Well, the way they make shows is, they make one show ..." 112 | }, 113 | { 114 | id: 2, 115 | date: "4 days ago", 116 | author: { 117 | image: require("../../images/avatars/2.jpg"), 118 | name: "John Doe", 119 | url: "#" 120 | }, 121 | post: { 122 | title: "Hello World!", 123 | url: "#" 124 | }, 125 | body: "After the avalanche, it took us a week to climb out. Now..." 126 | }, 127 | { 128 | id: 3, 129 | date: "5 days ago", 130 | author: { 131 | image: require("../../images/avatars/3.jpg"), 132 | name: "John Doe", 133 | url: "#" 134 | }, 135 | post: { 136 | title: "Hello World!", 137 | url: "#" 138 | }, 139 | body: "My money's in that office, right? If she start giving me..." 140 | } 141 | ] 142 | }; 143 | 144 | export default Discussions; 145 | -------------------------------------------------------------------------------- /src/components/blog/NewDraft.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import PropTypes from "prop-types"; 3 | import { 4 | Card, 5 | CardHeader, 6 | CardBody, 7 | Form, 8 | FormGroup, 9 | FormInput, 10 | FormTextarea, 11 | Button 12 | } from "shards-react"; 13 | 14 | const NewDraft = ({ title }) => ( 15 | 16 | {/* Card Header */} 17 | 18 |
{title}
19 |
20 | 21 | 22 |
23 | {/* Title */} 24 | 25 | 26 | 27 | 28 | {/* Body */} 29 | 30 | 31 | 32 | 33 | {/* Create Draft */} 34 | 35 | 38 | 39 |
40 |
41 |
42 | ); 43 | 44 | NewDraft.propTypes = { 45 | /** 46 | * The component's title. 47 | */ 48 | title: PropTypes.string 49 | }; 50 | 51 | NewDraft.defaultProps = { 52 | title: "New Draft" 53 | }; 54 | 55 | export default NewDraft; 56 | -------------------------------------------------------------------------------- /src/components/blog/UsersByDevice.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import PropTypes from "prop-types"; 3 | import { 4 | Row, 5 | Col, 6 | FormSelect, 7 | Card, 8 | CardHeader, 9 | CardBody, 10 | CardFooter 11 | } from "shards-react"; 12 | 13 | import Chart from "../../utils/chart"; 14 | 15 | class UsersByDevice extends React.Component { 16 | constructor(props) { 17 | super(props); 18 | 19 | this.canvasRef = React.createRef(); 20 | } 21 | 22 | componentDidMount() { 23 | const chartConfig = { 24 | type: "pie", 25 | data: this.props.chartData, 26 | options: { 27 | ...{ 28 | legend: { 29 | position: "bottom", 30 | labels: { 31 | padding: 25, 32 | boxWidth: 20 33 | } 34 | }, 35 | cutoutPercentage: 0, 36 | tooltips: { 37 | custom: false, 38 | mode: "index", 39 | position: "nearest" 40 | } 41 | }, 42 | ...this.props.chartOptions 43 | } 44 | }; 45 | 46 | new Chart(this.canvasRef.current, chartConfig); 47 | } 48 | 49 | render() { 50 | const { title } = this.props; 51 | return ( 52 | 53 | 54 |
{title}
55 |
56 | 57 | 62 | 63 | 64 | 65 | 66 | {}} 71 | > 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | {/* eslint-disable-next-line */} 80 | View full report → 81 | 82 | 83 | 84 |
85 | ); 86 | } 87 | } 88 | 89 | UsersByDevice.propTypes = { 90 | /** 91 | * The component's title. 92 | */ 93 | title: PropTypes.string, 94 | /** 95 | * The chart config object. 96 | */ 97 | chartConfig: PropTypes.object, 98 | /** 99 | * The Chart.js options. 100 | */ 101 | chartOptions: PropTypes.object, 102 | /** 103 | * The chart data. 104 | */ 105 | chartData: PropTypes.object 106 | }; 107 | 108 | UsersByDevice.defaultProps = { 109 | title: "Users by device", 110 | chartData: { 111 | datasets: [ 112 | { 113 | hoverBorderColor: "#ffffff", 114 | data: [68.3, 24.2, 7.5], 115 | backgroundColor: [ 116 | "rgba(0,123,255,0.9)", 117 | "rgba(0,123,255,0.5)", 118 | "rgba(0,123,255,0.3)" 119 | ] 120 | } 121 | ], 122 | labels: ["Desktop", "Tablet", "Mobile"] 123 | } 124 | }; 125 | 126 | export default UsersByDevice; 127 | -------------------------------------------------------------------------------- /src/components/blog/UsersOverview.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import PropTypes from "prop-types"; 3 | import { Row, Col, Card, CardHeader, CardBody, Button } from "shards-react"; 4 | 5 | import RangeDatePicker from "../common/RangeDatePicker"; 6 | import Chart from "../../utils/chart"; 7 | 8 | class UsersOverview extends React.Component { 9 | constructor(props) { 10 | super(props); 11 | 12 | this.canvasRef = React.createRef(); 13 | } 14 | 15 | componentDidMount() { 16 | const chartOptions = { 17 | ...{ 18 | responsive: true, 19 | legend: { 20 | position: "top" 21 | }, 22 | elements: { 23 | line: { 24 | // A higher value makes the line look skewed at this ratio. 25 | tension: 0.3 26 | }, 27 | point: { 28 | radius: 0 29 | } 30 | }, 31 | scales: { 32 | xAxes: [ 33 | { 34 | gridLines: false, 35 | ticks: { 36 | callback(tick, index) { 37 | // Jump every 7 values on the X axis labels to avoid clutter. 38 | return index % 7 !== 0 ? "" : tick; 39 | } 40 | } 41 | } 42 | ], 43 | yAxes: [ 44 | { 45 | ticks: { 46 | suggestedMax: 45, 47 | callback(tick) { 48 | if (tick === 0) { 49 | return tick; 50 | } 51 | // Format the amounts using Ks for thousands. 52 | return tick > 999 ? `${(tick / 1000).toFixed(1)}K` : tick; 53 | } 54 | } 55 | } 56 | ] 57 | }, 58 | hover: { 59 | mode: "nearest", 60 | intersect: false 61 | }, 62 | tooltips: { 63 | custom: false, 64 | mode: "nearest", 65 | intersect: false 66 | } 67 | }, 68 | ...this.props.chartOptions 69 | }; 70 | 71 | const BlogUsersOverview = new Chart(this.canvasRef.current, { 72 | type: "LineWithLine", 73 | data: this.props.chartData, 74 | options: chartOptions 75 | }); 76 | 77 | // They can still be triggered on hover. 78 | const buoMeta = BlogUsersOverview.getDatasetMeta(0); 79 | buoMeta.data[0]._model.radius = 0; 80 | buoMeta.data[ 81 | this.props.chartData.datasets[0].data.length - 1 82 | ]._model.radius = 0; 83 | 84 | // Render the chart. 85 | BlogUsersOverview.render(); 86 | } 87 | 88 | render() { 89 | const { title } = this.props; 90 | return ( 91 | 92 | 93 |
{title}
94 |
95 | 96 | 97 | 98 | 99 | 100 | 101 | 107 | 108 | 109 | 114 | 115 |
116 | ); 117 | } 118 | } 119 | 120 | UsersOverview.propTypes = { 121 | /** 122 | * The component's title. 123 | */ 124 | title: PropTypes.string, 125 | /** 126 | * The chart dataset. 127 | */ 128 | chartData: PropTypes.object, 129 | /** 130 | * The Chart.js options. 131 | */ 132 | chartOptions: PropTypes.object 133 | }; 134 | 135 | UsersOverview.defaultProps = { 136 | title: "Users Overview", 137 | chartData: { 138 | labels: Array.from(new Array(30), (_, i) => (i === 0 ? 1 : i)), 139 | datasets: [ 140 | { 141 | label: "Current Month", 142 | fill: "start", 143 | data: [ 144 | 500, 145 | 800, 146 | 320, 147 | 180, 148 | 240, 149 | 320, 150 | 230, 151 | 650, 152 | 590, 153 | 1200, 154 | 750, 155 | 940, 156 | 1420, 157 | 1200, 158 | 960, 159 | 1450, 160 | 1820, 161 | 2800, 162 | 2102, 163 | 1920, 164 | 3920, 165 | 3202, 166 | 3140, 167 | 2800, 168 | 3200, 169 | 3200, 170 | 3400, 171 | 2910, 172 | 3100, 173 | 4250 174 | ], 175 | backgroundColor: "rgba(0,123,255,0.1)", 176 | borderColor: "rgba(0,123,255,1)", 177 | pointBackgroundColor: "#ffffff", 178 | pointHoverBackgroundColor: "rgb(0,123,255)", 179 | borderWidth: 1.5, 180 | pointRadius: 0, 181 | pointHoverRadius: 3 182 | }, 183 | { 184 | label: "Past Month", 185 | fill: "start", 186 | data: [ 187 | 380, 188 | 430, 189 | 120, 190 | 230, 191 | 410, 192 | 740, 193 | 472, 194 | 219, 195 | 391, 196 | 229, 197 | 400, 198 | 203, 199 | 301, 200 | 380, 201 | 291, 202 | 620, 203 | 700, 204 | 300, 205 | 630, 206 | 402, 207 | 320, 208 | 380, 209 | 289, 210 | 410, 211 | 300, 212 | 530, 213 | 630, 214 | 720, 215 | 780, 216 | 1200 217 | ], 218 | backgroundColor: "rgba(255,65,105,0.1)", 219 | borderColor: "rgba(255,65,105,1)", 220 | pointBackgroundColor: "#ffffff", 221 | pointHoverBackgroundColor: "rgba(255,65,105,1)", 222 | borderDash: [3, 3], 223 | borderWidth: 1, 224 | pointRadius: 0, 225 | pointHoverRadius: 2, 226 | pointBorderColor: "rgba(255,65,105,1)" 227 | } 228 | ] 229 | } 230 | }; 231 | 232 | export default UsersOverview; 233 | -------------------------------------------------------------------------------- /src/components/common/CountryReports.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import PropTypes from "prop-types"; 3 | import { 4 | Card, 5 | CardHeader, 6 | CardBody, 7 | CardFooter, 8 | Col, 9 | Row, 10 | FormSelect 11 | } from "shards-react"; 12 | 13 | class CountryReports extends React.Component { 14 | constructor(props) { 15 | super(props); 16 | 17 | this.mapRef = React.createRef(); 18 | 19 | this.createGoogleMaps = this.createGoogleMaps.bind(this); 20 | this.initCountriesMap = this.initCountriesMap.bind(this); 21 | } 22 | 23 | componentDidMount() { 24 | this.createGoogleMaps().then(this.initCountriesMap); 25 | } 26 | 27 | render() { 28 | const { title, countries } = this.props; 29 | 30 | return ( 31 | 32 | 33 |
{title}
34 |
35 | 36 | 37 | 38 | {/* Map Container */} 39 |
45 | 46 | {/* Countries Table List */} 47 | 48 | 49 | {countries.map((country, idx) => ( 50 | 51 | 59 | 60 | 61 | 62 | ))} 63 | 64 |
52 | {country.title} 57 | {country.title} 58 | {country.visitorsAmount}{country.visitorsPercentage}
65 | 66 | 67 | 68 | 69 | {/* Time Span */} 70 | 71 | {}} 76 | > 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | {/* View Full Report */} 85 | 86 | {/* eslint-disable-next-line */} 87 | View full report → 88 | 89 | 90 | 91 | 92 | ); 93 | } 94 | 95 | createGoogleMaps() { 96 | if (window.__SDPGoogleChartLoaded__) { 97 | return new Promise(resolve => { 98 | resolve(); 99 | }); 100 | } 101 | 102 | window.__SDPGoogleChartLoaded__ = true; 103 | 104 | return new Promise((resolve, reject) => { 105 | const gmap = document.createElement("script"); 106 | gmap.src = "https://www.gstatic.com/charts/loader.js"; 107 | gmap.type = "text/javascript"; 108 | gmap.onload = resolve; 109 | gmap.onerror = reject; 110 | document.body.appendChild(gmap); 111 | }); 112 | } 113 | 114 | initCountriesMap() { 115 | /* global google */ 116 | 117 | google.charts.load("current", { 118 | packages: ["geochart"], 119 | mapsApiKey: "AIzaSyD-9tSrke72PouQMnMX-a7eZSW0jkFMBWY" 120 | }); 121 | 122 | google.charts.setOnLoadCallback(() => { 123 | const data = google.visualization.arrayToDataTable(this.props.mapsData); 124 | 125 | const options = { 126 | colorAxis: { 127 | colors: ["#B9C2D4", "#E4E8EF"] 128 | }, 129 | legend: false, 130 | width: "100%" 131 | }; 132 | 133 | const chart = new google.visualization.GeoChart(this.mapRef.current); 134 | 135 | function drawGeochart() { 136 | chart.draw(data, options); 137 | } 138 | 139 | drawGeochart(); 140 | window.addEventListener("resize", drawGeochart); 141 | }); 142 | } 143 | } 144 | 145 | CountryReports.propTypes = { 146 | /** 147 | * The component's title. 148 | */ 149 | title: PropTypes.string, 150 | /** 151 | * The countries data. 152 | */ 153 | countries: PropTypes.array, 154 | /** 155 | * The map data. 156 | */ 157 | mapsData: PropTypes.array 158 | }; 159 | 160 | CountryReports.defaultProps = { 161 | title: "Users by Country", 162 | countries: [ 163 | { 164 | flag: require("../../images/flags/flag-us.png"), 165 | title: "United States", 166 | visitorsAmount: "12,291", 167 | visitorsPercentage: "23.32%" 168 | }, 169 | { 170 | flag: require("../../images/flags/flag-uk.png"), 171 | title: "United Kingdom", 172 | visitorsAmount: "11,192", 173 | visitorsPercentage: "18.8%" 174 | }, 175 | { 176 | flag: require("../../images/flags/flag-au.png"), 177 | title: "Australia", 178 | visitorsAmount: "9,291", 179 | visitorsPercentage: "12.3%" 180 | }, 181 | { 182 | flag: require("../../images/flags/flag-jp.png"), 183 | title: "Japan", 184 | visitorsAmount: "2,291", 185 | visitorsPercentage: "8.14%" 186 | } 187 | ], 188 | mapsData: [ 189 | ["Country", "Users"], 190 | ["United States", 12219], 191 | ["United Kingdom", 11192], 192 | ["Australia", 9291], 193 | ["Japan", 2291] 194 | ] 195 | }; 196 | 197 | export default CountryReports; 198 | -------------------------------------------------------------------------------- /src/components/common/PageTitle.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import classNames from "classnames"; 3 | import PropTypes from "prop-types"; 4 | import { Col } from "shards-react"; 5 | 6 | const PageTitle = ({ title, subtitle, className, ...attrs }) => { 7 | const classes = classNames( 8 | className, 9 | "text-center", 10 | "text-md-left", 11 | "mb-sm-0" 12 | ); 13 | 14 | return ( 15 | 16 | {subtitle} 17 |

{title}

18 | 19 | ) 20 | }; 21 | 22 | PageTitle.propTypes = { 23 | /** 24 | * The page title. 25 | */ 26 | title: PropTypes.string, 27 | /** 28 | * The page subtitle. 29 | */ 30 | subtitle: PropTypes.string 31 | }; 32 | 33 | export default PageTitle; 34 | -------------------------------------------------------------------------------- /src/components/common/RangeDatePicker.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import classNames from "classnames"; 3 | import { 4 | InputGroup, 5 | DatePicker, 6 | InputGroupAddon, 7 | InputGroupText 8 | } from "shards-react"; 9 | 10 | import "../../assets/range-date-picker.css"; 11 | 12 | class RangeDatePicker extends React.Component { 13 | constructor(props) { 14 | super(props); 15 | 16 | this.state = { 17 | startDate: undefined, 18 | endDate: undefined 19 | }; 20 | 21 | this.handleStartDateChange = this.handleStartDateChange.bind(this); 22 | this.handleEndDateChange = this.handleEndDateChange.bind(this); 23 | } 24 | 25 | handleStartDateChange(value) { 26 | this.setState({ 27 | ...this.state, 28 | ...{ startDate: new Date(value) } 29 | }); 30 | } 31 | 32 | handleEndDateChange(value) { 33 | this.setState({ 34 | ...this.state, 35 | ...{ endDate: new Date(value) } 36 | }); 37 | } 38 | 39 | render() { 40 | const { className } = this.props; 41 | const classes = classNames(className, "d-flex", "my-auto", "date-range"); 42 | 43 | return ( 44 | 45 | 53 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | ); 68 | } 69 | } 70 | 71 | export default RangeDatePicker; 72 | -------------------------------------------------------------------------------- /src/components/common/SmallStats.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import PropTypes from "prop-types"; 3 | import classNames from "classnames"; 4 | import shortid from "shortid"; 5 | import { Card, CardBody } from "shards-react"; 6 | 7 | import Chart from "../../utils/chart"; 8 | 9 | class SmallStats extends React.Component { 10 | constructor(props) { 11 | super(props); 12 | 13 | this.canvasRef = React.createRef(); 14 | } 15 | 16 | componentDidMount() { 17 | const chartOptions = { 18 | ...{ 19 | maintainAspectRatio: true, 20 | responsive: true, 21 | legend: { 22 | display: false 23 | }, 24 | tooltips: { 25 | enabled: false, 26 | custom: false 27 | }, 28 | elements: { 29 | point: { 30 | radius: 0 31 | }, 32 | line: { 33 | tension: 0.33 34 | } 35 | }, 36 | scales: { 37 | xAxes: [ 38 | { 39 | gridLines: false, 40 | ticks: { 41 | display: false 42 | } 43 | } 44 | ], 45 | yAxes: [ 46 | { 47 | gridLines: false, 48 | scaleLabel: false, 49 | ticks: { 50 | display: false, 51 | isplay: false, 52 | // Avoid getting the graph line cut of at the top of the canvas. 53 | // Chart.js bug link: https://github.com/chartjs/Chart.js/issues/4790 54 | suggestedMax: Math.max(...this.props.chartData[0].data) + 1 55 | } 56 | } 57 | ] 58 | } 59 | }, 60 | ...this.props.chartOptions 61 | }; 62 | 63 | const chartConfig = { 64 | ...{ 65 | type: "line", 66 | data: { 67 | ...{ 68 | labels: this.props.chartLabels 69 | }, 70 | ...{ 71 | datasets: this.props.chartData 72 | } 73 | }, 74 | options: chartOptions 75 | }, 76 | ...this.props.chartConfig 77 | }; 78 | 79 | new Chart(this.canvasRef.current, chartConfig); 80 | } 81 | 82 | render() { 83 | const { variation, label, value, percentage, increase } = this.props; 84 | 85 | const cardClasses = classNames( 86 | "stats-small", 87 | variation && `stats-small--${variation}` 88 | ); 89 | 90 | const cardBodyClasses = classNames( 91 | variation === "1" ? "p-0 d-flex" : "px-0 pb-0" 92 | ); 93 | 94 | const innerWrapperClasses = classNames( 95 | "d-flex", 96 | variation === "1" ? "flex-column m-auto" : "px-3" 97 | ); 98 | 99 | const dataFieldClasses = classNames( 100 | "stats-small__data", 101 | variation === "1" && "text-center" 102 | ); 103 | 104 | const labelClasses = classNames( 105 | "stats-small__label", 106 | "text-uppercase", 107 | variation !== "1" && "mb-1" 108 | ); 109 | 110 | const valueClasses = classNames( 111 | "stats-small__value", 112 | "count", 113 | variation === "1" ? "my-3" : "m-0" 114 | ); 115 | 116 | const innerDataFieldClasses = classNames( 117 | "stats-small__data", 118 | variation !== "1" && "text-right align-items-center" 119 | ); 120 | 121 | const percentageClasses = classNames( 122 | "stats-small__percentage", 123 | `stats-small__percentage--${increase ? "increase" : "decrease"}` 124 | ); 125 | 126 | const canvasHeight = variation === "1" ? 120 : 60; 127 | 128 | return ( 129 | 130 | 131 |
132 |
133 | {label} 134 |
{value}
135 |
136 |
137 | {percentage} 138 |
139 |
140 | 145 |
146 |
147 | ); 148 | } 149 | } 150 | 151 | SmallStats.propTypes = { 152 | /** 153 | * The Small Stats variation. 154 | */ 155 | variation: PropTypes.string, 156 | /** 157 | * The label. 158 | */ 159 | label: PropTypes.string, 160 | /** 161 | * The value. 162 | */ 163 | value: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), 164 | /** 165 | * The percentage number or string. 166 | */ 167 | percentage: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), 168 | /** 169 | * Whether is a value increase, or not. 170 | */ 171 | increase: PropTypes.bool, 172 | /** 173 | * The Chart.js configuration object. 174 | */ 175 | chartConfig: PropTypes.object, 176 | /** 177 | * The Chart.js options object. 178 | */ 179 | chartOptions: PropTypes.object, 180 | /** 181 | * The chart data. 182 | */ 183 | chartData: PropTypes.array.isRequired, 184 | /** 185 | * The chart labels. 186 | */ 187 | chartLabels: PropTypes.array 188 | }; 189 | 190 | SmallStats.defaultProps = { 191 | increase: true, 192 | percentage: 0, 193 | value: 0, 194 | label: "Label", 195 | chartOptions: Object.create(null), 196 | chartConfig: Object.create(null), 197 | chartData: [], 198 | chartLabels: [] 199 | }; 200 | 201 | export default SmallStats; 202 | -------------------------------------------------------------------------------- /src/components/common/TopReferrals.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import PropTypes from "prop-types"; 3 | import { 4 | Card, 5 | CardHeader, 6 | CardBody, 7 | ListGroup, 8 | ListGroupItem, 9 | CardFooter, 10 | Row, 11 | Col, 12 | FormSelect 13 | } from "shards-react"; 14 | 15 | const TopReferrals = ({ title, referralData }) => ( 16 | 17 | 18 |
{title}
19 |
20 | 21 | 22 | 23 | 24 | {referralData.map((item, idx) => ( 25 | 26 | {item.title} 27 | 28 | {item.value} 29 | 30 | 31 | ))} 32 | 33 | 34 | 35 | 36 | 37 | {/* Time Span */} 38 | 39 | {}} 44 | > 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | {/* View Full Report */} 53 | 54 | {/* eslint-disable-next-line */} 55 | Full report → 56 | 57 | 58 | 59 | 60 | ); 61 | 62 | TopReferrals.propTypes = { 63 | /** 64 | * The component's title. 65 | */ 66 | title: PropTypes.string, 67 | /** 68 | * The referral data. 69 | */ 70 | referralData: PropTypes.array 71 | }; 72 | 73 | TopReferrals.defaultProps = { 74 | title: "Top Referrals", 75 | referralData: [ 76 | { 77 | title: "GitHub", 78 | value: "19,291" 79 | }, 80 | { 81 | title: "Stack Overflow", 82 | value: "11,201" 83 | }, 84 | { 85 | title: "Hacker News", 86 | value: "9,291" 87 | }, 88 | { 89 | title: "Reddit", 90 | value: "8,281" 91 | }, 92 | { 93 | title: "The Next Web", 94 | value: "7,128" 95 | }, 96 | { 97 | title: "Tech Crunch", 98 | value: "6,218" 99 | }, 100 | { 101 | title: "YouTube", 102 | value: "1,218" 103 | }, 104 | { 105 | title: "Adobe", 106 | value: "1,171" 107 | } 108 | ] 109 | }; 110 | 111 | export default TopReferrals; 112 | -------------------------------------------------------------------------------- /src/components/components-overview/ButtonGroups.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { ButtonGroup, Button } from "shards-react"; 3 | 4 | const ButtonGroups = () => ( 5 | 6 | 7 | 8 | 9 | 10 | 11 | ); 12 | 13 | export default ButtonGroups; 14 | -------------------------------------------------------------------------------- /src/components/components-overview/Checkboxes.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Col, FormCheckbox } from "shards-react"; 3 | 4 | const Checkboxes = () => ( 5 | 6 | Checkboxes 7 |
8 | Default 9 | Checked 10 | Disabled 11 | 12 | Disabled Checked 13 | 14 |
15 | 16 | ); 17 | 18 | export default Checkboxes; 19 | -------------------------------------------------------------------------------- /src/components/components-overview/Colors.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Row, Col } from "shards-react"; 3 | 4 | const Colors = () => ( 5 | 6 | 7 | 8 | Colors 9 | 10 | 11 | 12 | 13 |
16 | Primary 17 |
18 | 19 | 20 |
23 | Secondary 24 |
25 | 26 | 27 |
30 | Success 31 |
32 | 33 | 34 |
37 | Info 38 |
39 | 40 | 41 |
44 | Warning 45 |
46 | 47 | 48 |
51 | Danger 52 |
53 | 54 | 55 |
58 | Dark 59 |
60 | 61 |
62 | ); 63 | 64 | export default Colors; 65 | -------------------------------------------------------------------------------- /src/components/components-overview/CompleteFormExample.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { 3 | ListGroup, 4 | ListGroupItem, 5 | Row, 6 | Col, 7 | Form, 8 | FormInput, 9 | FormGroup, 10 | FormCheckbox, 11 | FormSelect, 12 | Button 13 | } from "shards-react"; 14 | 15 | const CompleteFormExample = () => ( 16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 29 | 30 | 31 | 32 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | {/* eslint-disable-next-line */}I agree with your{" "} 72 | Privacy Policy. 73 | 74 | 75 | 76 | 77 |
78 | 79 |
80 |
81 |
82 | ); 83 | 84 | export default CompleteFormExample; 85 | -------------------------------------------------------------------------------- /src/components/components-overview/CustomFileUpload.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const CustomFileUpload = () => ( 4 |
5 | 6 | 9 |
10 | ); 11 | 12 | export default CustomFileUpload; 13 | -------------------------------------------------------------------------------- /src/components/components-overview/CustomSelect.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { 3 | InputGroup, 4 | InputGroupAddon, 5 | InputGroupText, 6 | FormSelect 7 | } from "shards-react"; 8 | 9 | const CustomSelect = () => ( 10 |
11 | 12 | 13 | Options 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | Options 28 | 29 | 30 |
31 | ); 32 | 33 | export default CustomSelect; 34 | -------------------------------------------------------------------------------- /src/components/components-overview/DropdownInputGroups.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { 3 | InputGroup, 4 | FormInput, 5 | Dropdown, 6 | DropdownToggle, 7 | DropdownMenu, 8 | DropdownItem 9 | } from "shards-react"; 10 | 11 | class DropdownInputGroups extends React.Component { 12 | constructor(props) { 13 | super(props); 14 | 15 | this.toggle = this.toggle.bind(this); 16 | 17 | this.state = { 18 | dropdown1: false, 19 | dropdown2: false 20 | }; 21 | } 22 | 23 | toggle(which) { 24 | const newState = { ...this.state }; 25 | newState[which] = !this.state[which]; 26 | this.setState(newState); 27 | } 28 | 29 | render() { 30 | return ( 31 |
32 | 33 | 34 | this.toggle("dropdown1")} 37 | addonType="append" 38 | > 39 | Dropdown 40 | 41 | Action 42 | Another action 43 | Something else here 44 | 45 | 46 | 47 | 48 | 49 | this.toggle("dropdown2")} 52 | addonType="prepend" 53 | > 54 | Dropdown 55 | 56 | Action 57 | Another action 58 | Something else here 59 | 60 | 61 | 62 | 63 |
64 | ); 65 | } 66 | } 67 | 68 | export default DropdownInputGroups; 69 | -------------------------------------------------------------------------------- /src/components/components-overview/FormValidation.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { 3 | Row, 4 | Col, 5 | Form, 6 | FormGroup, 7 | FormFeedback, 8 | FormInput, 9 | FormSelect 10 | } from "shards-react"; 11 | 12 | const FormValidation = () => ( 13 | 14 | Form Validation 15 |
16 | 17 | 18 | {}} 24 | /> 25 | The first name looks good! 26 | 27 | 28 | {}} 34 | /> 35 | The last name looks good! 36 | 37 | 38 | 39 | 40 | The username is taken. 41 | 42 | 43 | 44 | 45 | 46 | 47 | Please select your state 48 | 49 |
50 | 51 | ); 52 | 53 | export default FormValidation; 54 | -------------------------------------------------------------------------------- /src/components/components-overview/Forms.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { 3 | Row, 4 | Col, 5 | Form, 6 | FormInput, 7 | FormSelect, 8 | FormGroup, 9 | InputGroup, 10 | InputGroupAddon, 11 | InputGroupText 12 | } from "shards-react"; 13 | 14 | const Forms = () => ( 15 | 16 | Forms 17 |
18 | 19 | 20 | 21 | @ 22 | 23 | 24 | 25 | 26 | 27 | {}} 32 | /> 33 | 34 | 35 | {}} 39 | /> 40 | 41 | 42 | 43 | {}} /> 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 |
53 | 54 | ); 55 | 56 | export default Forms; 57 | -------------------------------------------------------------------------------- /src/components/components-overview/InputGroups.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { 3 | FormInput, 4 | InputGroup, 5 | InputGroupAddon, 6 | InputGroupText 7 | } from "shards-react"; 8 | 9 | const InputGroups = () => ( 10 |
11 | 12 | 13 | @ 14 | 15 | 16 | 17 | 18 | 19 | {}} /> 20 | 21 | @designrevision.com 22 | 23 | 24 | 25 | 26 | 27 | $ 28 | 29 | {}} /> 30 | 31 | .00 32 | 33 | 34 |
35 | ); 36 | 37 | export default InputGroups; 38 | -------------------------------------------------------------------------------- /src/components/components-overview/NormalButtons.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Row, Col, Button } from "shards-react"; 3 | 4 | const NormalButtons = () => ( 5 | 6 | 7 | 10 | 13 | 16 | 19 | 22 | 25 | 28 | 31 | 32 | 33 | ); 34 | 35 | export default NormalButtons; 36 | -------------------------------------------------------------------------------- /src/components/components-overview/NormalOutlineButtons.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Row, Col, Button } from "shards-react"; 3 | 4 | const NormalOutlineButtons = () => ( 5 | 6 | 7 | 10 | 13 | 16 | 19 | 22 | 25 | 28 | 31 | 32 | 33 | ); 34 | 35 | export default NormalOutlineButtons; 36 | -------------------------------------------------------------------------------- /src/components/components-overview/ProgressBars.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { ListGroupItem, Progress } from "shards-react"; 3 | 4 | const ProgressBars = () => ( 5 | 6 |
7 | Progress Bars 8 | 9 | 15 | 21 | 27 |
28 |
29 | ); 30 | 31 | export default ProgressBars; 32 | -------------------------------------------------------------------------------- /src/components/components-overview/RadioButtons.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Col, FormRadio } from "shards-react"; 3 | 4 | const RadioButtons = () => ( 5 | 6 | Radio Buttons 7 |
8 | Default 9 | Checked 10 | Disabled 11 | 12 | Disabled Checked 13 | 14 |
15 | 16 | ); 17 | 18 | export default RadioButtons; 19 | -------------------------------------------------------------------------------- /src/components/components-overview/SeamlessInputGroups.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { 3 | InputGroup, 4 | InputGroupAddon, 5 | InputGroupText, 6 | FormInput, 7 | Button 8 | } from "shards-react"; 9 | 10 | const SeamlessInputGroups = () => ( 11 |
12 | 13 | 14 | 15 | person 16 | 17 | 18 | {}} /> 19 | 20 | 21 | 22 | {}} 26 | /> 27 | 28 | 29 | lock 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 |
41 | ); 42 | 43 | export default SeamlessInputGroups; 44 | -------------------------------------------------------------------------------- /src/components/components-overview/Sliders.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { ListGroupItem, Slider } from "shards-react"; 3 | 4 | const Sliders = () => ( 5 | 6 |
7 | Custom Sliders 8 | 16 | 23 | 34 |
35 |
36 | ); 37 | 38 | export default Sliders; 39 | -------------------------------------------------------------------------------- /src/components/components-overview/SmallButtons.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Row, Col, Button } from "shards-react"; 3 | 4 | const SmallButtons = () => ( 5 | 6 | 7 | 10 | 13 | 16 | 19 | 22 | 25 | 28 | 31 | 32 | 33 | ); 34 | 35 | export default SmallButtons; 36 | -------------------------------------------------------------------------------- /src/components/components-overview/SmallOutlineButtons.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Row, Col, Button } from "shards-react"; 3 | 4 | const SmallOutlineButtons = () => ( 5 | 6 | 7 | 10 | 13 | 16 | 19 | 22 | 25 | 28 | 31 | 32 | 33 | ); 34 | 35 | export default SmallOutlineButtons; 36 | -------------------------------------------------------------------------------- /src/components/components-overview/ToggleButtons.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Col, FormCheckbox } from "shards-react"; 3 | 4 | const ToggleButtons = () => ( 5 | 6 | Toggle Switches 7 |
8 | 9 | Default 10 | 11 | 12 | Checked 13 | 14 | 15 | Disabled 16 | 17 | 18 | Disabled Checked 19 | 20 |
21 | 22 | ); 23 | 24 | export default ToggleButtons; 25 | -------------------------------------------------------------------------------- /src/components/layout/MainFooter.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import PropTypes from "prop-types"; 3 | import { Container, Row, Nav, NavItem, NavLink } from "shards-react"; 4 | import { Link } from "react-router-dom"; 5 | 6 | const MainFooter = ({ contained, menuItems, copyright }) => ( 7 |
8 | 9 | 10 | 19 | {copyright} 20 | 21 | 22 |
23 | ); 24 | 25 | MainFooter.propTypes = { 26 | /** 27 | * Whether the content is contained, or not. 28 | */ 29 | contained: PropTypes.bool, 30 | /** 31 | * The menu items array. 32 | */ 33 | menuItems: PropTypes.array, 34 | /** 35 | * The copyright info. 36 | */ 37 | copyright: PropTypes.string 38 | }; 39 | 40 | MainFooter.defaultProps = { 41 | contained: false, 42 | copyright: "Copyright © 2018 DesignRevision", 43 | menuItems: [ 44 | { 45 | title: "Home", 46 | to: "#" 47 | }, 48 | { 49 | title: "Services", 50 | to: "#" 51 | }, 52 | { 53 | title: "About", 54 | to: "#" 55 | }, 56 | { 57 | title: "Products", 58 | to: "#" 59 | }, 60 | { 61 | title: "Blog", 62 | to: "#" 63 | } 64 | ] 65 | }; 66 | 67 | export default MainFooter; 68 | -------------------------------------------------------------------------------- /src/components/layout/MainNavbar/MainNavbar.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import PropTypes from "prop-types"; 3 | import classNames from "classnames"; 4 | import { Container, Navbar } from "shards-react"; 5 | 6 | import NavbarSearch from "./NavbarSearch"; 7 | import NavbarNav from "./NavbarNav/NavbarNav"; 8 | import NavbarToggle from "./NavbarToggle"; 9 | 10 | const MainNavbar = ({ layout, stickyTop }) => { 11 | const classes = classNames( 12 | "main-navbar", 13 | "bg-white", 14 | stickyTop && "sticky-top" 15 | ); 16 | 17 | return ( 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | ); 28 | }; 29 | 30 | MainNavbar.propTypes = { 31 | /** 32 | * The layout type where the MainNavbar is used. 33 | */ 34 | layout: PropTypes.string, 35 | /** 36 | * Whether the main navbar is sticky to the top, or not. 37 | */ 38 | stickyTop: PropTypes.bool 39 | }; 40 | 41 | MainNavbar.defaultProps = { 42 | stickyTop: true 43 | }; 44 | 45 | export default MainNavbar; 46 | -------------------------------------------------------------------------------- /src/components/layout/MainNavbar/NavbarNav/NavbarNav.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Nav } from "shards-react"; 3 | 4 | import Notifications from "./Notifications"; 5 | import UserActions from "./UserActions"; 6 | 7 | export default () => ( 8 | 12 | ); 13 | -------------------------------------------------------------------------------- /src/components/layout/MainNavbar/NavbarNav/Notifications.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { NavItem, NavLink, Badge, Collapse, DropdownItem } from "shards-react"; 3 | 4 | export default class Notifications extends React.Component { 5 | constructor(props) { 6 | super(props); 7 | 8 | this.state = { 9 | visible: false 10 | }; 11 | 12 | this.toggleNotifications = this.toggleNotifications.bind(this); 13 | } 14 | 15 | toggleNotifications() { 16 | this.setState({ 17 | visible: !this.state.visible 18 | }); 19 | } 20 | 21 | render() { 22 | return ( 23 | 24 | 28 |
29 | 30 | 31 | 2 32 | 33 |
34 |
35 | 39 | 40 |
41 |
42 | 43 |
44 |
45 |
46 | Analytics 47 |

48 | Your website’s active users count increased by{" "} 49 | 28% in the 50 | last week. Great job! 51 |

52 |
53 |
54 | 55 |
56 |
57 | 58 |
59 |
60 |
61 | Sales 62 |

63 | Last week your store’s sales count decreased by{" "} 64 | 5.52%. It 65 | could have been worse! 66 |

67 |
68 |
69 | 70 | View all Notifications 71 | 72 |
73 |
74 | ); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/components/layout/MainNavbar/NavbarNav/UserActions.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Link } from "react-router-dom"; 3 | import { 4 | Dropdown, 5 | DropdownToggle, 6 | DropdownMenu, 7 | DropdownItem, 8 | Collapse, 9 | NavItem, 10 | NavLink 11 | } from "shards-react"; 12 | 13 | export default class UserActions extends React.Component { 14 | constructor(props) { 15 | super(props); 16 | 17 | this.state = { 18 | visible: false 19 | }; 20 | 21 | this.toggleUserActions = this.toggleUserActions.bind(this); 22 | } 23 | 24 | toggleUserActions() { 25 | this.setState({ 26 | visible: !this.state.visible 27 | }); 28 | } 29 | 30 | render() { 31 | return ( 32 | 33 | 34 | User Avatar{" "} 39 | Sierra Brooks 40 | 41 | 42 | 43 | Profile 44 | 45 | 46 | Edit Profile 47 | 48 | 49 | Files 50 | 51 | 52 | Transactions 53 | 54 | 55 | 56 | Logout 57 | 58 | 59 | 60 | ); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/components/layout/MainNavbar/NavbarSearch.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { 3 | Form, 4 | InputGroup, 5 | InputGroupAddon, 6 | InputGroupText, 7 | FormInput 8 | } from "shards-react"; 9 | 10 | export default () => ( 11 |
12 | 13 | 14 | 15 | search 16 | 17 | 18 | 22 | 23 |
24 | ); 25 | -------------------------------------------------------------------------------- /src/components/layout/MainNavbar/NavbarToggle.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | import { Dispatcher, Constants } from "../../../flux"; 4 | 5 | class NavbarToggle extends React.Component { 6 | constructor(props) { 7 | super(props); 8 | 9 | this.handleClick = this.handleClick.bind(this); 10 | } 11 | 12 | handleClick() { 13 | Dispatcher.dispatch({ 14 | actionType: Constants.TOGGLE_SIDEBAR 15 | }); 16 | } 17 | 18 | render() { 19 | return ( 20 | 26 | ) 27 | } 28 | } 29 | 30 | export default NavbarToggle; 31 | -------------------------------------------------------------------------------- /src/components/layout/MainSidebar/MainSidebar.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import PropTypes from "prop-types"; 3 | import classNames from "classnames"; 4 | import { Col } from "shards-react"; 5 | 6 | import SidebarMainNavbar from "./SidebarMainNavbar"; 7 | import SidebarSearch from "./SidebarSearch"; 8 | import SidebarNavItems from "./SidebarNavItems"; 9 | 10 | import { Store } from "../../../flux"; 11 | 12 | class MainSidebar extends React.Component { 13 | constructor(props) { 14 | super(props); 15 | 16 | this.state = { 17 | menuVisible: false, 18 | sidebarNavItems: Store.getSidebarItems() 19 | }; 20 | 21 | this.onChange = this.onChange.bind(this); 22 | } 23 | 24 | componentWillMount() { 25 | Store.addChangeListener(this.onChange); 26 | } 27 | 28 | componentWillUnmount() { 29 | Store.removeChangeListener(this.onChange); 30 | } 31 | 32 | onChange() { 33 | this.setState({ 34 | ...this.state, 35 | menuVisible: Store.getMenuState(), 36 | sidebarNavItems: Store.getSidebarItems() 37 | }); 38 | } 39 | 40 | render() { 41 | const classes = classNames( 42 | "main-sidebar", 43 | "px-0", 44 | "col-12", 45 | this.state.menuVisible && "open" 46 | ); 47 | 48 | return ( 49 | 55 | 56 | 57 | 58 | 59 | ); 60 | } 61 | } 62 | 63 | MainSidebar.propTypes = { 64 | /** 65 | * Whether to hide the logo text, or not. 66 | */ 67 | hideLogoText: PropTypes.bool 68 | }; 69 | 70 | MainSidebar.defaultProps = { 71 | hideLogoText: false 72 | }; 73 | 74 | export default MainSidebar; 75 | -------------------------------------------------------------------------------- /src/components/layout/MainSidebar/SidebarMainNavbar.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import PropTypes from "prop-types"; 3 | import { Navbar, NavbarBrand } from "shards-react"; 4 | 5 | import { Dispatcher, Constants } from "../../../flux"; 6 | 7 | class SidebarMainNavbar extends React.Component { 8 | constructor(props) { 9 | super(props); 10 | 11 | this.handleToggleSidebar = this.handleToggleSidebar.bind(this); 12 | } 13 | 14 | handleToggleSidebar() { 15 | Dispatcher.dispatch({ 16 | actionType: Constants.TOGGLE_SIDEBAR 17 | }); 18 | } 19 | 20 | render() { 21 | const { hideLogoText } = this.props; 22 | return ( 23 |
24 | 28 | 33 |
34 | 41 | {!hideLogoText && ( 42 | 43 | Shards Dashboard 44 | 45 | )} 46 |
47 |
48 | {/* eslint-disable-next-line */} 49 | 53 | 54 | 55 |
56 |
57 | ); 58 | } 59 | } 60 | 61 | SidebarMainNavbar.propTypes = { 62 | /** 63 | * Whether to hide the logo text, or not. 64 | */ 65 | hideLogoText: PropTypes.bool 66 | }; 67 | 68 | SidebarMainNavbar.defaultProps = { 69 | hideLogoText: false 70 | }; 71 | 72 | export default SidebarMainNavbar; 73 | -------------------------------------------------------------------------------- /src/components/layout/MainSidebar/SidebarNavItem.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import PropTypes from "prop-types"; 3 | import { NavLink as RouteNavLink } from "react-router-dom"; 4 | import { NavItem, NavLink } from "shards-react"; 5 | 6 | const SidebarNavItem = ({ item }) => ( 7 | 8 | 9 | {item.htmlBefore && ( 10 |
14 | )} 15 | {item.title && {item.title}} 16 | {item.htmlAfter && ( 17 |
21 | )} 22 | 23 | 24 | ); 25 | 26 | SidebarNavItem.propTypes = { 27 | /** 28 | * The item object. 29 | */ 30 | item: PropTypes.object 31 | }; 32 | 33 | export default SidebarNavItem; 34 | -------------------------------------------------------------------------------- /src/components/layout/MainSidebar/SidebarNavItems.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Nav } from "shards-react"; 3 | 4 | import SidebarNavItem from "./SidebarNavItem"; 5 | import { Store } from "../../../flux"; 6 | 7 | class SidebarNavItems extends React.Component { 8 | constructor(props) { 9 | super(props) 10 | 11 | this.state = { 12 | navItems: Store.getSidebarItems() 13 | }; 14 | 15 | this.onChange = this.onChange.bind(this); 16 | } 17 | 18 | componentWillMount() { 19 | Store.addChangeListener(this.onChange); 20 | } 21 | 22 | componentWillUnmount() { 23 | Store.removeChangeListener(this.onChange); 24 | } 25 | 26 | onChange() { 27 | this.setState({ 28 | ...this.state, 29 | navItems: Store.getSidebarItems() 30 | }); 31 | } 32 | 33 | render() { 34 | const { navItems: items } = this.state; 35 | return ( 36 |
37 | 42 |
43 | ) 44 | } 45 | } 46 | 47 | export default SidebarNavItems; 48 | -------------------------------------------------------------------------------- /src/components/layout/MainSidebar/SidebarSearch.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { 3 | Form, 4 | FormInput, 5 | InputGroup, 6 | InputGroupAddon, 7 | InputGroupText 8 | } from "shards-react"; 9 | 10 | export default () => ( 11 |
12 | 13 | 14 | 15 | search 16 | 17 | 22 | 23 | 24 |
25 | ); 26 | -------------------------------------------------------------------------------- /src/components/user-profile-lite/UserAccountDetails.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import PropTypes from "prop-types"; 3 | import { 4 | Card, 5 | CardHeader, 6 | ListGroup, 7 | ListGroupItem, 8 | Row, 9 | Col, 10 | Form, 11 | FormGroup, 12 | FormInput, 13 | FormSelect, 14 | FormTextarea, 15 | Button 16 | } from "shards-react"; 17 | 18 | const UserAccountDetails = ({ title }) => ( 19 | 20 | 21 |
{title}
22 |
23 | 24 | 25 | 26 | 27 |
28 | 29 | {/* First Name */} 30 | 31 | 32 | {}} 37 | /> 38 | 39 | {/* Last Name */} 40 | 41 | 42 | {}} 47 | /> 48 | 49 | 50 | 51 | {/* Email */} 52 | 53 | 54 | {}} 60 | autoComplete="email" 61 | /> 62 | 63 | {/* Password */} 64 | 65 | 66 | {}} 72 | autoComplete="current-password" 73 | /> 74 | 75 | 76 | 77 | 78 | {}} 83 | /> 84 | 85 | 86 | {/* City */} 87 | 88 | 89 | {}} 93 | /> 94 | 95 | {/* State */} 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | {/* Zip Code */} 104 | 105 | 106 | {}} 110 | /> 111 | 112 | 113 | 114 | {/* Description */} 115 | 116 | 117 | 118 | 119 | 120 | 121 |
122 | 123 |
124 |
125 |
126 |
127 | ); 128 | 129 | UserAccountDetails.propTypes = { 130 | /** 131 | * The component's title. 132 | */ 133 | title: PropTypes.string 134 | }; 135 | 136 | UserAccountDetails.defaultProps = { 137 | title: "Account Details" 138 | }; 139 | 140 | export default UserAccountDetails; 141 | -------------------------------------------------------------------------------- /src/components/user-profile-lite/UserDetails.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import PropTypes from "prop-types"; 3 | import { 4 | Card, 5 | CardHeader, 6 | Button, 7 | ListGroup, 8 | ListGroupItem, 9 | Progress 10 | } from "shards-react"; 11 | 12 | const UserDetails = ({ userDetails }) => ( 13 | 14 | 15 |
16 | {userDetails.name} 22 |
23 |

{userDetails.name}

24 | {userDetails.jobTitle} 25 | 28 |
29 | 30 | 31 |
32 | 33 | {userDetails.performanceReportTitle} 34 | 35 | 39 | 40 | {userDetails.performanceReportValue}% 41 | 42 | 43 |
44 |
45 | 46 | 47 | {userDetails.metaTitle} 48 | 49 | {userDetails.metaValue} 50 | 51 |
52 |
53 | ); 54 | 55 | UserDetails.propTypes = { 56 | /** 57 | * The user details object. 58 | */ 59 | userDetails: PropTypes.object 60 | }; 61 | 62 | UserDetails.defaultProps = { 63 | userDetails: { 64 | name: "Sierra Brooks", 65 | avatar: require("./../../images/avatars/0.jpg"), 66 | jobTitle: "Project Manager", 67 | performanceReportTitle: "Workload", 68 | performanceReportValue: 74, 69 | metaTitle: "Description", 70 | metaValue: 71 | "Lorem ipsum dolor sit amet consectetur adipisicing elit. Odio eaque, quidem, commodi soluta qui quae minima obcaecati quod dolorum sint alias, possimus illum assumenda eligendi cumque?" 72 | } 73 | }; 74 | 75 | export default UserDetails; 76 | -------------------------------------------------------------------------------- /src/data/sidebar-nav-items.js: -------------------------------------------------------------------------------- 1 | export default function() { 2 | return [ 3 | { 4 | title: "Blog Dashboard", 5 | to: "/blog-overview", 6 | htmlBefore: 'edit', 7 | htmlAfter: "" 8 | }, 9 | { 10 | title: "Blog Posts", 11 | htmlBefore: 'vertical_split', 12 | to: "/blog-posts", 13 | }, 14 | { 15 | title: "Add New Post", 16 | htmlBefore: 'note_add', 17 | to: "/add-new-post", 18 | }, 19 | { 20 | title: "Forms & Components", 21 | htmlBefore: 'view_module', 22 | to: "/components-overview", 23 | }, 24 | { 25 | title: "Tables", 26 | htmlBefore: 'table_chart', 27 | to: "/tables", 28 | }, 29 | { 30 | title: "User Profile", 31 | htmlBefore: 'person', 32 | to: "/user-profile-lite", 33 | }, 34 | { 35 | title: "Errors", 36 | htmlBefore: 'error', 37 | to: "/errors", 38 | } 39 | ]; 40 | } 41 | -------------------------------------------------------------------------------- /src/flux/constants.js: -------------------------------------------------------------------------------- 1 | export default { 2 | CHANGE: "CHANGE", 3 | TOGGLE_SIDEBAR: "TOGGLE_SIDEBAR" 4 | }; 5 | -------------------------------------------------------------------------------- /src/flux/dispatcher.js: -------------------------------------------------------------------------------- 1 | import { Dispatcher } from "flux"; 2 | 3 | export default new Dispatcher(); 4 | -------------------------------------------------------------------------------- /src/flux/index.js: -------------------------------------------------------------------------------- 1 | import Constants from "./constants"; 2 | import Dispatcher from "./dispatcher"; 3 | import Store from "./store"; 4 | 5 | export { 6 | Constants, 7 | Dispatcher, 8 | Store 9 | }; 10 | -------------------------------------------------------------------------------- /src/flux/store.js: -------------------------------------------------------------------------------- 1 | import { EventEmitter } from "events"; 2 | 3 | import Dispatcher from "./dispatcher"; 4 | import Constants from "./constants"; 5 | import getSidebarNavItems from "../data/sidebar-nav-items"; 6 | 7 | let _store = { 8 | menuVisible: false, 9 | navItems: getSidebarNavItems() 10 | }; 11 | 12 | class Store extends EventEmitter { 13 | constructor() { 14 | super(); 15 | 16 | this.registerToActions = this.registerToActions.bind(this); 17 | this.toggleSidebar = this.toggleSidebar.bind(this); 18 | 19 | Dispatcher.register(this.registerToActions.bind(this)); 20 | } 21 | 22 | registerToActions({ actionType, payload }) { 23 | switch (actionType) { 24 | case Constants.TOGGLE_SIDEBAR: 25 | this.toggleSidebar(); 26 | break; 27 | default: 28 | } 29 | } 30 | 31 | toggleSidebar() { 32 | _store.menuVisible = !_store.menuVisible; 33 | this.emit(Constants.CHANGE); 34 | } 35 | 36 | getMenuState() { 37 | return _store.menuVisible; 38 | } 39 | 40 | getSidebarItems() { 41 | return _store.navItems; 42 | } 43 | 44 | addChangeListener(callback) { 45 | this.on(Constants.CHANGE, callback); 46 | } 47 | 48 | removeChangeListener(callback) { 49 | this.removeListener(Constants.CHANGE, callback); 50 | } 51 | } 52 | 53 | export default new Store(); 54 | -------------------------------------------------------------------------------- /src/images/avatars/0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DesignRevision/shards-dashboard-react/6f8840524e4de2965e5585cfefd2a9b6bb088eb9/src/images/avatars/0.jpg -------------------------------------------------------------------------------- /src/images/avatars/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DesignRevision/shards-dashboard-react/6f8840524e4de2965e5585cfefd2a9b6bb088eb9/src/images/avatars/1.jpg -------------------------------------------------------------------------------- /src/images/avatars/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DesignRevision/shards-dashboard-react/6f8840524e4de2965e5585cfefd2a9b6bb088eb9/src/images/avatars/2.jpg -------------------------------------------------------------------------------- /src/images/avatars/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DesignRevision/shards-dashboard-react/6f8840524e4de2965e5585cfefd2a9b6bb088eb9/src/images/avatars/3.jpg -------------------------------------------------------------------------------- /src/images/content-management/1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DesignRevision/shards-dashboard-react/6f8840524e4de2965e5585cfefd2a9b6bb088eb9/src/images/content-management/1.jpeg -------------------------------------------------------------------------------- /src/images/content-management/10.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DesignRevision/shards-dashboard-react/6f8840524e4de2965e5585cfefd2a9b6bb088eb9/src/images/content-management/10.jpeg -------------------------------------------------------------------------------- /src/images/content-management/11.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DesignRevision/shards-dashboard-react/6f8840524e4de2965e5585cfefd2a9b6bb088eb9/src/images/content-management/11.jpeg -------------------------------------------------------------------------------- /src/images/content-management/12.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DesignRevision/shards-dashboard-react/6f8840524e4de2965e5585cfefd2a9b6bb088eb9/src/images/content-management/12.jpeg -------------------------------------------------------------------------------- /src/images/content-management/13.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DesignRevision/shards-dashboard-react/6f8840524e4de2965e5585cfefd2a9b6bb088eb9/src/images/content-management/13.jpeg -------------------------------------------------------------------------------- /src/images/content-management/14.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DesignRevision/shards-dashboard-react/6f8840524e4de2965e5585cfefd2a9b6bb088eb9/src/images/content-management/14.jpeg -------------------------------------------------------------------------------- /src/images/content-management/15.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DesignRevision/shards-dashboard-react/6f8840524e4de2965e5585cfefd2a9b6bb088eb9/src/images/content-management/15.jpeg -------------------------------------------------------------------------------- /src/images/content-management/16.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DesignRevision/shards-dashboard-react/6f8840524e4de2965e5585cfefd2a9b6bb088eb9/src/images/content-management/16.jpeg -------------------------------------------------------------------------------- /src/images/content-management/2.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DesignRevision/shards-dashboard-react/6f8840524e4de2965e5585cfefd2a9b6bb088eb9/src/images/content-management/2.jpeg -------------------------------------------------------------------------------- /src/images/content-management/3.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DesignRevision/shards-dashboard-react/6f8840524e4de2965e5585cfefd2a9b6bb088eb9/src/images/content-management/3.jpeg -------------------------------------------------------------------------------- /src/images/content-management/4.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DesignRevision/shards-dashboard-react/6f8840524e4de2965e5585cfefd2a9b6bb088eb9/src/images/content-management/4.jpeg -------------------------------------------------------------------------------- /src/images/content-management/5.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DesignRevision/shards-dashboard-react/6f8840524e4de2965e5585cfefd2a9b6bb088eb9/src/images/content-management/5.jpeg -------------------------------------------------------------------------------- /src/images/content-management/6.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DesignRevision/shards-dashboard-react/6f8840524e4de2965e5585cfefd2a9b6bb088eb9/src/images/content-management/6.jpeg -------------------------------------------------------------------------------- /src/images/content-management/7.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DesignRevision/shards-dashboard-react/6f8840524e4de2965e5585cfefd2a9b6bb088eb9/src/images/content-management/7.jpeg -------------------------------------------------------------------------------- /src/images/content-management/8.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DesignRevision/shards-dashboard-react/6f8840524e4de2965e5585cfefd2a9b6bb088eb9/src/images/content-management/8.jpeg -------------------------------------------------------------------------------- /src/images/content-management/9.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DesignRevision/shards-dashboard-react/6f8840524e4de2965e5585cfefd2a9b6bb088eb9/src/images/content-management/9.jpeg -------------------------------------------------------------------------------- /src/images/file-manager/document-preview-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DesignRevision/shards-dashboard-react/6f8840524e4de2965e5585cfefd2a9b6bb088eb9/src/images/file-manager/document-preview-1.jpg -------------------------------------------------------------------------------- /src/images/flags/flag-au.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DesignRevision/shards-dashboard-react/6f8840524e4de2965e5585cfefd2a9b6bb088eb9/src/images/flags/flag-au.png -------------------------------------------------------------------------------- /src/images/flags/flag-jp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DesignRevision/shards-dashboard-react/6f8840524e4de2965e5585cfefd2a9b6bb088eb9/src/images/flags/flag-jp.png -------------------------------------------------------------------------------- /src/images/flags/flag-uk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DesignRevision/shards-dashboard-react/6f8840524e4de2965e5585cfefd2a9b6bb088eb9/src/images/flags/flag-uk.png -------------------------------------------------------------------------------- /src/images/flags/flag-us.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DesignRevision/shards-dashboard-react/6f8840524e4de2965e5585cfefd2a9b6bb088eb9/src/images/flags/flag-us.png -------------------------------------------------------------------------------- /src/images/sales-overview/no-product-image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DesignRevision/shards-dashboard-react/6f8840524e4de2965e5585cfefd2a9b6bb088eb9/src/images/sales-overview/no-product-image.jpg -------------------------------------------------------------------------------- /src/images/sales-overview/product-basics.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DesignRevision/shards-dashboard-react/6f8840524e4de2965e5585cfefd2a9b6bb088eb9/src/images/sales-overview/product-basics.jpg -------------------------------------------------------------------------------- /src/images/sales-overview/product-order-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DesignRevision/shards-dashboard-react/6f8840524e4de2965e5585cfefd2a9b6bb088eb9/src/images/sales-overview/product-order-1.jpg -------------------------------------------------------------------------------- /src/images/sales-overview/product-order-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DesignRevision/shards-dashboard-react/6f8840524e4de2965e5585cfefd2a9b6bb088eb9/src/images/sales-overview/product-order-2.jpg -------------------------------------------------------------------------------- /src/images/sales-overview/product-order-3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DesignRevision/shards-dashboard-react/6f8840524e4de2965e5585cfefd2a9b6bb088eb9/src/images/sales-overview/product-order-3.jpg -------------------------------------------------------------------------------- /src/images/sales-overview/product-shoes.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DesignRevision/shards-dashboard-react/6f8840524e4de2965e5585cfefd2a9b6bb088eb9/src/images/sales-overview/product-shoes.jpg -------------------------------------------------------------------------------- /src/images/sales-overview/product-sportswear.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DesignRevision/shards-dashboard-react/6f8840524e4de2965e5585cfefd2a9b6bb088eb9/src/images/sales-overview/product-sportswear.jpg -------------------------------------------------------------------------------- /src/images/sales-overview/product-sweaters.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DesignRevision/shards-dashboard-react/6f8840524e4de2965e5585cfefd2a9b6bb088eb9/src/images/sales-overview/product-sweaters.jpg -------------------------------------------------------------------------------- /src/images/shards-dashboards-logo-danger.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Logo Icon 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/images/shards-dashboards-logo-info.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Logo Icon 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/images/shards-dashboards-logo-java.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Logo Icon 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/images/shards-dashboards-logo-royal-blue.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Logo Icon 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/images/shards-dashboards-logo-salmon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Logo Icon 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/images/shards-dashboards-logo-secondary.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Logo Icon 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/images/shards-dashboards-logo-success.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Logo Icon 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/images/shards-dashboards-logo-warning.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Logo Icon 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/images/shards-dashboards-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Logo Icon 5 | Created with Sketch. 6 | 7 | 8 | 9 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/images/user-profile/team-thumb-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DesignRevision/shards-dashboard-react/6f8840524e4de2965e5585cfefd2a9b6bb088eb9/src/images/user-profile/team-thumb-1.png -------------------------------------------------------------------------------- /src/images/user-profile/team-thumb-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DesignRevision/shards-dashboard-react/6f8840524e4de2965e5585cfefd2a9b6bb088eb9/src/images/user-profile/team-thumb-2.png -------------------------------------------------------------------------------- /src/images/user-profile/team-thumb-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DesignRevision/shards-dashboard-react/6f8840524e4de2965e5585cfefd2a9b6bb088eb9/src/images/user-profile/team-thumb-3.png -------------------------------------------------------------------------------- /src/images/user-profile/up-user-details-background.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DesignRevision/shards-dashboard-react/6f8840524e4de2965e5585cfefd2a9b6bb088eb9/src/images/user-profile/up-user-details-background.jpg -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | 5 | import * as serviceWorker from './serviceWorker'; 6 | 7 | ReactDOM.render(, document.getElementById('root')); 8 | 9 | // If you want your app to work offline and load faster, you can change 10 | // unregister() to register() below. Note this comes with some pitfalls. 11 | // Learn more about service workers: http://bit.ly/CRA-PWA 12 | serviceWorker.unregister(); 13 | -------------------------------------------------------------------------------- /src/layouts/Default.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import PropTypes from "prop-types"; 3 | import { Container, Row, Col } from "shards-react"; 4 | 5 | import MainNavbar from "../components/layout/MainNavbar/MainNavbar"; 6 | import MainSidebar from "../components/layout/MainSidebar/MainSidebar"; 7 | import MainFooter from "../components/layout/MainFooter"; 8 | 9 | const DefaultLayout = ({ children, noNavbar, noFooter }) => ( 10 | 11 | 12 | 13 | 20 | {!noNavbar && } 21 | {children} 22 | {!noFooter && } 23 | 24 | 25 | 26 | ); 27 | 28 | DefaultLayout.propTypes = { 29 | /** 30 | * Whether to display the navbar, or not. 31 | */ 32 | noNavbar: PropTypes.bool, 33 | /** 34 | * Whether to display the footer, or not. 35 | */ 36 | noFooter: PropTypes.bool 37 | }; 38 | 39 | DefaultLayout.defaultProps = { 40 | noNavbar: false, 41 | noFooter: false 42 | }; 43 | 44 | export default DefaultLayout; 45 | -------------------------------------------------------------------------------- /src/layouts/index.js: -------------------------------------------------------------------------------- 1 | import DefaultLayout from "./Default"; 2 | 3 | export { DefaultLayout }; 4 | -------------------------------------------------------------------------------- /src/routes.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Redirect } from "react-router-dom"; 3 | 4 | // Layout Types 5 | import { DefaultLayout } from "./layouts"; 6 | 7 | // Route Views 8 | import BlogOverview from "./views/BlogOverview"; 9 | import UserProfileLite from "./views/UserProfileLite"; 10 | import AddNewPost from "./views/AddNewPost"; 11 | import Errors from "./views/Errors"; 12 | import ComponentsOverview from "./views/ComponentsOverview"; 13 | import Tables from "./views/Tables"; 14 | import BlogPosts from "./views/BlogPosts"; 15 | 16 | export default [ 17 | { 18 | path: "/", 19 | exact: true, 20 | layout: DefaultLayout, 21 | component: () => 22 | }, 23 | { 24 | path: "/blog-overview", 25 | layout: DefaultLayout, 26 | component: BlogOverview 27 | }, 28 | { 29 | path: "/user-profile-lite", 30 | layout: DefaultLayout, 31 | component: UserProfileLite 32 | }, 33 | { 34 | path: "/add-new-post", 35 | layout: DefaultLayout, 36 | component: AddNewPost 37 | }, 38 | { 39 | path: "/errors", 40 | layout: DefaultLayout, 41 | component: Errors 42 | }, 43 | { 44 | path: "/components-overview", 45 | layout: DefaultLayout, 46 | component: ComponentsOverview 47 | }, 48 | { 49 | path: "/tables", 50 | layout: DefaultLayout, 51 | component: Tables 52 | }, 53 | { 54 | path: "/blog-posts", 55 | layout: DefaultLayout, 56 | component: BlogPosts 57 | } 58 | ]; 59 | -------------------------------------------------------------------------------- /src/serviceWorker.js: -------------------------------------------------------------------------------- 1 | // This optional code is used to register a service worker. 2 | // register() is not called by default. 3 | 4 | // This lets the app load faster on subsequent visits in production, and gives 5 | // it offline capabilities. However, it also means that developers (and users) 6 | // will only see deployed updates on subsequent visits to a page, after all the 7 | // existing tabs open on the page have been closed, since previously cached 8 | // resources are updated in the background. 9 | 10 | // To learn more about the benefits of this model and instructions on how to 11 | // opt-in, read http://bit.ly/CRA-PWA 12 | 13 | const isLocalhost = Boolean( 14 | window.location.hostname === 'localhost' || 15 | // [::1] is the IPv6 localhost address. 16 | window.location.hostname === '[::1]' || 17 | // 127.0.0.1/8 is considered localhost for IPv4. 18 | window.location.hostname.match( 19 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ 20 | ) 21 | ); 22 | 23 | export function register(config) { 24 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { 25 | // The URL constructor is available in all browsers that support SW. 26 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href); 27 | if (publicUrl.origin !== window.location.origin) { 28 | // Our service worker won't work if PUBLIC_URL is on a different origin 29 | // from what our page is served on. This might happen if a CDN is used to 30 | // serve assets; see https://github.com/facebook/create-react-app/issues/2374 31 | return; 32 | } 33 | 34 | window.addEventListener('load', () => { 35 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; 36 | 37 | if (isLocalhost) { 38 | // This is running on localhost. Let's check if a service worker still exists or not. 39 | checkValidServiceWorker(swUrl, config); 40 | 41 | // Add some additional logging to localhost, pointing developers to the 42 | // service worker/PWA documentation. 43 | navigator.serviceWorker.ready.then(() => { 44 | console.log( 45 | 'This web app is being served cache-first by a service ' + 46 | 'worker. To learn more, visit http://bit.ly/CRA-PWA' 47 | ); 48 | }); 49 | } else { 50 | // Is not localhost. Just register service worker 51 | registerValidSW(swUrl, config); 52 | } 53 | }); 54 | } 55 | } 56 | 57 | function registerValidSW(swUrl, config) { 58 | navigator.serviceWorker 59 | .register(swUrl) 60 | .then(registration => { 61 | registration.onupdatefound = () => { 62 | const installingWorker = registration.installing; 63 | if (installingWorker == null) { 64 | return; 65 | } 66 | installingWorker.onstatechange = () => { 67 | if (installingWorker.state === 'installed') { 68 | if (navigator.serviceWorker.controller) { 69 | // At this point, the updated precached content has been fetched, 70 | // but the previous service worker will still serve the older 71 | // content until all client tabs are closed. 72 | console.log( 73 | 'New content is available and will be used when all ' + 74 | 'tabs for this page are closed. See http://bit.ly/CRA-PWA.' 75 | ); 76 | 77 | // Execute callback 78 | if (config && config.onUpdate) { 79 | config.onUpdate(registration); 80 | } 81 | } else { 82 | // At this point, everything has been precached. 83 | // It's the perfect time to display a 84 | // "Content is cached for offline use." message. 85 | console.log('Content is cached for offline use.'); 86 | 87 | // Execute callback 88 | if (config && config.onSuccess) { 89 | config.onSuccess(registration); 90 | } 91 | } 92 | } 93 | }; 94 | }; 95 | }) 96 | .catch(error => { 97 | console.error('Error during service worker registration:', error); 98 | }); 99 | } 100 | 101 | function checkValidServiceWorker(swUrl, config) { 102 | // Check if the service worker can be found. If it can't reload the page. 103 | fetch(swUrl) 104 | .then(response => { 105 | // Ensure service worker exists, and that we really are getting a JS file. 106 | const contentType = response.headers.get('content-type'); 107 | if ( 108 | response.status === 404 || 109 | (contentType != null && contentType.indexOf('javascript') === -1) 110 | ) { 111 | // No service worker found. Probably a different app. Reload the page. 112 | navigator.serviceWorker.ready.then(registration => { 113 | registration.unregister().then(() => { 114 | window.location.reload(); 115 | }); 116 | }); 117 | } else { 118 | // Service worker found. Proceed as normal. 119 | registerValidSW(swUrl, config); 120 | } 121 | }) 122 | .catch(() => { 123 | console.log( 124 | 'No internet connection found. App is running in offline mode.' 125 | ); 126 | }); 127 | } 128 | 129 | export function unregister() { 130 | if ('serviceWorker' in navigator) { 131 | navigator.serviceWorker.ready.then(registration => { 132 | registration.unregister(); 133 | }); 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /src/utils/chart.js: -------------------------------------------------------------------------------- 1 | import Chart from 'chart.js'; 2 | 3 | Chart.defaults.LineWithLine = Chart.defaults.line; 4 | Chart.controllers.LineWithLine = Chart.controllers.line.extend({ 5 | draw(ease) { 6 | Chart.controllers.line.prototype.draw.call(this, ease); 7 | 8 | if (this.chart.tooltip._active && this.chart.tooltip._active.length) { 9 | const activePoint = this.chart.tooltip._active[0]; 10 | const { ctx } = this.chart; 11 | const { x } = activePoint.tooltipPosition(); 12 | const topY = this.chart.scales['y-axis-0'].top; 13 | const bottomY = this.chart.scales['y-axis-0'].bottom; 14 | 15 | // Draw the line 16 | ctx.save(); 17 | ctx.beginPath(); 18 | ctx.moveTo(x, topY); 19 | ctx.lineTo(x, bottomY); 20 | ctx.lineWidth = 0.5; 21 | ctx.strokeStyle = '#ddd'; 22 | ctx.stroke(); 23 | ctx.restore(); 24 | } 25 | }, 26 | }); 27 | 28 | export default Chart; 29 | -------------------------------------------------------------------------------- /src/views/AddNewPost.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Container, Row, Col } from "shards-react"; 3 | 4 | import PageTitle from "../components/common/PageTitle"; 5 | import Editor from "../components/add-new-post/Editor"; 6 | import SidebarActions from "../components/add-new-post/SidebarActions"; 7 | import SidebarCategories from "../components/add-new-post/SidebarCategories"; 8 | 9 | const AddNewPost = () => ( 10 | 11 | {/* Page Header */} 12 | 13 | 14 | 15 | 16 | 17 | {/* Editor */} 18 | 19 | 20 | 21 | 22 | {/* Sidebar Widgets */} 23 | 24 | 25 | 26 | 27 | 28 | 29 | ); 30 | 31 | export default AddNewPost; 32 | -------------------------------------------------------------------------------- /src/views/BlogOverview.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import PropTypes from "prop-types"; 3 | import { Container, Row, Col } from "shards-react"; 4 | 5 | import PageTitle from "./../components/common/PageTitle"; 6 | import SmallStats from "./../components/common/SmallStats"; 7 | import UsersOverview from "./../components/blog/UsersOverview"; 8 | import UsersByDevice from "./../components/blog/UsersByDevice"; 9 | import NewDraft from "./../components/blog/NewDraft"; 10 | import Discussions from "./../components/blog/Discussions"; 11 | import TopReferrals from "./../components/common/TopReferrals"; 12 | 13 | const BlogOverview = ({ smallStats }) => ( 14 | 15 | {/* Page Header */} 16 | 17 | 18 | 19 | 20 | {/* Small Stats Blocks */} 21 | 22 | {smallStats.map((stats, idx) => ( 23 | 24 | 35 | 36 | ))} 37 | 38 | 39 | 40 | {/* Users Overview */} 41 | 42 | 43 | 44 | 45 | {/* Users by Device */} 46 | 47 | 48 | 49 | 50 | {/* New Draft */} 51 | 52 | 53 | 54 | 55 | {/* Discussions */} 56 | 57 | 58 | 59 | 60 | {/* Top Referrals */} 61 | 62 | 63 | 64 | 65 | 66 | ); 67 | 68 | BlogOverview.propTypes = { 69 | /** 70 | * The small stats dataset. 71 | */ 72 | smallStats: PropTypes.array 73 | }; 74 | 75 | BlogOverview.defaultProps = { 76 | smallStats: [ 77 | { 78 | label: "Posts", 79 | value: "2,390", 80 | percentage: "4.7%", 81 | increase: true, 82 | chartLabels: [null, null, null, null, null, null, null], 83 | attrs: { md: "6", sm: "6" }, 84 | datasets: [ 85 | { 86 | label: "Today", 87 | fill: "start", 88 | borderWidth: 1.5, 89 | backgroundColor: "rgba(0, 184, 216, 0.1)", 90 | borderColor: "rgb(0, 184, 216)", 91 | data: [1, 2, 1, 3, 5, 4, 7] 92 | } 93 | ] 94 | }, 95 | { 96 | label: "Pages", 97 | value: "182", 98 | percentage: "12.4", 99 | increase: true, 100 | chartLabels: [null, null, null, null, null, null, null], 101 | attrs: { md: "6", sm: "6" }, 102 | datasets: [ 103 | { 104 | label: "Today", 105 | fill: "start", 106 | borderWidth: 1.5, 107 | backgroundColor: "rgba(23,198,113,0.1)", 108 | borderColor: "rgb(23,198,113)", 109 | data: [1, 2, 3, 3, 3, 4, 4] 110 | } 111 | ] 112 | }, 113 | { 114 | label: "Comments", 115 | value: "8,147", 116 | percentage: "3.8%", 117 | increase: false, 118 | decrease: true, 119 | chartLabels: [null, null, null, null, null, null, null], 120 | attrs: { md: "4", sm: "6" }, 121 | datasets: [ 122 | { 123 | label: "Today", 124 | fill: "start", 125 | borderWidth: 1.5, 126 | backgroundColor: "rgba(255,180,0,0.1)", 127 | borderColor: "rgb(255,180,0)", 128 | data: [2, 3, 3, 3, 4, 3, 3] 129 | } 130 | ] 131 | }, 132 | { 133 | label: "New Customers", 134 | value: "29", 135 | percentage: "2.71%", 136 | increase: false, 137 | decrease: true, 138 | chartLabels: [null, null, null, null, null, null, null], 139 | attrs: { md: "4", sm: "6" }, 140 | datasets: [ 141 | { 142 | label: "Today", 143 | fill: "start", 144 | borderWidth: 1.5, 145 | backgroundColor: "rgba(255,65,105,0.1)", 146 | borderColor: "rgb(255,65,105)", 147 | data: [1, 7, 1, 3, 1, 4, 8] 148 | } 149 | ] 150 | }, 151 | { 152 | label: "Subscribers", 153 | value: "17,281", 154 | percentage: "2.4%", 155 | increase: false, 156 | decrease: true, 157 | chartLabels: [null, null, null, null, null, null, null], 158 | attrs: { md: "4", sm: "6" }, 159 | datasets: [ 160 | { 161 | label: "Today", 162 | fill: "start", 163 | borderWidth: 1.5, 164 | backgroundColor: "rgb(0,123,255,0.1)", 165 | borderColor: "rgb(0,123,255)", 166 | data: [3, 2, 3, 2, 4, 5, 4] 167 | } 168 | ] 169 | } 170 | ] 171 | }; 172 | 173 | export default BlogOverview; 174 | -------------------------------------------------------------------------------- /src/views/BlogPosts.js: -------------------------------------------------------------------------------- 1 | /* eslint jsx-a11y/anchor-is-valid: 0 */ 2 | 3 | import React from "react"; 4 | import { 5 | Container, 6 | Row, 7 | Col, 8 | Card, 9 | CardBody, 10 | CardFooter, 11 | Badge, 12 | Button 13 | } from "shards-react"; 14 | 15 | import PageTitle from "../components/common/PageTitle"; 16 | 17 | class BlogPosts extends React.Component { 18 | constructor(props) { 19 | super(props); 20 | 21 | this.state = { 22 | // First list of posts. 23 | PostsListOne: [ 24 | { 25 | backgroundImage: require("../images/content-management/1.jpeg"), 26 | category: "Business", 27 | categoryTheme: "dark", 28 | author: "Anna Kunis", 29 | authorAvatar: require("../images/avatars/1.jpg"), 30 | title: "Conduct at an replied removal an amongst", 31 | body: 32 | "However venture pursuit he am mr cordial. Forming musical am hearing studied be luckily. But in for determine what would see...", 33 | date: "28 February 2019" 34 | }, 35 | { 36 | backgroundImage: require("../images/content-management/2.jpeg"), 37 | category: "Travel", 38 | categoryTheme: "info", 39 | author: "James Jamerson", 40 | authorAvatar: require("../images/avatars/2.jpg"), 41 | title: "Off tears are day blind smile alone had ready", 42 | body: 43 | "Is at purse tried jokes china ready decay an. Small its shy way had woody downs power. To denoting admitted speaking learning my...", 44 | date: "29 February 2019" 45 | }, 46 | { 47 | backgroundImage: require("../images/content-management/3.jpeg"), 48 | category: "Technology", 49 | categoryTheme: "royal-blue", 50 | author: "Jimmy Jackson", 51 | authorAvatar: require("../images/avatars/2.jpg"), 52 | title: "Difficult in delivered extensive at direction", 53 | body: 54 | "Is at purse tried jokes china ready decay an. Small its shy way had woody downs power. To denoting admitted speaking learning my...", 55 | date: "29 February 2019" 56 | }, 57 | { 58 | backgroundImage: require("../images/content-management/4.jpeg"), 59 | category: "Business", 60 | categoryTheme: "warning", 61 | author: "John James", 62 | authorAvatar: require("../images/avatars/3.jpg"), 63 | title: "It so numerous if he may outlived disposal", 64 | body: 65 | "How but sons mrs lady when. Her especially are unpleasant out alteration continuing unreserved ready road market resolution...", 66 | date: "29 February 2019" 67 | } 68 | ], 69 | 70 | // Second list of posts. 71 | PostsListTwo: [ 72 | { 73 | backgroundImage: require("../images/content-management/5.jpeg"), 74 | category: "Travel", 75 | categoryTheme: "info", 76 | author: "Anna Ken", 77 | authorAvatar: require("../images/avatars/0.jpg"), 78 | title: 79 | "Attention he extremity unwilling on otherwise cars backwards yet", 80 | body: 81 | "Conviction up partiality as delightful is discovered. Yet jennings resolved disposed exertion you off. Left did fond drew fat head poor jet pan flying over...", 82 | date: "29 February 2019" 83 | }, 84 | { 85 | backgroundImage: require("../images/content-management/6.jpeg"), 86 | category: "Business", 87 | categoryTheme: "dark", 88 | author: "John James", 89 | authorAvatar: require("../images/avatars/1.jpg"), 90 | title: 91 | "Totally words widow one downs few age every seven if miss part by fact", 92 | body: 93 | "Discovered had get considered projection who favourable. Necessary up knowledge it tolerably. Unwilling departure education to admitted speaking...", 94 | date: "29 February 2019" 95 | } 96 | ], 97 | 98 | // Third list of posts. 99 | PostsListThree: [ 100 | { 101 | author: "John James", 102 | authorAvatar: require("../images/avatars/1.jpg"), 103 | title: "Had denoting properly jointure which well books beyond", 104 | body: 105 | "In said to of poor full be post face snug. Introduced imprudence see say unpleasing devonshire acceptance son. Exeter longer wisdom work...", 106 | date: "29 February 2019" 107 | }, 108 | { 109 | author: "John James", 110 | authorAvatar: require("../images/avatars/2.jpg"), 111 | title: "Husbands ask repeated resolved but laughter debating", 112 | body: 113 | "It abode words began enjoy years no do no. Tried spoil as heart visit blush or. Boy possible blessing sensible set but margaret interest. Off tears...", 114 | date: "29 February 2019" 115 | }, 116 | { 117 | author: "John James", 118 | authorAvatar: require("../images/avatars/3.jpg"), 119 | title: 120 | "Instantly gentleman contained belonging exquisite now direction", 121 | body: 122 | "West room at sent if year. Numerous indulged distance old law you. Total state as merit court green decay he. Steepest merit checking railway...", 123 | date: "29 February 2019" 124 | } 125 | ], 126 | 127 | // Fourth list of posts. 128 | PostsListFour: [ 129 | { 130 | backgroundImage: require("../images/content-management/7.jpeg"), 131 | author: "Alene Trenton", 132 | authorUrl: "#", 133 | category: "News", 134 | categoryUrl: "#", 135 | title: "Extremity so attending objection as engrossed", 136 | body: 137 | "Pursuit chamber as elderly amongst on. Distant however warrant farther to of. My justice wishing prudent waiting in be...", 138 | date: "29 February 2019" 139 | }, 140 | { 141 | backgroundImage: require("../images/content-management/8.jpeg"), 142 | author: "Chris Jamie", 143 | authorUrl: "#", 144 | category: "News", 145 | categoryUrl: "#", 146 | title: "Bed sincerity yet therefore forfeited his", 147 | body: 148 | "Speaking throwing breeding betrayed children my to. Me marianne no he horrible produced ye. Sufficient unpleasing and...", 149 | date: "29 February 2019" 150 | }, 151 | { 152 | backgroundImage: require("../images/content-management/9.jpeg"), 153 | author: "Monica Jordan", 154 | authorUrl: "#", 155 | category: "News", 156 | categoryUrl: "#", 157 | title: "Object remark lively all did feebly excuse our", 158 | body: 159 | "Morning prudent removal an letters by. On could my in order never it. Or excited certain sixteen it to parties colonel not seeing...", 160 | date: "29 February 2019" 161 | }, 162 | { 163 | backgroundImage: require("../images/content-management/10.jpeg"), 164 | author: "Monica Jordan", 165 | authorUrl: "#", 166 | category: "News", 167 | categoryUrl: "#", 168 | title: "His followed carriage proposal entrance", 169 | body: 170 | "For county now sister engage had season better had waited. Occasional mrs interested far expression directly as regard...", 171 | date: "29 February 2019" 172 | } 173 | ] 174 | }; 175 | } 176 | 177 | render() { 178 | const { 179 | PostsListOne, 180 | PostsListTwo, 181 | PostsListThree, 182 | PostsListFour 183 | } = this.state; 184 | 185 | return ( 186 | 187 | {/* Page Header */} 188 | 189 | 190 | 191 | 192 | {/* First Row of Posts */} 193 | 194 | {PostsListOne.map((post, idx) => ( 195 | 196 | 197 |
201 | 205 | {post.category} 206 | 207 | 216 |
217 | 218 |
219 | 220 | {post.title} 221 | 222 |
223 |

{post.body}

224 | {post.date} 225 |
226 |
227 | 228 | ))} 229 |
230 | 231 | {/* Second Row of Posts */} 232 | 233 | {PostsListTwo.map((post, idx) => ( 234 | 235 | 236 |
240 | 244 | {post.category} 245 | 246 | 255 |
256 | 257 |
258 | 259 | {post.title} 260 | 261 |
262 |

{post.body}

263 | {post.date} 264 |
265 |
266 | 267 | ))} 268 |
269 | 270 | {/* Third Row of Posts */} 271 | 272 | {PostsListThree.map((post, idx) => ( 273 | 274 | 275 | 276 |
{post.title}
277 |

{post.body}

278 |
279 | 280 |
281 | 286 | Written by James Khan 287 | 288 |
289 | 290 | {post.author} 291 | 292 | {post.date} 293 |
294 |
295 |
296 | 299 |
300 |
301 |
302 | 303 | ))} 304 |
305 | 306 | {/* Fourth Row of posts */} 307 | 308 | {PostsListFour.map((post, idx) => ( 309 | 310 | 311 |
315 | 316 |
317 | 318 | {post.title} 319 | 320 |
321 |

{post.body}

322 |
323 | 324 | 325 | By 326 | 327 | {post.author} 328 | {" "} 329 | in 330 | 331 | {post.category} 332 | 333 | 334 | 335 | 336 | 337 | ))} 338 | 339 | 340 | ); 341 | } 342 | } 343 | 344 | export default BlogPosts; 345 | -------------------------------------------------------------------------------- /src/views/ComponentsOverview.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { 3 | Container, 4 | Row, 5 | Col, 6 | Card, 7 | CardHeader, 8 | ListGroup, 9 | ListGroupItem, 10 | Form, 11 | Alert 12 | } from "shards-react"; 13 | 14 | import PageTitle from "../components/common/PageTitle"; 15 | import Colors from "../components/components-overview/Colors"; 16 | import Checkboxes from "../components/components-overview/Checkboxes"; 17 | import RadioButtons from "../components/components-overview/RadioButtons"; 18 | import ToggleButtons from "../components/components-overview/ToggleButtons"; 19 | import SmallButtons from "../components/components-overview/SmallButtons"; 20 | import SmallOutlineButtons from "../components/components-overview/SmallOutlineButtons"; 21 | import NormalButtons from "../components/components-overview/NormalButtons"; 22 | import NormalOutlineButtons from "../components/components-overview/NormalOutlineButtons"; 23 | import Forms from "../components/components-overview/Forms"; 24 | import FormValidation from "../components/components-overview/FormValidation"; 25 | import CompleteFormExample from "../components/components-overview/CompleteFormExample"; 26 | import Sliders from "../components/components-overview/Sliders"; 27 | import ProgressBars from "../components/components-overview/ProgressBars"; 28 | import ButtonGroups from "../components/components-overview/ButtonGroups"; 29 | import InputGroups from "../components/components-overview/InputGroups"; 30 | import SeamlessInputGroups from "../components/components-overview/SeamlessInputGroups"; 31 | import CustomFileUpload from "../components/components-overview/CustomFileUpload"; 32 | import DropdownInputGroups from "../components/components-overview/DropdownInputGroups"; 33 | import CustomSelect from "../components/components-overview/CustomSelect"; 34 | 35 | const ComponentsOverview = () => ( 36 |
37 | 38 | 39 | How you doin'? I'm just a friendly, good-looking notification message and I come in all the colors you can see below. Pretty cool, huh? 40 | 41 | 42 | 43 | 44 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 |
Form Inputs
59 |
60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | Small Buttons 73 | 74 | 75 | 76 | 77 | Small Outline Button 78 | 79 | 80 | 81 | 82 | 83 | {/* Normal Buttons */} 84 | 85 | Normal Buttons 86 | 87 | 88 | 89 | {/* Normal Outline Buttons */} 90 | 91 | Normal Outline Buttons 92 | 93 | 94 | 95 | 96 | {/* Forms & Form Validation */} 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 |
105 | 106 | {/* Complete Form Example */} 107 | 108 | 109 |
Form Example
110 |
111 | 112 |
113 | 114 | 115 | 116 | {/* Sliders & Progress Bars */} 117 | 118 | 119 |
Sliders & Progress Bars
120 |
121 | 122 | 123 | 124 | 125 |
126 | 127 | {/* Groups */} 128 | 129 | 130 |
Groups
131 |
132 | 133 | 134 | 135 |
136 | 137 | Button Groups 138 | 139 | 140 | 141 | 142 | Input Groups 143 | 144 | 145 | 146 | 147 | Seamless Input Groups 148 | 149 | 150 | 151 |
152 |
153 |
154 | 155 | 156 | {/* Files & Dropdowns */} 157 | 158 |
Files & Dropdowns
159 |
160 | 161 | 162 | 163 | 164 | Custom File Upload 165 | 166 | 167 | 168 | 169 | Dropdown Input Groups 170 | 171 | 172 | 173 | 174 | Custom Select 175 | 176 | 177 | 178 | 179 |
180 | 181 |
182 |
183 |
184 | ); 185 | 186 | export default ComponentsOverview; 187 | -------------------------------------------------------------------------------- /src/views/Errors.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Container, Button } from "shards-react"; 3 | 4 | const Errors = () => ( 5 | 6 |
7 |
8 |

500

9 |

Something went wrong!

10 |

There was a problem on our end. Please try again later.

11 | 12 |
13 |
14 |
15 | ); 16 | 17 | export default Errors; 18 | -------------------------------------------------------------------------------- /src/views/Tables.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Container, Row, Col, Card, CardHeader, CardBody } from "shards-react"; 3 | 4 | import PageTitle from "../components/common/PageTitle"; 5 | 6 | const Tables = () => ( 7 | 8 | {/* Page Header */} 9 | 10 | 11 | 12 | 13 | {/* Default Light Table */} 14 | 15 | 16 | 17 | 18 |
Active Users
19 |
20 | 21 | 22 | 23 | 24 | 27 | 30 | 33 | 36 | 39 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 |
25 | # 26 | 28 | First Name 29 | 31 | Last Name 32 | 34 | Country 35 | 37 | City 38 | 40 | Phone 41 |
1AliKerryRussian FederationGdańsk107-0339
2ClarkAngelaEstoniaBorghetto di Vara1-660-850-1647
3JerryNathanCyprusBraunau am Inn214-4225
4ColtAngelaLiberiaBad Hersfeld1-848-473-7416
79 |
80 |
81 | 82 |
83 | 84 | {/* Default Dark Table */} 85 | 86 | 87 | 88 | 89 |
Active Users
90 |
91 | 92 | 93 | 94 | 95 | 98 | 101 | 104 | 107 | 110 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 |
96 | # 97 | 99 | First Name 100 | 102 | Last Name 103 | 105 | Country 106 | 108 | City 109 | 111 | Phone 112 |
1AliKerryRussian FederationGdańsk107-0339
2ClarkAngelaEstoniaBorghetto di Vara1-660-850-1647
3JerryNathanCyprusBraunau am Inn214-4225
4ColtAngelaLiberiaBad Hersfeld1-848-473-7416
150 |
151 |
152 | 153 |
154 |
155 | ); 156 | 157 | export default Tables; 158 | -------------------------------------------------------------------------------- /src/views/UserProfileLite.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Container, Row, Col } from "shards-react"; 3 | 4 | import PageTitle from "../components/common/PageTitle"; 5 | import UserDetails from "../components/user-profile-lite/UserDetails"; 6 | import UserAccountDetails from "../components/user-profile-lite/UserAccountDetails"; 7 | 8 | const UserProfileLite = () => ( 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | ); 23 | 24 | export default UserProfileLite; 25 | -------------------------------------------------------------------------------- /src/withTracker.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react"; 2 | import GoogleAnalytics from "react-ga"; 3 | 4 | GoogleAnalytics.initialize(process.env.REACT_APP_GAID || "UA-115105611-2"); 5 | 6 | const withTracker = (WrappedComponent, options = {}) => { 7 | const trackPage = page => { 8 | if (process.env.NODE_ENV !== "production") { 9 | return; 10 | } 11 | 12 | GoogleAnalytics.set({ 13 | page, 14 | ...options 15 | }); 16 | GoogleAnalytics.pageview(page); 17 | }; 18 | 19 | const BASENAME = process.env.REACT_APP_BASENAME || ""; 20 | 21 | // eslint-disable-next-line 22 | const HOC = class extends Component { 23 | componentDidMount() { 24 | // eslint-disable-next-line 25 | const page = this.props.location.pathname + this.props.location.search; 26 | trackPage(`${BASENAME}${page}`); 27 | } 28 | 29 | componentDidUpdate(prevProps) { 30 | const currentPage = 31 | prevProps.location.pathname + prevProps.location.search; 32 | const nextPage = 33 | this.props.location.pathname + this.props.location.search; 34 | 35 | if (currentPage !== nextPage) { 36 | trackPage(`${BASENAME}${nextPage}`); 37 | } 38 | } 39 | 40 | render() { 41 | return ; 42 | } 43 | }; 44 | 45 | return HOC; 46 | }; 47 | 48 | export default withTracker; 49 | --------------------------------------------------------------------------------