Skip to content

Commit

Permalink
feat: Employers Bank accounts (JobCore#8)
Browse files Browse the repository at this point in the history
feat: Employers Bank accounts
  • Loading branch information
alacret authored Jan 10, 2020
2 parents 01ca6ed + 4423ff7 commit 79c6741
Show file tree
Hide file tree
Showing 14 changed files with 284 additions and 2 deletions.
4 changes: 3 additions & 1 deletion .env.dev
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
API_HOST=https://jobcore.herokuapp.com
GOOGLE_MAPS_KEY=AIzaSyDsJKar6kRvBW6_y84fmT9fEJgj3F0djSY
DEBUG=true

PLAID_PUBLIC_KEY=037db4bdc6e10afa8721a838cc6138
//PLAID_ENVIRONMENT=sandbox
PLAID_ENVIRONMENT=production
APPSTORE=https://apps.apple.com/us/app/jobcore-talent/id1437290430
ANDROID=https://play.google.com/store/apps/details?id=co.jobcore.talent&hl=en_US
62 changes: 62 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,14 @@
"react-dropzone": "^10.1.5",
"react-joyride": "^2.0.0-14",
"react-places-autocomplete": "^7.2.0",
"react-plaid-link": "^1.5.0",
"react-polyfills": "0.0.1",
"react-router": "^4.2.0",
"react-router-dom": "^4.2.2",
"react-select": "^2.0.0",
"react-svg-inline": "^2.1.1",
"react-transition-group": "^2.4.0",
"snake-case": "^3.0.3",
"underscore": "^1.9.1",
"validator": "^10.4.0"
}
Expand Down
1 change: 1 addition & 0 deletions src/js/Layout.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class Layout extends Flux.View{
<PrivateRoute exact path='/favorites' component={PrivateLayout} />
<PrivateRoute exact path='/rate' component={PrivateLayout} />
<PrivateRoute exact path='/profile' component={PrivateLayout} />
<PrivateRoute exact path='/employer-bank-accounts' component={PrivateLayout} />
<PrivateRoute exact path='/applicants' component={PrivateLayout} />
<PrivateRoute exact path='/calendar' component={PrivateLayout} />
<PrivateRoute exact path='/shifts' component={PrivateLayout} />
Expand Down
2 changes: 2 additions & 0 deletions src/js/PrivateLayout.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import logoURL from '../img/logo.png';
import loadingURL from '../img/loading2.gif';
import moment from 'moment';
import {EngineComponent} from "./utils/write_engine";
import EmployerBankAccounts from "../js/views/employerBankAccounts";
class PrivateLayout extends Flux.DashView{

constructor(){
Expand Down Expand Up @@ -348,6 +349,7 @@ class PrivateLayout extends Flux.DashView{
<Route exact path='/talents' component={ManageTalents} />
<Route exact path='/favorites' component={ManageFavorites} />
<Route exact path='/locations' component={ManageLocations} />
<Route exact path='/employer-bank-accounts' component={EmployerBankAccounts} />
<Route exact path='/payroll-settings' component={PayrollSettings} />
<Route exact path='/profile' component={Profile} />
<Route exact path='/payroll' component={ManagePayroll} />
Expand Down
45 changes: 44 additions & 1 deletion src/js/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {POST, GET, PUT, DELETE, PUTFiles} from './utils/api_wrapper';
import log from './utils/log';
import WEngine from "./utils/write_engine.js";
import qs from "query-string";

import { normalizeToSnakeCase } from "./utils/snakeCase";
const Models = {
"shifts": Shift,
"ratings": Rating,
Expand Down Expand Up @@ -49,6 +49,20 @@ export const login = (email, password, keep, history) => new Promise((resolve, r
})
);

export const addBankAccount = (token, metadata) => new Promise((resolve, reject) => POST('bank-accounts/',
normalizeToSnakeCase({ publicToken: token, institutionName: metadata.institution.name }))
.then(function(data){
console.log('addBankAccount data: ', data);
resolve();
searchBankAccounts();
})
.catch(function(error) {
reject(error.message || error);
Notify.error(error.message || error);
log.error(error);
})
);

export const signup = (formData, history) => new Promise((resolve, reject) => POST('user/register', {
email: formData.email,
account_type: formData.account_type,
Expand Down Expand Up @@ -241,6 +255,20 @@ export const searchMe = (entity, queryString) => new Promise((accept, reject) =>
})
);

export const searchBankAccounts = () => new Promise((accept, reject) =>
GET('bank-accounts/')
.then(function(list){
console.log("bank-accounts list: ", list);
Flux.dispatchEvent('bank-accounts', list);
accept(list);
})
.catch(function(error) {
Notify.error(error.message || error);
log.error(error);
reject(error);
})
);

export const create = (entity, data, status='live') => POST('employers/me/'+(entity.url || entity), data)
.then(function(incoming){
let entities = store.getState(entity.slug || entity);
Expand Down Expand Up @@ -325,6 +353,20 @@ export const remove = (entity, data) => {
});
};

export const removeBankAccount = (route, data) => {
const path = `${route}/${data.id}`;
DELETE(path)
.then(() => {
Notify.success("The "+data.name+" was deleted successfully");
searchBankAccounts();
})
.catch((error) => {
console.log("bank-accounts error: ", error);
Notify.error(error.message || error);
log.error(error);
});
};

export const rejectCandidate = (shiftId, applicant) => {
const shift = store.get('shifts', shiftId);
if(shift){
Expand Down Expand Up @@ -460,6 +502,7 @@ class _Store extends Flux.DashStore{
this.addEvent('clockins', clockins => !Array.isArray(clockins) ? [] : clockins.map(c => ({...c, started_at: moment(c.starting_at), ended_at: moment(c.ended_at) })));
this.addEvent('jobcore-invites');
this.addEvent('ratings');
this.addEvent('bank-accounts');
this.addEvent('employees', (employees) => {
if(!Array.isArray(employees)) return [];
return employees.filter(em => em.user.profile).map(em => Talent(em).defaults().unserialize());
Expand Down
36 changes: 36 additions & 0 deletions src/js/components/bankaccount-card/BankAccountExtendedCard.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import './style.scss';
import React from "react";
import PropTypes from 'prop-types';
import deleteIcon from "../../../img/icons/delete.png";

const BankAccountExtendedCard = ({
account,
onDelete,
}) => {
return (
<tr>
<td>
<b>{account.institution_name}</b>
</td>
<td>
<b>{account.name}</b>
</td>
<td>
<img
onClick={() => onDelete(account)}
src={deleteIcon}
className={"delete-icon"}
/>
</td>
</tr>);
};
BankAccountExtendedCard.propTypes = {
account: PropTypes.object.isRequired,
onDelete: PropTypes.func
};
BankAccountExtendedCard.defaultProps = {
account: {},
onDelete: null,
};

export default BankAccountExtendedCard;
8 changes: 8 additions & 0 deletions src/js/components/bankaccount-card/style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
@import '../theme/style.scss';
.delete-icon{
width: 15px;
cursor: pointer;
}
.b{
word-wrap: break-word;
}
1 change: 1 addition & 0 deletions src/js/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export const AcceptReject = require('./accept-reject/AcceptReject').default;
export const ApplicantCard = require('./applicant-card/ApplicantCard').default;
export const EmployeeExtendedCard = require('./applicant-card/EmployeeExtendedCard').default;
export const DeductionExtendedCard = require('./deduction-card/DeductionExtendedCard').default;
export const BankAccountExtendedCard = require('./bankaccount-card/BankAccountExtendedCard').default;
export const Avatar = require('./avatar/Avatar').default;
export const DashboardBox = require('./dashboard-box/DashboardBox').default;
export const ShiftCard = require('./shift-card/ShiftCard').default;
Expand Down
10 changes: 10 additions & 0 deletions src/js/utils/snakeCase.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { snakeCase } from 'snake-case';

export const normalizeToSnakeCase = (map) => {
const entries = Object.entries(map);
const newMap = {};
entries.forEach(([key, value]) => {
newMap[snakeCase(key)] = value;
});
return newMap;
};
7 changes: 7 additions & 0 deletions src/js/views/ButtonBar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ class ButtonBar extends React.Component {
{ slug: "select_timesheet", title: 'Select Timesheet', to: 'payroll'},
],
"profile": [
{ slug: "manage_locations", title: 'Company Locations', to: 'locations'},
{ slug: "payroll_settings", title: 'Payroll Settings', to: 'payroll-settings'},
{ slug: "my_ratings", title: 'Company Ratings', to: 'ratings'},
{ slug: "employer_bank_accounts", title: 'Employer bank accounts', to: 'employer-bank-accounts'},
// { slug: "company_users", title: 'Company Users', to: 'company-users'}
],
"employer-bank-accounts": [
{ slug: "manage_locations", title: 'Company Locations', to: 'locations'},
{ slug: "payroll_settings", title: 'Payroll Settings', to: 'payroll-settings'},
{ slug: "my_ratings", title: 'Company Ratings', to: 'ratings'},
Expand Down
Loading

0 comments on commit 79c6741

Please sign in to comment.