├── .gitignore
├── _config.yml
├── logo.png
├── favicon.ico
├── public
├── logo.png
├── favicon.ico
├── manifest.json
└── index.html
├── .idea
├── dictionaries
│ └── albiona.xml
├── misc.xml
├── vcs.xml
├── modules.xml
├── react_admin_dashboard.iml
└── workspace.xml
├── .storybook
├── addons.js
└── config.js
├── src
├── components
│ ├── layout
│ │ ├── App.test.js
│ │ ├── Layout.js
│ │ ├── App.js
│ │ ├── Notification.js
│ │ ├── NavMenu.js
│ │ ├── NotificationContent.js
│ │ ├── VerticalMenu.js
│ │ ├── TopMenu.js
│ │ └── SideMenu.js
│ ├── pages
│ │ ├── Button.js
│ │ ├── Home.js
│ │ ├── Card.js
│ │ └── UserManagement.js
│ ├── extension
│ │ └── TextIcon.js
│ └── common
│ │ └── registerServiceWorker.js
├── store
│ ├── SideMenu.js
│ ├── SearchStore.js
│ ├── Card.js
│ ├── configureStore.js
│ └── UserManagement.js
├── stories
│ └── index.js
├── index.js
└── styles
│ ├── NavMenu.css
│ └── index.css
├── manifest.json
├── CONTRIBUTING.md
├── index.html
├── README.md
├── package.json
├── asset-manifest.json
└── service-worker.js
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 | theme: jekyll-theme-slate
--------------------------------------------------------------------------------
/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlbionaHoti/react_admin_dashboard/HEAD/logo.png
--------------------------------------------------------------------------------
/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlbionaHoti/react_admin_dashboard/HEAD/favicon.ico
--------------------------------------------------------------------------------
/public/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlbionaHoti/react_admin_dashboard/HEAD/public/logo.png
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AlbionaHoti/react_admin_dashboard/HEAD/public/favicon.ico
--------------------------------------------------------------------------------
/.idea/dictionaries/albiona.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/.storybook/addons.js:
--------------------------------------------------------------------------------
1 | import '@storybook/addon-actions/register';
2 | import '@storybook/addon-links/register';
3 | import '@storybook/addon-notes/register';
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.storybook/config.js:
--------------------------------------------------------------------------------
1 | import {
2 | configure
3 | } from '@storybook/react';
4 |
5 | function loadStories() {
6 | import('../src/stories/index.js');
7 | // You can require as many stories as you need.
8 | }
9 |
10 | configure(loadStories, module);
--------------------------------------------------------------------------------
/src/components/layout/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import App from './components/layout/App';
4 |
5 | it('renders without crashing', () => {
6 | const div = document.createElement('div');
7 | ReactDOM.render(, div);
8 | });
9 |
--------------------------------------------------------------------------------
/src/components/pages/Button.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { connect } from 'react-redux';
3 | import {Button} from "semantic-ui-react";
4 |
5 | const ClickButton = props => (
6 |
9 | );
10 |
11 | export default connect()(ClickButton);
12 |
--------------------------------------------------------------------------------
/src/components/pages/Home.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { connect } from 'react-redux';
3 | import {Segment} from "semantic-ui-react";
4 |
5 | const Home = props => (
6 |
7 | React Admin Dashboard
8 |
9 | );
10 |
11 | export default connect()(Home);
12 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "ReactAdmin",
3 | "name": "ReactAdminDashboard",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | }
10 | ],
11 | "start_url": "./index.html",
12 | "display": "standalone",
13 | "theme_color": "#000000",
14 | "background_color": "#ffffff"
15 | }
16 |
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "ReactAdmin",
3 | "name": "ReactAdminDashboard",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | }
10 | ],
11 | "start_url": "./index.html",
12 | "display": "standalone",
13 | "theme_color": "#000000",
14 | "background_color": "#ffffff"
15 | }
16 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | ### Installing / Getting started
2 |
3 | ```
4 | git clone https://github.com/AlbionaHoti/react_admin_dashboard.git
5 | cd react_admin_dashboard
6 | ```
7 |
8 | To start the project run
9 | ```
10 | npm install
11 | npm start
12 | ```
13 | To start storybook run
14 |
15 | ```
16 | npm run storybook
17 | ```
18 | Feel free to add issues if you want to fix something or add new features :)
19 |
--------------------------------------------------------------------------------
/src/store/SideMenu.js:
--------------------------------------------------------------------------------
1 | const toggleMenu = 'TOGGLE_MENU';
2 | const initialState = { smallMenu: false };
3 |
4 | export const actionCreators = {
5 | toggleSideMenu: () => ({ type: toggleMenu }),
6 | };
7 |
8 | export const reducer = (state, action) => {
9 | state = state || initialState;
10 |
11 | if (action.type === toggleMenu) {
12 | return { ...state, smallMenu: !state.smallMenu};
13 | }
14 |
15 | return state;
16 | };
17 |
--------------------------------------------------------------------------------
/src/components/layout/Layout.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import SideMenu from "../layout/SideMenu";
3 | import TopMenu from "../layout/TopMenu";
4 |
5 | export default props => (
6 |
7 |
8 |
9 |
10 |
11 |
12 | {props.children}
13 |
14 |
15 |
16 | );
17 |
--------------------------------------------------------------------------------
/src/stories/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { storiesOf } from '@storybook/react';
3 | import { action } from '@storybook/addon-actions';
4 | import Button from '../components/';
5 |
6 | storiesOf('Button', module)
7 | .add('with text', () => (
8 |
9 | ))
10 | .add('with some emoji', () => (
11 |
12 | ));
--------------------------------------------------------------------------------
/src/store/SearchStore.js:
--------------------------------------------------------------------------------
1 | const SEARCH_BY_TEXT = 'SEARCH_BY_TEXT';
2 | const initialState = { text: '' };
3 |
4 | export const actionCreators = {
5 | search: (text) => async (dispatch, getState) => {
6 | dispatch({ type: SEARCH_BY_TEXT, text: text });
7 | },
8 | };
9 |
10 | export const reducer = (state, action) => {
11 | state = state || initialState;
12 |
13 | if (action.type === SEARCH_BY_TEXT) {
14 | return { ...state, text: action.text };
15 | }
16 |
17 | return state;
18 | };
19 |
--------------------------------------------------------------------------------
/src/components/layout/App.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { Route } from 'react-router'
3 | import Layout from '.././layout/Layout'
4 | import Home from '.././pages/Home'
5 | import UserManagement from '.././pages/UserManagement'
6 | import CardForm from '.././pages/Card'
7 |
8 | export default () => (
9 |
10 |
11 |
12 |
13 |
14 | );
15 |
--------------------------------------------------------------------------------
/.idea/react_admin_dashboard.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/components/layout/Notification.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import { Popup, Icon } from "semantic-ui-react";
3 | import NotificationContent from "./NotificationContent";
4 |
5 | export default class Notification extends Component {
6 | state = {};
7 |
8 | render() {
9 | return (
10 | }
13 | position='bottom right'
14 | verticalOffset={18}
15 | size="small"
16 |
17 | >
18 |
19 |
20 |
21 | );
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/store/Card.js:
--------------------------------------------------------------------------------
1 | const incrementCountType = 'INCREMENT_COUNT';
2 | const decrementCountType = 'DECREMENT_COUNT';
3 | const initialState = { count: 0 };
4 |
5 | export const actionCreators = {
6 | increment: () => ({ type: incrementCountType }),
7 | decrement: () => ({ type: decrementCountType })
8 | };
9 |
10 | export const reducer = (state, action) => {
11 | state = state || initialState;
12 |
13 | if (action.type === incrementCountType) {
14 | return { ...state, count: state.count + 1 };
15 | }
16 |
17 | if (action.type === decrementCountType) {
18 | return { ...state, count: state.count - 1 };
19 | }
20 |
21 | return state;
22 | };
23 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 | React Admin UI
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # React Admin Dashboard
2 | Admin Dashboard build with ReactJs and React Semantic UI. Which enables jump starting a new
3 | project with a prepared layout and React Semantic UI provides access to many useful [components](https://react.semantic-ui.com/).
4 |
5 | ## Installing / Getting started
6 |
7 | ```shell
8 | git clone https://github.com/AlbionaHoti/react_admin_dashboard.git
9 | cd react_admin_dashboard
10 | ```
11 | ## To start the project run
12 | ```
13 | npm install
14 | npm start
15 | ```
16 |
17 | ## To start storybook run
18 | ```
19 | npm run storybook
20 | ```
21 |
22 | [Project Demo](https://albionahoti.github.io/react_admin_dashboard/)
23 |
24 | Author: [Albiona Hoti](https://albionahoti.github.io)
25 |
26 | 
27 |
28 | ## Demo Details
29 |
30 | 
31 |
--------------------------------------------------------------------------------
/src/components/extension/TextIcon.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from 'react';
2 | import PropTypes from 'prop-types';
3 | import {Icon} from "semantic-ui-react";
4 |
5 | export default class TextIcon extends Component {
6 |
7 | style = {
8 | alignSelf: 'center',
9 | paddingLeft: '4px'
10 | };
11 |
12 | static propTypes = {
13 | name: PropTypes.string.isRequired,
14 | hideText: PropTypes.bool.isRequired,
15 | color: PropTypes.string
16 | };
17 |
18 | render() {
19 | return (
20 |
21 |
24 |
25 | {this.props.children}
26 |
27 |
28 | );
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/components/layout/NavMenu.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Link } from 'react-router-dom';
3 | import { Glyphicon, Nav, Navbar, NavItem } from 'react-bootstrap';
4 | import { LinkContainer } from 'react-router-bootstrap';
5 | import './NavMenu.css';
6 |
7 | export default props => (
8 |
9 |
10 |
11 | React Admin Dashboard
12 |
13 |
14 |
15 |
16 |
28 |
29 |
30 | );
31 |
--------------------------------------------------------------------------------
/src/components/pages/Card.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { bindActionCreators } from 'redux'
3 | import { connect } from 'react-redux'
4 | import { actionCreators } from '../../store/Card'
5 | import 'semantic-ui-css/semantic.min.css'
6 | import { Card, Icon, Image } from 'semantic-ui-react'
7 |
8 |
9 | const CardForm = props => (
10 |
11 |
12 |
13 | Matthew
14 |
15 | Joined in 2015
16 |
17 | Matthew is a musician living in Nashville.
18 |
19 |
20 |
21 |
22 | 22 Friends
23 |
24 |
25 |
26 | );
27 |
28 | export default connect(
29 | state => state.card,
30 | dispatch => bindActionCreators(actionCreators, dispatch)
31 | )(CardForm)
32 |
--------------------------------------------------------------------------------
/src/components/layout/NotificationContent.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 |
3 | import {
4 | Button,
5 | Grid,
6 | Header,
7 | Segment
8 | } from "semantic-ui-react";
9 |
10 | export default class NotificationContent extends Component {
11 | state = {};
12 | render() {
13 | const patients = [
14 | {
15 | name: "Elliot Fu",
16 | bio: "Elliot has been a member since July 2012",
17 | button: "More Info"
18 | },
19 | {
20 | name: "James Frank",
21 | bio: "James has been a member since Sep 2011",
22 | button: "More Info"
23 | },
24 | {
25 | name: "Algo Hemil",
26 | bio: "Algo has been a member since Nov 2015",
27 | button: "More Info"
28 | }
29 | ];
30 |
31 | return (
32 |
33 | {patients.map(patient => (
34 |
35 |
36 |
37 |
38 | {patient.bio}
39 |
40 |
41 |
42 | ))}
43 |
44 | );
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import 'bootstrap/dist/css/bootstrap.css'
2 | import 'bootstrap/dist/css/bootstrap-theme.css'
3 | import './styles/index.css'
4 | import React from 'react'
5 | import ReactDOM from 'react-dom'
6 | import { Provider } from 'react-redux'
7 | import { ConnectedRouter } from 'react-router-redux'
8 | import { createBrowserHistory } from 'history'
9 | import configureStore from './store/configureStore'
10 | import App from './components/layout/App'
11 | import registerServiceWroker from './components/common/registerServiceWorker'
12 |
13 | // Create browser history to use in the Redux store
14 | const baseUrl = document.getElementsByTagName('base')[0].getAttribute('href')
15 | const history = createBrowserHistory({ basename: baseUrl })
16 |
17 | // Get the application-wide store instance, prepopulating with state from the server where available.
18 | const initialState = window.initialReduxState
19 | const store = configureStore(history, initialState)
20 |
21 | const rootElement = document.getElementById('root')
22 |
23 | ReactDOM.render(
24 |
25 |
26 |
27 |
28 | ,
29 | rootElement)
30 |
31 | registerServiceWroker()
32 |
--------------------------------------------------------------------------------
/src/store/configureStore.js:
--------------------------------------------------------------------------------
1 | import { applyMiddleware, combineReducers, compose, createStore } from 'redux';
2 | import thunk from 'redux-thunk';
3 | import { routerReducer, routerMiddleware } from 'react-router-redux';
4 | import * as Card from './Card';
5 | import * as SideMenu from "./SideMenu";
6 | import * as UserManagement from "./UserManagement";
7 | import * as SearchStore from "./SearchStore";
8 |
9 | export default function configureStore(history, initialState) {
10 | const reducers = {
11 | card: Card.reducer,
12 | sideMenu: SideMenu.reducer,
13 | userManagement: UserManagement.reducer,
14 | searchStore: SearchStore.reducer,
15 | };
16 |
17 | const middleware = [
18 | thunk,
19 | routerMiddleware(history)
20 | ];
21 |
22 | // In development, use the browser's Redux dev tools extension if installed
23 | const enhancers = [];
24 | const isDevelopment = process.env.NODE_ENV === 'development';
25 | if (isDevelopment && typeof window !== 'undefined' && window.devToolsExtension) {
26 | enhancers.push(window.devToolsExtension());
27 | }
28 |
29 | const rootReducer = combineReducers({
30 | ...reducers,
31 | routing: routerReducer
32 | });
33 |
34 | return createStore(
35 | rootReducer,
36 | initialState,
37 | compose(applyMiddleware(...middleware), ...enhancers)
38 | );
39 | }
40 |
--------------------------------------------------------------------------------
/src/styles/NavMenu.css:
--------------------------------------------------------------------------------
1 | .navbar li .glyphicon {
2 | margin-right: 10px;
3 | }
4 |
5 | /* Highlighting rules for nav menu items */
6 | .navbar .navbar-nav .active a,
7 | .navbar .navbar-nav .active a:hover,
8 | .navbar .navbar-nav .active a:focus {
9 | background-image: none;
10 | background-color: #4189C7;
11 | color: white;
12 | }
13 |
14 | @media (min-width: 768px) {
15 | /* On large screens, convert the nav menu to a vertical sidebar */
16 | .navbar {
17 | height: 100%;
18 | width: calc(25% - 20px);
19 | }
20 | .navbar {
21 | border-radius: 0;
22 | border-width: 0;
23 | height: 100%;
24 | }
25 | .navbar-header {
26 | float: none;
27 | }
28 | .navbar .navbar-collapse {
29 | border-top: 1px solid #444;
30 | padding: 0;
31 | }
32 | .navbar .container-fluid {
33 | padding: 0;
34 | margin: 0;
35 | }
36 | .navbar .container-fluid .navbar-brand {
37 | margin: 0;
38 | }
39 | .navbar ul {
40 | float: none;
41 | }
42 | .navbar li {
43 | float: none;
44 | font-size: 15px;
45 | margin: 6px;
46 | }
47 | .navbar li a {
48 | padding: 10px 16px;
49 | border-radius: 4px;
50 | }
51 | .navbar a {
52 | /* If a menu item's text is too long, truncate it */
53 | width: 100%;
54 | white-space: nowrap;
55 | overflow: hidden;
56 | text-overflow: ellipsis;
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "homepage": "http://AlbionaHoti/react_admin_dashboard",
3 | "name": "ReactAdminDashboard",
4 | "version": "0.1.0",
5 | "private": true,
6 | "dependencies": {
7 | "bootstrap": "^3.3.7",
8 | "file-loader": "^1.1.9",
9 | "informed": "^1.10.4",
10 | "prop-types": "latest",
11 | "react": "^16.4.2",
12 | "react-bootstrap": "^0.31.5",
13 | "react-dom": "^16.4.2",
14 | "react-redux": "^5.0.6",
15 | "react-router-bootstrap": "^0.24.4",
16 | "react-router-dom": "^4.2.2",
17 | "react-router-redux": "^5.0.0-alpha.8",
18 | "react-scripts": "^2.1.8",
19 | "redux": "^3.7.2",
20 | "redux-thunk": "^2.2.0",
21 | "rimraf": "^2.6.2",
22 | "semantic-ui-css": "^2.3.1",
23 | "semantic-ui-react": "^0.78.3",
24 | "url-loader": "^0.6.2"
25 | },
26 | "scripts": {
27 | "start": "rimraf ./build && react-scripts start",
28 | "build": "react-scripts build",
29 | "test": "react-scripts test --env=jsdom",
30 | "eject": "react-scripts eject",
31 | "predeploy": "npm run build",
32 | "deploy": "gh-pages -d build",
33 | "storybook": "start-storybook -p 9001 -c .storybook"
34 | },
35 | "devDependencies": {
36 | "@storybook/addon-actions": "^3.4.8",
37 | "@storybook/addon-links": "^3.4.8",
38 | "@storybook/addon-notes": "^3.4.8",
39 | "@storybook/addons": "^3.4.8",
40 | "@storybook/react": "^5.0.6",
41 | "babel-core": "^6.26.3",
42 | "gh-pages": "^1.2.0"
43 | },
44 | "browserslist": [
45 | ">0.2%",
46 | "not dead",
47 | "not ie <= 11",
48 | "not op_mini all"
49 | ]
50 | }
51 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
13 |
14 |
15 |
24 | React Admin UI
25 |
26 |
27 |
28 |
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/src/styles/index.css:
--------------------------------------------------------------------------------
1 | @media (max-width: 767px) {
2 | /* On small screens, the nav menu spans the full width of the screen. Leave a space for it. */
3 | body {
4 | padding-top: 50px;
5 | }
6 | }
7 | :root {
8 | --top-menu-height: 4em;
9 | }
10 |
11 | .top-menu {
12 | height: var(--top-menu-height);
13 | }
14 | .grid {
15 | width: 100%;
16 | display: grid;
17 | grid: var(--top-menu-height) / 1fr;
18 | grid-template-areas: "menu"
19 | "maincontent";
20 | min-height: 100vh;
21 | }
22 |
23 | .menu {
24 | grid-area: menu;
25 | z-index: 100;
26 | }
27 |
28 | .main-content {
29 | grid-area: maincontent;
30 | background-color: #f9fafb;
31 | }
32 |
33 | .parent {
34 | display: inline-flex;
35 | }
36 |
37 | .side {
38 | transition: width 0.3s;
39 | width: 14em !important;
40 | overflow: hidden;
41 | padding-top: var(--top-menu-height);
42 | z-index: 99;
43 | }
44 |
45 | .small-side {
46 | width: 4em !important;
47 | flex-basis: 4em;
48 | }
49 |
50 | .content {
51 | position: absolute;
52 | right: 0;
53 | transition: all 0.3s;
54 | padding: 10px;
55 | width: calc(100% - 14em);
56 | }
57 |
58 | .small-content {
59 | padding: 10px;
60 | width: calc(100% - 4em);
61 | }
62 |
63 | .logo-space-menu-item {
64 | width: 14em;
65 | }
66 |
67 | .display-inline {
68 | display: inline-flex;
69 | align-items: center;
70 | }
71 |
72 | .logo-space {
73 | font-family: "Roboto Light", serif;
74 | font-size: 24px;
75 | margin: 0 auto;
76 |
77 | }
78 |
79 | .logo-space img, .display-inline img {
80 | margin-right: 8px;
81 | }
82 |
83 | .no-border::before {
84 | display: none;
85 | }
86 | .top-menu i.icon
87 | {
88 | margin: 0 !important;
89 | }
90 |
91 |
92 | .drop-left-padding{
93 | padding-left: 0 !important;
94 | }
95 |
96 | .label-on-corner {
97 | top: 0.8em !important;
98 | left: 78% !important;
99 | }
--------------------------------------------------------------------------------
/asset-manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "main.css": "static/css/main.8b61b94c.css",
3 | "main.css.map": "static/css/main.8b61b94c.css.map",
4 | "main.js": "static/js/main.511cd0c4.js",
5 | "main.js.map": "static/js/main.511cd0c4.js.map",
6 | "static/media/brand-icons.eot": "static/media/brand-icons.13db00b7.eot",
7 | "static/media/brand-icons.svg": "static/media/brand-icons.a1a749e8.svg",
8 | "static/media/brand-icons.ttf": "static/media/brand-icons.c5ebe0b3.ttf",
9 | "static/media/brand-icons.woff": "static/media/brand-icons.a046592b.woff",
10 | "static/media/brand-icons.woff2": "static/media/brand-icons.e8c322de.woff2",
11 | "static/media/flags.png": "static/media/flags.9c74e172.png",
12 | "static/media/glyphicons-halflings-regular.eot": "static/media/glyphicons-halflings-regular.f4769f9b.eot",
13 | "static/media/glyphicons-halflings-regular.svg": "static/media/glyphicons-halflings-regular.89889688.svg",
14 | "static/media/glyphicons-halflings-regular.ttf": "static/media/glyphicons-halflings-regular.e18bbf61.ttf",
15 | "static/media/glyphicons-halflings-regular.woff": "static/media/glyphicons-halflings-regular.fa277232.woff",
16 | "static/media/glyphicons-halflings-regular.woff2": "static/media/glyphicons-halflings-regular.448c34a5.woff2",
17 | "static/media/icons.eot": "static/media/icons.8e3c7f55.eot",
18 | "static/media/icons.svg": "static/media/icons.962a1bf3.svg",
19 | "static/media/icons.ttf": "static/media/icons.b87b9ba5.ttf",
20 | "static/media/icons.woff": "static/media/icons.faff9214.woff",
21 | "static/media/icons.woff2": "static/media/icons.0ab54153.woff2",
22 | "static/media/outline-icons.eot": "static/media/outline-icons.701ae6ab.eot",
23 | "static/media/outline-icons.svg": "static/media/outline-icons.82f60bd0.svg",
24 | "static/media/outline-icons.ttf": "static/media/outline-icons.ad97afd3.ttf",
25 | "static/media/outline-icons.woff": "static/media/outline-icons.ef60a4f6.woff",
26 | "static/media/outline-icons.woff2": "static/media/outline-icons.cd6c777f.woff2"
27 | }
--------------------------------------------------------------------------------
/src/store/UserManagement.js:
--------------------------------------------------------------------------------
1 | const GET_ALL_USERS_ACTION = "GET_ALL_USERS";
2 | const DELETE_USER_ACTION = "DELETE_USER";
3 | const UPDATE_USER_ACTION = "UPDATE_USER";
4 | const ADD_USER_ACTION = "ADD_USER";
5 |
6 | const initialState = {
7 | users: [
8 | {
9 | name: "Albiona",
10 | email: "alb@gmail.com",
11 | role: "Admin",
12 | caloryLimit: 123
13 | },
14 | {
15 | name: "Albiona",
16 | email: "alb@gmail.com",
17 | role: "Admin",
18 | caloryLimit: 123
19 | },
20 | {
21 | name: "Albiona",
22 | email: "alb@gmail.com",
23 | role: "Admin",
24 | caloryLimit: 123
25 | }
26 | ]
27 | };
28 |
29 | export const actionCreators = {
30 | getUsers: () => async (dispatch, getState) => {
31 | // dispatch({ type: GET_ALL_USERS_ACTION, users: json });
32 | },
33 | removeUser: id => async (dispatch, getState) => {
34 | dispatch({
35 | type: DELETE_USER_ACTION,
36 | users: getState().userManagement.users.filter(m => m.id !== id)
37 | });
38 | },
39 | editUser: user => async (dispatch, getState) => {
40 | dispatch({
41 | type: UPDATE_USER_ACTION,
42 | users: getState().userManagement.users.map(
43 | m => (m.id === user.id ? user : m)
44 | )
45 | });
46 | },
47 | addUser: user => async (dispatch, getState) => {
48 | dispatch({
49 | type: ADD_USER_ACTION,
50 | user: Object.assign({}, user, { id: Math.random() })
51 | });
52 | }
53 | };
54 |
55 | export const reducer = (state, action) => {
56 | state = state || initialState;
57 |
58 | if (action.type === GET_ALL_USERS_ACTION) {
59 | return { ...state, users: action.users };
60 | }
61 | if (action.type === DELETE_USER_ACTION) {
62 | return { ...state, users: action.users };
63 | }
64 | if (action.type === UPDATE_USER_ACTION) {
65 | return { ...state, users: action.users };
66 | }
67 | if (action.type === ADD_USER_ACTION) {
68 | return { ...state, users: [...state.users, action.user] };
69 | }
70 |
71 | return state;
72 | };
73 |
--------------------------------------------------------------------------------
/src/components/layout/VerticalMenu.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import { Icon, Menu, Rail } from "semantic-ui-react";
3 | import { NavLink } from "react-router-dom";
4 |
5 | export default class VerticalMenu extends Component {
6 | state = { activeItem: "dashboard" };
7 | handleItemClick = (e, { name }) => this.setState({ activeItem: name });
8 |
9 | render() {
10 | const { activeItem } = this.state;
11 |
12 | return (
13 |
70 | );
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/components/layout/TopMenu.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from 'react'
2 | import {Icon,
3 | Image,
4 | Input,
5 | Label,
6 | Menu,
7 | } from 'semantic-ui-react'
8 | import {actionCreators as sideAction} from "../../store/SideMenu";
9 | import {actionCreators as searchAction} from "../../store/SearchStore";
10 | import {bindActionCreators} from "redux";
11 | import { connect } from 'react-redux';
12 | import Notification from './Notification';
13 |
14 | class TopMenu extends Component {
15 | state = {};
16 |
17 | handleItemClick = (e, { name }) => this.setState({ activeItem: name });
18 |
19 | doSearch(event) {
20 | this.props.actions.search(event.target.value);
21 | }
22 |
23 | render() {
24 | return (
25 |
74 | );
75 | }
76 | }
77 |
78 | export default connect(
79 | state => state.sideMenu,
80 | dispatch => {
81 | return {
82 | actions: bindActionCreators(Object.assign({}, sideAction, searchAction), dispatch)
83 | }}
84 | )(TopMenu);
85 |
--------------------------------------------------------------------------------
/src/components/layout/SideMenu.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from 'react'
2 | import {Menu} from 'semantic-ui-react'
3 | import {Link} from "react-router-dom";
4 | import TextIcon from "../extension/TextIcon";
5 | import {bindActionCreators} from "redux";
6 | import {connect} from "react-redux";
7 | import { actionCreators } from "../../store/SideMenu";
8 |
9 | class SideMenu extends Component {
10 | state = {
11 | activeItem: 'dashboard',
12 | };
13 |
14 | handleItemClick = (e, {name}) => this.setState({activeItem: name});
15 | changeSize = () => this.setState({smallSidebar: !this.props.smallMenu});
16 |
17 | getMenu() {
18 | const {activeItem} = this.state;
19 | return (
20 |
63 | )
64 | }
65 |
66 | render() {
67 | return (
68 |
69 |
70 | {this.getMenu()}
71 |
72 |
73 | {this.props.children}
74 |
75 |
76 | )
77 | }
78 | }
79 |
80 | export default connect(
81 | state => state.sideMenu,
82 | dispatch => bindActionCreators(actionCreators, dispatch)
83 | )(SideMenu);
84 |
--------------------------------------------------------------------------------
/src/components/common/registerServiceWorker.js:
--------------------------------------------------------------------------------
1 | // In production, we register a service worker to serve assets from local cache.
2 |
3 | // This lets the app load faster on subsequent visits in production, and gives
4 | // it offline capabilities. However, it also means that developers (and users)
5 | // will only see deployed updates on the "N+1" visit to a page, since previously
6 | // cached resources are updated in the background.
7 |
8 | // To learn more about the benefits of this model, read https://goo.gl/KwvDNy.
9 | // This link also includes instructions on opting out of this behavior.
10 |
11 | const isLocalhost = Boolean(
12 | window.location.hostname === 'localhost' ||
13 | // [::1] is the IPv6 localhost address.
14 | window.location.hostname === '[::1]' ||
15 | // 127.0.0.1/8 is considered localhost for IPv4.
16 | window.location.hostname.match(
17 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
18 | )
19 | );
20 |
21 | export default function register() {
22 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
23 | // The URL constructor is available in all browsers that support SW.
24 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location);
25 | if (publicUrl.origin !== window.location.origin) {
26 | // Our service worker won't work if PUBLIC_URL is on a different origin
27 | // from what our page is served on. This might happen if a CDN is used to
28 | // serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374
29 | return;
30 | }
31 |
32 | window.addEventListener('load', () => {
33 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
34 |
35 | if (isLocalhost) {
36 | // This is running on localhost. Lets check if a service worker still exists or not.
37 | checkValidServiceWorker(swUrl);
38 | } else {
39 | // Is not local host. Just register service worker
40 | registerValidSW(swUrl);
41 | }
42 | });
43 | }
44 | }
45 |
46 | function registerValidSW(swUrl) {
47 | navigator.serviceWorker
48 | .register(swUrl)
49 | .then(registration => {
50 | registration.onupdatefound = () => {
51 | const installingWorker = registration.installing;
52 | installingWorker.onstatechange = () => {
53 | if (installingWorker.state === 'installed') {
54 | if (navigator.serviceWorker.controller) {
55 | // At this point, the old content will have been purged and
56 | // the fresh content will have been added to the cache.
57 | // It's the perfect time to display a "New content is
58 | // available; please refresh." message in your web app.
59 | console.log('New content is available; please refresh.');
60 | } else {
61 | // At this point, everything has been precached.
62 | // It's the perfect time to display a
63 | // "Content is cached for offline use." message.
64 | console.log('Content is cached for offline use.');
65 | }
66 | }
67 | };
68 | };
69 | })
70 | .catch(error => {
71 | console.error('Error during service worker registration:', error);
72 | });
73 | }
74 |
75 | function checkValidServiceWorker(swUrl) {
76 | // Check if the service worker can be found. If it can't reload the page.
77 | fetch(swUrl)
78 | .then(response => {
79 | // Ensure service worker exists, and that we really are getting a JS file.
80 | if (
81 | response.status === 404 ||
82 | response.headers.get('content-type').indexOf('javascript') === -1
83 | ) {
84 | // No service worker found. Probably a different app. Reload the page.
85 | navigator.serviceWorker.ready.then(registration => {
86 | registration.unregister().then(() => {
87 | window.location.reload();
88 | });
89 | });
90 | } else {
91 | // Service worker found. Proceed as normal.
92 | registerValidSW(swUrl);
93 | }
94 | })
95 | .catch(() => {
96 | console.log(
97 | 'No internet connection found. App is running in offline mode.'
98 | );
99 | });
100 | }
101 |
102 | export function unregister() {
103 | if ('serviceWorker' in navigator) {
104 | navigator.serviceWorker.ready.then(registration => {
105 | registration.unregister();
106 | });
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/service-worker.js:
--------------------------------------------------------------------------------
1 | "use strict";var precacheConfig=[["/react_admin_dashboard/index.html","eb685f747f816197c324765c8c27e331"],["/react_admin_dashboard/static/css/main.8b61b94c.css","760997b04eb646c970ea09376b99e04a"],["/react_admin_dashboard/static/js/main.511cd0c4.js","abb50e667c21f3144abaa930898195ee"],["/react_admin_dashboard/static/media/brand-icons.13db00b7.eot","13db00b7a34fee4d819ab7f9838cc428"],["/react_admin_dashboard/static/media/brand-icons.a046592b.woff","a046592bac8f2fd96e994733faf3858c"],["/react_admin_dashboard/static/media/brand-icons.a1a749e8.svg","a1a749e89f578a49306ec2b055c073da"],["/react_admin_dashboard/static/media/brand-icons.c5ebe0b3.ttf","c5ebe0b32dc1b5cc449a76c4204d13bb"],["/react_admin_dashboard/static/media/brand-icons.e8c322de.woff2","e8c322de9658cbeb8a774b6624167c2c"],["/react_admin_dashboard/static/media/flags.9c74e172.png","9c74e172f87984c48ddf5c8108cabe67"],["/react_admin_dashboard/static/media/glyphicons-halflings-regular.448c34a5.woff2","448c34a56d699c29117adc64c43affeb"],["/react_admin_dashboard/static/media/glyphicons-halflings-regular.89889688.svg","89889688147bd7575d6327160d64e760"],["/react_admin_dashboard/static/media/glyphicons-halflings-regular.e18bbf61.ttf","e18bbf611f2a2e43afc071aa2f4e1512"],["/react_admin_dashboard/static/media/glyphicons-halflings-regular.f4769f9b.eot","f4769f9bdb7466be65088239c12046d1"],["/react_admin_dashboard/static/media/glyphicons-halflings-regular.fa277232.woff","fa2772327f55d8198301fdb8bcfc8158"],["/react_admin_dashboard/static/media/icons.0ab54153.woff2","0ab54153eeeca0ce03978cc463b257f7"],["/react_admin_dashboard/static/media/icons.8e3c7f55.eot","8e3c7f5520f5ae906c6cf6d7f3ddcd19"],["/react_admin_dashboard/static/media/icons.962a1bf3.svg","962a1bf31c081691065fe333d9fa8105"],["/react_admin_dashboard/static/media/icons.b87b9ba5.ttf","b87b9ba532ace76ae9f6edfe9f72ded2"],["/react_admin_dashboard/static/media/icons.faff9214.woff","faff92145777a3cbaf8e7367b4807987"],["/react_admin_dashboard/static/media/outline-icons.701ae6ab.eot","701ae6abd4719e9c2ada3535a497b341"],["/react_admin_dashboard/static/media/outline-icons.82f60bd0.svg","82f60bd0b94a1ed68b1e6e309ce2e8c3"],["/react_admin_dashboard/static/media/outline-icons.ad97afd3.ttf","ad97afd3337e8cda302d10ff5a4026b8"],["/react_admin_dashboard/static/media/outline-icons.cd6c777f.woff2","cd6c777f1945164224dee082abaea03a"],["/react_admin_dashboard/static/media/outline-icons.ef60a4f6.woff","ef60a4f6c25ef7f39f2d25a748dbecfe"]],cacheName="sw-precache-v3-sw-precache-webpack-plugin-"+(self.registration?self.registration.scope:""),ignoreUrlParametersMatching=[/^utm_/],addDirectoryIndex=function(e,a){var t=new URL(e);return"/"===t.pathname.slice(-1)&&(t.pathname+=a),t.toString()},cleanResponse=function(e){if(!e.redirected)return Promise.resolve(e);return("body"in e?Promise.resolve(e.body):e.blob()).then(function(a){return new Response(a,{headers:e.headers,status:e.status,statusText:e.statusText})})},createCacheKey=function(e,a,t,n){var r=new URL(e);return n&&r.pathname.match(n)||(r.search+=(r.search?"&":"")+encodeURIComponent(a)+"="+encodeURIComponent(t)),r.toString()},isPathWhitelisted=function(e,a){if(0===e.length)return!0;var t=new URL(a).pathname;return e.some(function(e){return t.match(e)})},stripIgnoredUrlParameters=function(e,a){var t=new URL(e);return t.hash="",t.search=t.search.slice(1).split("&").map(function(e){return e.split("=")}).filter(function(e){return a.every(function(a){return!a.test(e[0])})}).map(function(e){return e.join("=")}).join("&"),t.toString()},hashParamName="_sw-precache",urlsToCacheKeys=new Map(precacheConfig.map(function(e){var a=e[0],t=e[1],n=new URL(a,self.location),r=createCacheKey(n,hashParamName,t,/\.\w{8}\./);return[n.toString(),r]}));function setOfCachedUrls(e){return e.keys().then(function(e){return e.map(function(e){return e.url})}).then(function(e){return new Set(e)})}self.addEventListener("install",function(e){e.waitUntil(caches.open(cacheName).then(function(e){return setOfCachedUrls(e).then(function(a){return Promise.all(Array.from(urlsToCacheKeys.values()).map(function(t){if(!a.has(t)){var n=new Request(t,{credentials:"same-origin"});return fetch(n).then(function(a){if(!a.ok)throw new Error("Request for "+t+" returned a response with status "+a.status);return cleanResponse(a).then(function(a){return e.put(t,a)})})}}))})}).then(function(){return self.skipWaiting()}))}),self.addEventListener("activate",function(e){var a=new Set(urlsToCacheKeys.values());e.waitUntil(caches.open(cacheName).then(function(e){return e.keys().then(function(t){return Promise.all(t.map(function(t){if(!a.has(t.url))return e.delete(t)}))})}).then(function(){return self.clients.claim()}))}),self.addEventListener("fetch",function(e){if("GET"===e.request.method){var a,t=stripIgnoredUrlParameters(e.request.url,ignoreUrlParametersMatching),n="index.html";(a=urlsToCacheKeys.has(t))||(t=addDirectoryIndex(t,n),a=urlsToCacheKeys.has(t));var r="/react_admin_dashboard/index.html";!a&&"navigate"===e.request.mode&&isPathWhitelisted(["^(?!\\/__).*"],e.request.url)&&(t=new URL(r,self.location).toString(),a=urlsToCacheKeys.has(t)),a&&e.respondWith(caches.open(cacheName).then(function(e){return e.match(urlsToCacheKeys.get(t)).then(function(e){if(e)return e;throw Error("The cached response that was expected is missing.")})}).catch(function(a){return console.warn('Couldn\'t serve response for "%s" from cache: %O',e.request.url,a),fetch(e.request)}))}});
--------------------------------------------------------------------------------
/src/components/pages/UserManagement.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import {
3 | Button,
4 | Form,
5 | Header,
6 | Icon,
7 | Input,
8 | Message,
9 | Segment,
10 | Table
11 | } from "semantic-ui-react";
12 | import { bindActionCreators } from "redux";
13 | import { actionCreators } from "../../store/UserManagement";
14 | import { connect } from "react-redux";
15 |
16 | class UserManagement extends Component {
17 | constructor(props) {
18 | super(props);
19 | this.state = {
20 | newUser: {
21 | name: "",
22 | email: "",
23 | role: "",
24 | caloryLimit: 0
25 | }
26 | };
27 | this.handleSubmit = this.handleSubmit.bind(this);
28 | }
29 |
30 | getTableData = props => {
31 | return props.state.userManagement.users.filter(user => {
32 | return user.name.includes(props.state.searchStore.text)
33 | }).map(user =>
34 |
35 | {user.name +
36 | (user.password
37 | ? ' | Pass: "' + user.password + '" !!Attention'
38 | : "")}
39 |
40 | {user.email}
41 | {user.role}
42 | {user.caloryLimit}
43 |
44 |
47 |
50 |
51 | );
52 | };
53 |
54 | deleteUser = id => {
55 | this.props.removeUser(id);
56 | };
57 |
58 | selectUserForEditing = id => {
59 | let user = this.props.state.userManagement.users.find(v => v.id === id);
60 |
61 | this.setState({
62 | newUser: user
63 | });
64 | };
65 |
66 | handleSubmit = () => {
67 | if (this.state.newUser.id) this.props.editUser(this.state.newUser);
68 | else this.props.addUser(this.state.newUser);
69 |
70 | this.clearUserForm();
71 | };
72 |
73 | handleChange = event => {
74 | const target = event.target;
75 | const value = target.type === "checkbox" ? target.checked : target.value;
76 | const name = target.name;
77 |
78 | this.setState({
79 | newUser: Object.assign({}, this.state.newUser, {
80 | [name]: value
81 | })
82 | });
83 | };
84 |
85 | onDropdownSelection = (e, { value }) => {
86 | this.setState({
87 | newUser: Object.assign({}, this.state.newUser, {
88 | role: value
89 | })
90 | });
91 | };
92 |
93 | clearUserForm = () => {
94 | this.setState({
95 | newUser: {
96 | name: "",
97 | email: "",
98 | role: "",
99 | caloryLimit: 0
100 | }
101 | });
102 | };
103 |
104 | render() {
105 | if (!this.props.state.userManagement.users) {
106 | return USERMNG Loading;
107 | }
108 | return [
109 |
110 |
111 |
112 |
113 |
114 | Name
115 | Email
116 | Role
117 | Calory Limit
118 | Actions
119 |
120 |
121 |
122 | {this.getTableData(this.props)}
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 | ,
131 |
132 |
134 |
135 |
136 |
143 |
144 |
145 |
146 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
166 |
167 |
168 |
169 |
177 |
178 |
179 |
182 |
183 |
184 |
185 | ];
186 | }
187 | }
188 |
189 |
190 | export default connect(
191 | state => {
192 | const { searchStore, userManagement } = state;
193 | return {
194 | state: { searchStore, userManagement }
195 | };
196 | },
197 | dispatch => bindActionCreators(actionCreators, dispatch)
198 | )(UserManagement);
199 |
--------------------------------------------------------------------------------
/.idea/workspace.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
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 |
150 |
151 | weatherforecast
152 | forecasts
153 | toggle
154 | submit
155 | import cou
156 |
157 |
158 |
159 |
160 |
161 |
162 |
174 |
175 |
176 |
177 |
178 |
179 |
180 | true
181 | DEFINITION_ORDER
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 | 1533233995929
317 |
318 |
319 | 1533233995929
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 |
445 |
446 |
447 |
448 |
449 |
450 |
451 |
452 |
453 |
454 |
455 |
456 |
457 |
458 |
459 |
460 |
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 |
469 |
470 |
471 |
472 |
473 |
474 |
475 |
476 |
477 |
478 |
479 |
480 |
481 |
482 |
483 |
484 |
485 |
486 |
487 |
488 |
489 |
490 |
491 |
492 |
493 |
494 |
495 |
496 |
497 |
498 |
499 |
500 |
501 |
502 |
503 |
504 |
505 |
506 |
507 |
508 |
509 |
510 |
511 |
512 |
513 |
514 |
--------------------------------------------------------------------------------