├── src ├── config.js ├── hooks │ └── useSettings.js ├── components │ ├── Logo.js │ ├── Page.js │ └── GlobalStyles.js ├── constants.js ├── setupTests.js ├── App.test.js ├── index.css ├── reportWebVitals.js ├── index.js ├── theme │ ├── typography.js │ └── index.js ├── App.css ├── views │ └── home │ │ └── HomeView │ │ ├── MessageBody.js │ │ ├── ConnectSettingsForm.js │ │ ├── MessagesList.js │ │ └── index.js ├── App.js ├── routes.js ├── layouts │ └── MainLayout │ │ ├── index.js │ │ └── TopBar │ │ ├── index.js │ │ └── Settings.js └── contexts │ └── SettingsContext.js ├── public ├── robots.txt ├── favicon.ico ├── logo192.png ├── logo512.png ├── manifest.json ├── static │ └── logo.svg └── index.html ├── .gitignore ├── package.json └── README.md /src/config.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potentialdev-web/mail-app-demo/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potentialdev-web/mail-app-demo/HEAD/public/logo192.png -------------------------------------------------------------------------------- /public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/potentialdev-web/mail-app-demo/HEAD/public/logo512.png -------------------------------------------------------------------------------- /src/hooks/useSettings.js: -------------------------------------------------------------------------------- 1 | import { useContext } from 'react'; 2 | import SettingsContext from '../contexts/SettingsContext'; 3 | 4 | const useSettings = () => useContext(SettingsContext); 5 | 6 | export default useSettings; 7 | -------------------------------------------------------------------------------- /src/components/Logo.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const Logo = (props) => { 4 | return ( 5 | Logo 10 | ); 11 | } 12 | 13 | export default Logo; 14 | -------------------------------------------------------------------------------- /src/constants.js: -------------------------------------------------------------------------------- 1 | export const THEMES = { 2 | LIGHT: 'LIGHT', 3 | ONE_DARK: 'ONE_DARK' 4 | }; 5 | 6 | export const USER = { 7 | name: 'Gavin Lin', 8 | avatar: 'https://lh3.googleusercontent.com/ogw/ADGmqu-6aoE6_y--6B7lzHm8RjuIYF5QNdd6F_-CH4jf=s32-c-mo' 9 | }; 10 | -------------------------------------------------------------------------------- /src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /src/App.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import App from './App'; 3 | 4 | test('renders learn react link', () => { 5 | render(); 6 | const linkElement = screen.getByText(/learn react/i); 7 | expect(linkElement).toBeInTheDocument(); 8 | }); 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env 17 | .env.local 18 | .env.development.local 19 | .env.test.local 20 | .env.production.local 21 | 22 | npm-debug.log* 23 | yarn-debug.log* 24 | yarn-error.log* 25 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = onPerfEntry => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 4 | getCLS(onPerfEntry); 5 | getFID(onPerfEntry); 6 | getFCP(onPerfEntry); 7 | getLCP(onPerfEntry); 8 | getTTFB(onPerfEntry); 9 | }); 10 | } 11 | }; 12 | 13 | export default reportWebVitals; 14 | -------------------------------------------------------------------------------- /src/components/Page.js: -------------------------------------------------------------------------------- 1 | import React, { 2 | forwardRef 3 | } from 'react'; 4 | import PropTypes from 'prop-types'; 5 | 6 | const Page = forwardRef(({ 7 | children, 8 | title = '', 9 | ...rest 10 | }, ref) => { 11 | return ( 12 |
16 | {/* Willing to use Helmet here */} 17 | {/* {title} */} 18 | {children} 19 |
20 | ); 21 | }); 22 | 23 | Page.propTypes = { 24 | children: PropTypes.node.isRequired, 25 | // title: PropTypes.string 26 | }; 27 | 28 | export default Page; 29 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import 'react-perfect-scrollbar/dist/css/styles.css'; 2 | import React from 'react'; 3 | import ReactDOM from 'react-dom'; 4 | import App from './App'; 5 | import reportWebVitals from './reportWebVitals'; 6 | import { SettingsProvider } from './contexts/SettingsContext'; 7 | 8 | ReactDOM.render( 9 | 10 | 11 | , 12 | document.getElementById('root') 13 | ); 14 | 15 | // If you want to start measuring performance in your app, pass a function 16 | // to log results (for example: reportWebVitals(console.log)) 17 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 18 | reportWebVitals(); 19 | -------------------------------------------------------------------------------- /src/theme/typography.js: -------------------------------------------------------------------------------- 1 | export default { 2 | h1: { 3 | fontWeight: 500, 4 | fontSize: 35, 5 | letterSpacing: '-0.24px' 6 | }, 7 | h2: { 8 | fontWeight: 500, 9 | fontSize: 29, 10 | letterSpacing: '-0.24px' 11 | }, 12 | h3: { 13 | fontWeight: 500, 14 | fontSize: 24, 15 | letterSpacing: '-0.06px' 16 | }, 17 | h4: { 18 | fontWeight: 500, 19 | fontSize: 20, 20 | letterSpacing: '-0.06px' 21 | }, 22 | h5: { 23 | fontWeight: 500, 24 | fontSize: 16, 25 | letterSpacing: '-0.05px' 26 | }, 27 | h6: { 28 | fontWeight: 500, 29 | fontSize: 14, 30 | letterSpacing: '-0.05px' 31 | }, 32 | overline: { 33 | fontWeight: 500 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | height: 40vmin; 7 | pointer-events: none; 8 | } 9 | 10 | @media (prefers-reduced-motion: no-preference) { 11 | .App-logo { 12 | animation: App-logo-spin infinite 20s linear; 13 | } 14 | } 15 | 16 | .App-header { 17 | background-color: #282c34; 18 | min-height: 100vh; 19 | display: flex; 20 | flex-direction: column; 21 | align-items: center; 22 | justify-content: center; 23 | font-size: calc(10px + 2vmin); 24 | color: white; 25 | } 26 | 27 | .App-link { 28 | color: #61dafb; 29 | } 30 | 31 | @keyframes App-logo-spin { 32 | from { 33 | transform: rotate(0deg); 34 | } 35 | to { 36 | transform: rotate(360deg); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/components/GlobalStyles.js: -------------------------------------------------------------------------------- 1 | import { createStyles, makeStyles } from '@material-ui/core'; 2 | 3 | const useStyles = makeStyles(() => createStyles({ 4 | '@global': { 5 | '*': { 6 | boxSizing: 'border-box', 7 | margin: 0, 8 | padding: 0, 9 | }, 10 | html: { 11 | '-webkit-font-smoothing': 'antialiased', 12 | '-moz-osx-font-smoothing': 'grayscale', 13 | height: '100%', 14 | width: '100%' 15 | }, 16 | body: { 17 | height: '100%', 18 | width: '100%' 19 | }, 20 | '#root': { 21 | height: '100%', 22 | width: '100%' 23 | } 24 | } 25 | })); 26 | 27 | const GlobalStyles = () => { 28 | useStyles(); 29 | 30 | return null; 31 | }; 32 | 33 | export default GlobalStyles; 34 | -------------------------------------------------------------------------------- /src/views/home/HomeView/MessageBody.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import clsx from 'clsx'; 4 | 5 | import { 6 | Box, 7 | Card, 8 | CardContent, 9 | CardHeader, 10 | Container, 11 | Divider, 12 | Grid, 13 | makeStyles, 14 | TextField 15 | } from '@material-ui/core'; 16 | 17 | const useStyles = makeStyles((theme) => ({ 18 | root: { 19 | display: 'flex', 20 | flexDirection: 'column', 21 | flex: '1 1 auto' 22 | } 23 | })); 24 | 25 | const MessageBody = ({ 26 | className, 27 | ...rest 28 | }) => { 29 | const classes = useStyles(); 30 | 31 | return ( 32 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | ); 43 | }; 44 | 45 | export default MessageBody; 46 | -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Router, Route } from 'react-router-dom'; 3 | import { createBrowserHistory } from 'history'; 4 | import { SnackbarProvider } from 'notistack'; 5 | import { 6 | StylesProvider, 7 | ThemeProvider 8 | } from '@material-ui/core'; 9 | import useSettings from './hooks/useSettings'; 10 | import GlobalStyles from './components/GlobalStyles'; 11 | import { createTheme } from './theme'; 12 | import routes, { renderRoutes } from './routes'; 13 | 14 | const history = createBrowserHistory(); 15 | 16 | const App = () => { 17 | const { settings } = useSettings(); 18 | 19 | const theme = createTheme({ 20 | theme: settings.theme 21 | }); 22 | 23 | return ( 24 | 25 | 26 | 30 | 31 | 32 | {renderRoutes(routes)} 33 | 34 | 35 | 36 | 37 | ); 38 | } 39 | 40 | export default App; 41 | -------------------------------------------------------------------------------- /src/routes.js: -------------------------------------------------------------------------------- 1 | import React, { 2 | Fragment 3 | } from 'react'; 4 | import { 5 | Switch, 6 | Route 7 | } from 'react-router-dom'; 8 | import MainLayout from './layouts/MainLayout'; 9 | import HomeView from './views/home/HomeView'; 10 | 11 | export const renderRoutes = (routes = []) => ( 12 | 13 | {routes.map((route, i) => { 14 | const Layout = route.layout || Fragment; 15 | const Component = route.component; 16 | 17 | return ( 18 | ( 23 | 24 | {route.routes 25 | ? renderRoutes(route.routes) 26 | : } 27 | 28 | )} 29 | /> 30 | ); 31 | })} 32 | 33 | ); 34 | 35 | const routes = [ 36 | { 37 | path: '*', 38 | layout: MainLayout, 39 | routes: [ 40 | { 41 | exact: true, 42 | path: '/', 43 | component: HomeView 44 | } 45 | ] 46 | } 47 | ]; 48 | 49 | export default routes; 50 | -------------------------------------------------------------------------------- /src/layouts/MainLayout/index.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { makeStyles } from '@material-ui/core'; 4 | import TopBar from './TopBar'; 5 | 6 | const useStyles = makeStyles((theme) => ({ 7 | root: { 8 | backgroundColor: theme.palette.background.dark, 9 | display: 'flex', 10 | height: '100%', 11 | overflow: 'hidden', 12 | width: '100%' 13 | }, 14 | wrapper: { 15 | display: 'flex', 16 | flex: '1 1 auto', 17 | overflow: 'hidden', 18 | paddingTop: 47 19 | }, 20 | contentContainer: { 21 | display: 'flex', 22 | flex: '1 1 auto', 23 | overflow: 'hidden' 24 | }, 25 | content: { 26 | flex: '1 1 auto', 27 | height: '100%', 28 | overflow: 'auto', 29 | padding: 16 30 | } 31 | })); 32 | 33 | const Layout = ({ children }) => { 34 | const classes = useStyles(); 35 | 36 | return ( 37 |
38 | 39 |
40 |
41 |
42 | {children} 43 |
44 |
45 |
46 |
47 | ); 48 | }; 49 | 50 | Layout.propTypes = { 51 | children: PropTypes.node 52 | }; 53 | 54 | export default Layout; 55 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "email-app-demo", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@material-ui/core": "^4.11.4", 7 | "@material-ui/icons": "^4.11.2", 8 | "@testing-library/jest-dom": "^5.12.0", 9 | "@testing-library/react": "^11.2.7", 10 | "@testing-library/user-event": "^12.8.3", 11 | "change-case": "^4.1.2", 12 | "lodash": "^4.17.21", 13 | "moment": "^2.29.1", 14 | "notistack": "^1.0.7", 15 | "react": "^17.0.2", 16 | "react-dom": "^17.0.2", 17 | "react-perfect-scrollbar": "^1.5.8", 18 | "react-router-dom": "^5.2.0", 19 | "react-scripts": "4.0.3", 20 | "styled-components": "^5.3.0", 21 | "web-vitals": "^1.1.2" 22 | }, 23 | "scripts": { 24 | "start": "react-scripts start", 25 | "build": "react-scripts build", 26 | "test": "react-scripts test", 27 | "eject": "react-scripts eject" 28 | }, 29 | "eslintConfig": { 30 | "extends": [ 31 | "react-app", 32 | "react-app/jest" 33 | ] 34 | }, 35 | "browserslist": { 36 | "production": [ 37 | ">0.2%", 38 | "not dead", 39 | "not op_mini all" 40 | ], 41 | "development": [ 42 | "last 1 chrome version", 43 | "last 1 firefox version", 44 | "last 1 safari version" 45 | ] 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /public/static/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 10 | 11 | 12 | 13 | 15 | 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 | -------------------------------------------------------------------------------- /src/contexts/SettingsContext.js: -------------------------------------------------------------------------------- 1 | import React, { 2 | createContext, 3 | useEffect, 4 | useState 5 | } from 'react'; 6 | import _ from 'lodash'; 7 | import { THEMES } from '../constants'; 8 | 9 | const defaultSettings = () => ({ 10 | theme: THEMES.ONE_DARK 11 | }); 12 | 13 | export const restoreSettings = () => { 14 | let settings = null; 15 | 16 | try { 17 | const storedData = window.localStorage.getItem('settings'); 18 | 19 | if (storedData) { 20 | settings = JSON.parse(storedData); 21 | } 22 | console.log('settings', settings); 23 | } catch (err) { 24 | console.error(err); 25 | // If stored data is not a strigified JSON this will fail, 26 | // that's why we catch the error 27 | } 28 | 29 | return settings; 30 | }; 31 | 32 | export const storeSettings = (settings) => { 33 | window.localStorage.setItem('settings', JSON.stringify(settings)); 34 | }; 35 | 36 | const SettingsContext = createContext({ 37 | settings: defaultSettings, 38 | saveSettings: () => { } 39 | }); 40 | 41 | export const SettingsProvider = ({ children }) => { 42 | const [currentSettings, setCurrentSettings] = useState(restoreSettings()); 43 | 44 | const handleSaveSettings = (update = {}) => { 45 | const mergedSettings = _.merge({}, currentSettings, update); 46 | 47 | setCurrentSettings(mergedSettings); 48 | storeSettings(mergedSettings); 49 | }; 50 | console.log('current settings', currentSettings); 51 | 52 | return ( 53 | 59 | {children} 60 | 61 | ); 62 | }; 63 | 64 | export const SettingsConsumer = SettingsContext.Consumer; 65 | 66 | export default SettingsContext; 67 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | Mail App Demo 28 | 29 | 30 | 31 |
32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /src/layouts/MainLayout/TopBar/index.js: -------------------------------------------------------------------------------- 1 | import React, { useRef } from 'react'; 2 | import { Link as RouterLink } from 'react-router-dom'; 3 | import PropTypes from 'prop-types'; 4 | import clsx from 'clsx'; 5 | import { 6 | AppBar, 7 | Avatar, 8 | Box, 9 | ButtonBase, 10 | Hidden, 11 | Toolbar, 12 | Typography, 13 | makeStyles 14 | } from '@material-ui/core'; 15 | import Logo from '../../../components/Logo'; 16 | import { THEMES, USER } from '../../../constants'; 17 | import Settings from './Settings'; 18 | 19 | const useStyles = makeStyles((theme) => ({ 20 | root: { 21 | zIndex: theme.zIndex.drawer + 100, 22 | ...theme.name === THEMES.LIGHT ? { 23 | boxShadow: 'none', 24 | backgroundColor: theme.palette.primary.main 25 | } : {}, 26 | ...theme.name === THEMES.ONE_DARK ? { 27 | backgroundColor: theme.palette.background.default 28 | } : {} 29 | }, 30 | toolbar: { 31 | minHeight: 47 32 | }, 33 | avatar: { 34 | height: 24, 35 | width: 24, 36 | marginRight: theme.spacing(1) 37 | } 38 | })); 39 | 40 | const TopBar = ({ 41 | className, 42 | ...rest 43 | }) => { 44 | const classes = useStyles(); 45 | const ref = useRef(null); 46 | 47 | return ( 48 | 52 | 53 | 54 | 55 | 56 | 60 | 61 | 67 | 72 | 73 | 77 | {USER.name} 78 | 79 | 80 | 81 | 82 | 83 | ); 84 | }; 85 | 86 | TopBar.propTypes = { 87 | className: PropTypes.string 88 | }; 89 | 90 | export default TopBar; 91 | -------------------------------------------------------------------------------- /src/theme/index.js: -------------------------------------------------------------------------------- 1 | import _ from 'lodash'; 2 | import { 3 | colors, 4 | createMuiTheme, 5 | responsiveFontSizes 6 | } from '@material-ui/core'; 7 | import { THEMES } from '../constants'; 8 | import typography from './typography'; 9 | 10 | const baseOptions = { 11 | typography, 12 | overrides: { 13 | MuiCardContent: { 14 | root: { 15 | display: 'flex', 16 | flexDirection: 'column', 17 | flexGrow: 1, 18 | }, 19 | }, 20 | MuiCard: { 21 | root: { 22 | display: 'flex', 23 | flexDirection: 'column' 24 | } 25 | }, 26 | MuiTablePagination: { 27 | root: { 28 | overflow: 'hidden' 29 | } 30 | } 31 | } 32 | }; 33 | 34 | const themesOptions = [ 35 | { 36 | name: THEMES.LIGHT, 37 | overrides: { 38 | MuiInputBase: { 39 | input: { 40 | '&::placeholder': { 41 | opacity: 1, 42 | color: colors.blueGrey[600] 43 | } 44 | } 45 | } 46 | }, 47 | palette: { 48 | type: 'light', 49 | action: { 50 | active: colors.blueGrey[600] 51 | }, 52 | background: { 53 | default: colors.common.white, 54 | dark: '#f4f6f8', 55 | paper: colors.common.white 56 | }, 57 | primary: { 58 | main: colors.indigo[600] 59 | }, 60 | secondary: { 61 | main: '#5850EC' 62 | }, 63 | text: { 64 | primary: colors.blueGrey[900], 65 | secondary: colors.blueGrey[600] 66 | } 67 | }, 68 | }, 69 | { 70 | name: THEMES.ONE_DARK, 71 | palette: { 72 | type: 'dark', 73 | action: { 74 | active: 'rgba(255, 255, 255, 0.54)', 75 | hover: 'rgba(255, 255, 255, 0.04)', 76 | selected: 'rgba(255, 255, 255, 0.08)', 77 | disabled: 'rgba(255, 255, 255, 0.26)', 78 | disabledBackground: 'rgba(255, 255, 255, 0.12)', 79 | focus: 'rgba(255, 255, 255, 0.12)' 80 | }, 81 | background: { 82 | default: '#282C34', 83 | dark: '#1c2025', 84 | paper: '#282C34' 85 | }, 86 | primary: { 87 | main: '#8a85ff' 88 | }, 89 | secondary: { 90 | main: '#8a85ff' 91 | }, 92 | text: { 93 | primary: '#e6e5e8', 94 | secondary: '#adb0bb' 95 | } 96 | } 97 | } 98 | ]; 99 | 100 | export const createTheme = (config = {}) => { 101 | let themeOptions = themesOptions.find((theme) => theme.name === config.theme); 102 | 103 | if (!themeOptions) { 104 | console.warn(new Error(`The theme ${config.theme} is not valid`)); 105 | [themeOptions] = themesOptions; 106 | } 107 | 108 | let theme = createMuiTheme( 109 | _.merge( 110 | {}, 111 | baseOptions, 112 | themeOptions 113 | ) 114 | ); 115 | 116 | return theme; 117 | } 118 | -------------------------------------------------------------------------------- /src/layouts/MainLayout/TopBar/Settings.js: -------------------------------------------------------------------------------- 1 | import React, { 2 | useState, 3 | useRef 4 | } from 'react'; 5 | import { capitalCase } from 'change-case'; 6 | import { 7 | Box, 8 | Button, 9 | FormControlLabel, 10 | IconButton, 11 | Popover, 12 | SvgIcon, 13 | Switch, 14 | TextField, 15 | Tooltip, 16 | Typography, 17 | makeStyles 18 | } from '@material-ui/core'; 19 | import SettingsIcon from '@material-ui/icons/Settings'; 20 | import useSettings from '../../../hooks/useSettings'; 21 | import { THEMES } from '../../../constants'; 22 | 23 | const useStyles = makeStyles((theme) => ({ 24 | badge: { 25 | height: 10, 26 | width: 10, 27 | borderRadius: 5, 28 | marginTop: 10, 29 | marginRight: 5 30 | }, 31 | popover: { 32 | width: 320, 33 | padding: theme.spacing(2) 34 | } 35 | })); 36 | 37 | const Settings = () => { 38 | const classes = useStyles(); 39 | const ref = useRef(null); 40 | const { settings, saveSettings } = useSettings(); 41 | const [isOpen, setOpen] = useState(false); 42 | const [values, setValues] = useState({ 43 | theme: settings.theme 44 | }); 45 | console.log('settings topbar', values); 46 | 47 | const handleOpen = () => { 48 | setOpen(true); 49 | }; 50 | 51 | const handleClose = () => { 52 | setOpen(false); 53 | }; 54 | 55 | const handleChange = (field, value) => { 56 | setValues({ 57 | ...values, 58 | [field]: value 59 | }); 60 | }; 61 | 62 | const handleSave = () => { 63 | saveSettings(values); 64 | setOpen(false); 65 | }; 66 | 67 | return ( 68 | <> 69 | 70 | 75 | 76 | 77 | 78 | 79 | 80 | 90 | 94 | Settings 95 | 96 | 97 | handleChange('theme', event.target.value)} 102 | select 103 | SelectProps={{ native: true }} 104 | value={values.theme} 105 | variant="outlined" 106 | > 107 | {Object.keys(THEMES).map((theme) => ( 108 | 114 | ))} 115 | 116 | 117 | 118 | 126 | 127 | 128 | 129 | ); 130 | } 131 | 132 | export default Settings; 133 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Getting Started with Create React App 2 | 3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 4 | 5 | ## Available Scripts 6 | 7 | In the project directory, you can run: 8 | 9 | ### `npm start` 10 | 11 | Runs the app in the development mode.\ 12 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser. 13 | 14 | The page will reload if you make edits.\ 15 | You will also see any lint errors in the console. 16 | 17 | ### `npm test` 18 | 19 | Launches the test runner in the interactive watch mode.\ 20 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. 21 | 22 | ### `npm run build` 23 | 24 | Builds the app for production to the `build` folder.\ 25 | It correctly bundles React in production mode and optimizes the build for the best performance. 26 | 27 | The build is minified and the filenames include the hashes.\ 28 | Your app is ready to be deployed! 29 | 30 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. 31 | 32 | ### `npm run eject` 33 | 34 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!** 35 | 36 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. 37 | 38 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own. 39 | 40 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it. 41 | 42 | ## Learn More 43 | 44 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). 45 | 46 | To learn React, check out the [React documentation](https://reactjs.org/). 47 | 48 | ### Code Splitting 49 | 50 | This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting) 51 | 52 | ### Analyzing the Bundle Size 53 | 54 | This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size) 55 | 56 | ### Making a Progressive Web App 57 | 58 | This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app) 59 | 60 | ### Advanced Configuration 61 | 62 | This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration) 63 | 64 | ### Deployment 65 | 66 | This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment) 67 | 68 | ### `npm run build` fails to minify 69 | 70 | This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify) 71 | -------------------------------------------------------------------------------- /src/views/home/HomeView/ConnectSettingsForm.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import clsx from 'clsx'; 4 | import { 5 | Box, 6 | Button, 7 | Card, 8 | CardContent, 9 | CardHeader, 10 | Collapse, 11 | Divider, 12 | Grid, 13 | IconButton, 14 | LinearProgress, 15 | TextField, 16 | SvgIcon, 17 | makeStyles, 18 | Typography 19 | } from '@material-ui/core'; 20 | import CheckCircleOutlineIcon from '@material-ui/icons/CheckCircleOutline'; 21 | import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; 22 | 23 | const useStyles = makeStyles((theme) => ({ 24 | root: {}, 25 | expand: { 26 | transform: 'rotate(0deg)', 27 | marginLeft: 'auto', 28 | transition: theme.transitions.create('transform', { 29 | duration: theme.transitions.duration.shortest, 30 | }), 31 | }, 32 | expandOpen: { 33 | transform: 'rotate(180deg)', 34 | } 35 | })); 36 | 37 | const ConnectSettingsForm = ({ 38 | className, 39 | settings, 40 | ...rest 41 | }) => { 42 | const classes = useStyles(); 43 | const [emailSettings, setSettings] = useState({ 44 | serverType: null, 45 | encryption: null, 46 | server: null, 47 | port: null, 48 | username: null, 49 | password: null 50 | }); 51 | const [isConnecting, setConnecting] = useState(false); 52 | const [expanded, setExpanded] = useState(false); 53 | 54 | const handleExpandClick = () => { 55 | setExpanded(!expanded); 56 | }; 57 | 58 | return ( 59 | 63 | 74 | 75 | 76 | } 77 | title={ 78 | 79 | 80 | Email Config 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | } 89 | > 90 | Test 91 | 92 | 93 | 94 | 95 | 96 | 97 | 104 | 107 | 108 | 109 | 110 | 117 | 120 | 121 | 122 | 123 | 129 | 130 | 131 | 137 | 138 | 139 | 145 | 146 | 147 | 154 | 155 | 156 | 157 | 158 | 163 | 170 | 171 | 172 | 173 | ); 174 | }; 175 | 176 | ConnectSettingsForm.propTypes = { 177 | className: PropTypes.string, 178 | settings: PropTypes.object.isRequired 179 | }; 180 | 181 | export default ConnectSettingsForm; 182 | -------------------------------------------------------------------------------- /src/views/home/HomeView/MessagesList.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import clsx from 'clsx'; 4 | import PerfectScrollbar from 'react-perfect-scrollbar'; 5 | import moment from 'moment'; 6 | import { 7 | Box, 8 | Button, 9 | Card, 10 | CardContent, 11 | CardHeader, 12 | Checkbox, 13 | Divider, 14 | Hidden, 15 | IconButton, 16 | InputAdornment, 17 | Table, 18 | TableBody, 19 | TableCell, 20 | TableHead, 21 | TablePagination, 22 | TableRow, 23 | TextField, 24 | Tooltip, 25 | Typography, 26 | SvgIcon, 27 | makeStyles 28 | } from '@material-ui/core'; 29 | import DoneIcon from '@material-ui/icons/Done'; 30 | import DeleteIcon from '@material-ui/icons/Delete'; 31 | import SearchIcon from '@material-ui/icons/Search'; 32 | 33 | const applyFilters = (messages, query) => { 34 | console.log('apply filter', messages); 35 | return messages && messages.length > 0 && messages.filter((message) => { 36 | let matches = true; 37 | 38 | if (query) { 39 | const properties = ['title', 'name']; 40 | let containsQuery = false; 41 | 42 | properties.forEach((property) => { 43 | if (message[property].toLowerCase().includes(query.toLowerCase())) { 44 | containsQuery = true; 45 | } 46 | }); 47 | 48 | if (!containsQuery) { 49 | matches = false; 50 | } 51 | } 52 | 53 | return matches; 54 | }); 55 | }; 56 | 57 | const applyPagination = (messages, page, limit) => { 58 | return messages && messages.length > 0 && messages.slice(page * limit, page * limit + limit); 59 | }; 60 | 61 | const useStyles = makeStyles((theme) => ({ 62 | root: { 63 | display: 'flex', 64 | flexDirection: 'column', 65 | height: '100%' 66 | }, 67 | queryField: { 68 | width: '100%' 69 | }, 70 | bulkOperations: { 71 | position: 'relative' 72 | }, 73 | bulkActions: { 74 | paddingLeft: 4, 75 | paddingRight: 4, 76 | marginTop: 6, 77 | position: 'absolute', 78 | width: '100%', 79 | zIndex: 2, 80 | backgroundColor: theme.palette.background.default 81 | }, 82 | bulkAction: { 83 | marginLeft: theme.spacing(2) 84 | }, 85 | details: { 86 | [theme.breakpoints.up('md')]: { 87 | display: 'flex', 88 | alignItems: 'center', 89 | flexGrow: 1 90 | } 91 | }, 92 | subject: { 93 | maxWidth: 150, 94 | whiteSpace: 'nowrap', 95 | overflow: 'hidden', 96 | textOverflow: 'ellipsis' 97 | }, 98 | message: { 99 | maxWidth: 150, 100 | flexGrow: 1, 101 | whiteSpace: 'nowrap', 102 | overflow: 'hidden', 103 | textOverflow: 'ellipsis', 104 | marginRight: 'auto' 105 | } 106 | })); 107 | 108 | const MessagesList = ({ 109 | className, 110 | messages, 111 | ...rest 112 | }) => { 113 | const classes = useStyles(); 114 | const [selectedMessages, setSelectedMessages] = useState([]); 115 | const [page, setPage] = useState(0); 116 | const [limit, setLimit] = useState(5); 117 | const [query, setQuery] = useState(''); 118 | 119 | const handleQueryChange = (event) => { 120 | event.persist(); 121 | setQuery(event.target.value); 122 | }; 123 | 124 | const handleSelectAllMessages = (event) => { 125 | setSelectedMessages(event.target.checked 126 | ? messages.map((message) => message.id) 127 | : []); 128 | }; 129 | 130 | const handleSelectOneMessage = (event, messageId) => { 131 | if (!selectedMessages.includes(messageId)) { 132 | setSelectedMessages((prevSelected) => [...prevSelected, messageId]); 133 | } else { 134 | setSelectedMessages((prevSelected) => prevSelected.filter((id) => id !== messageId)); 135 | } 136 | }; 137 | 138 | const handlePageChange = (event, newPage) => { 139 | setPage(newPage); 140 | }; 141 | 142 | const handleLimitChange = (event) => { 143 | setLimit(parseInt(event.target.value)); 144 | }; 145 | 146 | const filteredMessages = applyFilters(messages, query);console.log('filtered', filteredMessages); 147 | const paginatedMessages = applyPagination(filteredMessages, page, limit); 148 | const enableBulkOperations = selectedMessages.length > 0; 149 | const selectedSomeMessages = selectedMessages.length > 0 && selectedMessages.length < messages.length; 150 | const selectedAllMessages = selectedMessages.length === messages.length; 151 | 152 | return ( 153 | 157 | 158 | 159 | 160 | 165 | 170 | 174 | 175 | 176 | 177 | ) 178 | }} 179 | onChange={handleQueryChange} 180 | placeholder="Search messages" 181 | value={query} 182 | variant="outlined" 183 | /> 184 | 185 | 186 | {enableBulkOperations && ( 187 |
188 |
189 | 194 | 200 | 206 |
207 |
208 | )} 209 | 210 | 211 | 212 | 213 | 214 | 215 | 220 | 221 | 222 | From 223 | 224 | 225 | Body 226 | 227 | 228 | Time 229 | 230 | 231 | Actions 232 | 233 | 234 | 235 | 236 | {paginatedMessages.length > 0 && paginatedMessages.map((message) => { 237 | const isMessageSelected = selectedMessages.includes(message.id); 238 | 239 | return ( 240 | 245 | 246 | handleSelectOneMessage(event, message.id)} 249 | value={isMessageSelected} 250 | /> 251 | 252 | 253 | 254 | {message.from.name} 255 | 256 | 257 | 258 | 263 | 268 | {message.subject} 269 | 270 | 271 | 276 | 280 | - 281 | 282 | {message.message} 283 | 284 | 285 | 286 | 287 | 288 | {moment(message.createdAt).format('l')} 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | ); 310 | })} 311 | { 312 | paginatedMessages.length === 0 && ( 313 | 314 | 315 | No Messages 316 | 317 | 318 | ) 319 | } 320 | 321 |
322 |
323 |
324 | 325 | 334 |
335 |
336 | ); 337 | }; 338 | 339 | MessagesList.propTypes = { 340 | className: PropTypes.string, 341 | messages: PropTypes.array.isRequired 342 | }; 343 | 344 | MessagesList.defaultProps = { 345 | messages: [] 346 | }; 347 | 348 | export default MessagesList; 349 | -------------------------------------------------------------------------------- /src/views/home/HomeView/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | Box, 4 | Container, 5 | Grid as GridBase, 6 | makeStyles 7 | } from '@material-ui/core'; 8 | import styled from 'styled-components'; 9 | import Page from '../../../components/Page'; 10 | import ConnectSettingsForm from './ConnectSettingsForm'; 11 | import MessagesList from './MessagesList'; 12 | import MessageBody from './MessageBody'; 13 | import moment from 'moment'; 14 | 15 | const Grid = styled(GridBase)` 16 | &.MuiGrid-container { 17 | flex-grow: 1; 18 | .MuiGrid-item { 19 | display: flex; 20 | flex-direction: column; 21 | flex: 1 1 auto; 22 | } 23 | } 24 | `; 25 | 26 | const useStyles = makeStyles((theme) => ({ 27 | root: { 28 | backgroundColor: theme.palette.background.dark, 29 | height: '100%', 30 | display: 'flex', 31 | overflow: 'hidden', 32 | flexDirection: 'column' 33 | }, 34 | fullHeight: { 35 | height: '100%' 36 | }, 37 | flexFullHeight: { 38 | display: 'flex', 39 | flex: '1 1 auto' 40 | }, 41 | grow: { 42 | flexGrow: 1 43 | } 44 | })); 45 | 46 | const messages = [ 47 | { 48 | id: '5e86bcc3e1b53b6365d71638', 49 | isUnread: true, 50 | subject: 'Website redesign. Interested in collaboration', 51 | message: ` 52 | Hi Matt, I saw your work on instagram and would be interested in getting a quote for Logo and slider 53 | 54 | Integer velit massa, pharetra sed lacus eu, pulvinar faucibus ex. Ut pretium ex id turpis elementum, aliquam accumsan enim sollicitudin. Sed nec consectetur lorem, ac ullamcorper augue. Suspendisse tempus ligula suscipit finibus vehicula. Morbi viverra finibus lectus, egestas dictum mi mollis nec. Proin eget vehicula eros, sit amet molestie ipsum. Morbi feugiat, elit non placerat fringilla, leo risus tristique felis, sollicitudin tristique nibh arcu nec arcu. Maecenas vel turpis nibh. Etiam in lectus quis felis facilisis dictum. Morbi id vehicula lectus, vel imperdiet dolor. Phasellus consequat tempor tellus, quis placerat quam posuere eget. Mauris blandit, nisl eu sollicitudin tincidunt, tellus diam accumsan arcu, vel pharetra lectus est nec nisi. In sem dolor, mollis sed risus eu, mattis dictum lectus. Suspendisse urna est, finibus et urna non, tincidunt placerat eros. 55 | 56 | Donec viverra ipsum id auctor rutrum. Morbi consequat a nunc non interdum. Nulla accumsan eget felis a dictum. Cras rhoncus tortor eget velit fringilla suscipit. Donec quis arcu eu nibh aliquet auctor eget fringilla felis. Sed commodo efficitur massa. Proin maximus elit in suscipit laoreet. Integer pretium arcu ac mauris ullamcorper auctor. Vivamus tincidunt lacus eget purus feugiat tincidunt. Etiam feugiat gravida ullamcorper. Pellentesque cursus vehicula lectus et consectetur. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam ligula risus, congue eu pellentesque id, volutpat aliquam arcu. Donec efficitur ipsum id neque rhoncus viverra. Vestibulum hendrerit et eros eu bibendum. 57 | 58 | 59 | Kind regards, 60 | 61 | Ekaterina Tankova 62 | `, 63 | from: { 64 | name: 'Jose Lopez', 65 | email: 'jose@maildemo.com', 66 | }, 67 | to: [ 68 | { 69 | name: 'Gavin Lin', 70 | email: 'gavin@maildemo.com', 71 | } 72 | ], 73 | createdAt: moment() 74 | .toDate() 75 | .getTime() 76 | }, 77 | { 78 | id: '5e86bcc3e1b53b6365d71638', 79 | isUnread: true, 80 | subject: 'Website redesign. Interested in collaboration', 81 | message: ` 82 | Hi Matt, I saw your work on instagram and would be interested in getting a quote for Logo and slider 83 | 84 | Integer velit massa, pharetra sed lacus eu, pulvinar faucibus ex. Ut pretium ex id turpis elementum, aliquam accumsan enim sollicitudin. Sed nec consectetur lorem, ac ullamcorper augue. Suspendisse tempus ligula suscipit finibus vehicula. Morbi viverra finibus lectus, egestas dictum mi mollis nec. Proin eget vehicula eros, sit amet molestie ipsum. Morbi feugiat, elit non placerat fringilla, leo risus tristique felis, sollicitudin tristique nibh arcu nec arcu. Maecenas vel turpis nibh. Etiam in lectus quis felis facilisis dictum. Morbi id vehicula lectus, vel imperdiet dolor. Phasellus consequat tempor tellus, quis placerat quam posuere eget. Mauris blandit, nisl eu sollicitudin tincidunt, tellus diam accumsan arcu, vel pharetra lectus est nec nisi. In sem dolor, mollis sed risus eu, mattis dictum lectus. Suspendisse urna est, finibus et urna non, tincidunt placerat eros. 85 | 86 | Donec viverra ipsum id auctor rutrum. Morbi consequat a nunc non interdum. Nulla accumsan eget felis a dictum. Cras rhoncus tortor eget velit fringilla suscipit. Donec quis arcu eu nibh aliquet auctor eget fringilla felis. Sed commodo efficitur massa. Proin maximus elit in suscipit laoreet. Integer pretium arcu ac mauris ullamcorper auctor. Vivamus tincidunt lacus eget purus feugiat tincidunt. Etiam feugiat gravida ullamcorper. Pellentesque cursus vehicula lectus et consectetur. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam ligula risus, congue eu pellentesque id, volutpat aliquam arcu. Donec efficitur ipsum id neque rhoncus viverra. Vestibulum hendrerit et eros eu bibendum. 87 | 88 | 89 | Kind regards, 90 | 91 | Ekaterina Tankova 92 | `, 93 | from: { 94 | name: 'Jose Lopez', 95 | email: 'jose@maildemo.com', 96 | }, 97 | to: [ 98 | { 99 | name: 'Gavin Lin', 100 | email: 'gavin@maildemo.com', 101 | } 102 | ], 103 | createdAt: moment() 104 | .toDate() 105 | .getTime() 106 | }, 107 | { 108 | id: '5e86bcc3e1b53b6365d71638', 109 | isUnread: true, 110 | subject: 'Website redesign. Interested in collaboration', 111 | message: ` 112 | Hi Matt, I saw your work on instagram and would be interested in getting a quote for Logo and slider 113 | 114 | Integer velit massa, pharetra sed lacus eu, pulvinar faucibus ex. Ut pretium ex id turpis elementum, aliquam accumsan enim sollicitudin. Sed nec consectetur lorem, ac ullamcorper augue. Suspendisse tempus ligula suscipit finibus vehicula. Morbi viverra finibus lectus, egestas dictum mi mollis nec. Proin eget vehicula eros, sit amet molestie ipsum. Morbi feugiat, elit non placerat fringilla, leo risus tristique felis, sollicitudin tristique nibh arcu nec arcu. Maecenas vel turpis nibh. Etiam in lectus quis felis facilisis dictum. Morbi id vehicula lectus, vel imperdiet dolor. Phasellus consequat tempor tellus, quis placerat quam posuere eget. Mauris blandit, nisl eu sollicitudin tincidunt, tellus diam accumsan arcu, vel pharetra lectus est nec nisi. In sem dolor, mollis sed risus eu, mattis dictum lectus. Suspendisse urna est, finibus et urna non, tincidunt placerat eros. 115 | 116 | Donec viverra ipsum id auctor rutrum. Morbi consequat a nunc non interdum. Nulla accumsan eget felis a dictum. Cras rhoncus tortor eget velit fringilla suscipit. Donec quis arcu eu nibh aliquet auctor eget fringilla felis. Sed commodo efficitur massa. Proin maximus elit in suscipit laoreet. Integer pretium arcu ac mauris ullamcorper auctor. Vivamus tincidunt lacus eget purus feugiat tincidunt. Etiam feugiat gravida ullamcorper. Pellentesque cursus vehicula lectus et consectetur. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam ligula risus, congue eu pellentesque id, volutpat aliquam arcu. Donec efficitur ipsum id neque rhoncus viverra. Vestibulum hendrerit et eros eu bibendum. 117 | 118 | 119 | Kind regards, 120 | 121 | Ekaterina Tankova 122 | `, 123 | from: { 124 | name: 'Jose Lopez', 125 | email: 'jose@maildemo.com', 126 | }, 127 | to: [ 128 | { 129 | name: 'Gavin Lin', 130 | email: 'gavin@maildemo.com', 131 | } 132 | ], 133 | createdAt: moment() 134 | .toDate() 135 | .getTime() 136 | }, 137 | { 138 | id: '5e86bcc3e1b53b6365d71638', 139 | isUnread: true, 140 | subject: 'Website redesign. Interested in collaboration', 141 | message: ` 142 | Hi Matt, I saw your work on instagram and would be interested in getting a quote for Logo and slider 143 | 144 | Integer velit massa, pharetra sed lacus eu, pulvinar faucibus ex. Ut pretium ex id turpis elementum, aliquam accumsan enim sollicitudin. Sed nec consectetur lorem, ac ullamcorper augue. Suspendisse tempus ligula suscipit finibus vehicula. Morbi viverra finibus lectus, egestas dictum mi mollis nec. Proin eget vehicula eros, sit amet molestie ipsum. Morbi feugiat, elit non placerat fringilla, leo risus tristique felis, sollicitudin tristique nibh arcu nec arcu. Maecenas vel turpis nibh. Etiam in lectus quis felis facilisis dictum. Morbi id vehicula lectus, vel imperdiet dolor. Phasellus consequat tempor tellus, quis placerat quam posuere eget. Mauris blandit, nisl eu sollicitudin tincidunt, tellus diam accumsan arcu, vel pharetra lectus est nec nisi. In sem dolor, mollis sed risus eu, mattis dictum lectus. Suspendisse urna est, finibus et urna non, tincidunt placerat eros. 145 | 146 | Donec viverra ipsum id auctor rutrum. Morbi consequat a nunc non interdum. Nulla accumsan eget felis a dictum. Cras rhoncus tortor eget velit fringilla suscipit. Donec quis arcu eu nibh aliquet auctor eget fringilla felis. Sed commodo efficitur massa. Proin maximus elit in suscipit laoreet. Integer pretium arcu ac mauris ullamcorper auctor. Vivamus tincidunt lacus eget purus feugiat tincidunt. Etiam feugiat gravida ullamcorper. Pellentesque cursus vehicula lectus et consectetur. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam ligula risus, congue eu pellentesque id, volutpat aliquam arcu. Donec efficitur ipsum id neque rhoncus viverra. Vestibulum hendrerit et eros eu bibendum. 147 | 148 | 149 | Kind regards, 150 | 151 | Ekaterina Tankova 152 | `, 153 | from: { 154 | name: 'Jose Lopez', 155 | email: 'jose@maildemo.com', 156 | }, 157 | to: [ 158 | { 159 | name: 'Gavin Lin', 160 | email: 'gavin@maildemo.com', 161 | } 162 | ], 163 | createdAt: moment() 164 | .toDate() 165 | .getTime() 166 | }, 167 | { 168 | id: '5e86bcc3e1b53b6365d71638', 169 | isUnread: true, 170 | subject: 'Website redesign. Interested in collaboration', 171 | message: ` 172 | Hi Matt, I saw your work on instagram and would be interested in getting a quote for Logo and slider 173 | 174 | Integer velit massa, pharetra sed lacus eu, pulvinar faucibus ex. Ut pretium ex id turpis elementum, aliquam accumsan enim sollicitudin. Sed nec consectetur lorem, ac ullamcorper augue. Suspendisse tempus ligula suscipit finibus vehicula. Morbi viverra finibus lectus, egestas dictum mi mollis nec. Proin eget vehicula eros, sit amet molestie ipsum. Morbi feugiat, elit non placerat fringilla, leo risus tristique felis, sollicitudin tristique nibh arcu nec arcu. Maecenas vel turpis nibh. Etiam in lectus quis felis facilisis dictum. Morbi id vehicula lectus, vel imperdiet dolor. Phasellus consequat tempor tellus, quis placerat quam posuere eget. Mauris blandit, nisl eu sollicitudin tincidunt, tellus diam accumsan arcu, vel pharetra lectus est nec nisi. In sem dolor, mollis sed risus eu, mattis dictum lectus. Suspendisse urna est, finibus et urna non, tincidunt placerat eros. 175 | 176 | Donec viverra ipsum id auctor rutrum. Morbi consequat a nunc non interdum. Nulla accumsan eget felis a dictum. Cras rhoncus tortor eget velit fringilla suscipit. Donec quis arcu eu nibh aliquet auctor eget fringilla felis. Sed commodo efficitur massa. Proin maximus elit in suscipit laoreet. Integer pretium arcu ac mauris ullamcorper auctor. Vivamus tincidunt lacus eget purus feugiat tincidunt. Etiam feugiat gravida ullamcorper. Pellentesque cursus vehicula lectus et consectetur. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam ligula risus, congue eu pellentesque id, volutpat aliquam arcu. Donec efficitur ipsum id neque rhoncus viverra. Vestibulum hendrerit et eros eu bibendum. 177 | 178 | 179 | Kind regards, 180 | 181 | Ekaterina Tankova 182 | `, 183 | from: { 184 | name: 'Jose Lopez', 185 | email: 'jose@maildemo.com', 186 | }, 187 | to: [ 188 | { 189 | name: 'Gavin Lin', 190 | email: 'gavin@maildemo.com', 191 | } 192 | ], 193 | createdAt: moment() 194 | .toDate() 195 | .getTime() 196 | }, 197 | { 198 | id: '5e86bcc3e1b53b6365d71638', 199 | isUnread: true, 200 | subject: 'Website redesign. Interested in collaboration', 201 | message: ` 202 | Hi Matt, I saw your work on instagram and would be interested in getting a quote for Logo and slider 203 | 204 | Integer velit massa, pharetra sed lacus eu, pulvinar faucibus ex. Ut pretium ex id turpis elementum, aliquam accumsan enim sollicitudin. Sed nec consectetur lorem, ac ullamcorper augue. Suspendisse tempus ligula suscipit finibus vehicula. Morbi viverra finibus lectus, egestas dictum mi mollis nec. Proin eget vehicula eros, sit amet molestie ipsum. Morbi feugiat, elit non placerat fringilla, leo risus tristique felis, sollicitudin tristique nibh arcu nec arcu. Maecenas vel turpis nibh. Etiam in lectus quis felis facilisis dictum. Morbi id vehicula lectus, vel imperdiet dolor. Phasellus consequat tempor tellus, quis placerat quam posuere eget. Mauris blandit, nisl eu sollicitudin tincidunt, tellus diam accumsan arcu, vel pharetra lectus est nec nisi. In sem dolor, mollis sed risus eu, mattis dictum lectus. Suspendisse urna est, finibus et urna non, tincidunt placerat eros. 205 | 206 | Donec viverra ipsum id auctor rutrum. Morbi consequat a nunc non interdum. Nulla accumsan eget felis a dictum. Cras rhoncus tortor eget velit fringilla suscipit. Donec quis arcu eu nibh aliquet auctor eget fringilla felis. Sed commodo efficitur massa. Proin maximus elit in suscipit laoreet. Integer pretium arcu ac mauris ullamcorper auctor. Vivamus tincidunt lacus eget purus feugiat tincidunt. Etiam feugiat gravida ullamcorper. Pellentesque cursus vehicula lectus et consectetur. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam ligula risus, congue eu pellentesque id, volutpat aliquam arcu. Donec efficitur ipsum id neque rhoncus viverra. Vestibulum hendrerit et eros eu bibendum. 207 | 208 | 209 | Kind regards, 210 | 211 | Ekaterina Tankova 212 | `, 213 | from: { 214 | name: 'Jose Lopez', 215 | email: 'jose@maildemo.com', 216 | }, 217 | to: [ 218 | { 219 | name: 'Gavin Lin', 220 | email: 'gavin@maildemo.com', 221 | } 222 | ], 223 | createdAt: moment() 224 | .toDate() 225 | .getTime() 226 | }, 227 | { 228 | id: '5e86bcc3e1b53b6365d71638', 229 | isUnread: true, 230 | subject: 'Website redesign. Interested in collaboration', 231 | message: ` 232 | Hi Matt, I saw your work on instagram and would be interested in getting a quote for Logo and slider 233 | 234 | Integer velit massa, pharetra sed lacus eu, pulvinar faucibus ex. Ut pretium ex id turpis elementum, aliquam accumsan enim sollicitudin. Sed nec consectetur lorem, ac ullamcorper augue. Suspendisse tempus ligula suscipit finibus vehicula. Morbi viverra finibus lectus, egestas dictum mi mollis nec. Proin eget vehicula eros, sit amet molestie ipsum. Morbi feugiat, elit non placerat fringilla, leo risus tristique felis, sollicitudin tristique nibh arcu nec arcu. Maecenas vel turpis nibh. Etiam in lectus quis felis facilisis dictum. Morbi id vehicula lectus, vel imperdiet dolor. Phasellus consequat tempor tellus, quis placerat quam posuere eget. Mauris blandit, nisl eu sollicitudin tincidunt, tellus diam accumsan arcu, vel pharetra lectus est nec nisi. In sem dolor, mollis sed risus eu, mattis dictum lectus. Suspendisse urna est, finibus et urna non, tincidunt placerat eros. 235 | 236 | Donec viverra ipsum id auctor rutrum. Morbi consequat a nunc non interdum. Nulla accumsan eget felis a dictum. Cras rhoncus tortor eget velit fringilla suscipit. Donec quis arcu eu nibh aliquet auctor eget fringilla felis. Sed commodo efficitur massa. Proin maximus elit in suscipit laoreet. Integer pretium arcu ac mauris ullamcorper auctor. Vivamus tincidunt lacus eget purus feugiat tincidunt. Etiam feugiat gravida ullamcorper. Pellentesque cursus vehicula lectus et consectetur. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam ligula risus, congue eu pellentesque id, volutpat aliquam arcu. Donec efficitur ipsum id neque rhoncus viverra. Vestibulum hendrerit et eros eu bibendum. 237 | 238 | 239 | Kind regards, 240 | 241 | Ekaterina Tankova 242 | `, 243 | from: { 244 | name: 'Jose Lopez', 245 | email: 'jose@maildemo.com', 246 | }, 247 | to: [ 248 | { 249 | name: 'Gavin Lin', 250 | email: 'gavin@maildemo.com', 251 | } 252 | ], 253 | createdAt: moment() 254 | .toDate() 255 | .getTime() 256 | }, 257 | { 258 | id: '5e86bcc3e1b53b6365d71638', 259 | isUnread: true, 260 | subject: 'Website redesign. Interested in collaboration', 261 | message: ` 262 | Hi Matt, I saw your work on instagram and would be interested in getting a quote for Logo and slider 263 | 264 | Integer velit massa, pharetra sed lacus eu, pulvinar faucibus ex. Ut pretium ex id turpis elementum, aliquam accumsan enim sollicitudin. Sed nec consectetur lorem, ac ullamcorper augue. Suspendisse tempus ligula suscipit finibus vehicula. Morbi viverra finibus lectus, egestas dictum mi mollis nec. Proin eget vehicula eros, sit amet molestie ipsum. Morbi feugiat, elit non placerat fringilla, leo risus tristique felis, sollicitudin tristique nibh arcu nec arcu. Maecenas vel turpis nibh. Etiam in lectus quis felis facilisis dictum. Morbi id vehicula lectus, vel imperdiet dolor. Phasellus consequat tempor tellus, quis placerat quam posuere eget. Mauris blandit, nisl eu sollicitudin tincidunt, tellus diam accumsan arcu, vel pharetra lectus est nec nisi. In sem dolor, mollis sed risus eu, mattis dictum lectus. Suspendisse urna est, finibus et urna non, tincidunt placerat eros. 265 | 266 | Donec viverra ipsum id auctor rutrum. Morbi consequat a nunc non interdum. Nulla accumsan eget felis a dictum. Cras rhoncus tortor eget velit fringilla suscipit. Donec quis arcu eu nibh aliquet auctor eget fringilla felis. Sed commodo efficitur massa. Proin maximus elit in suscipit laoreet. Integer pretium arcu ac mauris ullamcorper auctor. Vivamus tincidunt lacus eget purus feugiat tincidunt. Etiam feugiat gravida ullamcorper. Pellentesque cursus vehicula lectus et consectetur. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam ligula risus, congue eu pellentesque id, volutpat aliquam arcu. Donec efficitur ipsum id neque rhoncus viverra. Vestibulum hendrerit et eros eu bibendum. 267 | 268 | 269 | Kind regards, 270 | 271 | Ekaterina Tankova 272 | `, 273 | from: { 274 | name: 'Jose Lopez', 275 | email: 'jose@maildemo.com', 276 | }, 277 | to: [ 278 | { 279 | name: 'Gavin Lin', 280 | email: 'gavin@maildemo.com', 281 | } 282 | ], 283 | createdAt: moment() 284 | .toDate() 285 | .getTime() 286 | }, 287 | { 288 | id: '5e86bcc3e1b53b6365d71638', 289 | isUnread: true, 290 | subject: 'Website redesign. Interested in collaboration', 291 | message: ` 292 | Hi Matt, I saw your work on instagram and would be interested in getting a quote for Logo and slider 293 | 294 | Integer velit massa, pharetra sed lacus eu, pulvinar faucibus ex. Ut pretium ex id turpis elementum, aliquam accumsan enim sollicitudin. Sed nec consectetur lorem, ac ullamcorper augue. Suspendisse tempus ligula suscipit finibus vehicula. Morbi viverra finibus lectus, egestas dictum mi mollis nec. Proin eget vehicula eros, sit amet molestie ipsum. Morbi feugiat, elit non placerat fringilla, leo risus tristique felis, sollicitudin tristique nibh arcu nec arcu. Maecenas vel turpis nibh. Etiam in lectus quis felis facilisis dictum. Morbi id vehicula lectus, vel imperdiet dolor. Phasellus consequat tempor tellus, quis placerat quam posuere eget. Mauris blandit, nisl eu sollicitudin tincidunt, tellus diam accumsan arcu, vel pharetra lectus est nec nisi. In sem dolor, mollis sed risus eu, mattis dictum lectus. Suspendisse urna est, finibus et urna non, tincidunt placerat eros. 295 | 296 | Donec viverra ipsum id auctor rutrum. Morbi consequat a nunc non interdum. Nulla accumsan eget felis a dictum. Cras rhoncus tortor eget velit fringilla suscipit. Donec quis arcu eu nibh aliquet auctor eget fringilla felis. Sed commodo efficitur massa. Proin maximus elit in suscipit laoreet. Integer pretium arcu ac mauris ullamcorper auctor. Vivamus tincidunt lacus eget purus feugiat tincidunt. Etiam feugiat gravida ullamcorper. Pellentesque cursus vehicula lectus et consectetur. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam ligula risus, congue eu pellentesque id, volutpat aliquam arcu. Donec efficitur ipsum id neque rhoncus viverra. Vestibulum hendrerit et eros eu bibendum. 297 | 298 | 299 | Kind regards, 300 | 301 | Ekaterina Tankova 302 | `, 303 | from: { 304 | name: 'Jose Lopez', 305 | email: 'jose@maildemo.com', 306 | }, 307 | to: [ 308 | { 309 | name: 'Gavin Lin', 310 | email: 'gavin@maildemo.com', 311 | } 312 | ], 313 | createdAt: moment() 314 | .toDate() 315 | .getTime() 316 | }, 317 | { 318 | id: '5e86bcc3e1b53b6365d71638', 319 | isUnread: true, 320 | subject: 'Website redesign. Interested in collaboration', 321 | message: ` 322 | Hi Matt, I saw your work on instagram and would be interested in getting a quote for Logo and slider 323 | 324 | Integer velit massa, pharetra sed lacus eu, pulvinar faucibus ex. Ut pretium ex id turpis elementum, aliquam accumsan enim sollicitudin. Sed nec consectetur lorem, ac ullamcorper augue. Suspendisse tempus ligula suscipit finibus vehicula. Morbi viverra finibus lectus, egestas dictum mi mollis nec. Proin eget vehicula eros, sit amet molestie ipsum. Morbi feugiat, elit non placerat fringilla, leo risus tristique felis, sollicitudin tristique nibh arcu nec arcu. Maecenas vel turpis nibh. Etiam in lectus quis felis facilisis dictum. Morbi id vehicula lectus, vel imperdiet dolor. Phasellus consequat tempor tellus, quis placerat quam posuere eget. Mauris blandit, nisl eu sollicitudin tincidunt, tellus diam accumsan arcu, vel pharetra lectus est nec nisi. In sem dolor, mollis sed risus eu, mattis dictum lectus. Suspendisse urna est, finibus et urna non, tincidunt placerat eros. 325 | 326 | Donec viverra ipsum id auctor rutrum. Morbi consequat a nunc non interdum. Nulla accumsan eget felis a dictum. Cras rhoncus tortor eget velit fringilla suscipit. Donec quis arcu eu nibh aliquet auctor eget fringilla felis. Sed commodo efficitur massa. Proin maximus elit in suscipit laoreet. Integer pretium arcu ac mauris ullamcorper auctor. Vivamus tincidunt lacus eget purus feugiat tincidunt. Etiam feugiat gravida ullamcorper. Pellentesque cursus vehicula lectus et consectetur. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam ligula risus, congue eu pellentesque id, volutpat aliquam arcu. Donec efficitur ipsum id neque rhoncus viverra. Vestibulum hendrerit et eros eu bibendum. 327 | 328 | 329 | Kind regards, 330 | 331 | Ekaterina Tankova 332 | `, 333 | from: { 334 | name: 'Jose Lopez', 335 | email: 'jose@maildemo.com', 336 | }, 337 | to: [ 338 | { 339 | name: 'Gavin Lin', 340 | email: 'gavin@maildemo.com', 341 | } 342 | ], 343 | createdAt: moment() 344 | .toDate() 345 | .getTime() 346 | }, 347 | { 348 | id: '5e86bcc3e1b53b6365d71638', 349 | isUnread: true, 350 | subject: 'Website redesign. Interested in collaboration', 351 | message: ` 352 | Hi Matt, I saw your work on instagram and would be interested in getting a quote for Logo and slider 353 | 354 | Integer velit massa, pharetra sed lacus eu, pulvinar faucibus ex. Ut pretium ex id turpis elementum, aliquam accumsan enim sollicitudin. Sed nec consectetur lorem, ac ullamcorper augue. Suspendisse tempus ligula suscipit finibus vehicula. Morbi viverra finibus lectus, egestas dictum mi mollis nec. Proin eget vehicula eros, sit amet molestie ipsum. Morbi feugiat, elit non placerat fringilla, leo risus tristique felis, sollicitudin tristique nibh arcu nec arcu. Maecenas vel turpis nibh. Etiam in lectus quis felis facilisis dictum. Morbi id vehicula lectus, vel imperdiet dolor. Phasellus consequat tempor tellus, quis placerat quam posuere eget. Mauris blandit, nisl eu sollicitudin tincidunt, tellus diam accumsan arcu, vel pharetra lectus est nec nisi. In sem dolor, mollis sed risus eu, mattis dictum lectus. Suspendisse urna est, finibus et urna non, tincidunt placerat eros. 355 | 356 | Donec viverra ipsum id auctor rutrum. Morbi consequat a nunc non interdum. Nulla accumsan eget felis a dictum. Cras rhoncus tortor eget velit fringilla suscipit. Donec quis arcu eu nibh aliquet auctor eget fringilla felis. Sed commodo efficitur massa. Proin maximus elit in suscipit laoreet. Integer pretium arcu ac mauris ullamcorper auctor. Vivamus tincidunt lacus eget purus feugiat tincidunt. Etiam feugiat gravida ullamcorper. Pellentesque cursus vehicula lectus et consectetur. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam ligula risus, congue eu pellentesque id, volutpat aliquam arcu. Donec efficitur ipsum id neque rhoncus viverra. Vestibulum hendrerit et eros eu bibendum. 357 | 358 | 359 | Kind regards, 360 | 361 | Ekaterina Tankova 362 | `, 363 | from: { 364 | name: 'Jose Lopez', 365 | email: 'jose@maildemo.com', 366 | }, 367 | to: [ 368 | { 369 | name: 'Gavin Lin', 370 | email: 'gavin@maildemo.com', 371 | } 372 | ], 373 | createdAt: moment() 374 | .toDate() 375 | .getTime() 376 | }, 377 | { 378 | id: '5e86bcc3e1b53b6365d71638', 379 | isUnread: true, 380 | subject: 'Website redesign. Interested in collaboration', 381 | message: ` 382 | Hi Matt, I saw your work on instagram and would be interested in getting a quote for Logo and slider 383 | 384 | Integer velit massa, pharetra sed lacus eu, pulvinar faucibus ex. Ut pretium ex id turpis elementum, aliquam accumsan enim sollicitudin. Sed nec consectetur lorem, ac ullamcorper augue. Suspendisse tempus ligula suscipit finibus vehicula. Morbi viverra finibus lectus, egestas dictum mi mollis nec. Proin eget vehicula eros, sit amet molestie ipsum. Morbi feugiat, elit non placerat fringilla, leo risus tristique felis, sollicitudin tristique nibh arcu nec arcu. Maecenas vel turpis nibh. Etiam in lectus quis felis facilisis dictum. Morbi id vehicula lectus, vel imperdiet dolor. Phasellus consequat tempor tellus, quis placerat quam posuere eget. Mauris blandit, nisl eu sollicitudin tincidunt, tellus diam accumsan arcu, vel pharetra lectus est nec nisi. In sem dolor, mollis sed risus eu, mattis dictum lectus. Suspendisse urna est, finibus et urna non, tincidunt placerat eros. 385 | 386 | Donec viverra ipsum id auctor rutrum. Morbi consequat a nunc non interdum. Nulla accumsan eget felis a dictum. Cras rhoncus tortor eget velit fringilla suscipit. Donec quis arcu eu nibh aliquet auctor eget fringilla felis. Sed commodo efficitur massa. Proin maximus elit in suscipit laoreet. Integer pretium arcu ac mauris ullamcorper auctor. Vivamus tincidunt lacus eget purus feugiat tincidunt. Etiam feugiat gravida ullamcorper. Pellentesque cursus vehicula lectus et consectetur. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam ligula risus, congue eu pellentesque id, volutpat aliquam arcu. Donec efficitur ipsum id neque rhoncus viverra. Vestibulum hendrerit et eros eu bibendum. 387 | 388 | 389 | Kind regards, 390 | 391 | Ekaterina Tankova 392 | `, 393 | from: { 394 | name: 'Jose Lopez', 395 | email: 'jose@maildemo.com', 396 | }, 397 | to: [ 398 | { 399 | name: 'Gavin Lin', 400 | email: 'gavin@maildemo.com', 401 | } 402 | ], 403 | createdAt: moment() 404 | .toDate() 405 | .getTime() 406 | }, 407 | { 408 | id: '5e86bcc3e1b53b6365d71638', 409 | isUnread: true, 410 | subject: 'Website redesign. Interested in collaboration', 411 | message: ` 412 | Hi Matt, I saw your work on instagram and would be interested in getting a quote for Logo and slider 413 | 414 | Integer velit massa, pharetra sed lacus eu, pulvinar faucibus ex. Ut pretium ex id turpis elementum, aliquam accumsan enim sollicitudin. Sed nec consectetur lorem, ac ullamcorper augue. Suspendisse tempus ligula suscipit finibus vehicula. Morbi viverra finibus lectus, egestas dictum mi mollis nec. Proin eget vehicula eros, sit amet molestie ipsum. Morbi feugiat, elit non placerat fringilla, leo risus tristique felis, sollicitudin tristique nibh arcu nec arcu. Maecenas vel turpis nibh. Etiam in lectus quis felis facilisis dictum. Morbi id vehicula lectus, vel imperdiet dolor. Phasellus consequat tempor tellus, quis placerat quam posuere eget. Mauris blandit, nisl eu sollicitudin tincidunt, tellus diam accumsan arcu, vel pharetra lectus est nec nisi. In sem dolor, mollis sed risus eu, mattis dictum lectus. Suspendisse urna est, finibus et urna non, tincidunt placerat eros. 415 | 416 | Donec viverra ipsum id auctor rutrum. Morbi consequat a nunc non interdum. Nulla accumsan eget felis a dictum. Cras rhoncus tortor eget velit fringilla suscipit. Donec quis arcu eu nibh aliquet auctor eget fringilla felis. Sed commodo efficitur massa. Proin maximus elit in suscipit laoreet. Integer pretium arcu ac mauris ullamcorper auctor. Vivamus tincidunt lacus eget purus feugiat tincidunt. Etiam feugiat gravida ullamcorper. Pellentesque cursus vehicula lectus et consectetur. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam ligula risus, congue eu pellentesque id, volutpat aliquam arcu. Donec efficitur ipsum id neque rhoncus viverra. Vestibulum hendrerit et eros eu bibendum. 417 | 418 | 419 | Kind regards, 420 | 421 | Ekaterina Tankova 422 | `, 423 | from: { 424 | name: 'Jose Lopez', 425 | email: 'jose@maildemo.com', 426 | }, 427 | to: [ 428 | { 429 | name: 'Gavin Lin', 430 | email: 'gavin@maildemo.com', 431 | } 432 | ], 433 | createdAt: moment() 434 | .toDate() 435 | .getTime() 436 | }, 437 | { 438 | id: '5e86bcc3e1b53b6365d71638', 439 | isUnread: true, 440 | subject: 'Website redesign. Interested in collaboration', 441 | message: ` 442 | Hi Matt, I saw your work on instagram and would be interested in getting a quote for Logo and slider 443 | 444 | Integer velit massa, pharetra sed lacus eu, pulvinar faucibus ex. Ut pretium ex id turpis elementum, aliquam accumsan enim sollicitudin. Sed nec consectetur lorem, ac ullamcorper augue. Suspendisse tempus ligula suscipit finibus vehicula. Morbi viverra finibus lectus, egestas dictum mi mollis nec. Proin eget vehicula eros, sit amet molestie ipsum. Morbi feugiat, elit non placerat fringilla, leo risus tristique felis, sollicitudin tristique nibh arcu nec arcu. Maecenas vel turpis nibh. Etiam in lectus quis felis facilisis dictum. Morbi id vehicula lectus, vel imperdiet dolor. Phasellus consequat tempor tellus, quis placerat quam posuere eget. Mauris blandit, nisl eu sollicitudin tincidunt, tellus diam accumsan arcu, vel pharetra lectus est nec nisi. In sem dolor, mollis sed risus eu, mattis dictum lectus. Suspendisse urna est, finibus et urna non, tincidunt placerat eros. 445 | 446 | Donec viverra ipsum id auctor rutrum. Morbi consequat a nunc non interdum. Nulla accumsan eget felis a dictum. Cras rhoncus tortor eget velit fringilla suscipit. Donec quis arcu eu nibh aliquet auctor eget fringilla felis. Sed commodo efficitur massa. Proin maximus elit in suscipit laoreet. Integer pretium arcu ac mauris ullamcorper auctor. Vivamus tincidunt lacus eget purus feugiat tincidunt. Etiam feugiat gravida ullamcorper. Pellentesque cursus vehicula lectus et consectetur. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam ligula risus, congue eu pellentesque id, volutpat aliquam arcu. Donec efficitur ipsum id neque rhoncus viverra. Vestibulum hendrerit et eros eu bibendum. 447 | 448 | 449 | Kind regards, 450 | 451 | Ekaterina Tankova 452 | `, 453 | from: { 454 | name: 'Jose Lopez', 455 | email: 'jose@maildemo.com', 456 | }, 457 | to: [ 458 | { 459 | name: 'Gavin Lin', 460 | email: 'gavin@maildemo.com', 461 | } 462 | ], 463 | createdAt: moment() 464 | .toDate() 465 | .getTime() 466 | }, 467 | { 468 | id: '5e86bcbd8406cd3055f2b6c8', 469 | isUnread: false, 470 | subject: 'Amazing work', 471 | message: ` 472 | Hey, nice projects! I really liked the one in react. What's your quote on kinda similar project? 473 | `, 474 | from: { 475 | name: 'Jose Lopez', 476 | email: 'jose@maildemo.com' 477 | }, 478 | to: [ 479 | { 480 | name: 'Gavin Lin', 481 | email: 'gavin@maildemo.com' 482 | } 483 | ], 484 | createdAt: moment() 485 | .toDate() 486 | .getTime() 487 | }, 488 | { 489 | id: '5e86bcb9fee1ec12453fa13b', 490 | folder: 'inbox', 491 | isImportant: false, 492 | isStarred: false, 493 | isUnread: false, 494 | labelIds: ['5e892628d4bc60b4514d5d36'], 495 | subject: 'Flight reminder', 496 | message: ` 497 | Dear Shen, Your flight is coming up soon. Please don’t forget to check in for your scheduled flight. 498 | `, 499 | from: { 500 | name: 'Jose Lopez', 501 | email: 'jose@maildemo.com' 502 | }, 503 | to: [ 504 | { 505 | name: 'Gavin Lin', 506 | email: 'gavin@maildemo.com' 507 | } 508 | ], 509 | createdAt: moment() 510 | .toDate() 511 | .getTime() 512 | }, 513 | { 514 | id: '5e86bcb5575181a5e527e24f', 515 | isUnread: true, 516 | subject: 'Posible candidates for the position', 517 | message: ` 518 | My market leading client has another fantastic opportunity for an experienced Software Developer to join them on a heavily remote basis 519 | `, 520 | from: { 521 | name: 'Rebeca Mejia', 522 | email: 'rebeca@maildemo.com' 523 | }, 524 | to: [ 525 | { 526 | name: 'Gavin Lin', 527 | email: 'gavin@maildemo.com' 528 | } 529 | ], 530 | createdAt: moment() 531 | .toDate() 532 | .getTime() 533 | } 534 | ]; 535 | 536 | const Index = ({ 537 | ...rest 538 | }) => { 539 | const classes = useStyles(); 540 | // const [messages, setMessages] = useState([]); 541 | 542 | return ( 543 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | 554 | 555 | 556 | 557 | 558 | 559 | ); 560 | }; 561 | 562 | export default Index; 563 | --------------------------------------------------------------------------------