[
  {
    "path": ".config/tomahawkci.yml",
    "content": "version: '1.0.0'\n\ndependencies:\n  - npm install --ignore-scripts\n\ntasks:\n  test:\n    - npm run test"
  },
  {
    "path": ".gitignore",
    "content": "# dependencies\n/node_modules\n\n# testing\n/coverage\n\n# production\n/build\n\n# misc\n.DS_Store\n.env.local\n.env.development.local\n.env.test.local\n.env.production.local\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\nfunctions/\nfunctions-src/\n\n.vscode/settings.json\n"
  },
  {
    "path": "Procfile",
    "content": "web: npm run deploy"
  },
  {
    "path": "README.md",
    "content": "## Description\nThis is a boilerplate for React using Typescript, Material UI and Redux, React Router.\n\n## Demo\n*Visit [Demo link](https://material-ui-admin.herokuapp.com/)*\n#### Login credentials\n* username/email: *anything*\n* password: *anything*\n\n## Features\n### Authentication\nThe app uses redux to manage the authentication state, and uses redux-auth-wrapper library to guard the routes\n#### Pages\n*  Login Page\n\n### Admin dashboard\nThe template comes with responsive modern charts, analytics, tables that are easily customizable to meet your data. \n\n### Other pages\n* Inbox, Outbox, Drafts\n* Profile Page (coming soon)\n\n## How to run\n### Local development\n* Clone the project and cd into project\n* npm install\n* npm start and go to [link](*http://localhost:3000*)\n\n### Deployment\n* npm install\n* npm run build\n* npm run deploy\n\n## Key technologies & Libraries used\n* Material UI (1.1.0) - (for ui components)\n* React Router\n* Redux\n* Typescript\n* React (of course)\n\n\n\n"
  },
  {
    "path": "_config.yml",
    "content": "theme: jekyll-theme-cayman"
  },
  {
    "path": "images.d.ts",
    "content": "declare module '*.svg'\ndeclare module '*.png'\ndeclare module '*.jpg'\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"react-boilerplate\",\n  \"version\": \"0.1.0\",\n  \"private\": true,\n  \"dependencies\": {\n    \"@material-ui/core\": \"^1.5.1\",\n    \"@material-ui/icons\": \"^1.1.1\",\n    \"@types/immutable\": \"^3.8.7\",\n    \"@types/lodash\": \"^4.14.119\",\n    \"@types/moment\": \"^2.13.0\",\n    \"@types/react-redux\": \"^6.0.13\",\n    \"@types/react-router-dom\": \"^4.3.1\",\n    \"@types/recharts\": \"^1.1.6\",\n    \"@types/redux\": \"^3.6.31\",\n    \"@types/redux-auth-wrapper\": \"^2.0.9\",\n    \"@types/redux-devtools-extension\": \"^2.13.2\",\n    \"@types/redux-thunk\": \"^2.1.32\",\n    \"@types/reselect\": \"^2.2.0\",\n    \"classnames\": \"^2.2.6\",\n    \"express\": \"^4.16.4\",\n    \"immutable\": \"^3.8.2\",\n    \"lodash\": \"^4.17.11\",\n    \"mobx\": \"^4.8.0\",\n    \"mobx-react-devtools\": \"^5.0.1\",\n    \"moment\": \"^2.23.0\",\n    \"querystring\": \"^0.2.0\",\n    \"randomcolor\": \"^0.5.3\",\n    \"react\": \"^16.7.0\",\n    \"react-dom\": \"^16.7.0\",\n    \"react-mobx\": \"0.0.3\",\n    \"react-redux\": \"^5.1.1\",\n    \"react-router-dom\": \"^4.3.1\",\n    \"react-scripts-ts\": \"2.16.0\",\n    \"recharts\": \"^1.4.2\",\n    \"redux\": \"^4.0.1\",\n    \"redux-auth-wrapper\": \"^2.0.3\",\n    \"redux-devtools-extension\": \"^2.13.7\",\n    \"redux-rest-resource\": \"^0.18.0\",\n    \"redux-thunk\": \"^2.3.0\",\n    \"reselect\": \"^3.0.1\"\n  },\n  \"scripts\": {\n    \"start\": \"react-scripts-ts start\",\n    \"build\": \"react-scripts-ts build\",\n    \"test\": \"react-scripts-ts test --env=jsdom\",\n    \"postinstall\": \"npm run build\",\n    \"deploy\": \"node server.js\",\n    \"eject\": \"react-scripts-ts eject\"\n  },\n  \"devDependencies\": {\n    \"@types/jest\": \"^22.2.3\",\n    \"@types/node\": \"^10.12.18\",\n    \"@types/react\": \"^16.7.18\",\n    \"@types/react-dom\": \"^16.0.11\",\n    \"babel-plugin-transform-decorators-legacy\": \"^1.3.4\",\n    \"typescript\": \"^3.2.2\"\n  },\n  \"babel\": {\n    \"plugins\": [\n      \"transform-decorators-legacy\"\n    ],\n    \"presets\": [\n      \"react-app\"\n    ]\n  }\n}\n"
  },
  {
    "path": "public/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, shrink-to-fit=no\">\n    <meta name=\"theme-color\" content=\"#000000\">\n    <link rel=\"stylesheet\" href=\"https://fonts.googleapis.com/css?family=Roboto:300,400,500\">\n    <link rel=\"stylesheet\" href=\"https://fonts.googleapis.com/icon?family=Material+Icons\">\n\n    <!--\n      manifest.json provides metadata used when your web app is added to the\n      homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/\n    -->\n    <link rel=\"manifest\" href=\"%PUBLIC_URL%/manifest.json\">\n    <link rel=\"shortcut icon\" href=\"%PUBLIC_URL%/favicon.ico\">\n    <!--\n      Notice the use of %PUBLIC_URL% in the tags above.\n      It will be replaced with the URL of the `public` folder during the build.\n      Only files inside the `public` folder can be referenced from the HTML.\n\n      Unlike \"/favicon.ico\" or \"favicon.ico\", \"%PUBLIC_URL%/favicon.ico\" will\n      work correctly both with client-side routing and a non-root public URL.\n      Learn how to configure a non-root public URL by running `npm run build`.\n    -->\n    <title>Tomahawk</title>\n  </head>\n  <body>\n    <noscript>\n      You need to enable JavaScript to run this app.\n    </noscript>\n    <div id=\"root\"></div>\n    <!--\n      This HTML file is a template.\n      If you open it directly in the browser, you will see an empty page.\n\n      You can add webfonts, meta tags, or analytics to this file.\n      The build step will place the bundled scripts into the <body> tag.\n\n      To begin the development, run `npm start` or `yarn start`.\n      To create a production bundle, use `npm run build` or `yarn build`.\n    -->\n  </body>\n</html>\n"
  },
  {
    "path": "public/manifest.json",
    "content": "{\n  \"short_name\": \"React App\",\n  \"name\": \"Create React App Sample\",\n  \"icons\": [\n    {\n      \"src\": \"favicon.ico\",\n      \"sizes\": \"64x64 32x32 24x24 16x16\",\n      \"type\": \"image/x-icon\"\n    }\n  ],\n  \"start_url\": \"./index.html\",\n  \"display\": \"standalone\",\n  \"theme_color\": \"#000000\",\n  \"background_color\": \"#ffffff\"\n}\n"
  },
  {
    "path": "server.js",
    "content": "const express = require('express');\nconst path = require('path');\nconst app = express();\n\napp.use(express.static(path.join(__dirname, 'build')));\napp.get('*', function (req, res) {\n  res.sendFile(path.join(__dirname, 'build', 'index.html'));\n});\n\napp.listen(process.env.PORT || 3000);\n"
  },
  {
    "path": "src/App.css",
    "content": ".App {\n  text-align: center;\n}\n\n.App-logo {\n  animation: App-logo-spin infinite 20s linear;\n  height: 80px;\n}\n\n.App-header {\n  background-color: #222;\n  height: 150px;\n  padding: 20px;\n  color: white;\n}\n\n.App-title {\n  font-size: 1.5em;\n}\n\n.App-intro {\n  font-size: large;\n}\n\n@keyframes App-logo-spin {\n  from { transform: rotate(0deg); }\n  to { transform: rotate(360deg); }\n}\n"
  },
  {
    "path": "src/App.test.tsx",
    "content": "import * as React from 'react';\nimport * as ReactDOM from 'react-dom';\nimport App from './App';\n\nit('renders without crashing', () => {\n  const div = document.createElement('div');\n  ReactDOM.render(<App />, div);\n  ReactDOM.unmountComponentAtNode(div);\n});\n"
  },
  {
    "path": "src/App.tsx",
    "content": "import * as React from 'react';\nimport './App.css';\nimport AppNavBar from './navigation/App.Bar';\nimport { BrowserRouter as Router } from 'react-router-dom';\nimport { Provider } from 'react-redux';\nimport { store } from './store/Store';\nimport blue from '@material-ui/core/colors/blue';\nimport { createMuiTheme, MuiThemeProvider } from '@material-ui/core';\nimport { pink } from '@material-ui/core/colors';\n\nconst theme = createMuiTheme({\n  palette: {\n    primary: blue,\n    secondary: pink\n  }\n})\nclass App extends React.Component {\n  public render() {\n    return (\n      <Provider store={store}>\n        <Router>\n          <MuiThemeProvider theme={theme}>\n            <AppNavBar />\n          </MuiThemeProvider>\n        </Router>\n      </Provider>\n    );\n  }\n}\n\nexport default App;\n"
  },
  {
    "path": "src/actions/App.Actions.ts",
    "content": "import { IAppAction, ActionType } from './Helpers';\nimport { match } from 'react-router';\nimport { Utility } from '../state/Utility';\nimport { Alert } from '../state/Alert';\nimport { Spinner } from '../state/Spinner';\nimport { User } from '../state/User';\n\nexport interface IApplicationProps {\n    openDrawer: () => IAppAction;\n    closeDrawer: () => IAppAction;\n    showPopup: (alert: Alert) => IAppAction;\n    closePopup: () => IAppAction;  \n    showSpinner: (message: string) => IAppAction;\n    hideSpinner: () => IAppAction; \n    login: (data: any) => IAppAction; \n    logout: () => IAppAction;\n    createUser: (content: any) => any;\n    getUser: (id: any) => any;\n    fetchUsers: (context?: any) => any;\n    updateUser: (context: any) => any;\n    deleteUser: (context: any) => any;\n    createMaterial: (content: any) => any;\n    getMaterial: (id: any) => any;\n    fetchMaterials: (context?: any) => any;\n    updateMaterial: (context: any) => any;\n    deleteMaterial: (context: any) => any;\n    getMail: (id: any) => any;\n    fetchMails: (context?: any) => any;\n    updateMail: (context: any) => any;\n    deleteMail: (context: any) => any;\n    match: match<any>,\n    location: any,\n    history: any,\n    utility: Utility;\n    authentication: User;\n    users: any;\n    materials: any;\n    mail: any[];\n    materialCharts: Array<{name: string, value: number, fill: string}>;\n}\n\nexport const openDrawer = (): IAppAction => {\n    return {\n        type: ActionType.OPEN_DRAWER\n    };\n};\n\nexport const closeDrawer = (): IAppAction => {\n    return {\n        type: ActionType.CLOSE_DRAWER\n    };\n};\n\nexport const showPopup = (data: Alert): IAppAction => {\n    return {\n        type: ActionType.OPEN_ALERT,\n        payload: data\n    };\n};\n\nexport const closePopup = (): IAppAction => {\n    return {\n        type: ActionType.CLOSE_ALERT\n    };\n};\n\nexport const showSpinner = (message: string): IAppAction => {\n    return {\n        type: ActionType.OPEN_SPINNER,\n        payload: new Spinner({message})\n    };\n};\n\nexport const hideSpinner = (): IAppAction => {\n    return {\n        type: ActionType.CLOSE_SPINNER\n    };\n};\n\nexport const login = (data: any): IAppAction => {\n    return { type: ActionType.LOGIN_REQUEST, payload: data };\n};\n\nexport const logout = (): IAppAction => {\n    return { type: ActionType.LOGOUT_REQUEST };\n};\n"
  },
  {
    "path": "src/actions/Helpers.ts",
    "content": "import { Action } from \"redux\";\n\nexport enum ActionType {\n    OPEN_DRAWER,\n    CLOSE_DRAWER,\n    OPEN_ALERT,\n    CLOSE_ALERT,\n    OPEN_SPINNER,\n    CLOSE_SPINNER,\n    LOGIN_REQUEST,\n    LOGIN_SUCCESS,\n    LOGIN_FAIL,\n    LOGOUT_REQUEST,\n    LOGOUT_SUCCESS,\n    LOGOUT_FAIL\n}\n\nexport interface IAppAction extends Action<ActionType> {\n    payload?: any;\n}"
  },
  {
    "path": "src/alert/Alert.tsx",
    "content": "import * as React from 'react';\nimport Button from '@material-ui/core/Button';\nimport Dialog from '@material-ui/core/Dialog';\nimport DialogActions from '@material-ui/core/DialogActions';\nimport DialogContent from '@material-ui/core/DialogContent';\nimport DialogContentText from '@material-ui/core/DialogContentText';\nimport DialogTitle from '@material-ui/core/DialogTitle';\nimport { Alert } from '../state/Alert';\n\ninterface IAlertProps {\n    data?: Alert;\n    handleClose: () => void;\n    children?: any;\n}\nexport class AlertDialog extends React.Component<IAlertProps, {}> {\n\n    public handleClose = () => {\n        this.props.handleClose();\n    };\n\n    public render() {\n        return (\n\n            <Dialog\n                open={this.props.data !== null}\n                onClose={this.handleClose}\n                aria-labelledby=\"alert-dialog-title\"\n                aria-describedby=\"alert-dialog-description\"\n            >\n                <DialogTitle id=\"alert-dialog-title\">{this.props.data.title}</DialogTitle>\n                <DialogContent>\n                    <DialogContentText id=\"alert-dialog-description\">\n                    { this.props.data.message }\n            </DialogContentText>\n                </DialogContent>\n                <DialogActions>\n                    <Button onClick={this.handleClose} color=\"primary\">\n                        Disagree\n            </Button>\n                    <Button onClick={this.handleClose} color=\"primary\" autoFocus={true}>\n                        Agree\n            </Button>\n                </DialogActions>\n            </Dialog>\n        );\n    }\n}\n"
  },
  {
    "path": "src/components/MailList.tsx",
    "content": "import * as React from 'react';\nimport { withStyles, Theme } from '@material-ui/core/styles';\nimport ExpansionPanel from '@material-ui/core/ExpansionPanel';\nimport ExpansionPanelDetails from '@material-ui/core/ExpansionPanelDetails';\nimport ExpansionPanelSummary from '@material-ui/core/ExpansionPanelSummary';\nimport ExpansionPanelActions from '@material-ui/core/ExpansionPanelActions';\nimport Typography from '@material-ui/core/Typography';\nimport ExpandMoreIcon from '@material-ui/icons/ExpandMore';\nimport { Avatar } from '@material-ui/core';\nimport Divider from '@material-ui/core/Divider';\nimport Button from '@material-ui/core/Button';\n\nconst styles = (theme: Theme) => ({\n    root: {\n        width: '100%',\n    },\n    avatar: {\n        marginRight: 5\n    },\n    summary: {\n        display: 'flex',\n        alignContent: 'center',\n        alignItems: 'center',\n    },\n    heading: {\n        fontSize: theme.typography.pxToRem(15),\n        height: '100%',\n        verticalAlign: 'middle',\n        flexBasis: '33.33%',\n        flexShrink: 0,\n        color: theme.palette.text.secondary,\n    },\n    secondaryHeading: {\n        fontSize: theme.typography.pxToRem(15),\n    },\n});\n\ninterface IMailListProps {\n    items: any[];\n    classes: any;\n}\n\ninterface IState {\n    expanded?: number;\n}\n\nclass MailList extends React.Component<IMailListProps, IState> {\n    public state: IState = {\n        expanded: null,\n    };\n\n    private handleChange = (panel: any) => (event: any, expanded: any) => {\n        this.setState({\n            expanded: expanded ? panel : false,\n        });\n    };\n\n    public render() {\n        const { classes } = this.props;\n        const { expanded } = this.state;\n\n        return (\n            <div className={classes.root}>\n                {this.props.items.map((item: any) => {\n                    return (\n\n                        <ExpansionPanel key={item.id} expanded={expanded === item.id} onChange={this.handleChange(item.id)}>\n                            <ExpansionPanelSummary className={classes.summary} expandIcon={<ExpandMoreIcon />}>\n                                <Avatar className={classes.avatar} src={item.avatar} />\n                                <Typography className={classes.heading}>{item.from}</Typography>\n                                <Typography className={classes.secondaryHeading}>{item.subject}</Typography>\n                            </ExpansionPanelSummary>\n                            <ExpansionPanelDetails>\n                                <Typography>\n                                    {item.content}\n                                </Typography>\n                            </ExpansionPanelDetails>\n                            <Divider />\n                            <ExpansionPanelActions>\n                                <Button size=\"small\">Cancel</Button>\n                                <Button size=\"small\" color=\"primary\">\n                                    Delete\n                                </Button>\n                            </ExpansionPanelActions>\n                        </ExpansionPanel>\n                    );\n                })}\n            </div>\n        );\n    }\n}\n\nexport default withStyles(styles)(MailList);\n"
  },
  {
    "path": "src/components/TableHeader.tsx",
    "content": "import * as React from 'react';\nimport { TableHead, TableRow, TableCell, Checkbox, Tooltip, TableSortLabel } from '@material-ui/core';\n\nexport interface IColumnData {\n    id?: string;\n    numeric?: boolean;\n    disablePadding?: boolean;\n    label?: string;\n}\n\ninterface IEnhancedTableHeadProps {\n    onRequestSort?: (event: any, property: any) => any;\n    onSelectAllClick?: any;\n    order?: any;\n    orderBy?: any;\n    selected?: number;\n    count?: number;\n    columns?: IColumnData[];\n}\n\nexport class EnhancedTableHead extends React.Component<IEnhancedTableHeadProps, {}> {\n    private createSortHandler = (property: any) => (event: any) => {\n        this.props.onRequestSort(event, property);\n    };\n\n    public render() {\n        const { columns, onSelectAllClick, order, orderBy, selected, count } = this.props;\n\n        return (\n            <TableHead>\n                <TableRow>\n                    <TableCell padding=\"checkbox\">\n                        <Checkbox\n                            indeterminate={selected > 0 && selected < count}\n                            checked={selected === count}\n                            onChange={onSelectAllClick}\n                        />\n                    </TableCell>\n                    {columns.map(column => {\n                        return (\n                            <TableCell\n                                key={column.id}\n                                numeric={column.numeric}\n                                padding={column.disablePadding ? 'none' : 'default'}\n                                sortDirection={orderBy === column.id ? order : false}\n                            >\n                                <Tooltip\n                                    title=\"Sort\"\n                                    placement={column.numeric ? 'bottom-end' : 'bottom-start'}\n                                    enterDelay={300}\n                                >\n                                    <TableSortLabel\n                                        active={orderBy === column.id}\n                                        direction={order}\n                                        onClick={this.createSortHandler(column.id)}\n                                    >\n                                        {column.label}\n                                    </TableSortLabel>\n                                </Tooltip>\n                            </TableCell>\n                        );\n                    }, this)}\n                </TableRow>\n            </TableHead>\n        );\n    }\n}"
  },
  {
    "path": "src/components/TableToolbar.tsx",
    "content": "import * as React from 'react';\nimport { Toolbar, Typography, Tooltip, IconButton, Theme, withStyles } from '@material-ui/core';\nconst classNames = require('classnames');\nimport DeleteIcon from '@material-ui/icons/Delete';\nimport FilterListIcon from '@material-ui/icons/FilterList';\n\ninterface IEnhancedTableToolbarProps {\n    classes?: any;\n    selected?: number;\n}\n\nclass EnhancedTableToolbar extends React.Component<IEnhancedTableToolbarProps, {}> {\n\n    public render(): JSX.Element {\n        const { selected, classes } = this.props;\n\n        return (\n            <Toolbar\n                className={classNames(classes.root, {\n                    [classes.highlight]: selected > 0,\n                })}\n            >\n                <div className={classes.title}>\n                    {selected > 0 ? (\n                        <Typography color=\"inherit\" variant=\"subheading\">\n                            {selected} selected\n            </Typography>\n                    ) : (\n                            <Typography variant=\"title\" id=\"tableTitle\">\n                                Nutrition\n            </Typography>\n                        )}\n                </div>\n                <div className={classes.spacer} />\n                <div className={classes.actions}>\n                    {selected > 0 ? (\n                        <Tooltip title=\"Delete\">\n                            <IconButton aria-label=\"Delete\">\n                                <DeleteIcon />\n                            </IconButton>\n                        </Tooltip>\n                    ) : (\n                            <Tooltip title=\"Filter list\">\n                                <IconButton aria-label=\"Filter list\">\n                                    <FilterListIcon />\n                                </IconButton>\n                            </Tooltip>\n                        )}\n                </div>\n            </Toolbar>\n        );\n    }\n}\n\nconst toolbarStyles = (theme: Theme) => ({\n    root: {\n        paddingRight: theme.spacing.unit,\n    },\n    highlight:\n        theme.palette.type === 'light'\n            ? {\n                color: theme.palette.secondary.main,\n                backgroundColor: `lighten(${theme.palette.secondary.light}, 0.85)`,\n            }\n            : {\n                color: theme.palette.text.primary,\n                backgroundColor: theme.palette.secondary.dark,\n            },\n    spacer: {\n        flex: '1 1 100%',\n    },\n    actions: {\n        color: theme.palette.text.secondary,\n    },\n    title: {\n        flex: '0 0 auto',\n    },\n});\n\nexport default withStyles(toolbarStyles)(EnhancedTableToolbar as any);\n"
  },
  {
    "path": "src/data/mail.ts",
    "content": "const Resourcer = require('redux-rest-resource');\n\nexport const { types, actions, rootReducer } = Resourcer.createResource({\n    name: 'mail',\n    url: `https://5b1b0a966e0fd400146aaee2.mockapi.io/mail/:id`\n});\n"
  },
  {
    "path": "src/data/material.ts",
    "content": "const Resourcer = require('redux-rest-resource');\n\nexport const { types, actions, rootReducer } = Resourcer.createResource({\n    name: 'material',\n    url: `https://5b1b0a966e0fd400146aaee2.mockapi.io/materials/:id`\n});\n"
  },
  {
    "path": "src/data/users.ts",
    "content": "const Resourcer = require('redux-rest-resource');\n\nexport const { types, actions, rootReducer } = Resourcer.createResource({\n    name: 'user',\n    url: `https://5b1b0a966e0fd400146aaee2.mockapi.io/users/:id`\n});\n"
  },
  {
    "path": "src/index.css",
    "content": "body {\n  margin: 0;\n  padding: 0;\n  font-family: sans-serif;\n}\n"
  },
  {
    "path": "src/index.tsx",
    "content": "import * as React from 'react';\nimport * as ReactDOM from 'react-dom';\nimport App from './App';\nimport './index.css';\nimport registerServiceWorker from './registerServiceWorker';\n\nReactDOM.render(\n  <App />,\n  document.getElementById('root') as HTMLElement);\nregisterServiceWorker();\n"
  },
  {
    "path": "src/navigation/App.Bar.tsx",
    "content": "//#region \nimport * as React from 'react';\nconst classNames = require('classnames');\nimport { withStyles } from '@material-ui/core/styles';\nimport AppBar from '@material-ui/core/AppBar';\nimport Toolbar from '@material-ui/core/Toolbar';\nimport Typography from '@material-ui/core/Typography';\nimport IconButton from '@material-ui/core/IconButton';\nimport MenuIcon from '@material-ui/icons/Menu';\nimport { ListItemText, Menu, MenuItem, Badge, Avatar } from '@material-ui/core';\nimport { Route, withRouter } from 'react-router-dom';\nimport Hidden from '@material-ui/core/Hidden';\nimport { styles } from './styles';\nimport { IApplicationProps } from '../actions/App.Actions';\nimport * as AppActionCreators from '../actions/App.Actions';\nimport { AppState, isAuthenticated } from '../state/AppState';\nimport { connect } from 'react-redux';\nimport * as _ from 'lodash';\nimport { bindActionCreators, Dispatch} from 'redux';\nimport { Alert } from '../state/Alert';\nimport { AlertDialog } from '../alert/Alert';\nimport SpinnerDialog from '../spinner/Spinner';\nimport { AccountPage } from '../pages/account/Account';\nimport { MailPage } from '../pages/mail/Mail';\nimport HomePage from '../pages/Home';\nimport AccountCircle from '@material-ui/icons/AccountCircle';\nimport { actions as UserActionCreators } from '../data/users';\nimport { actions as MailActionCreators } from '../data/mail';\nimport { actions as MaterialActionCreators } from '../data/material';\nimport { getMaterialChartItems, getMailitems } from '../selectors';\nimport AppDrawer from './App.Drawer';\nimport NotificationIcon from '@material-ui/icons/Notifications';\n//#endregion\n\ninterface IAppProps extends IApplicationProps {\n  classes: any;\n  theme?: any;\n}\n\ninterface IState {\n  anchorEl: any;\n  notificationEl: any;\n}\n\nclass MiniDrawer extends React.Component<IAppProps, IState> {\n\n  public state: IState = {\n    anchorEl: null,\n    notificationEl: null\n  };\n\n  public componentWillMount() {\n    this.props.fetchUsers();\n    this.props.fetchMaterials();\n    this.props.fetchMails();\n  }\n\n  private handleNotificationMenu = (event: any) => {\n    this.setState({ notificationEl: event.currentTarget });\n  };\n\n  private handleNotificationMenuClose = () => {\n    this.setState({ notificationEl: null });\n  };\n\n  private handleMenu = (event: any) => {\n    this.setState({ anchorEl: event.currentTarget });\n  };\n\n  private handleMenuClose = (path?: string) => {\n    this.setState({ anchorEl: null });\n    this.navigate(path);\n  };\n\n  public handleLogout = () => {\n    this.props.logout();\n    this.handleMenuClose();\n  };\n\n  private navigate = (path?: string) => {\n    if (path) {\n      this.props.history.push(path);\n    }\n  }\n\n  public handleDrawerOpen = () => {\n    this.props.openDrawer();\n  };\n\n  public handleDrawerClose = () => {\n    this.props.closeDrawer();\n  };\n\n  public showPopup = () => {\n    this.props.showPopup(new Alert({\n      title: \"Testing title\",\n      message: \"This is a very long message, expect alert to be very wide\"\n    }))\n  }\n\n  public showSpinner = () => {\n    this.props.showSpinner(\"I am loading here please...\")\n  }\n\n  private renderAlert(): JSX.Element {\n    if (this.props.utility.alert) {\n      return (\n        <AlertDialog\n          handleClose={this.props.closePopup}\n          data={this.props.utility.alert}\n        />\n      );\n    }\n\n    return null\n  }\n\n  private renderSpinner(): JSX.Element {\n    if (this.props.utility.spinner) {\n      return (\n        <SpinnerDialog\n          message={this.props.utility.spinner.message}\n        />\n      );\n    }\n\n    return null\n  }\n\n  private renderNotifications(notifications: any[]) {\n    const { classes } = this.props;\n    return (\n      <Menu\n        id=\"notifications\"\n        anchorEl={this.state.notificationEl}\n        anchorOrigin={{\n          vertical: 'top',\n          horizontal: 'right',\n        }}\n        transformOrigin={{\n          vertical: 'top',\n          horizontal: 'right',\n        }}\n        className={classes.notifications}\n        open={Boolean(this.state.notificationEl)}\n        onClose={this.handleNotificationMenuClose}  \n      >\n          {notifications.map((n: any) => (\n            <MenuItem key={n.id} onClick={this.handleNotificationMenuClose} dense={true} button={true} className={classes.notificationListItem}>\n              <Avatar src={n.avatar} />\n              <ListItemText primary={n.subject} />\n            </MenuItem>\n          ))}\n      </Menu>\n    );\n  }\n\n  private renderAppBar() {\n    if (this.props.authentication) {\n      const { classes, utility } = this.props;\n      const { anchorEl, notificationEl } = this.state;\n      const open = Boolean(anchorEl);\n      const notificationsOpen = Boolean(notificationEl);\n      const unreadMessages = this.props.mail.filter(x => x.seen === false);\n\n      return (\n        <AppBar\n          position=\"fixed\"\n          className={classNames(classes.appBar, utility.drawerOpen && classes.appBarShift)}\n        >\n          <Toolbar disableGutters={!utility.drawerOpen}>\n            <IconButton\n              color=\"inherit\"\n              aria-label=\"open drawer\"\n              onClick={this.handleDrawerOpen}\n              className={classNames(classes.menuButton, utility.drawerOpen && classes.hide)}\n            >\n              <MenuIcon />\n            </IconButton>\n            <Typography className={classes.fillSpace} variant=\"title\" color=\"inherit\" noWrap={true}>\n              Tomahawk\n            </Typography>\n            <div>\n              <IconButton\n                aria-owns={notificationsOpen ? 'notifications' : null}\n                aria-haspopup=\"true\"\n                color=\"inherit\"\n                onClick={this.handleNotificationMenu}\n              >\n                <Badge badgeContent={unreadMessages.length} color=\"secondary\">\n                  <NotificationIcon />\n                </Badge>\n              </IconButton>\n              {this.renderNotifications(unreadMessages)}\n              <IconButton\n                aria-owns={open ? 'menu-appbar' : null}\n                aria-haspopup=\"true\"\n                onClick={this.handleMenu}\n                color=\"inherit\"\n              >\n                <AccountCircle />\n              </IconButton>\n              <Menu\n                id=\"menu-appbar\"\n                anchorEl={anchorEl}\n                anchorOrigin={{\n                  vertical: 'top',\n                  horizontal: 'right',\n                }}\n                transformOrigin={{\n                  vertical: 'top',\n                  horizontal: 'right',\n                }}\n                open={open}\n                onClose={this.handleMenuClose.bind(this, null)}\n              >\n                <MenuItem onClick={this.handleMenuClose.bind(this, '/account')}>{this.props.authentication.name}</MenuItem>\n                <MenuItem onClick={this.handleLogout}>Logout</MenuItem>\n              </Menu>\n            </div>\n          </Toolbar>\n        </AppBar>\n      );\n    }\n\n    return null;\n  }\n\n  private renderAccount = () => {\n    return (\n      <AccountPage user={this.props.authentication} login={this.props.login} match={this.props.match} location={this.props.location} />\n    );\n  }\n\n  private renderDrawer() {\n    const { utility, authentication } = this.props;\n    return (\n      <Hidden mdDown={!utility.drawerOpen && true}>\n        <AppDrawer\n          utility={utility}\n          authentication={authentication}\n          handleDrawerClose={this.handleDrawerClose}\n        />\n      </Hidden>\n    );\n  }\n\n  public render() {\n    const { classes } = this.props;\n    const Dashboard = isAuthenticated((props: any): any => {\n      return (\n        <HomePage\n          users={this.props.users}\n          fetchUsers={this.props.fetchUsers}\n          materialChartData={this.props.materialCharts}\n        />\n      );\n    });\n\n    const MailBoard = isAuthenticated((props: any): any => {\n      return (\n        <MailPage\n          mail={this.props.mail}\n        />\n      );\n    });\n\n\n    return (\n      <div className={classes.root}>\n        {this.renderAppBar()}\n        {this.renderDrawer()}\n\n        <main className={classes.content}>\n          <div className={classes.toolbar} />\n          <Route path='/' exact={true} component={Dashboard} />\n          <Route path='/dashboard' component={Dashboard} />\n          <Route path='/mail' component={MailBoard} />\n          <Route path='/account' render={this.renderAccount} />\n          {this.renderAlert()}\n          {this.renderSpinner()}\n        </main>\n      </div>\n    );\n  }\n}\n\nconst mapStateToProps = (state: AppState) => ({\n  utility: state.utility,\n  authentication: state.authentication,\n  users: state.users,\n  materials: state.materials,\n  materialCharts: getMaterialChartItems(state),\n  mail: getMailitems(state)\n});\n\nconst mapDispatchtoProps = (dispatch: Dispatch) =>\n  bindActionCreators(_.assign({}, AppActionCreators, MailActionCreators,\n    UserActionCreators, MaterialActionCreators), dispatch);\n\nexport default withRouter(connect(mapStateToProps, mapDispatchtoProps)(withStyles(styles as any, { withTheme: true })(MiniDrawer as any)) as any);\n"
  },
  {
    "path": "src/navigation/App.Drawer.tsx",
    "content": "import * as React from 'react';\nimport InboxIcon from '@material-ui/icons/Inbox';\nimport DraftsIcon from '@material-ui/icons/Drafts';\nimport SendIcon from '@material-ui/icons/Send';\nimport AccountCircleIcon from '@material-ui/icons/AccountCircle';\nimport DashboardIcon from '@material-ui/icons/Dashboard';\nimport { Drawer, IconButton, Divider, Theme, ListItem, ListItemIcon, ListItemText, withStyles } from '@material-ui/core';\nimport ChevronLeftIcon from '@material-ui/icons/ChevronLeft';\nimport ChevronRightIcon from '@material-ui/icons/ChevronRight';\nimport { User } from '../state/User';\nimport { Utility } from '../state/Utility';\nimport { NavLink } from 'react-router-dom';\nimport { styles } from './styles';\nconst classNames = require('classnames');\n\ninterface IAppDrawer {\n    authentication?: User;\n    utility: Utility;\n    classes?: any;\n    theme?: Theme;\n    handleDrawerClose?: () => void;\n}\n\nclass AppDrawer extends React.Component<IAppDrawer, {}> {\n    public routes = [\n        { path: '/', title: 'Dashboard', icon: () => <DashboardIcon /> },\n        { path: '/mail/inbox', title: 'Inbox', icon: () => <InboxIcon /> },\n        { path: '/mail/sent', title: 'Sent', icon: () => <SendIcon /> },\n        { path: '/mail/drafts', title: 'Drafts', icon: () => <DraftsIcon /> },\n        { path: '/account', title: 'Profile', icon: () => <AccountCircleIcon /> }\n    ]\n\n    public render(): JSX.Element {\n        const { authentication, classes, utility, theme } = this.props;\n        return (\n            <Drawer\n                hidden={!authentication}\n                variant=\"permanent\"\n                classes={{\n                    paper: classNames(classes.drawerPaper, !utility.drawerOpen && classes.drawerPaperClose),\n                }}\n                open={utility.drawerOpen}\n            >\n                <div className={classes.toolbar}>\n                    <IconButton onClick={this.props.handleDrawerClose}>\n                        {theme.direction === 'rtl' ? <ChevronRightIcon /> : <ChevronLeftIcon />}\n                    </IconButton>\n                </div>\n                <Divider />\n                {this.routes.map((route, index) => {\n                    return (\n                        <NavLink key={index} exact={true} activeClassName={classes.current} className={classes.link} to={route.path} >\n                            <ListItem button={true}>\n                                <ListItemIcon>\n                                    {route.icon()}\n                                </ListItemIcon>\n                                <ListItemText primary={route.title} />\n                            </ListItem>\n                        </NavLink>\n                    );\n                })}\n                <Divider />\n            </Drawer>\n        );\n    }\n}\n\nexport default withStyles(styles as any, { withTheme: true })(AppDrawer as any) as any;"
  },
  {
    "path": "src/navigation/styles.ts",
    "content": "import { Theme } from \"@material-ui/core\";\n\nconst drawerWidth = 240;\n\nexport const styles = (theme: Theme) => ({\n    root: {\n      flexGrow: 1,\n      height: '100vh',\n      minHeight: '100%',\n      zIndex: 1,\n      overflow: 'hidden',\n      position: 'relative',\n      display: 'flex',\n      width: '100%',\n      backgroundColor: theme.palette.background.default,\n    },\n    appBar: {\n      zIndex: theme.zIndex.drawer + 1,\n      transition: theme.transitions.create(['width', 'margin'], {\n        easing: theme.transitions.easing.sharp,\n        duration: theme.transitions.duration.leavingScreen,\n      }),\n      [theme.breakpoints.up('md')]: {\n        width: `100%`,\n      },\n    },\n    appBarShift: {\n      marginLeft: drawerWidth,\n      width: `calc(100% - ${drawerWidth}px)`,\n      transition: theme.transitions.create(['width', 'margin'], {\n        easing: theme.transitions.easing.sharp,\n        duration: theme.transitions.duration.enteringScreen,\n      }),\n    },\n    menuButton: {\n      marginLeft: 12,\n      marginRight: 36,\n    },\n    hide: {\n      display: 'none',\n    },\n    drawerPaper: {\n      position: 'relative',\n      top: 0,\n      whiteSpace: 'nowrap',\n      width: drawerWidth,\n      transition: theme.transitions.create('width', {\n        easing: theme.transitions.easing.sharp,\n        duration: theme.transitions.duration.enteringScreen,\n      })\n  \n    },\n    drawerPaperClose: {\n      overflowX: 'hidden',\n      transition: theme.transitions.create('width', {\n        easing: theme.transitions.easing.sharp,\n        duration: theme.transitions.duration.leavingScreen,\n      }),\n      width: theme.spacing.unit * 7,\n      [theme.breakpoints.up('sm')]: {\n        width: theme.spacing.unit * 9,\n      },\n    },\n    toolbar: {\n      display: 'flex',\n      alignItems: 'center',\n      justifyContent: 'flex-end',\n      padding: '0 8px',\n      ...theme.mixins.toolbar,\n    },\n    content: {\n      flexGrow: 1,\n      backgroundColor: theme.palette.background.default,\n      padding: theme.spacing.unit * 3,\n      minHeight: '100%',\n      height: '100%',\n      flex: '1 1 auto',\n      overflowY: 'scroll'\n    },\n    button: {\n      margin: theme.spacing.unit,\n    },\n    link: {\n      textDecoration: 'none',\n    },\n    current: {\n      color: 'red !important',\n    },\n    notifications: {\n      overflowX: 'hidden'\n    },\n    fillSpace: {\n      flex: '1 1 auto'\n    }\n  });"
  },
  {
    "path": "src/pages/Home.tsx",
    "content": "import * as React from 'react';\nimport {\n    Theme, withStyles, Paper, Table, TableHead, TableRow,\n    TableCell, TableBody, TablePagination, Grid, Typography\n} from '@material-ui/core';\nimport { BarChart, CartesianGrid, XAxis, YAxis, Bar, Tooltip, Legend, PieChart, Pie, ResponsiveContainer } from 'recharts';\nconst classNames = require('classnames');\nimport GroupIcon from '@material-ui/icons/Group';\nimport MailIcon from '@material-ui/icons/Mail';\nimport SettingsIcon from '@material-ui/icons/Settings';\nimport BusinessIcon from '@material-ui/icons/BusinessCenter';\n\ninterface IDashboardProps {\n    fetchUsers: (context?: any) => void;\n    users: any;\n    materialChartData: any[];\n    classes?: any;\n    theme?: any;\n    children?: any;\n}\n\ninterface IPageState {\n    usersTablePage?: number;\n    usersTableRowsPerPage: number;\n}\n\nclass HomePage extends React.Component<IDashboardProps, IPageState> {\n\n    public state: IPageState = {\n        usersTablePage: 0,\n        usersTableRowsPerPage: 5\n    };\n\n    private handleChangeUsersPage = (event: any, page: number) => {\n        console.log(event);\n        this.setState({ usersTablePage: page });\n    };\n\n    private handleChangeTableRowsPerPage = (event: any) => {\n        this.setState({ usersTableRowsPerPage: event.target.value });\n    };\n\n    private renderUsers(): JSX.Element {\n        const { users, classes } = this.props;\n        if (!users) {\n            return null;\n        }\n\n        return (\n            <Paper className={classNames(classes.paper, classes.users)}>\n                <h3 className={classes.sectionTitle}>Customers</h3>\n                <Table className={classes.table}>\n                    <TableHead>\n                        <TableRow>\n                            <TableCell>Id</TableCell>\n                            <TableCell>Name</TableCell>\n                            <TableCell>Email</TableCell>\n                        </TableRow>\n                    </TableHead>\n                    <TableBody>\n                        {users.items.slice(this.state.usersTablePage * this.state.usersTableRowsPerPage,\n                            this.state.usersTablePage * this.state.usersTableRowsPerPage + this.state.usersTableRowsPerPage).map((n: any) => {\n                                return (\n                                    <TableRow key={n.id}>\n                                        <TableCell component=\"th\" scope=\"row\">\n                                            {n.id}\n                                        </TableCell>\n                                        <TableCell>{n.name}</TableCell>\n                                        <TableCell>{n.email}</TableCell>\n                                    </TableRow>\n                                );\n                            })}\n                    </TableBody>\n                </Table>\n                <TablePagination\n                    component=\"div\"\n                    count={users.items.length}\n                    rowsPerPage={this.state.usersTableRowsPerPage}\n                    page={this.state.usersTablePage}\n                    backIconButtonProps={{\n                        'aria-label': 'Previous Page',\n                    }}\n                    nextIconButtonProps={{\n                        'aria-label': 'Next Page',\n                    }}\n                    onChangePage={this.handleChangeUsersPage}\n                    onChangeRowsPerPage={this.handleChangeTableRowsPerPage}\n                />\n            </Paper>\n        );\n\n    }\n\n    private renderRadialBarChart(): JSX.Element {\n        return (\n            <Paper className={this.props.classes.paper}>\n                <h3 className={this.props.classes.sectionTitle}>Material Inventory</h3>\n                <ResponsiveContainer width=\"100%\" height={300}>\n                    <PieChart>\n                        <Pie\n                            data={this.props.materialChartData}\n                            dataKey=\"value\"\n                            nameKey=\"name\"\n                            cx=\"50%\"\n                            cy=\"50%\"\n                            label={true}\n                            fill=\"#8884d8\" />\n                        <Legend />\n                    </PieChart>\n                </ResponsiveContainer>\n            </Paper>\n        );\n    }\n\n    private renderBarChart(): JSX.Element {\n        return (\n            <Paper className={this.props.classes.paper}>\n                <h3 className={this.props.classes.sectionTitle}>Material Sales</h3>\n                <ResponsiveContainer width=\"100%\" height={300}>\n                    <BarChart data={this.props.materialChartData}>\n                        <CartesianGrid strokeDasharray=\"3 3\" />\n                        <XAxis dataKey=\"name\" />\n                        <YAxis />\n                        <Tooltip />\n                        <Bar dataKey=\"value\" fill=\"#8884d8\" />\n                    </BarChart>\n                </ResponsiveContainer>\n            </Paper>\n        );\n    }\n\n    public render(): JSX.Element {\n        const { classes } = this.props;\n        return (\n            <div className={classes.root}>\n                <Grid container={true} spacing={24}>\n                    <Grid item={true} lg={3} xs={12} sm={6}>\n                        <Paper className={classNames(classes.paper, classes.headerTiles)}>\n                            <GroupIcon className={classes.headerTileIcon} />\n                            <Typography className={classes.tileText}> {this.props.users.items.length} Customers</Typography>\n                        </Paper>\n                    </Grid>\n                    <Grid item={true} lg={3} xs={12} sm={6}>\n                        <Paper className={classNames(classes.paper, classes.headerTiles)}>\n                            <MailIcon className={classes.headerTileIcon} />\n                            <Typography className={classes.tileText}>Inbox</Typography>\n                        </Paper>\n                    </Grid>\n                    <Grid item={true} lg={3} xs={12} sm={6}>\n                        <Paper className={classNames(classes.paper, classes.headerTiles)}>\n                            <BusinessIcon className={classes.headerTileIcon} />\n                            <Typography className={classes.tileText}>Purchases</Typography>\n                        </Paper>\n                    </Grid>\n                    <Grid item={true} lg={3} xs={12} sm={6}>\n                        <Paper className={classNames(classes.paper, classes.headerTiles)}>\n                            <SettingsIcon className={classes.headerTileIcon} />\n                            <Typography className={classes.tileText}>Settings</Typography>\n                        </Paper>\n                    </Grid>\n                    <Grid item={true} xs={12} md={6}>\n                        {this.renderBarChart()}\n                    </Grid>\n                    <Grid item={true} xs={12} md={6}>\n                        {this.renderRadialBarChart()}\n                    </Grid>\n                    <Grid item={true} xs={12}>\n                        {this.renderUsers()}\n                    </Grid>\n                </Grid>\n            </div>\n        );\n    }\n}\n\nconst styles = (theme: Theme) => ({\n    root: {\n        flexGrow: 1,\n        marginBottom: 24,\n    },\n    paper: {\n        padding: theme.spacing.unit * 2,\n        textAlign: 'center',\n        color: theme.palette.text.secondary,\n    },\n    headerTiles: {\n        overflowX: 'hidden',\n        display: 'flex',\n        justifyContent: 'center',\n        alignItems: 'center',\n        borderRight: `5px solid ${theme.palette.secondary.main}`,\n    },\n    headerTileIcon: {\n        fontSize: 40,\n        color: theme.palette.primary.main,\n        paddingRight: 5\n    },\n    tileText: {\n        fontSize: 20,\n        color: theme.palette.grey[\"400\"],\n    },\n    sectionTitle: {\n        paddingLeft: theme.spacing.unit * 2,\n    },\n    users: {\n        marginBottom: 24,\n        overflowX: 'scroll'\n    },\n    chart: {\n        width: '100%'\n    },\n});\n\nexport default withStyles(styles as any)(HomePage as any) as any;"
  },
  {
    "path": "src/pages/account/Account.tsx",
    "content": "import * as React from 'react';\nimport { User } from '../../state/User';\nimport LoginPage from './Login';\nimport { Route, Switch } from 'react-router';\nimport { ProfilePage } from './Profile';\nimport { isAuthenticated } from '../../state/AppState';\n\ninterface IAccountProps {\n    login?: (data: any) => void;\n    match?: any;\n    location?: any;\n    classes?: any;\n    user: User;\n}\n\nexport class AccountPage extends React.Component<IAccountProps, {}> {\n    private renderLogin = () => {\n        return (\n            <LoginPage\n                user={this.props.user}\n                login={this.props.login}\n                match={this.props.match}\n                location={this.props.location} />\n        );\n    }\n\n    public render(): JSX.Element {\n        return (<Switch>\n            <Route path=\"/account\" exact={true} component={isAuthenticated(ProfilePage as any)} />\n            <Route path={'/account/login'} render={this.renderLogin} />\n        </Switch>);\n    }\n\n}"
  },
  {
    "path": "src/pages/account/Login.tsx",
    "content": "import * as React from 'react';\nimport { Theme, withStyles, FormControl, InputLabel, Input, InputAdornment, Button, Icon } from '@material-ui/core';\nimport Paper from '@material-ui/core/Paper';\nimport * as querystring from 'querystring';\nimport { User } from '../../state/User';\nimport { Redirect } from 'react-router';\n\ninterface ILoginProps {\n    login?: (data: any) => void;\n    match?: any;\n    location?: any;\n    classes?: any;\n    user: User;\n}\n\ninterface ILoginState {\n    email: string;\n    password: string;\n}\n\nclass LoginPage extends React.Component<ILoginProps, ILoginState> {\n    public state = {\n        email: \"\",\n        password: \"\"\n    };\n\n    private handleEmailAddressChange = (event: any) => {\n        this.setState({ email: event.target.value })\n    }\n\n    private handlePasswordChange = (event: any) => {\n        this.setState({ password: event.target.value })\n    }\n\n    private handleLogin = () => {\n        this.props.login(this.state);\n    }\n\n    public render(): JSX.Element {\n        const classes = this.props.classes;\n\n        if (this.props.user) {\n            const path: string = querystring.\n                parse((this.props.location.search as string).substr(1)).redirect as any || '/inbox';\n            return <Redirect to={path} />\n        }\n\n        return (\n            <div className={classes.container}>\n                <Paper className={classes.paper}>\n                    <h2>{'Login'}</h2>\n                    <FormControl required={true} fullWidth={true} className={classes.field}>\n                        <InputLabel htmlFor=\"email\">Email Address</InputLabel>\n                        <Input\n                            value={this.state.email}\n                            onChange={this.handleEmailAddressChange}\n                            id=\"email\"\n                            startAdornment={\n                                <InputAdornment position=\"start\">\n                                    <Icon>email</Icon>\n                                </InputAdornment>}\n                        />\n                    </FormControl>\n                    <FormControl required={true} fullWidth={true} className={classes.field}>\n                        <InputLabel htmlFor=\"password\">Password</InputLabel>\n                        <Input\n                            value={this.state.password}\n                            onChange={this.handlePasswordChange}\n                            type=\"password\"\n                            id=\"password\"\n                            startAdornment={\n                                <InputAdornment position=\"start\">\n                                    <Icon>lock</Icon>\n                                </InputAdornment>}\n                        />\n                    </FormControl>\n                    <div className={classes.actions}>\n                        <Button variant=\"raised\" className={classes.button}>\n                            Cancel\n                        </Button>\n                        <Button\n                            onClick={this.handleLogin}\n                            variant=\"raised\"\n                            color=\"primary\"\n                            className={classes.button}>\n                            Submit\n                        </Button>\n                    </div>\n                </Paper>\n            </div>\n        );\n    }\n}\n\nconst styles = (theme: Theme) => ({\n    container: {\n        display: 'flex',\n        justifyContent: 'center'\n    },\n    paper: theme.mixins.gutters({\n        paddingTop: 16,\n        paddingBottom: 16,\n        marginTop: theme.spacing.unit * 3,\n        width: '30%',\n        display: 'flex',\n        flexDirection: 'column',\n        alignContent: 'center',\n        [theme.breakpoints.down('md')]: {\n            width: '100%',\n        },\n    }),\n    field: {\n        marginTop: theme.spacing.unit * 3\n    },\n    actions: theme.mixins.gutters({\n        paddingTop: 16,\n        paddingBottom: 16,\n        marginTop: theme.spacing.unit * 3,\n        display: 'flex',\n        flexDirection: 'row',\n        alignContent: 'center'\n    }),\n    button: {\n        marginRight: theme.spacing.unit\n    },\n});\n\nexport default withStyles(styles, { withTheme: true })(LoginPage as any) as any;\n\n"
  },
  {
    "path": "src/pages/account/Profile.tsx",
    "content": "import * as React from 'react';\nimport { Typography } from '@material-ui/core';\n\nexport class ProfilePage extends React.Component<{}, {}> {\n    public render(): JSX.Element {\n        return (<Typography noWrap={false}>{\"Profile Page\"}</Typography>)\n    }\n}"
  },
  {
    "path": "src/pages/mail/Drafts.tsx",
    "content": "import * as React from 'react'\nimport MailList from '../../components/MailList';\nimport { Paper, Typography, Theme, withStyles } from '@material-ui/core';\nimport { Button } from '@material-ui/core';\n\ninterface IDraftsProps {\n    items: any[];\n    classes: any;\n}\n\nclass DraftsPage extends React.Component<IDraftsProps, {}> {\n\n    public render(): JSX.Element {\n        const { classes } = this.props;\n        return (\n            <Paper className={classes.root}>\n                <div className={classes.boxHeader}>\n                    <Typography className={classes.boxHeaderTitle}>Drafts</Typography>\n                    <span className={classes.fillRemainingSpace}/>\n                    <Button>Delete all</Button>\n                </div>\n                <MailList {...this.props} />\n            </Paper>\n        );\n    }\n}\n\nconst styles = (theme: Theme) => ({\n    root: {\n        width: '100%',\n    },\n    boxHeader: {\n        width: '100%',\n        display: 'flex',\n        [theme.breakpoints.down('md')]: {\n            flexDirection: 'column',\n        },\n    },\n    boxHeaderTitle: {\n        padding: '5px 10px',\n        fontSize: 35,\n    },\n    fillRemainingSpace: {\n        flex: '1 1 auto',\n        [theme.breakpoints.down('md')]: {\n            display: 'none',\n        },\n    },\n});\n\nexport default withStyles(styles as any)(DraftsPage as any) as any;"
  },
  {
    "path": "src/pages/mail/Inbox.tsx",
    "content": "import * as React from 'react'\nimport MailList from '../../components/MailList';\nimport { Paper, Typography, Theme, withStyles } from '@material-ui/core';\nimport { Button } from '@material-ui/core';\n\ninterface InboxProps {\n    items: any[];\n    classes: any;\n}\n\nclass InboxPage extends React.Component<InboxProps, {}> {\n\n    public render(): JSX.Element {\n        const { classes } = this.props;\n        return (\n            <Paper className={classes.root}>\n                <div className={classes.boxHeader}>\n                    <Typography className={classes.boxHeaderTitle}>Inbox</Typography>\n                    <span className={classes.fillRemainingSpace}/>\n                    <Button>Mark All As Read</Button>\n                    <Button>Delete all</Button>\n                </div>\n                <MailList {...this.props} />\n            </Paper>\n        );\n    }\n}\n\nconst styles = (theme: Theme) => ({\n    root: {\n        width: '100%',\n    },\n    boxHeader: {\n        width: '100%',\n        display: 'flex',\n        [theme.breakpoints.down('md')]: {\n            flexDirection: 'column',\n        },\n    },\n    boxHeaderTitle: {\n        padding: '5px 10px',\n        fontSize: 35,\n    },\n    fillRemainingSpace: {\n        flex: '1 1 auto',\n        [theme.breakpoints.down('md')]: {\n            display: 'none',\n        },\n    },\n});\n\nexport default withStyles(styles as any)(InboxPage as any) as any;"
  },
  {
    "path": "src/pages/mail/Mail.tsx",
    "content": "import * as React from 'react';\nimport { Route, Switch } from 'react-router';\nimport InboxPage from './Inbox';\nimport SentPage from './Sent';\nimport DraftsPage from './Drafts';\n\ninterface IMailProps {\n    match?: any;\n    location?: any;\n    classes?: any;\n    mail: any[];\n}\n\nexport class MailPage extends React.Component<IMailProps, {}> {\n\n    private renderInbox = () => {\n        return (<InboxPage\n            items={this.props.mail}\n        />);\n    }\n\n    private renderSent = () => {\n        return (<SentPage\n            items={this.props.mail}\n        />);\n    }\n\n    private renderDrafts = () => {\n        return (<DraftsPage\n            items={this.props.mail}\n        />);\n    }\n\n    public render(): JSX.Element {\n        return (\n        <Switch>\n            <Route path=\"/mail\" exact={true} render={this.renderInbox} />\n            <Route path=\"/mail/inbox\" render={this.renderInbox} />\n            <Route path=\"/mail/sent\" render={this.renderSent} />\n            <Route path=\"/mail/drafts\" render={this.renderDrafts} />\n        </Switch>);\n    }\n\n}"
  },
  {
    "path": "src/pages/mail/Sent.tsx",
    "content": "import * as React from 'react'\nimport MailList from '../../components/MailList';\nimport { Paper, Typography, Theme, withStyles } from '@material-ui/core';\nimport { Button } from '@material-ui/core';\n\ninterface ISentProps {\n    items: any[];\n    classes: any;\n}\n\nclass SentPage extends React.Component<ISentProps, {}> {\n\n    public render(): JSX.Element {\n        const { classes } = this.props;\n        return (\n            <Paper className={classes.root}>\n                <div className={classes.boxHeader}>\n                    <Typography className={classes.boxHeaderTitle}>Sent</Typography>\n                    <span className={classes.fillRemainingSpace}/>\n                    <Button>Delete all</Button>\n                </div>\n                <MailList {...this.props} />\n            </Paper>\n        );\n    }\n}\n\nconst styles = (theme: Theme) => ({\n    root: {\n        width: '100%',\n    },\n    boxHeader: {\n        width: '100%',\n        display: 'flex',\n        [theme.breakpoints.down('md')]: {\n            flexDirection: 'column',\n        },\n    },\n    boxHeaderTitle: {\n        padding: '5px 10px',\n        fontSize: 35,\n    },\n    fillRemainingSpace: {\n        flex: '1 1 auto',\n        [theme.breakpoints.down('md')]: {\n            display: 'none',\n        },\n    },\n});\n\nexport default withStyles(styles as any)(SentPage as any) as any;"
  },
  {
    "path": "src/reducers/AuthenticationReducer.ts",
    "content": "import { IAppAction, ActionType } from './../actions/Helpers';\nimport { User } from '../state/User';\n\nexport const AuthenticationReducer = (state: User = null, action: IAppAction): User => {\n    switch (action.type) {\n        case ActionType.LOGIN_REQUEST:\n            return new User({email: action.payload.email, name: 'Goeme Nthomiwa', roles: ['Admin']});\n        case ActionType.LOGOUT_REQUEST:\n            return null;\n        default:\n            return state;\n    }\n};"
  },
  {
    "path": "src/reducers/CombinedReducers.ts",
    "content": "import { combineReducers } from \"redux\";\nimport { UtilityReducer } from './UtilityReducer';\nimport { AuthenticationReducer } from \"./AuthenticationReducer\";\nimport { rootReducer as usersReducers } from \"../data/users\";\nimport { rootReducer as materialsReducers } from \"../data/material\";\nimport { rootReducer as mailReducers } from \"../data/mail\";\n\nexport const reducers = combineReducers({\n    utility: UtilityReducer,\n    authentication: AuthenticationReducer,\n    users: usersReducers,\n    materials: materialsReducers,\n    mail: mailReducers\n});"
  },
  {
    "path": "src/reducers/UtilityReducer.ts",
    "content": "import { IAppAction, ActionType } from './../actions/Helpers';\nimport { Utility } from '../state/Utility';\n\nexport const UtilityReducer = (state: Utility = new Utility(), action: IAppAction): Utility => {\n    switch (action.type) {\n        case ActionType.OPEN_DRAWER:\n            return state.set(Utility.DRAWER_OPEN, true) as Utility;\n        case ActionType.CLOSE_DRAWER:\n            return state.set(Utility.DRAWER_OPEN, false) as Utility;\n        case ActionType.OPEN_ALERT:\n            return state.set(Utility.ALERT, action.payload) as Utility;\n        case ActionType.CLOSE_ALERT:\n            return state.set(Utility.ALERT, null) as Utility;\n        case ActionType.OPEN_SPINNER:\n            return state.set(Utility.SPINNER, action.payload) as Utility;\n        case ActionType.CLOSE_SPINNER:\n            return state.set(Utility.SPINNER, null) as Utility;\n        default:\n            return state;\n    }\n};"
  },
  {
    "path": "src/registerServiceWorker.ts",
    "content": "// tslint:disable:no-console\n// In production, we register a service worker to serve assets from local cache.\n\n// This lets the app load faster on subsequent visits in production, and gives\n// it offline capabilities. However, it also means that developers (and users)\n// will only see deployed updates on the 'N+1' visit to a page, since previously\n// cached resources are updated in the background.\n\n// To learn more about the benefits of this model, read https://goo.gl/KwvDNy.\n// This link also includes instructions on opting out of this behavior.\n\nconst isLocalhost = Boolean(\n  window.location.hostname === 'localhost' ||\n    // [::1] is the IPv6 localhost address.\n    window.location.hostname === '[::1]' ||\n    // 127.0.0.1/8 is considered localhost for IPv4.\n    window.location.hostname.match(\n      /^127(?:\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/\n    )\n);\n\nexport default function register() {\n  if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {\n    // The URL constructor is available in all browsers that support SW.\n    const publicUrl = new URL(\n      process.env.PUBLIC_URL!,\n      window.location.toString()\n    );\n    if (publicUrl.origin !== window.location.origin) {\n      // Our service worker won't work if PUBLIC_URL is on a different origin\n      // from what our page is served on. This might happen if a CDN is used to\n      // serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374\n      return;\n    }\n\n    window.addEventListener('load', () => {\n      const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;\n\n      if (isLocalhost) {\n        // This is running on localhost. Lets check if a service worker still exists or not.\n        checkValidServiceWorker(swUrl);\n\n        // Add some additional logging to localhost, pointing developers to the\n        // service worker/PWA documentation.\n        navigator.serviceWorker.ready.then(() => {\n          console.log(\n            'This web app is being served cache-first by a service ' +\n              'worker. To learn more, visit https://goo.gl/SC7cgQ'\n          );\n        });\n      } else {\n        // Is not local host. Just register service worker\n        registerValidSW(swUrl);\n      }\n    });\n  }\n}\n\nfunction registerValidSW(swUrl: string) {\n  navigator.serviceWorker\n    .register(swUrl)\n    .then(registration => {\n      registration.onupdatefound = () => {\n        const installingWorker = registration.installing;\n        if (installingWorker) {\n          installingWorker.onstatechange = () => {\n            if (installingWorker.state === 'installed') {\n              if (navigator.serviceWorker.controller) {\n                // At this point, the old content will have been purged and\n                // the fresh content will have been added to the cache.\n                // It's the perfect time to display a 'New content is\n                // available; please refresh.' message in your web app.\n                console.log('New content is available; please refresh.');\n              } else {\n                // At this point, everything has been precached.\n                // It's the perfect time to display a\n                // 'Content is cached for offline use.' message.\n                console.log('Content is cached for offline use.');\n              }\n            }\n          };\n        }\n      };\n    })\n    .catch(error => {\n      console.error('Error during service worker registration:', error);\n    });\n}\n\nfunction checkValidServiceWorker(swUrl: string) {\n  // Check if the service worker can be found. If it can't reload the page.\n  fetch(swUrl)\n    .then(response => {\n      // Ensure service worker exists, and that we really are getting a JS file.\n      if (\n        response.status === 404 ||\n        response.headers.get('content-type')!.indexOf('javascript') === -1\n      ) {\n        // No service worker found. Probably a different app. Reload the page.\n        navigator.serviceWorker.ready.then(registration => {\n          registration.unregister().then(() => {\n            window.location.reload();\n          });\n        });\n      } else {\n        // Service worker found. Proceed as normal.\n        registerValidSW(swUrl);\n      }\n    })\n    .catch(() => {\n      console.log(\n        'No internet connection found. App is running in offline mode.'\n      );\n    });\n}\n\nexport function unregister() {\n  if ('serviceWorker' in navigator) {\n    navigator.serviceWorker.ready.then(registration => {\n      registration.unregister();\n    });\n  }\n}\n"
  },
  {
    "path": "src/selectors/index.ts",
    "content": "import { AppState } from '../state/AppState';\nimport { createSelector } from 'reselect';\nconst randomColor = require('randomcolor');\nimport * as _ from 'lodash';\nimport * as moment from 'moment';\n\nconst materialItemsSelector = (state: AppState) => state.materials.items;\nconst mailSelector = (state: AppState) => state.mail;\n\nexport const getMaterialChartItems = createSelector(materialItemsSelector, (items: any[]) => {\n    const categories = _.groupBy(items, x => x.category);\n    const data = _.keys(categories).map(category => ({ name: category, value: categories[category].length, fill: randomColor() }));\n\n    return data;\n});\n\nexport const getMailitems = createSelector(mailSelector, (mail: any) => {\n    return _.sortBy(mail.items.map((item: any) => \n    _.assign({}, item, {createdAt: moment(item.createdAt)}), (i: any) => i.createdAt));\n});"
  },
  {
    "path": "src/spinner/Spinner.tsx",
    "content": "import * as React from 'react';\nimport Dialog from '@material-ui/core/Dialog';\nimport DialogContent from '@material-ui/core/DialogContent';\nimport DialogContentText from '@material-ui/core/DialogContentText';\nimport { withStyles, CircularProgress, WithStyles } from '@material-ui/core';\n\nconst styles = (theme: any) => ({\n    progress: {\n        margin: theme.spacing.unit * 2,\n    },\n    content: {\n        display: 'flex',\n        alignItems: 'center'\n    }\n});\n\ninterface ISpinnerProps {\n    message?: string;\n    classes?: any;\n}\n\nclass SpinnerDialog extends React.Component<ISpinnerProps & WithStyles<\"progress\">, {}> {\n\n    public render() {\n        return (\n\n            <Dialog\n                open={this.props.message !== null}\n                aria-labelledby=\"alert-dialog-title\"\n                aria-describedby=\"alert-dialog-description\"\n            >\n                <DialogContent className={this.props.classes.content}>\n                    <CircularProgress className={this.props.classes.progress} />\n                    <DialogContentText id=\"alert-dialog-description\">\n                        {this.props.message}\n                    </DialogContentText>\n                </DialogContent>\n\n            </Dialog>\n        );\n    }\n}\n\n\n\nexport default withStyles(styles)(SpinnerDialog);\n"
  },
  {
    "path": "src/state/Alert.ts",
    "content": "import { Model } from \"./Helpers\";\n\ninterface IAlertButtonOptions {\n    label: string;\n    handler: () => void;\n}\n\nexport interface IAlert {\n    title?: string;\n    message: string;\n    buttons?: IAlertButtonOptions[];\n}\n\nexport const AlertModel = Model<IAlert>({\n    title: null,\n    message: null,\n    buttons: null\n});\n\nexport class Alert extends AlertModel {\n    public title: string;\n    public message: string;\n    public buttons: IAlertButtonOptions[];\n\n    constructor(data: IAlert) {\n        super(data);\n    }\n}"
  },
  {
    "path": "src/state/AppState.ts",
    "content": "import { connectedRouterRedirect } from 'redux-auth-wrapper/history4/redirect';\nimport { Utility } from './Utility';\nimport { Model } from \"./Helpers\";\nimport { User } from './User';\n\nexport interface IAppState {\n    utility?: Utility;\n    authentication?: User;\n    users?: any;\n    materials?: any;\n    mail?: any;\n}\n\nexport const AppStateModel = Model<IAppState>({\n    utility: new Utility(),\n    authentication: null,\n    users: null,\n    materials: null,\n    mail: null\n});\n\nexport class AppState extends AppStateModel {\n    public static UTILITY = 'utility';\n    public static AUTHENTICATION = \"authentication\";\n\n    public utility: Utility;\n    public authentication: User;\n    public users: any;\n    public materials: any;\n    public mail: any;\n}\n\nexport const isAuthenticated = connectedRouterRedirect({\n    redirectPath: '/account/login',\n    authenticatedSelector: (state: AppState) => state.authentication !== null,\n    wrapperDisplayName: 'Authenticated'\n}) as any;"
  },
  {
    "path": "src/state/Helpers.ts",
    "content": "import { Record } from 'immutable';\n\nexport const Model = <T>(data: T): Record.Class => {\n    return Record(data);\n};"
  },
  {
    "path": "src/state/Spinner.ts",
    "content": "import { Model } from \"./Helpers\";\n\nexport interface ISpinner {\n    message: string;\n}\n\nexport const SpinnerModel = Model<ISpinner>({\n    message: null\n});\n\nexport class Spinner extends SpinnerModel {\n    public static MESSAGE = 'message';\n    \n    public message: string;\n}"
  },
  {
    "path": "src/state/User.ts",
    "content": "import { Model } from \"./Helpers\";\nimport * as _ from 'lodash';\n\nexport interface IUser {\n    email?: string;\n    name?: string;\n    roles?: string[];\n}\n\nconst UserModel = Model<IUser>({\n    email: null,\n    name: null,\n    roles: null\n});\n\nexport class User extends UserModel {\n    public static EMAIL = 'email';\n    public static NAME = 'name';\n    public static ROLES = 'roles';\n\n    public email: string;\n    public name: string;\n    public roles: string[];\n\n    public isInRole(candidate: string) {\n        return _.intersection(this.roles, [candidate]).length > 0;\n    }\n}\n"
  },
  {
    "path": "src/state/Utility.ts",
    "content": "import { Model } from \"./Helpers\";\nimport { Alert } from './Alert';\nimport { Spinner } from \"./Spinner\";\n\nexport interface IUtility {\n    drawerOpen?: boolean;\n    alert?: Alert;\n    spinner?: Spinner;\n}\n\nexport const UtilityModel = Model<IUtility>({\n    drawerOpen: false,\n    alert: null,\n    spinner: null\n});\n\nexport class Utility extends UtilityModel {\n    public static DRAWER_OPEN = 'drawerOpen';\n    public static ALERT = 'alert';\n    public static SPINNER = 'spinner';\n\n    public drawerOpen: boolean;\n    public alert: Alert;\n    public spinner: Spinner;\n}\n"
  },
  {
    "path": "src/store/Store.ts",
    "content": "import { reducers } from '../reducers/CombinedReducers';\nimport { createStore, applyMiddleware } from 'redux'\nimport thunk from 'redux-thunk';\n\nexport const store = createStore(reducers, applyMiddleware(thunk));"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"baseUrl\": \".\",\n    \"outDir\": \"build/dist\",\n    \"module\": \"esnext\",\n    \"target\": \"es5\",\n    \"lib\": [\"es6\", \"dom\"],\n    \"sourceMap\": true,\n    \"allowJs\": true,\n    \"jsx\": \"react\",\n    \"moduleResolution\": \"node\",\n    \"rootDir\": \"src\",\n    \"forceConsistentCasingInFileNames\": true,\n    \"noImplicitReturns\": true,\n    \"noImplicitThis\": true,\n    \"noImplicitAny\": true,\n    \"strictNullChecks\": false,\n    \"suppressImplicitAnyIndexErrors\": true,\n    \"noUnusedLocals\": true,\n    \"experimentalDecorators\": true,\n    \"emitDecoratorMetadata\": true\n  },\n  \"exclude\": [\n    \"node_modules\",\n    \"build\",\n    \"scripts\",\n    \"acceptance-tests\",\n    \"webpack\",\n    \"jest\",\n    \"src/setupTests.ts\"\n  ]\n}\n"
  },
  {
    "path": "tsconfig.prod.json",
    "content": "{\n  \"extends\": \"./tsconfig.json\"\n}"
  },
  {
    "path": "tsconfig.test.json",
    "content": "{\n  \"extends\": \"./tsconfig.json\",\n  \"compilerOptions\": {\n    \"module\": \"commonjs\"\n  }\n}"
  },
  {
    "path": "tslint.json",
    "content": "{\n  \"extends\": [\"tslint:recommended\", \"tslint-react\", \"tslint-config-prettier\"],\n  \"linterOptions\": {\n    \"exclude\": [\n      \"config/**/*.js\",\n      \"node_modules/**/*.ts\"\n    ]\n  },\n  \"rules\": {\n    \"ordered-imports\": false,\n    \"member-ordering\": false,\n    \"object-literal-sort-keys\": false,\n    \"no-var-requires\": false,\n    \"no-console\": false,\n    \"jsx-no-lambda\": false\n  }\n}\n"
  }
]