Adding some more controls & other clean-up
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"expoServerPort": 19000,
|
"expoServerPort": 19000,
|
||||||
"packagerPort": 19001,
|
"packagerPort": 19001,
|
||||||
"packagerPid": 7732
|
"packagerPid": 44581
|
||||||
}
|
}
|
||||||
42
website/package-lock.json
generated
@@ -1759,6 +1759,11 @@
|
|||||||
"hoek": "4.2.0"
|
"hoek": "4.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"bowser": {
|
||||||
|
"version": "1.9.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/bowser/-/bowser-1.9.2.tgz",
|
||||||
|
"integrity": "sha512-fuiANC1Bqbqa/S4gmvfCt7bGBmNELMsGZj4Wg3PrP6esP66Ttoj1JSlzFlXtHyduMv07kDNmDsX6VsMWT/MLGg=="
|
||||||
|
},
|
||||||
"boxen": {
|
"boxen": {
|
||||||
"version": "0.6.0",
|
"version": "0.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/boxen/-/boxen-0.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/boxen/-/boxen-0.6.0.tgz",
|
||||||
@@ -2789,6 +2794,14 @@
|
|||||||
"integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=",
|
"integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"css-in-js-utils": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-yuWmPMD9FLi50Xf3k8W8oO3WM1eVnxEGCldCLyfusQ+CgivFk0s23yst4ooW6tfxMuSa03S6uUEga9UhX6GRrA==",
|
||||||
|
"requires": {
|
||||||
|
"hyphenate-style-name": "1.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"css-loader": {
|
"css-loader": {
|
||||||
"version": "0.28.1",
|
"version": "0.28.1",
|
||||||
"resolved": "https://registry.npmjs.org/css-loader/-/css-loader-0.28.1.tgz",
|
"resolved": "https://registry.npmjs.org/css-loader/-/css-loader-0.28.1.tgz",
|
||||||
@@ -4034,6 +4047,11 @@
|
|||||||
"merge": "1.2.0"
|
"merge": "1.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"exenv": {
|
||||||
|
"version": "1.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/exenv/-/exenv-1.2.2.tgz",
|
||||||
|
"integrity": "sha1-KueOhdmJQVhnCwPUe+wfA72Ru50="
|
||||||
|
},
|
||||||
"exit-hook": {
|
"exit-hook": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz",
|
||||||
@@ -6215,6 +6233,11 @@
|
|||||||
"integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=",
|
"integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"hyphenate-style-name": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.2.tgz",
|
||||||
|
"integrity": "sha1-MRYKNpMK2vH8BMYHT360FGXU7Es="
|
||||||
|
},
|
||||||
"iconv-lite": {
|
"iconv-lite": {
|
||||||
"version": "0.4.19",
|
"version": "0.4.19",
|
||||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
|
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
|
||||||
@@ -6321,6 +6344,15 @@
|
|||||||
"integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=",
|
"integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"inline-style-prefixer": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-4.0.0.tgz",
|
||||||
|
"integrity": "sha1-MKA98bNGumsfuKgSvDydq+9IAi0=",
|
||||||
|
"requires": {
|
||||||
|
"bowser": "1.9.2",
|
||||||
|
"css-in-js-utils": "2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"inquirer": {
|
"inquirer": {
|
||||||
"version": "0.12.0",
|
"version": "0.12.0",
|
||||||
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz",
|
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz",
|
||||||
@@ -10404,6 +10436,16 @@
|
|||||||
"integrity": "sha1-DPf4T5Rj/wrlHExLFC2VvjdyTZw=",
|
"integrity": "sha1-DPf4T5Rj/wrlHExLFC2VvjdyTZw=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"radium": {
|
||||||
|
"version": "0.22.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/radium/-/radium-0.22.0.tgz",
|
||||||
|
"integrity": "sha512-9zOYegr4gXfgDiVcf02Qyj8zzupmYSTtIhxvSU/42Ls1Q/+r1cisuGUUJ5m06Ha2cc/f3e5vMM80rj2l34Slew==",
|
||||||
|
"requires": {
|
||||||
|
"exenv": "1.2.2",
|
||||||
|
"inline-style-prefixer": "4.0.0",
|
||||||
|
"prop-types": "15.6.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"raf": {
|
"raf": {
|
||||||
"version": "3.4.0",
|
"version": "3.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/raf/-/raf-3.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/raf/-/raf-3.4.0.tgz",
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
"moment": "^2.18.1",
|
"moment": "^2.18.1",
|
||||||
"papaparse": "^4.3.3",
|
"papaparse": "^4.3.3",
|
||||||
"prop-types": "^15.5.10",
|
"prop-types": "^15.5.10",
|
||||||
|
"radium": "^0.22.0",
|
||||||
"rc-datepicker": "^5.0.7",
|
"rc-datepicker": "^5.0.7",
|
||||||
"react": "^16.2.0",
|
"react": "^16.2.0",
|
||||||
"react-data-grid": "^2.0.51",
|
"react-data-grid": "^2.0.51",
|
||||||
|
|||||||
BIN
website/public/favicon-16x16.png
Normal file
|
After Width: | Height: | Size: 834 B |
BIN
website/public/favicon-32x32.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
website/public/favicon-96x96.png
Normal file
|
After Width: | Height: | Size: 6.1 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 834 B |
|
Before Width: | Height: | Size: 910 B |
@@ -1,20 +1,10 @@
|
|||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<title>Transition Management Resources</title>
|
<title>Deighton AR</title>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.png">
|
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.png">
|
||||||
<!--<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.2.9/semantic.min.css">-->
|
|
||||||
<!--
|
|
||||||
Notice the use of %PUBLIC_URL% in the tag above.
|
|
||||||
It will be replaced with the URL of the `public` folder during the build.
|
|
||||||
Only files inside the `public` folder can be referenced from the HTML.
|
|
||||||
|
|
||||||
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
|
|
||||||
work correctly both with client-side routing and a non-root public URL.
|
|
||||||
Learn how to configure a non-root public URL by running `npm run build`.
|
|
||||||
-->
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
|
|||||||
@@ -1,35 +1,38 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import './App.scss'
|
|
||||||
import { NavBar } from './Navigation'
|
|
||||||
import { Home } from './Home'
|
|
||||||
import { Login, Logout, ResetPassword, ForgotPassword, ConfirmEmail, ProtectedRoute } from './Auth'
|
import { Login, Logout, ResetPassword, ForgotPassword, ConfirmEmail, ProtectedRoute } from './Auth'
|
||||||
import { Dashboard } from './Dashboard'
|
import { Home } from './Home'
|
||||||
import { Profile } from './Profile'
|
import { Profile } from './Profile'
|
||||||
import { Users } from './Users'
|
import { Users } from './Users'
|
||||||
import { Footer } from './Footer'
|
import { HolyGrail } from './ui'
|
||||||
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'
|
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'
|
||||||
|
import logoImage from 'images/logo.png'
|
||||||
|
|
||||||
export class App extends React.Component {
|
export class App extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<Router basename='/'>
|
<HolyGrail>
|
||||||
<div className='App'>
|
<HolyGrail.Header>
|
||||||
<NavBar />
|
<img src={logoImage} style={{ width: '50px', height: '50px', margin: '5px' }} />
|
||||||
<Switch>
|
</HolyGrail.Header>
|
||||||
<Route exact path='/' component={Home} />
|
<HolyGrail.Body>
|
||||||
<Route path='/login' component={Login} />
|
<Router basename='/'>
|
||||||
<Route path='/confirm-email' component={ConfirmEmail} />
|
<Switch>
|
||||||
<Route path='/reset-password' component={ResetPassword} />
|
<Route path='/login' component={Login} />
|
||||||
<Route path='/forgot-password' component={ForgotPassword} />
|
<Route path='/confirm-email' component={ConfirmEmail} />
|
||||||
<ProtectedRoute path='/logout' component={Logout} />
|
<Route path='/reset-password' component={ResetPassword} />
|
||||||
<ProtectedRoute path='/profile' component={Profile} />
|
<Route path='/forgot-password' component={ForgotPassword} />
|
||||||
<ProtectedRoute roles={['administrator', 'normal']} path='/dashboard' component={Dashboard} />
|
<ProtectedRoute path='/logout' component={Logout} />
|
||||||
<ProtectedRoute roles={['administrator']} path='/users' component={Users} />
|
<ProtectedRoute path='/profile' component={Profile} />
|
||||||
<Route component={Home} />{/* No Match Route */}
|
<ProtectedRoute roles={['administrator', 'normal']} path='/' component={Home} />
|
||||||
</Switch>
|
<ProtectedRoute roles={['administrator']} path='/users' component={Users} />
|
||||||
<Footer />
|
<Route component={Home} />{/* No Match Route */}
|
||||||
</div>
|
</Switch>
|
||||||
</Router>
|
</Router>
|
||||||
|
</HolyGrail.Body>
|
||||||
|
<HolyGrail.Footer>
|
||||||
|
<div style={{ margin: '10px' }}>v1.0.0. Copyright © 2018, Deighton.</div>
|
||||||
|
</HolyGrail.Footer>
|
||||||
|
</HolyGrail>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
.App {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 768px) {
|
|
||||||
html, body {
|
|
||||||
padding-top: 4em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -4,9 +4,10 @@ import { Container, Header, Form, Message } from 'semantic-ui-react'
|
|||||||
import './Login.scss'
|
import './Login.scss'
|
||||||
import { regExpPattern } from 'regexp-pattern'
|
import { regExpPattern } from 'regexp-pattern'
|
||||||
import { api } from '../helpers'
|
import { api } from '../helpers'
|
||||||
import { Validator, ValidatedInput, ValidatedCheckbox, ValidatedButton } from '../Validated'
|
import { Validator, ValidatedInput, ValidatedCheckbox } from '../Validated'
|
||||||
import { WaitDialog, MessageDialog } from '../Dialog'
|
import { WaitDialog, MessageDialog } from '../Dialog'
|
||||||
import { Link } from 'react-router-dom'
|
import { Link } from 'react-router-dom'
|
||||||
|
import { Button } from '../ui'
|
||||||
|
|
||||||
export class Login extends React.Component {
|
export class Login extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
@@ -106,8 +107,9 @@ export class Login extends React.Component {
|
|||||||
name='rememberMe' onChange={this.handleChange} validator={this.state.validator}
|
name='rememberMe' onChange={this.handleChange} validator={this.state.validator}
|
||||||
message='Should we keep you logged in on this computer?' className='login-checkbox' />
|
message='Should we keep you logged in on this computer?' className='login-checkbox' />
|
||||||
</Form.Group>
|
</Form.Group>
|
||||||
<ValidatedButton className='submit' name='submit' content='Submit'
|
{ /* <ValidatedButton className='submit' name='submit' content='Submit'
|
||||||
primary submit validator={this.state.validator} />
|
primary submit validator={this.state.validator} /> */ }
|
||||||
|
<Button>Login</Button>
|
||||||
<Message info>
|
<Message info>
|
||||||
Please contact <a href='mailto:support@jamoki.com'>support@jamoki.com</a> to request login credentials.
|
Please contact <a href='mailto:support@jamoki.com'>support@jamoki.com</a> to request login credentials.
|
||||||
</Message>
|
</Message>
|
||||||
|
|||||||
@@ -1,31 +0,0 @@
|
|||||||
import React from 'react'
|
|
||||||
import { Container } from 'semantic-ui-react'
|
|
||||||
import { ProjectList } from './ProjectList'
|
|
||||||
import { api } from '../helpers'
|
|
||||||
|
|
||||||
export class Dashboard extends React.Component {
|
|
||||||
constructor(props) {
|
|
||||||
super(props)
|
|
||||||
this.state = {
|
|
||||||
projects: []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
api.listDashboardProjects().then((list) => {
|
|
||||||
this.setState({
|
|
||||||
projects: list.items
|
|
||||||
})
|
|
||||||
}).catch((error) => {
|
|
||||||
console.error(error)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<Container>
|
|
||||||
<ProjectList projects={this.state.projects} />
|
|
||||||
</Container>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
import React from 'react'
|
|
||||||
import PropTypes from 'prop-types'
|
|
||||||
import { Card, Image, Button, Icon, Popup } from 'semantic-ui-react'
|
|
||||||
import { Link } from 'react-router-dom'
|
|
||||||
import { Constants, api } from '../helpers'
|
|
||||||
import './ProjectCard.scss'
|
|
||||||
|
|
||||||
export class ProjectCard extends React.Component {
|
|
||||||
static propTypes = {
|
|
||||||
project: PropTypes.object.isRequired // TODO: Add required fields
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
let { project } = this.props
|
|
||||||
const corporationLink = `/corporations/${project.branch.corporation.fingerprint}`
|
|
||||||
const branchLink = corporationLink + `/branches/${project.branch.fingerprint}`
|
|
||||||
const projectLink = branchLink + `/projects/${project.fingerprint}`
|
|
||||||
return (
|
|
||||||
<Card className='project-card' fluid>
|
|
||||||
{/* Project/Corp Logo Link Section */}
|
|
||||||
<Card.Content>
|
|
||||||
<Image as={Link} to={corporationLink}
|
|
||||||
src={api.makeImageUrl(project.branch.corporation.imageId, Constants.logoImageSize)}
|
|
||||||
alt={project.branch.corporation.name} />
|
|
||||||
</Card.Content>
|
|
||||||
|
|
||||||
{/* Project Info Section */}
|
|
||||||
<Card.Content className='project-info'>
|
|
||||||
<Card.Header as={Link}
|
|
||||||
to={projectLink}
|
|
||||||
className='project-name' content={project.name} />
|
|
||||||
<Card.Description>
|
|
||||||
<Link to={branchLink}>{project.branch.name}</Link>
|
|
||||||
@
|
|
||||||
<Link to={corporationLink}>{project.branch.corporation.name}</Link>
|
|
||||||
</Card.Description>
|
|
||||||
</Card.Content>
|
|
||||||
|
|
||||||
{/* Project Link and Status Icon */}
|
|
||||||
<Card.Content className='project-links'>
|
|
||||||
<Button fluid as={Link} to={projectLink}
|
|
||||||
className='project-link' content='View Project' />
|
|
||||||
{ project.error
|
|
||||||
? <Popup trigger={<Icon name='check' size='large' />}
|
|
||||||
content='This project is underway with no errors!'
|
|
||||||
position='bottom left' />
|
|
||||||
: <Popup trigger={<Icon name='table' size='large' color='red' />}
|
|
||||||
content='The Client Data Sheet for this project has not been completed.'
|
|
||||||
position='bottom left' />
|
|
||||||
}
|
|
||||||
</Card.Content>
|
|
||||||
|
|
||||||
{/* Project Status Bar */}
|
|
||||||
<div className={`status in-progress`}>
|
|
||||||
In-Progress
|
|
||||||
</div>
|
|
||||||
</Card>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
.ui.card.project-card {
|
|
||||||
border-top: 2px solid #D4D4D5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.status {
|
|
||||||
color: WhiteSmoke;
|
|
||||||
padding: 0.25em 1em;
|
|
||||||
text-align: right;
|
|
||||||
font-size: 0.85em;
|
|
||||||
text-transform: capitalize;
|
|
||||||
}
|
|
||||||
|
|
||||||
.in-progress { background-color: #CF414A; }
|
|
||||||
.sending { background-color: #D66C0A; }
|
|
||||||
.receiving { background-color: #0062AF; }
|
|
||||||
|
|
||||||
.project-card img {
|
|
||||||
height: 2.5em !important;
|
|
||||||
width: auto !important;
|
|
||||||
margin: 0.25em auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.project-info {
|
|
||||||
height: 7em !important;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.project-info a {
|
|
||||||
padding: 0.25em;
|
|
||||||
color: black;
|
|
||||||
border-radius: 5px;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.project-name.header { font-size: 1em !important; }
|
|
||||||
|
|
||||||
.project-links {
|
|
||||||
padding: 0 !important;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.project-links a {
|
|
||||||
background-color: transparent !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.project-links i.icon {
|
|
||||||
position: absolute;
|
|
||||||
right: 0.25em;
|
|
||||||
color: LightSlateGrey;
|
|
||||||
}
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
import React from 'react'
|
|
||||||
import PropTypes from 'prop-types'
|
|
||||||
import { Grid } from 'semantic-ui-react'
|
|
||||||
import { ProjectCard } from './ProjectCard'
|
|
||||||
import './ProjectList.scss'
|
|
||||||
|
|
||||||
export class ProjectList extends React.Component {
|
|
||||||
static propTypes = {
|
|
||||||
projects: PropTypes.arrayOf(PropTypes.object)
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
let { projects } = this.props
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className='project-list'>
|
|
||||||
<Grid centered={(window.innerWidth <= 768)}>
|
|
||||||
<Grid.Column width={16} textAlign='left' className='project-list-heading'>
|
|
||||||
{projects.length} Projects Underway
|
|
||||||
</Grid.Column>
|
|
||||||
{this.props.projects
|
|
||||||
? projects.map((project, index) => (
|
|
||||||
<Grid.Column mobile={12} tablet={8} computer={4} textAlign='center' key={index}>
|
|
||||||
<ProjectCard project={project} />
|
|
||||||
</Grid.Column>))
|
|
||||||
: null
|
|
||||||
}
|
|
||||||
</Grid>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
.project-list {
|
|
||||||
margin: 3em 0 2em 0;
|
|
||||||
padding-bottom: 2em;
|
|
||||||
border-bottom: 1px solid Silver;
|
|
||||||
}
|
|
||||||
|
|
||||||
.project-list-heading {
|
|
||||||
font-size: 1.5em;
|
|
||||||
border-bottom: 1px solid Silver;
|
|
||||||
margin-bottom: 1em !important;
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
export { Dashboard } from './Dashboard'
|
|
||||||
@@ -1,169 +0,0 @@
|
|||||||
import React from 'react'
|
|
||||||
import PropTypes from 'prop-types'
|
|
||||||
import { autoBind } from 'auto-bind2'
|
|
||||||
import { Menu, Image, Button, Dropdown } from 'semantic-ui-react'
|
|
||||||
import { Link, NavLink } from 'react-router-dom'
|
|
||||||
import logoImg from 'images/logo.png'
|
|
||||||
import { Constants, api } from '../helpers'
|
|
||||||
import './NavBar.scss'
|
|
||||||
|
|
||||||
export class NavBar extends React.Component {
|
|
||||||
static propTypes = {
|
|
||||||
activeItem: PropTypes.string
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super()
|
|
||||||
autoBind(this, (name) => (name.startsWith('handle')))
|
|
||||||
this.state = {
|
|
||||||
activeItem: null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
handleItemClick = (event, { name }) => this.setState({ activeItem: name })
|
|
||||||
|
|
||||||
handleUpdate() {
|
|
||||||
this.forceUpdate()
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
api.addListener('login', this.handleUpdate)
|
|
||||||
api.addListener('logout', this.handleUpdate)
|
|
||||||
api.addListener('newThumbnailImage', this.handleUpdate)
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillUnmount() {
|
|
||||||
api.removeListener('login', this.handleUpdate)
|
|
||||||
api.removeListener('logout', this.handleUpdate)
|
|
||||||
api.addListener('newThumbnailImage', this.handleUpdate)
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const { activeItem } = this.state
|
|
||||||
const user = api.loggedInUser
|
|
||||||
|
|
||||||
if (!user) {
|
|
||||||
if (window.innerWidth <= 768) {
|
|
||||||
return (
|
|
||||||
<Menu fluid inverted borderless fixed='top' size='large' id='MobileNavMenu'>
|
|
||||||
<Menu.Item>
|
|
||||||
<Image as={Link} to='/' src={logoImg} alt='Deighton Logo' size='tiny' centered />
|
|
||||||
</Menu.Item>
|
|
||||||
<Menu.Menu position='right'>
|
|
||||||
<Menu.Item>
|
|
||||||
<Button as={Link} to='/login' color='facebook' content='Login' />
|
|
||||||
</Menu.Item>
|
|
||||||
</Menu.Menu>
|
|
||||||
</Menu>
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
return (<Menu pointing stackable secondary id='NavMenu'>
|
|
||||||
<Menu.Item link href='/' active={activeItem === 'logo'} onClick={this.handleItemClick}>
|
|
||||||
<Image className='menu-logo' src={logoImg} alt='Deighton Logo' />
|
|
||||||
</Menu.Item>
|
|
||||||
<Menu.Item id='nav-item1' name='meetTheTeam' active={activeItem === 'meetTheTeam'} onClick={this.handleItemClick} />
|
|
||||||
<Menu.Item id='nav-item2' name='testimonials' active={activeItem === 'testimonials'} onClick={this.handleItemClick} />
|
|
||||||
<Menu.Item id='nav-item3' name='contactUs' active={activeItem === 'contactUs'} onClick={this.handleItemClick} />
|
|
||||||
<Menu.Menu position='right'>
|
|
||||||
<Button as={Link} to='/login' primary content='Login' id='login-button' />
|
|
||||||
</Menu.Menu>
|
|
||||||
</Menu>)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (user.pending) {
|
|
||||||
return <div />
|
|
||||||
}
|
|
||||||
|
|
||||||
const userImageUrl = api.makeImageUrl(user.thumbnailImageId, Constants.smallUserImageSize)
|
|
||||||
const userName = user.firstName + ' ' + user.lastName
|
|
||||||
|
|
||||||
if (window.innerWidth <= 768) {
|
|
||||||
return (
|
|
||||||
user.role === 'broker'
|
|
||||||
? <Menu fluid inverted borderless fixed='top' size='large' id='MobileNavMenu'>
|
|
||||||
<Menu.Item>
|
|
||||||
<Image as={Link} to='/' src={logoImg} alt='Deighton Logo' size='tiny' centered />
|
|
||||||
</Menu.Item>
|
|
||||||
<Menu.Menu position='right'>
|
|
||||||
<Dropdown icon='content' item>
|
|
||||||
<Dropdown.Menu>
|
|
||||||
<Dropdown.Item as={Link} exact to='/'>Home</Dropdown.Item>
|
|
||||||
<Dropdown.Item as={Link} to='/broker-dashboard'>Dashboard</Dropdown.Item>
|
|
||||||
<Dropdown.Divider />
|
|
||||||
<Dropdown.Item as={Link} to='/profile'>Profile</Dropdown.Item>
|
|
||||||
<Dropdown.Divider />
|
|
||||||
<Dropdown.Item as={Link} to='/logout'>Logout</Dropdown.Item>
|
|
||||||
</Dropdown.Menu>
|
|
||||||
</Dropdown>
|
|
||||||
</Menu.Menu>
|
|
||||||
</Menu>
|
|
||||||
: <Menu fluid inverted borderless fixed='top' size='large' id='MobileNavMenu'>
|
|
||||||
<Menu.Item>
|
|
||||||
<Image as={Link} to='/' src={logoImg} alt='Deighton Logo' size='tiny' centered />
|
|
||||||
</Menu.Item>
|
|
||||||
<Menu.Menu position='right'>
|
|
||||||
<Dropdown icon='content' item>
|
|
||||||
<Dropdown.Menu>
|
|
||||||
<Dropdown.Item as={Link} exact to='/'>Home</Dropdown.Item>
|
|
||||||
<Dropdown.Item as={Link} to='/dashboard'>Dashboard</Dropdown.Item>
|
|
||||||
<Dropdown.Item as={Link} to='/corporations'>Corporations</Dropdown.Item>
|
|
||||||
{ api.loggedInUser.role === 'administrator' || api.loggedInUser.role === 'executive'
|
|
||||||
? <Dropdown.Item as={Link} to='/forms'>Forms</Dropdown.Item>
|
|
||||||
: null
|
|
||||||
}
|
|
||||||
{ api.loggedInUser.role === 'administrator' || api.loggedInUser.role === 'executive'
|
|
||||||
? <Dropdown.Item as={Link} to='/users'>Users</Dropdown.Item>
|
|
||||||
: null
|
|
||||||
}
|
|
||||||
<Dropdown.Divider />
|
|
||||||
<Dropdown.Item as={Link} to='/profile'>Profile</Dropdown.Item>
|
|
||||||
<Dropdown.Divider />
|
|
||||||
<Dropdown.Item as={Link} to='/logout'>Logout</Dropdown.Item>
|
|
||||||
</Dropdown.Menu>
|
|
||||||
</Dropdown>
|
|
||||||
</Menu.Menu>
|
|
||||||
</Menu>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
user.role === 'broker'
|
|
||||||
? <Menu pointing secondary stackable id='NavMenu'>
|
|
||||||
<Menu.Item as={NavLink} activeClassName='nav-menu-active' exact to='/' name='home' active={activeItem === 'home'} onClick={this.handleItemClick} />
|
|
||||||
<Menu.Item as={NavLink} activeClassName='nav-menu-active' to='/broker-dashboard' name='dashboard' active={activeItem === 'dashboard'} onClick={this.handleItemClick} />
|
|
||||||
<Menu.Menu position='right'>
|
|
||||||
<div className='logged-in-user'>
|
|
||||||
<NavLink to='/profile' activeClassName='nav-menu-active'>
|
|
||||||
<Image avatar src={this.userImage} />
|
|
||||||
<span className='user-name'>{userName}</span>
|
|
||||||
</NavLink>
|
|
||||||
<Button as={Link} to='/logout' content='Logout' id='logout-button' />
|
|
||||||
</div>
|
|
||||||
</Menu.Menu>
|
|
||||||
</Menu>
|
|
||||||
: <Menu pointing secondary stackable id='NavMenu'>
|
|
||||||
<Menu.Item as={NavLink} activeClassName='nav-menu-active' exact to='/' name='home' active={activeItem === 'home'} onClick={this.handleItemClick} />
|
|
||||||
<Menu.Item as={NavLink} activeClassName='nav-menu-active' to='/dashboard' name='dashboard' active={activeItem === 'dashboard'} onClick={this.handleItemClick} />
|
|
||||||
<Menu.Item as={NavLink} activeClassName='nav-menu-active' to='/corporations' name='corporations' active={activeItem === 'corporations'} onClick={this.handleItemClick} />
|
|
||||||
{ api.loggedInUser.role === 'administrator' || api.loggedInUser.role === 'executive'
|
|
||||||
? <Menu.Item as={NavLink} activeClassName='nav-menu-active' to='/forms' name='forms' active={activeItem === 'forms'} onClick={this.handleItemClick} />
|
|
||||||
: null
|
|
||||||
}
|
|
||||||
{ api.loggedInUser.role === 'administrator' || api.loggedInUser.role === 'executive'
|
|
||||||
? <Menu.Item as={NavLink} activeClassName='nav-menu-active' to='/users' name='users' active={activeItem === 'users'} onClick={this.handleItemClick} />
|
|
||||||
: null
|
|
||||||
}
|
|
||||||
<Menu.Menu position='right'>
|
|
||||||
<div className='logged-in-user'>
|
|
||||||
<NavLink to='/profile' activeClassName='nav-menu-active'>
|
|
||||||
<Image avatar src={userImageUrl} />
|
|
||||||
<span className='user-name'>{userName}</span>
|
|
||||||
</NavLink>
|
|
||||||
<Button as={Link} to='/logout' content='Logout' id='logout-button' />
|
|
||||||
</div>
|
|
||||||
</Menu.Menu>
|
|
||||||
</Menu>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,116 +0,0 @@
|
|||||||
/* === Nav Menu Stylesheet === */
|
|
||||||
|
|
||||||
#NavMenu {
|
|
||||||
background-color: #1b1b1b;
|
|
||||||
box-shadow: 0 0 20px 2px Grey;
|
|
||||||
}
|
|
||||||
|
|
||||||
#NavMenu a.item {
|
|
||||||
color: white;
|
|
||||||
align-self: flex-end;
|
|
||||||
}
|
|
||||||
|
|
||||||
#NavMenu a.item.nav-menu-active {
|
|
||||||
background-color: #2d2b2b;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#NavMenu a.item.nav-menu-active:nth-child(n) { border-bottom: 0.25em solid #CF414A; }
|
|
||||||
#NavMenu a.item.nav-menu-active:nth-child(2n) { border-bottom: 0.25em solid #2185D0; }
|
|
||||||
#NavMenu a.item.nav-menu-active:nth-child(3n) { border-bottom: 0.25em solid #DB822E; }
|
|
||||||
|
|
||||||
#NavMenu a.item:hover { background-color: #444344; }
|
|
||||||
|
|
||||||
#NavMenu img.menu-logo {
|
|
||||||
height: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
#login-button {
|
|
||||||
height: 60%;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
font-size: 1em;
|
|
||||||
margin: auto 1em;
|
|
||||||
background-color: #3f62ab;
|
|
||||||
}
|
|
||||||
|
|
||||||
#logout-button {
|
|
||||||
height: 60%;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
font-size: 1em;
|
|
||||||
margin: auto 1em;
|
|
||||||
background-color: silver;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logged-in-user {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logged-in-user a {
|
|
||||||
color: Silver;
|
|
||||||
margin-right: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logged-in-user a:hover {
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logged-in-user .user-name {
|
|
||||||
margin-left: 0.25em;
|
|
||||||
}
|
|
||||||
|
|
||||||
#nav-item1 { border-bottom: 5px solid #2e4d9a; }
|
|
||||||
#nav-item2 { border-bottom: 5px solid #db822e; }
|
|
||||||
#nav-item3 { border-bottom: 5px solid #cf414a; }
|
|
||||||
|
|
||||||
/* === Tablet-Specific Menu Styles === */
|
|
||||||
|
|
||||||
#MobileNavMenu {
|
|
||||||
border-radius: 0 !important;
|
|
||||||
border-bottom: 5px solid #db822e !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 992px) {
|
|
||||||
.user-name {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* === Mobile-Specific Menu Styles === */
|
|
||||||
|
|
||||||
@media screen and (max-width: 767px) {
|
|
||||||
#NavMenu {
|
|
||||||
font-size: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
#NavMenu a.item {
|
|
||||||
text-align: center !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logged-in-user {
|
|
||||||
width: 100%;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: flex-end;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-name {
|
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logged-in-user a {
|
|
||||||
width: 30%;
|
|
||||||
}
|
|
||||||
|
|
||||||
#logout-button {
|
|
||||||
width: 30%;
|
|
||||||
margin: 1.5em 0.5em 0.5em 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
export { NavBar } from './NavBar'
|
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import { Form, Popup, Checkbox } from 'semantic-ui-react'
|
import { Form } from 'semantic-ui-react'
|
||||||
|
import { Checkbox } from '../ui'
|
||||||
|
|
||||||
// This is an example of a validated component with a value that can change itself, that cannot ever be invalid.
|
// This is an example of a validated component with a value that can change itself, that cannot ever be invalid.
|
||||||
|
|
||||||
export class ValidatedCheckbox extends React.Component {
|
export class ValidatedCheckbox extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
name: PropTypes.string.isRequired,
|
name: PropTypes.string.isRequired,
|
||||||
message: PropTypes.string.isRequired,
|
|
||||||
label: PropTypes.string,
|
label: PropTypes.string,
|
||||||
width: PropTypes.number,
|
width: PropTypes.number,
|
||||||
validator: PropTypes.object.isRequired,
|
validator: PropTypes.object.isRequired,
|
||||||
@@ -39,9 +39,7 @@ export class ValidatedCheckbox extends React.Component {
|
|||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<Form.Field width={this.props.width} disabled={this.state.disabled} className={this.props.className}>
|
<Form.Field width={this.props.width} disabled={this.state.disabled} className={this.props.className}>
|
||||||
<Popup content={this.props.message} position='bottom center' hoverable trigger={
|
<Checkbox value={!!this.state.value} name={this.props.name} label={this.props.label} />
|
||||||
<Checkbox checked={!!this.state.value} name={this.props.name} label={this.props.label}
|
|
||||||
onChange={this.handleChange} />} />
|
|
||||||
</Form.Field>
|
</Form.Field>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import { Form, Popup, Input } from 'semantic-ui-react'
|
import { Form } from 'semantic-ui-react'
|
||||||
|
import { Input } from '../ui'
|
||||||
|
|
||||||
// This is an example of a validated component with a value that changes itself
|
// This is an example of a validated component with a value that changes itself
|
||||||
|
|
||||||
@@ -44,19 +45,14 @@ export class ValidatedInput extends React.Component {
|
|||||||
return (
|
return (
|
||||||
<Form.Field error={!this.state.valid} width={this.props.width} disabled={this.state.disabled} className={this.props.className}>
|
<Form.Field error={!this.state.valid} width={this.props.width} disabled={this.state.disabled} className={this.props.className}>
|
||||||
<label>{this.props.label}</label>
|
<label>{this.props.label}</label>
|
||||||
{this.props.message
|
<Input value={this.state.value}
|
||||||
? <Popup content={this.props.message} position='bottom center' hoverable trigger={
|
hidden={this.props.password}
|
||||||
<Input value={this.state.value} type={this.props.password ? 'password' : 'text'}
|
name={this.props.name}
|
||||||
name={this.props.name} onChange={this.handleChange} placeholder={this.props.placeholder}
|
onChange={this.handleChange}
|
||||||
className={this.props.className} icon={this.props.icon} iconPosition={this.props.iconPosition} />}
|
|
||||||
/>
|
|
||||||
: <Input value={this.state.value}
|
|
||||||
type={this.props.password ? 'password' : 'text'}
|
|
||||||
name={this.props.name} onChange={this.handleChange}
|
|
||||||
placeholder={this.props.placeholder}
|
placeholder={this.props.placeholder}
|
||||||
className={this.props.className} icon={this.props.icon}
|
className={this.props.className} icon={this.props.icon}
|
||||||
iconPosition={this.props.iconPosition} />
|
iconPosition={this.props.iconPosition} />
|
||||||
}
|
<label>{this.props.message}</label>
|
||||||
</Form.Field>
|
</Form.Field>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.5 KiB |
BIN
website/src/assets/images/deighton.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
@@ -1 +0,0 @@
|
|||||||
<?xml version="1.0" ?><svg enable-background="new 0 0 500 500" id="Layer_1" version="1.1" viewBox="0 0 500 500" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><g><g><path d="M427.9,402.1H72.1V128.4h355.9V402.1z M99.4,374.8h301.1v-219H99.4V374.8z"/></g><g><path d="M373.2,292.6H126.8c-30.2,0-54.8-24.6-54.8-54.8v-41.1h27.4v41.1c0,15.1,12.3,27.4,27.4,27.4h246.4 c15.1,0,27.4-12.3,27.4-27.4v-41.1h27.4v41.1C427.9,268.1,403.4,292.6,373.2,292.6z"/></g><g><path d="M304.8,155.8H195.2v-41.1c0-15.1,12.3-27.4,27.4-27.4h54.8c15.1,0,27.4,12.3,27.4,27.4V155.8z M222.6,128.4h54.8v-13.7 h-54.8V128.4z"/></g><g><rect height="41.1" width="27.4" x="318.4" y="210.5"/></g><g><rect height="41.1" width="27.4" x="154.2" y="210.5"/></g></g></svg>
|
|
||||||
|
Before Width: | Height: | Size: 784 B |
@@ -1,14 +1,6 @@
|
|||||||
@import '~semantic-ui-css/semantic.min.css';
|
@import '~semantic-ui-css/semantic.min.css';
|
||||||
|
|
||||||
html, body {
|
body #root {
|
||||||
margin: 0;
|
min-height: 100vh;
|
||||||
font-family: sans-serif;
|
|
||||||
height: 100%;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
#root {
|
|
||||||
min-height: 100%;
|
|
||||||
position: relative;
|
|
||||||
padding-bottom: 3em;
|
|
||||||
}
|
|
||||||
|
|||||||
19
website/src/ui/Button.js
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import Radium from 'radium'
|
||||||
|
import PropTypes from 'prop-types'
|
||||||
|
import React, { Component } from 'react'
|
||||||
|
import style from './Button.style'
|
||||||
|
|
||||||
|
class Button extends Component {
|
||||||
|
static propTypes = {
|
||||||
|
submit: PropTypes.string,
|
||||||
|
children: PropTypes.node
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<button type={this.props.submit ? 'submit' : 'button'} style={style.base}>{this.props.children}</button>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Radium(Button)
|
||||||
17
website/src/ui/Button.style.js
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
export default {
|
||||||
|
base: {
|
||||||
|
borderRadius: '10px',
|
||||||
|
fontFamily: 'Arial',
|
||||||
|
color: '#ffffff',
|
||||||
|
fontSize: '20px',
|
||||||
|
background: '#3498db',
|
||||||
|
padding: '10px 20px 10px 20px',
|
||||||
|
textDecoration: 'none',
|
||||||
|
outline: 'none',
|
||||||
|
|
||||||
|
':hover': {
|
||||||
|
background: '#3cb0fd',
|
||||||
|
textDecoration: 'none'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
33
website/src/ui/Checkbox.js
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
import Radium from 'radium'
|
||||||
|
import PropTypes from 'prop-types'
|
||||||
|
import React, { Component } from 'react'
|
||||||
|
import style from './Checkbox.style'
|
||||||
|
import { reactAutoBind } from 'auto-bind2'
|
||||||
|
|
||||||
|
class Checkbox extends Component {
|
||||||
|
static propTypes = {
|
||||||
|
value: PropTypes.bool
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props)
|
||||||
|
reactAutoBind(this)
|
||||||
|
this.state = {
|
||||||
|
checked: props.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onClick() {
|
||||||
|
this.setState({ checked: !this.state.checked })
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div style={[style.checkbox, !this.state.checked && style.checkboxUnchecked]} onClick={this.onClick}>
|
||||||
|
<div style={[style.checkmark, !this.state.checked && style.checkmarkUnchecked]} />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Radium(Checkbox)
|
||||||
36
website/src/ui/Checkbox.style.js
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
export default {
|
||||||
|
checkbox: {
|
||||||
|
cursor: 'pointer',
|
||||||
|
position: 'relative',
|
||||||
|
backgroundColor: '#2196F3',
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
height: 25,
|
||||||
|
width: 25
|
||||||
|
},
|
||||||
|
|
||||||
|
checkboxUnchecked: {
|
||||||
|
backgroundColor: '#E0E0E0',
|
||||||
|
':hover': {
|
||||||
|
backgroundColor: '#C0C0C0'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
checkmark: {
|
||||||
|
position: 'absolute',
|
||||||
|
display: 'block',
|
||||||
|
content: '',
|
||||||
|
left: 10,
|
||||||
|
top: 5,
|
||||||
|
width: 6,
|
||||||
|
height: 12,
|
||||||
|
borderStyle: 'solid',
|
||||||
|
borderColor: '#FFFFFF',
|
||||||
|
borderWidth: '0 3px 3px 0',
|
||||||
|
transform: 'rotate(45deg)'
|
||||||
|
},
|
||||||
|
|
||||||
|
checkmarkUnchecked: {
|
||||||
|
display: 'none'
|
||||||
|
}
|
||||||
|
}
|
||||||
54
website/src/ui/HolyGrail.js
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
import Radium from 'radium'
|
||||||
|
import React, { Component } from 'react'
|
||||||
|
import PropTypes from 'prop-types'
|
||||||
|
import style from './HolyGrail.style.js'
|
||||||
|
|
||||||
|
class HolyGrail extends Component {
|
||||||
|
static propTypes = {
|
||||||
|
children: PropTypes.node
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div style={style.base}>{this.props.children}</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HolyGrail.Header = Radium(class HolyGrailHeader extends Component {
|
||||||
|
static propTypes = {
|
||||||
|
children: PropTypes.node
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div style={style.header}>{this.props.children}</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
HolyGrail.Footer = Radium(class HolyGrailFooter extends Component {
|
||||||
|
static propTypes = {
|
||||||
|
children: PropTypes.node
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div style={style.footer}>{this.props.children}</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
HolyGrail.Body = Radium(class HolyGrailBody extends Component {
|
||||||
|
static propTypes = {
|
||||||
|
children: PropTypes.node
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div style={style.body}>{this.props.children}</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
export default Radium(HolyGrail)
|
||||||
19
website/src/ui/HolyGrail.style.js
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
export default {
|
||||||
|
base: {
|
||||||
|
display: 'flex',
|
||||||
|
minHeight: '100vh',
|
||||||
|
flexDirection: 'column'
|
||||||
|
},
|
||||||
|
body: {
|
||||||
|
display: 'flex',
|
||||||
|
flexGrow: 1
|
||||||
|
},
|
||||||
|
header: {
|
||||||
|
backgroundColor: '#FAFAFA',
|
||||||
|
borderBottom: '1px solid #B2B2B2'
|
||||||
|
},
|
||||||
|
footer: {
|
||||||
|
backgroundColor: '#FAFAFA',
|
||||||
|
borderTop: '1px solid #B2B2B2'
|
||||||
|
}
|
||||||
|
}
|
||||||
0
website/src/ui/Icon.js
Normal file
0
website/src/ui/Icon.style.js
Normal file
0
website/src/ui/Image.js
Normal file
0
website/src/ui/Image.style.js
Normal file
19
website/src/ui/Input.js
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import Radium from 'radium'
|
||||||
|
import PropTypes from 'prop-types'
|
||||||
|
import React, { Component } from 'react'
|
||||||
|
import style from './Input.style'
|
||||||
|
|
||||||
|
class Input extends Component {
|
||||||
|
static propTypes = {
|
||||||
|
hidden: PropTypes.bool,
|
||||||
|
children: PropTypes.node
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<input type={this.props.hidden ? 'password' : 'text'} style={style.base}>{this.props.children}</input>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Radium(Input)
|
||||||
18
website/src/ui/Input.style.js
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
export default {
|
||||||
|
base: {
|
||||||
|
padding: '5px',
|
||||||
|
fontSize: '16px',
|
||||||
|
borderWidth: '1px',
|
||||||
|
borderColor: '#b2b2b2',
|
||||||
|
backgroundColor: '#ffffff',
|
||||||
|
color: '#000000',
|
||||||
|
borderStyle: 'solid',
|
||||||
|
borderRadius: '5px',
|
||||||
|
// boxShadow: '0px 0px 0px rgba(66,66,66,.75)'
|
||||||
|
// textShadow: 'undefined 0px 0px 5px px rgba(66,66,66,.75)'
|
||||||
|
|
||||||
|
':focus': {
|
||||||
|
outline: 'none'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
0
website/src/ui/Text.js
Normal file
0
website/src/ui/Text.style.js
Normal file
4
website/src/ui/index.js
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
export { default as Button } from './Button'
|
||||||
|
export { default as Checkbox } from './Checkbox'
|
||||||
|
export { default as Input } from './Input'
|
||||||
|
export { default as HolyGrail } from './HolyGrail'
|
||||||