diff --git a/src/App.js b/src/App.js index f98f25f..3a5c079 100644 --- a/src/App.js +++ b/src/App.js @@ -1,21 +1,17 @@ import React, { Component } from 'react'; -import logo from './logo.svg'; import { Route, withRouter } from 'react-router-dom'; import PrivateRoute from './components/PrivateRoute'; import './App.scss'; import Main from './views/Main'; import Login from './views/Login'; import { connect } from 'react-redux'; -import { decrypt, encrypt } from './components/Cryptr'; +import { decrypt } from './components/Cryptr'; import { authenticateFromLocalStorage } from './actions/appActions'; import { loggedIn } from './actions/accountActions'; import Profile from './views/Profile'; -import MiniDrawer from './components/MiniDrawer'; -import unsplash from './actions/unsplash'; import Matches from './views/Matches'; import Messages from './views/Messages'; import SignOut from './views/SignOut'; -import MainStream from './components/MainStream'; class App extends Component { state = { diff --git a/src/actions/accountActions.js b/src/actions/accountActions.js index 28ff8fe..3b8fbd8 100644 --- a/src/actions/accountActions.js +++ b/src/actions/accountActions.js @@ -1,16 +1,12 @@ -import apiRequest, { requestWithToken } from './axios'; +import { requestWithToken } from './axios'; import actionCreator from './actionCreator'; -import uuid4 from 'uuid4'; export const UPDATING_ACCOUNT_INFO = 'UPDATING_ACCOUNT_INFO'; export const ACCOUNT_INFORMATION_UPDATED = 'ACCOUNT_INFORMATION_UPDATED'; export const ERROR = 'ERROR'; -export const REGISTERED = 'REGISTERED'; export const LOGGED_IN = 'LOGGED_IN'; export const LOGGED_OUT = 'LOGGED_OUT'; -let registered = []; - export const updateAccountInfo = ( account, token, @@ -26,16 +22,36 @@ export const updateAccountInfo = ( url = `/jobs/update/${account.id}`; } - requestWithToken(token) - .put(url, { ...account }) - .then(res => { - //debugger; - dispatch(actionCreator(ACCOUNT_INFORMATION_UPDATED, account)); - }) - .catch(err => { - //debugger; - dispatch(actionCreator(ERROR, err)); - }); + if (accountType === 'user') { + requestWithToken(token) + .put(url, { + firstName: account.firstName, + lastName: account.lastName, + occupation: account.occupation, + experience: account.experience, + interests: account.interests, + }) + .then(res => { + dispatch(actionCreator(ACCOUNT_INFORMATION_UPDATED, account)); + }) + .catch(err => { + dispatch(actionCreator(ERROR, err)); + }); + } else if (accountType === 'company') { + requestWithToken(token) + .put(url, { + companyName: account.companyName, + email: account.email, + bio: account.bio, + address: account.address, + }) + .then(res => { + dispatch(actionCreator(ACCOUNT_INFORMATION_UPDATED, account)); + }) + .catch(err => { + dispatch(actionCreator(ERROR, err)); + }); + } }; export const logOut = () => { diff --git a/src/actions/appActions.js b/src/actions/appActions.js index 4f62bf6..5ae64a5 100644 --- a/src/actions/appActions.js +++ b/src/actions/appActions.js @@ -1,7 +1,7 @@ -import { request, requestWithToken } from './axios'; +import { request } from './axios'; import actionCreator from './actionCreator'; import { LOGGED_IN } from './accountActions'; -import { decrypt, encrypt } from '../components/Cryptr'; +import { encrypt } from '../components/Cryptr'; export const CHECKING_AUTHENTICATION = 'CHECKING_AUTHENTICATION'; export const AUTHENTICATED = 'AUTHENTICATED'; @@ -10,11 +10,9 @@ export const REGISTERED = 'REGISTERED'; export const AUTHENTICATED_FROM_LOCAL_STORAGE = 'AUTHENTICATED_FROM_LOCAL_STORAGE'; -let registered = []; - export const checkAuthentication = account => async dispatch => { dispatch(actionCreator(CHECKING_AUTHENTICATION)); - //debugger; + request() .post('/auth/login', { email: account.email, @@ -32,9 +30,9 @@ export const checkAuthentication = account => async dispatch => { let key = encrypt('token'); let tokenValue = encrypt(res.data.token); localStorage.setItem(key, tokenValue); - let account = encrypt(JSON.stringify(data)); + let accountToStore = encrypt(JSON.stringify(data)); let accountKey = encrypt('account'); - localStorage.setItem(accountKey, account); + localStorage.setItem(accountKey, accountToStore); } dispatch(actionCreator(AUTHENTICATED, res.data.token)); dispatch(actionCreator(LOGGED_IN, data)); @@ -46,7 +44,6 @@ export const checkAuthentication = account => async dispatch => { export const submitRegistration = account => async dispatch => { if (account.type === 'company') { - //debugger; request() .post('/auth/register', { email: account.email, diff --git a/src/actions/matchActions.js b/src/actions/matchActions.js index 3a8f767..8f1f3be 100644 --- a/src/actions/matchActions.js +++ b/src/actions/matchActions.js @@ -27,12 +27,12 @@ export const getStream = (token, accountType) => async dispatch => { requestWithToken(token) .get(url) .then(res => { - let accountType = 'job'; + let profileType = 'job'; if (accountType === 'company') { - accountType = 'user'; + profileType = 'user'; } res.data = res.data.map(account => { - account.accountType = accountType; + account.accountType = profileType; return account; }); dispatch(actionCreator(MATCHES_FETCHED, res.data)); diff --git a/src/components/AvatarComponent.js b/src/components/AvatarComponent.js index cd22ed1..f6d8a3c 100644 --- a/src/components/AvatarComponent.js +++ b/src/components/AvatarComponent.js @@ -10,59 +10,88 @@ import { Typography, } from '@material-ui/core'; import red from '@material-ui/core/colors/red'; -import MoreVertIcon from '@material-ui/icons/MoreVert'; import faker from 'faker'; import moment from 'moment'; -import SimplePopover from './SimplePopOver'; import { Link } from 'react-router-dom'; +import uuid4 from 'uuid4'; +import MaterialUiPopOver from './MaterialUiPopOver'; class AvatarComponent extends React.Component { state = { popOverElement: null, + popoverOpen: false, + popoverKey: uuid4(), }; - handlePopOverClose = () => { - this.setState({ popOverElement: null }); + handlePopOverClose = event => { + if (event.target.value !== this.state.popOverElement) { + console.log('click outer'); + if (this.state.popoverOpen === true) { + this.setState(prevState => { + return { + popoverOpen: false, + }; + }); + } + // this.setState(state => { + // console.log('click inner'); + // return { + // popOverElement: null, + // popoverOpen: false, + // }; + // }); + } }; handleVertIconClick = event => { this.setState({ popOverElement: event.currentTarget, + popoverOpen: true, }); }; getPopOverContent = id => { - return ( - - View Profile - - ); + if (this.props.avatar.hasOwnProperty('companyName')) { + return View Profile ; + } + return View Profile; }; + // componentWillUpdate(nextProps, nextState, nextContext) { + // : + // if (nextState.popoverOpen !== this.state.popoverOpen) { + // return true; + // } + // } + render() { const { classes } = this.props; + + let url = ''; + if (this.props.avatar) { + if (this.props.avatar.hasOwnProperty('companyName')) { + url = `/profile/company/${this.props.avatar.id}`; + } else if (this.props.avatar.hasOwnProperty('jobTitle')) { + url = `/profile/jobs/${this.props.avatar.id}`; + } else { + url = `/profile/user/${this.props.avatar.id}`; + } + } + return ( } - action={ - - - - - } - title={this.props.avatar.title} + action={} + title={this.props.avatar && this.props.avatar.title} subheader={moment(faker.fake('{{date.past}}')).format( 'dddd, MMMM Do YYYY' )} diff --git a/src/components/CardDetails.js b/src/components/CardDetails.js index 0f44aa7..c94cfe4 100644 --- a/src/components/CardDetails.js +++ b/src/components/CardDetails.js @@ -8,10 +8,10 @@ import SimpleBottomNavigation from './SimpleBottomNavigation'; const CardDetails = ({ classes, - title, - subheader, - image, - imageTitle = null, + title = '', + subheader = '', + image = '', + imageTitle = '', chips = [], }) => { return ( @@ -36,9 +36,9 @@ const CardDetails = ({ CardDetails.propTypes = { classes: PropTypes.object.isRequired, - title: PropTypes.string.isRequired, - subheader: PropTypes.string.isRequired, - image: PropTypes.string.isRequired, + title: PropTypes.string, + subheader: PropTypes.string, + image: PropTypes.string, imageTitle: PropTypes.string, chips: PropTypes.array, }; diff --git a/src/components/CompanyProfile.js b/src/components/CompanyProfile.js new file mode 100644 index 0000000..ecfdcbb --- /dev/null +++ b/src/components/CompanyProfile.js @@ -0,0 +1,133 @@ +import React, { Component } from 'react'; +import { connect } from 'react-redux'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core'; +import DroomButton from './DroomButton'; +import SimpleModal from './SimpleModal'; +import InputText from './InputText'; +import { updateAccountInfo } from '../actions/accountActions'; + +class CompanyProfile extends Component { + state = { + modal: false, + profile: { + email: this.props.profile.email, + address: this.props.profile.address, + bio: this.props.profile.bio, + companyName: this.props.profile.companyName, + }, + }; + + editProfile = () => { + this.setState(state => { + return { modal: !state.modal }; + }); + }; + + getModalContent = props => { + return ( +
+ + + + + + + ); + }; + + onChange = e => { + e.persist(); + this.setState(state => { + return { + profile: { + ...state.profile, + [e.target.name]: e.target.value, + }, + }; + }); + }; + + onSubmit = e => { + e.preventDefault(); + + let profile = {}; + let errors = []; + for (let i = 0; i < e.target.length; i++) { + if (!!e.target[i].name) { + profile[e.target[i].name] = e.target[i].value; + + if (e.target[i].value === '') { + errors.push(e.target[i].name); + } + } + } + + this.props.updateAccountInfo(profile, this.props.token, 'company'); + this.setState({ modal: false }); + }; + + render() { + const { classes } = this.props; + return ( +
+

{this.state.profile.companyName}

+

{this.state.profile.email}

+

{this.state.profile.address}

+

{this.state.profile.bio}

+ {this.props.myProfile && ( + + )} + + +
+ ); + } +} + +const styles = { + root: { + marginTop: '3rem', + }, +}; + +CompanyProfile.propTypes = {}; + +function mapStateToProps(state) { + return { + token: state.appReducer.token, + }; +} + +export default connect( + mapStateToProps, + { updateAccountInfo } +)(withStyles(styles)(CompanyProfile)); diff --git a/src/components/InputText.js b/src/components/InputText.js index 23cf409..19a7610 100644 --- a/src/components/InputText.js +++ b/src/components/InputText.js @@ -1,7 +1,6 @@ -import React, { PureComponent } from 'react'; +import React from 'react'; import PropTypes from 'prop-types'; import { TextField, withStyles } from '@material-ui/core'; -import classes from 'classnames'; function getName(words) { let splitWords = words.toLowerCase().split(' '); @@ -36,7 +35,15 @@ const InputText = ({ /> ); -InputText.propTypes = {}; +InputText.propTypes = { + label: PropTypes.string, + multiLine: PropTypes.bool, + rows: PropTypes.number, + fullWidth: PropTypes.bool, + name: PropTypes.string, + errors: PropTypes.array, + classes: PropTypes.object.isRequired, +}; const styles = { textField: {}, diff --git a/src/components/JobComponent.js b/src/components/JobComponent.js index 4eb4b5b..5896be2 100644 --- a/src/components/JobComponent.js +++ b/src/components/JobComponent.js @@ -1,11 +1,10 @@ import React from 'react'; import PropTypes from 'prop-types'; import { withStyles } from '@material-ui/core'; -import MoreVertIcon from '@material-ui/icons/MoreVert'; -import { Card, CardHeader, IconButton } from '@material-ui/core'; -import SimplePopover from './SimplePopOver'; +import { Card, CardHeader } from '@material-ui/core'; import { Link } from 'react-router-dom'; import moment from 'moment'; +import MaterialUiPopOver from './MaterialUiPopOver'; class JobComponent extends React.Component { state = { @@ -32,21 +31,13 @@ class JobComponent extends React.Component { render() { const { classes } = this.props; + let url = `/profile/jobs/${this.props.job.id}`; + return (
- - - - } + action={} title={this.props.job.jobTitle} className={classes.cardHeader} subheader={moment(this.props.job.jobOpenDate).format( diff --git a/src/components/ListItemLink.js b/src/components/ListItemLink.js index dcedbbc..e126452 100644 --- a/src/components/ListItemLink.js +++ b/src/components/ListItemLink.js @@ -1,22 +1,10 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { withStyles } from '@material-ui/core/styles'; import ListItem from '@material-ui/core/ListItem'; import ListItemIcon from '@material-ui/core/ListItemIcon'; import ListItemText from '@material-ui/core/ListItemText'; import { Link } from 'react-router-dom'; -const styles = theme => ({ - root: { - display: 'flex', - flexDirection: 'column', - width: 360, - }, - lists: { - backgroundColor: theme.palette.background.paper, - }, -}); - class ListItemLink extends React.Component { renderLink = itemProps => ; @@ -55,4 +43,4 @@ ListItemLink.propTypes = { // to: PropTypes.string.isRequired, // }; -export default withStyles(styles)(ListItemLink); +export default ListItemLink; diff --git a/src/components/LoginForm.js b/src/components/LoginForm.js index d435223..2d08ea5 100644 --- a/src/components/LoginForm.js +++ b/src/components/LoginForm.js @@ -15,7 +15,7 @@ class LoginForm extends Component { e.preventDefault(); let account = {}; let errors = []; - //debugger; + for (let i = 0; i < e.target.length; i++) { if (!!e.target[i].name) { if (e.target[i].name === 'rememberMe') { diff --git a/src/components/MainStream.js b/src/components/MainStream.js index fc2b287..8ac786a 100644 --- a/src/components/MainStream.js +++ b/src/components/MainStream.js @@ -28,8 +28,12 @@ class MainStream extends Component { if (this.props.stream.length === 0) { return cards; } + let length = 5; + if (this.props.stream.length < 5) { + length = this.props.stream.length; + } - for (let i = 0; i < 5; i++) { + for (let i = 0; i < length; i++) { cards.push( ) : ( - + ) ) : ( '' diff --git a/src/components/MaterialUiPopOver.js b/src/components/MaterialUiPopOver.js new file mode 100644 index 0000000..049837c --- /dev/null +++ b/src/components/MaterialUiPopOver.js @@ -0,0 +1,73 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles, IconButton } from '@material-ui/core'; +import Popper from '@material-ui/core/Popper'; +import Typography from '@material-ui/core/Typography'; +import Button from '@material-ui/core/Button'; +import Fade from '@material-ui/core/Fade'; +import Paper from '@material-ui/core/Paper'; +import MoreVertIcon from '@material-ui/icons/MoreVert'; +import { Link } from 'react-router-dom'; + +const styles = theme => ({ + typography: { + padding: theme.spacing.unit * 2, + }, + navLink: { + color: 'black', + textDecoration: 'none', + }, +}); + +class MaterialUiPopOver extends React.Component { + state = { + anchorEl: null, + open: false, + }; + + handleClick = event => { + const { currentTarget } = event; + this.setState(state => ({ + anchorEl: currentTarget, + open: !state.open, + })); + }; + + render() { + const { classes } = this.props; + const { anchorEl, open } = this.state; + const id = open ? 'simple-popper' : null; + + return ( +
+ + + + + {({ TransitionProps }) => ( + + + +
+ + Profile + +
+
+
+
+ )} +
+
+ ); + } +} + +MaterialUiPopOver.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(MaterialUiPopOver); diff --git a/src/components/MiniDrawer.js b/src/components/MiniDrawer.js index 0d9c4fe..7aea461 100644 --- a/src/components/MiniDrawer.js +++ b/src/components/MiniDrawer.js @@ -1,67 +1,30 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { withStyles, Hidden } from '@material-ui/core'; +import { withStyles } from '@material-ui/core'; import Drawer from '@material-ui/core/Drawer'; -import CssBaseline from '@material-ui/core/CssBaseline'; import AppBar from '@material-ui/core/AppBar'; import Toolbar from '@material-ui/core/Toolbar'; -import List from '@material-ui/core/List'; import Typography from '@material-ui/core/Typography'; import Divider from '@material-ui/core/Divider'; -import ListItem from '@material-ui/core/ListItem'; -import ListItemIcon from '@material-ui/core/ListItemIcon'; -import ListItemText from '@material-ui/core/ListItemText'; -import InboxIcon from '@material-ui/icons/MoveToInbox'; -import MailIcon from '@material-ui/icons/Mail'; import MenuIcon from '@material-ui/icons/Menu'; import IconButton from '@material-ui/core/IconButton'; import SimpleList from './SimpleList'; import { Link } from 'react-router-dom'; -const drawerWidth = 240; - -const styles = theme => ({ - // root: { - // display: 'flex', - // }, - appBar: { - // marginRight: drawerWidth, - // width: '100%', - // [theme.breakpoints.down('lg')]: { - // width: `calc(100% - ${drawerWidth}px)`, - // }, - backgroundColor: '#2e4053', - }, - drawer: { - width: drawerWidth, - flexShrink: 0, +const styles = { + menuList: { + minWidth: '15%', + height: '25%', }, - drawerPaper: { - width: drawerWidth, - }, - // toolbar: theme.mixins.toolbar, - toolBar: { + header: { display: 'flex', justifyContent: 'space-between', }, - content: { - flexGrow: 1, - backgroundColor: theme.palette.background.default, - padding: theme.spacing.unit * 3, - }, - // header: { - // marginLeft: '200px', - // }, droomLink: { color: 'white', textDecoration: 'none', - fontFamily: 'Yellowtail, cursive', }, - // menuButton: { - // display: 'flex', - // alignSelf: 'flex-end', - // }, -}); +}; class PermanentDrawerRight extends React.Component { state = { @@ -76,62 +39,34 @@ class PermanentDrawerRight extends React.Component { const { classes } = this.props; return ( -
- - - - - + + + + + + - Droom + DROOM - - - - - - - - - - - - - - -
- - - - + + + +
); } diff --git a/src/components/MyMatches.js b/src/components/MyMatches.js index ba521a6..7e336d5 100644 --- a/src/components/MyMatches.js +++ b/src/components/MyMatches.js @@ -24,7 +24,7 @@ class MyMatches extends Component {
({ - root: { - width: '100%', - maxWidth: 360, - backgroundColor: theme.palette.background.paper, - }, -}); - function SimpleList(props) { - //debugger; const { classes } = props; let url = `/profile/user/${props.account.id}`; if (props.account.hasOwnProperty('companyName')) { url = `/profile/company/${props.account.id}`; } return ( -
- - } - /> - } - /> - } - /> - } - /> - -
+ + } /> + } + /> + } + /> + } + /> + ); } @@ -60,4 +44,4 @@ const mapStateToProps = state => ({ export default connect( mapStateToProps, {} -)(withStyles(styles)(SimpleList)); +)(SimpleList); diff --git a/src/components/SimpleModal.js b/src/components/SimpleModal.js index 2309668..80b0e53 100644 --- a/src/components/SimpleModal.js +++ b/src/components/SimpleModal.js @@ -1,6 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { withStyles, Typography, Button, Modal } from '@material-ui/core'; +import { withStyles, Typography, Modal } from '@material-ui/core'; function getModalStyle() { const top = 50; diff --git a/src/components/SimplePopOver.js b/src/components/SimplePopOver.js deleted file mode 100644 index 7c91cbf..0000000 --- a/src/components/SimplePopOver.js +++ /dev/null @@ -1,53 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import { withStyles } from '@material-ui/core/styles'; -import Popover from '@material-ui/core/Popover'; - -const styles = theme => ({ - typography: { - margin: theme.spacing.unit * 2, - }, -}); - -const SimplePopover = ({ - anchorEl, - classes, - handleClose, - getContent, - anchorOrginVert = 'bottom', - anchorOrginHorz = 'center', - transformOrginVert = 'top', - transformOrginHorz = 'center', - id, -}) => { - const open = Boolean(anchorEl); - return ( - - {getContent(id)} - - ); -}; - -SimplePopover.propTypes = { - classes: PropTypes.object.isRequired, - anchorEl: PropTypes.element, - handleClose: PropTypes.func.isRequired, - getContent: PropTypes.func.isRequired, - anchorOrginVert: PropTypes.string, - anchorOrginHorz: PropTypes.string, -}; - -export default withStyles(styles)(SimplePopover); diff --git a/src/components/UserProfile.js b/src/components/UserProfile.js index a0d04ba..45b4d3a 100644 --- a/src/components/UserProfile.js +++ b/src/components/UserProfile.js @@ -8,6 +8,7 @@ import SimpleModal from './SimpleModal'; import InputText from './InputText'; import { updateAccountInfo } from '../actions/accountActions'; import { connect } from 'react-redux'; +import faker from 'faker'; class UserProfile extends React.Component { state = { @@ -45,9 +46,18 @@ class UserProfile extends React.Component { ); }; + getChips = () => { + let chips = []; + let number = Math.floor(Math.random() * 5) + 5; + for (let i = 0; i < number; i++) { + chips.push(faker.fake('{{company.bsAdjective}}')); + } + return chips; + }; + onSubmit = e => { e.preventDefault(); - //debugger; + let profile = {}; let errors = []; for (let i = 0; i < e.target.length; i++) { @@ -66,7 +76,7 @@ class UserProfile extends React.Component { render() { const { classes } = this.props; - //debugger; + return (
{this.props.profile.userImg ? ( @@ -77,7 +87,7 @@ class UserProfile extends React.Component {

{this.props.profile.occupation}

{this.props.profile.interests ? ( - + ) : ( '' )} @@ -115,6 +125,7 @@ const styles = { root: { height: '100%', width: '100%', + marginTop: '3rem', }, }; diff --git a/src/reducers/accountReducer.js b/src/reducers/accountReducer.js index def6ce2..372d8ea 100644 --- a/src/reducers/accountReducer.js +++ b/src/reducers/accountReducer.js @@ -17,6 +17,7 @@ export const accountReducer = (state = initialState, action) => { case UPDATING_ACCOUNT_INFO: return { ...state, updatingAccountInfo: true }; case ACCOUNT_INFORMATION_UPDATED: + action.payload.account.id = state.account.id; return { ...state, updatingAccountInfo: false, diff --git a/src/views/Login.js b/src/views/Login.js index 9b406c8..78a7c6e 100644 --- a/src/views/Login.js +++ b/src/views/Login.js @@ -32,7 +32,6 @@ class Login extends Component { if (this.props.authenticated) { return ; } - const { classes } = this.props; return ( { + let id = props.match.params.id; + let profileType = props.match.params.accountType; let profileOwner = false; let accountType = 'user'; - if (this.props.account.hasOwnProperty('companyName')) { + if (props.account.hasOwnProperty('companyName')) { accountType = 'company'; } - if ( - parseInt(id) === this.props.account.id && - profileType === accountType - ) { + if (parseInt(id) === props.account.id && profileType === accountType) { profileOwner = true; } @@ -35,19 +35,19 @@ class Profile extends Component { if (profileType === 'job') { url = `/jobs/${id}`; } else if (profileType === 'company') { - url = `/company/${id}`; + url = `/companies/${id}`; } if (profileType === 'user' && profileOwner) { url = `/users/info`; } - requestWithToken(this.props.token) + requestWithToken(props.token) .get(url) .then(res => { - //debugger; + debugger; if (accountType === 'company' && profileType === 'job') { - if (res.data.company_id === this.props.account.id) { + if (res.data.company_id === props.account.id) { profileOwner = true; } } @@ -58,13 +58,22 @@ class Profile extends Component { }); }) .catch(err => { - //debugger; console.log(err.message); }); + }; + + componentWillUpdate(nextProps, nextState, nextContext) { + if ( + nextProps.match.params.id !== this.props.match.params.id || + nextProps.match.params.accountType !== + this.props.match.params.accountType + ) { + this.getProfile(nextProps); + return true; + } } render() { - //debugger; const { classes } = this.props; return (