├── .env ├── src ├── react-app-env.d.ts ├── components │ ├── portfolio │ │ ├── grid.module.css │ │ ├── GridComponent.jsx │ │ └── index.jsx │ ├── about │ │ └── index.jsx │ ├── home │ │ └── index.jsx │ ├── WarningMessage │ │ ├── warningmessage.module.css │ │ └── index.jsx │ ├── NavBar │ │ ├── navbar.module.css │ │ └── index.jsx │ ├── Footer │ │ ├── footer.module.css │ │ └── index.jsx │ └── detail │ │ ├── masterdetail.module.css │ │ ├── MasterDetailSideBarTab.jsx │ │ ├── MasterDetailPage.jsx │ │ └── index.jsx ├── images │ ├── GreyBox.svg │ └── GreyAvatar.svg ├── App.test.js ├── constants.js ├── index.jsx ├── App.css ├── App.jsx └── registerServiceWorker.js ├── public ├── favicon.ico ├── robots.txt ├── manifest.json └── index.html ├── .editorconfig ├── server ├── constants.js ├── package.json ├── routes │ └── index.js ├── app.js ├── server.js └── sampleData.js ├── .gitignore ├── tsconfig.json ├── package.json └── README.md /.env: -------------------------------------------------------------------------------- 1 | BROWSER=none 2 | -------------------------------------------------------------------------------- /src/react-app-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/plutonurmux/react_express_app/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: /static/ 4 | -------------------------------------------------------------------------------- /src/components/portfolio/grid.module.css: -------------------------------------------------------------------------------- 1 | .header { 2 | background-color: #cecece; 3 | padding-top: 7rem; 4 | padding-bottom: 7rem; 5 | } 6 | -------------------------------------------------------------------------------- /src/components/about/index.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export default function Blank() { 4 | return
; 5 | } 6 | -------------------------------------------------------------------------------- /src/components/home/index.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export default function Blank() { 4 | return
; 5 | } 6 | -------------------------------------------------------------------------------- /src/components/WarningMessage/warningmessage.module.css: -------------------------------------------------------------------------------- 1 | .warningPosition { 2 | position: fixed !important; 3 | bottom: 0; 4 | left: 0; 5 | z-index: 1030; 6 | } 7 | -------------------------------------------------------------------------------- /src/images/GreyBox.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = crlf 5 | charset = utf-8 6 | indent_size = 2 7 | indent_style = space 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /server/constants.js: -------------------------------------------------------------------------------- 1 | const CONSTANTS = {}; 2 | CONSTANTS.ENDPOINT = {}; 3 | 4 | CONSTANTS.PORT = process.env.PORT || "3001"; 5 | CONSTANTS.ENDPOINT.MASTERDETAIL = "/masterdetail"; 6 | 7 | CONSTANTS.ENDPOINT.GRID = "/grid"; 8 | 9 | 10 | module.exports = CONSTANTS; 11 | -------------------------------------------------------------------------------- /src/components/NavBar/navbar.module.css: -------------------------------------------------------------------------------- 1 | .skipLink a { 2 | position: absolute; 3 | left: -100px; 4 | top: -100px; 5 | } 6 | 7 | .skipLink a:focus { 8 | position: fixed; 9 | z-index: 1000; 10 | top: 0; 11 | left: 0; 12 | padding: 10px; 13 | color: #ffffff; 14 | background: #000000; 15 | } 16 | -------------------------------------------------------------------------------- /src/components/Footer/footer.module.css: -------------------------------------------------------------------------------- 1 | .footer { 2 | background-color: #1d1d1d; 3 | padding-top: 2rem; 4 | padding-bottom: 4rem; 5 | } 6 | 7 | .title { 8 | color: #fff; 9 | } 10 | 11 | .description { 12 | color: #fff; 13 | } 14 | 15 | .footerlink, 16 | .footerlink:hover { 17 | color: #fff; 18 | } 19 | -------------------------------------------------------------------------------- /src/images/GreyAvatar.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom' 3 | import {BrowserRouter} from 'react-router-dom' 4 | 5 | import App from './App' 6 | 7 | it('renders without crashing', () => { 8 | const div = document.createElement('div') 9 | 10 | ReactDOM.render( 11 | 12 | 13 | , 14 | div 15 | ) 16 | }) 17 | -------------------------------------------------------------------------------- /src/components/portfolio/GridComponent.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export default function GridComponent(props) { 4 | const { image, header, description } = props; 5 | return ( 6 |
7 | Default Grey Box 8 |

{header}

9 |

{description}

10 |
11 | ); 12 | } 13 | -------------------------------------------------------------------------------- /.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 | /server/build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /src/constants.js: -------------------------------------------------------------------------------- 1 | const CONSTANTS = {} 2 | 3 | CONSTANTS.ERROR_MESSAGE = {} 4 | 5 | CONSTANTS.ERROR_MESSAGE.GRID_GET = 'Request to get grid text failed:' 6 | 7 | CONSTANTS.ERROR_MESSAGE.MASTERDETAIL_GET = 'Request to get master detail text failed:' 8 | 9 | CONSTANTS.ENDPOINT = {} 10 | 11 | CONSTANTS.ENDPOINT.GRID = '/api/grid' 12 | 13 | CONSTANTS.ENDPOINT.MASTERDETAIL = '/api/masterdetail' 14 | 15 | export default CONSTANTS 16 | -------------------------------------------------------------------------------- /src/components/detail/masterdetail.module.css: -------------------------------------------------------------------------------- 1 | .sidebar { 2 | /* full height - footer height - navbar height */ 3 | min-height: calc(100vh - 160px - 57px); 4 | } 5 | .sidebarText { 6 | font-weight: 500; 7 | } 8 | 9 | .title { 10 | font-weight: 700; 11 | margin-bottom: 0; 12 | } 13 | 14 | .breadCrumbLink { 15 | color: #025fce; 16 | } 17 | 18 | .heading { 19 | background-color: #cecece; 20 | padding-top: 18em; 21 | } 22 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "react-express-app", 3 | "name": "Awesome and super-simple app with React front-end and Express back-end.", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": ".", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-express-app", 3 | "version": "0.0.0", 4 | "private": false, 5 | "license": "MIT", 6 | "scripts": { 7 | "start": "node ./server.js" 8 | }, 9 | "dependencies": { 10 | "cookie-parser": "~1.4.4", 11 | "debug": "~2.6.9", 12 | "express": "~4.17.1", 13 | "http-errors": "~1.7.3", 14 | "morgan": "~1.9.1" 15 | }, 16 | "engines": { 17 | "node": ">=10.14.1" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom' 3 | import { BrowserRouter } from 'react-router-dom' 4 | 5 | import registerServiceWorker from './registerServiceWorker' 6 | 7 | import App from './App' 8 | 9 | import 'bootstrap/dist/css/bootstrap.min.css' 10 | 11 | ReactDOM.render( 12 | 13 | 14 | , 15 | document.getElementById('root') 16 | ) 17 | 18 | registerServiceWorker() 19 | -------------------------------------------------------------------------------- /server/routes/index.js: -------------------------------------------------------------------------------- 1 | const express = require('express') 2 | 3 | const CONSTANTS = require('../constants') 4 | 5 | const sampleData = require('../sampleData') 6 | 7 | 8 | const router = express.Router() 9 | // MasterDetail Page Endpoint 10 | router.get(CONSTANTS.ENDPOINT.MASTERDETAIL, (req, res) => { 11 | res.json(sampleData.textAssets) 12 | }) 13 | 14 | // Grid Page Endpoint 15 | router.get(CONSTANTS.ENDPOINT.GRID, (req, res) => { 16 | res.json(sampleData.textAssets) 17 | }) 18 | 19 | 20 | module.exports = router 21 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": [ 5 | "dom", 6 | "dom.iterable", 7 | "esnext" 8 | ], 9 | "allowJs": true, 10 | "skipLibCheck": true, 11 | "esModuleInterop": true, 12 | "allowSyntheticDefaultImports": true, 13 | "strict": true, 14 | "forceConsistentCasingInFileNames": true, 15 | "module": "esnext", 16 | "moduleResolution": "node", 17 | "resolveJsonModule": true, 18 | "isolatedModules": true, 19 | "noEmit": true, 20 | "jsx": "react" 21 | }, 22 | "include": [ 23 | "src" 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /src/App.css: -------------------------------------------------------------------------------- 1 | html { 2 | box-sizing: border-box; 3 | position: relative; 4 | min-height: 100%; 5 | } 6 | 7 | *, 8 | *::before, 9 | *::after { 10 | box-sizing: inherit; 11 | } 12 | 13 | body { 14 | margin-bottom: 160px !important; /* Height of the footer */ 15 | padding: 0; 16 | } 17 | 18 | footer { 19 | position: absolute; 20 | bottom: 0; 21 | width: 100%; 22 | height: 160px; /* Set the fixed height of the footer here */ 23 | } 24 | 25 | /* Override Bootstrap Styling */ 26 | 27 | .btn-primary { 28 | background-color: #025fce !important; 29 | } 30 | 31 | button:focus, 32 | button:active { 33 | outline: none !important; 34 | box-shadow: none !important; 35 | } 36 | -------------------------------------------------------------------------------- /src/components/detail/MasterDetailSideBarTab.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import classnames from "classnames"; 3 | import styles from "./masterdetail.module.css"; 4 | 5 | export default function MasterDetailSideBarTab(props) { 6 | const { index, image, tabText, onDisplayTabClick } = props; 7 | return ( 8 | 20 | ); 21 | } 22 | -------------------------------------------------------------------------------- /src/components/WarningMessage/index.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import classnames from "classnames"; 3 | import styles from "./warningmessage.module.css"; 4 | 5 | // A pop up message used to warn users about failed API calls to the back end 6 | export default function index(props) { 7 | const { open, text, onWarningClose } = props; 8 | return ( 9 | 10 | {open && ( 11 |
20 | {text} 21 | 28 |
29 | )} 30 |
31 | ); 32 | } 33 | -------------------------------------------------------------------------------- /src/App.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import { Route, Switch, Redirect } from 'react-router-dom' 3 | 4 | import './App.css' 5 | 6 | import NavBar from './components/NavBar' 7 | import Footer from './components/Footer' 8 | 9 | import home from './components/home' 10 | import portfolio from './components/portfolio' 11 | import detail from './components/detail' 12 | import about from './components/about' 13 | 14 | // Add routes for your new pages here. 15 | class App extends Component { 16 | render() { 17 | return ( 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 |