diff --git a/src/actions/employer/reducer.actions.js b/src/actions/employer/reducer.actions.js new file mode 100644 index 0000000..9eaad0b --- /dev/null +++ b/src/actions/employer/reducer.actions.js @@ -0,0 +1,42 @@ +import { + IS_SENDING_EMPLOYER_REQUEST, + SET_EMPLOYER_REQUEST_ERROR, + CLEAR_EMPLOYER_REQUEST_ERROR, + SET_EMPLOYER_REQUEST_SUCCESS, + CLEAR_EMPLOYER_REQUEST_SUCCESS +} from "../../constants/employer.constants"; +import { parseError } from "../common.actions"; + +export function isSendingEmployerRequest(sendingRequest) { + return { + type: IS_SENDING_EMPLOYER_REQUEST, + data: sendingRequest + }; +} + +export function setEmployerRequestError(exception) { + let error = parseError(exception); + return { + type: SET_EMPLOYER_REQUEST_ERROR, + data: error + }; +} + +export function clearEmployerRequestError() { + return { + type: CLEAR_EMPLOYER_REQUEST_ERROR + }; +} + +export function setEmployerRequestSuccess(response) { + return { + type: SET_EMPLOYER_REQUEST_SUCCESS, + data: response.detail || response + }; +} + +export function clearEmployerRequestSuccess() { + return { + type: CLEAR_EMPLOYER_REQUEST_SUCCESS + }; +} diff --git a/src/actions/employer/saga.actions.js b/src/actions/employer/saga.actions.js new file mode 100644 index 0000000..a593fbb --- /dev/null +++ b/src/actions/employer/saga.actions.js @@ -0,0 +1,8 @@ +import { UPDATE_EMPLOYER_REQUEST } from "../../constants/employer.constants"; + +export function updateEmployerRequest(payload) { + return { + type: UPDATE_EMPLOYER_REQUEST, + data: payload + }; +} diff --git a/src/api/employer.api.js b/src/api/employer.api.js new file mode 100644 index 0000000..f6ee023 --- /dev/null +++ b/src/api/employer.api.js @@ -0,0 +1,12 @@ +import { put } from "./baseApi"; + +/** + * Function wrapping PATCH request for updating employer information + * @param {string} uuid - employer UUID + * @param {boolean} approved - whether or not to approve employment relationship + */ +export function updateEmployer(uuid, approved) { + return put(`/employer/${uuid}/`, { approved }).then(resp => + Promise.resolve(resp) + ); +} diff --git a/src/components/App.jsx b/src/components/App.jsx index c2c5881..bf45cd1 100644 --- a/src/components/App.jsx +++ b/src/components/App.jsx @@ -12,6 +12,7 @@ import UpdateWorkTypeForm from "./Worktype/UpdateWorkTypeForm"; import Worktypes from "./Worktype/Worktypes"; import ClientProviders from "./User/Client/ClientProviders"; import ClientAddProviderForm from "./User/Client/ClientAddProviderForm"; +import ProviderClients from "./User/Provider/ProviderClients"; import CompleteRegistration from "./User/CompleteRegistration"; import EditProfile from "./User/EditProfile"; import Profile from "./User/Profile"; @@ -71,6 +72,10 @@ class App extends Component { path="/user/profile/client/add-provider" component={ClientAddProviderForm} /> + diff --git a/src/components/Navbar.jsx b/src/components/Navbar.jsx index 83a7c9b..8086d27 100644 --- a/src/components/Navbar.jsx +++ b/src/components/Navbar.jsx @@ -73,6 +73,11 @@ const NavbarView = ({ isAuthenticated, dispatchLogoutRequest, selfUser }) => ( Providers )} + {selfUser.provider && ( + + Clients + + )} Settings diff --git a/src/components/User/Client/ClientAddProviderForm.jsx b/src/components/User/Client/ClientAddProviderForm.jsx index 31edcc3..b6aefe4 100644 --- a/src/components/User/Client/ClientAddProviderForm.jsx +++ b/src/components/User/Client/ClientAddProviderForm.jsx @@ -111,13 +111,13 @@ const ClientAddProviderFormView = ({ - Create Worktype successful! -

Worktype successfully created.

+ Create Provider successful! +

Provider successfully created.

{!!employeeRequestSuccess && ( )}
- Submit Worktype + Submit Provider ); diff --git a/src/components/User/Client/ClientProviders.jsx b/src/components/User/Client/ClientProviders.jsx index a733e06..9adb853 100644 --- a/src/components/User/Client/ClientProviders.jsx +++ b/src/components/User/Client/ClientProviders.jsx @@ -6,6 +6,8 @@ import { Card, Container, Header, + Label, + List, Popup, Segment } from "semantic-ui-react"; @@ -57,8 +59,48 @@ const ClientProvidersView = ({ user, deleteEmployee }) => ( .map((employee, index) => ( - {employee.provider} - {employee.note} + {(employee.approved === null || + employee.approved === false) && ( +
+ {employee.provider} + {employee.note} +
+ )} + {employee.approved && ( +
+ + {`${employee.provider.first_name} ${ + employee.provider.last_name + }`.trim() || "No Name!"} + + + {employee.provider.userinfo && ( + + {employee.provider.userinfo.phone_number && ( + + Phone Number:{" "} + {employee.provider.userinfo.phone_number} + + )} + + )} + +
+ )} + +
+ diff --git a/src/components/User/Provider/ProviderClients.jsx b/src/components/User/Provider/ProviderClients.jsx new file mode 100644 index 0000000..a7e627d --- /dev/null +++ b/src/components/User/Provider/ProviderClients.jsx @@ -0,0 +1,133 @@ +import React, { Component } from "react"; +import { connect } from "react-redux"; +import { Redirect } from "react-router-dom"; +import { + Button, + Card, + Container, + Header, + Label, + List +} from "semantic-ui-react"; +import { updateEmployerRequest } from "../../../actions/employer/saga.actions"; + +class ProviderClients extends Component { + updateEmployer = (uuid, approved) => { + this.props.dispatch(updateEmployerRequest({ uuid, approved })); + }; + + render() { + const { selfUser } = this.props; + if (selfUser.provider) { + return ( + + ); + } else { + return ; + } + } +} + +function mapStateToProps(state) { + return { selfUser: state.user.selfUser }; +} + +const ProviderClientsView = ({ user, updateEmployer }) => ( + +
Clients
+ {(user.provider.employers || []).filter(employer => !employer.deleted) + .length > 0 && ( + + {user.provider.employers + .filter(employer => !employer.deleted) + .map((employer, index) => ( + + + {(employer.approved === null || + employer.approved === false) && ( +
+ + {employer.client.trim() || "No Name!"} + + {employer.note} +
+ )} + {employer.approved && ( +
+ + {`${employer.client.first_name} ${ + employer.client.last_name + }`.trim() || "No Name!"} + + + {employer.client.userinfo && ( + + {employer.client.userinfo.phone_number && ( + + Phone Number:{" "} + {employer.client.userinfo.phone_number} + + )} + + )} + +
+ )} + +
+ + + {!employer.approved && ( + + )} + {employer.approved === null && ( + + )} + {employer.approved && ( + + )} + + +
+ ))} +
+ )} +
+); + +export default connect(mapStateToProps)(ProviderClients); diff --git a/src/constants/employee.constants.js b/src/constants/employee.constants.js index ce6db54..cf495f3 100644 --- a/src/constants/employee.constants.js +++ b/src/constants/employee.constants.js @@ -9,7 +9,7 @@ export const SET_FORM_EMPLOYEE_EMAIL = "SET_FORM_EMPLOYEE_EMAIL"; export const SET_FORM_EMPLOYEE_NOTE = "SET_FORM_EMPLOYEE_NOTE"; export const SET_CLEAR_EMPLOYEE_STATE = "SET_CLEAR_EMPLOYEE_STATE"; -// Saga Worktype Action Constants +// Saga Employee Action Constants export const CREATE_EMPLOYEE_REQUEST = "CREATE_EMPLOYEE_REQUEST"; export const READ_EMPLOYEE_REQUEST = "READ_EMPLOYEE_REQUEST"; export const DELETE_EMPLOYEE_REQUEST = "DELETE_EMPLOYEE_REQUEST"; diff --git a/src/constants/employer.constants.js b/src/constants/employer.constants.js new file mode 100644 index 0000000..98ac7ca --- /dev/null +++ b/src/constants/employer.constants.js @@ -0,0 +1,9 @@ +// Reducer Employer Action Constants +export const IS_SENDING_EMPLOYER_REQUEST = "IS_SENDING_EMPLOYER_REQUEST"; +export const SET_EMPLOYER_REQUEST_ERROR = "SET_EMPLOYER_REQUEST_ERROR"; +export const CLEAR_EMPLOYER_REQUEST_ERROR = "CLEAR_EMPLOYER_REQUEST_ERROR"; +export const SET_EMPLOYER_REQUEST_SUCCESS = "SET_EMPLOYER_REQUEST_SUCCESS"; +export const CLEAR_EMPLOYER_REQUEST_SUCCESS = "CLEAR_EMPLOYER_REQUEST_SUCCESS"; + +// Saga Employer Action Constants +export const UPDATE_EMPLOYER_REQUEST = "UPDATE_EMPLOYER_REQUEST"; diff --git a/src/reducers/employerReducer.js b/src/reducers/employerReducer.js new file mode 100644 index 0000000..5d1be41 --- /dev/null +++ b/src/reducers/employerReducer.js @@ -0,0 +1,47 @@ +import { + IS_SENDING_EMPLOYER_REQUEST, + SET_EMPLOYER_REQUEST_ERROR, + CLEAR_EMPLOYER_REQUEST_ERROR, + SET_EMPLOYER_REQUEST_SUCCESS, + CLEAR_EMPLOYER_REQUEST_SUCCESS +} from "../constants/employer.constants"; + +const initialState = { + isSendingEmployerRequest: false, + employerRequestError: "", + employerRequestSuccess: "" +}; + +function employerReducer(state = initialState, action) { + switch (action.type) { + case IS_SENDING_EMPLOYER_REQUEST: + return { + ...state, + isSendingEmployerRequest: action.data + }; + case SET_EMPLOYER_REQUEST_ERROR: + return { + ...state, + employerRequestError: action.data + }; + case CLEAR_EMPLOYER_REQUEST_ERROR: + return { + ...state, + employerRequestError: "" + }; + case SET_EMPLOYER_REQUEST_SUCCESS: + return { + ...state, + employerRequestSuccess: action.data + }; + case CLEAR_EMPLOYER_REQUEST_SUCCESS: + return { + ...state, + employerRequestSuccess: "" + }; + default: + return state; + } +} + +export default employerReducer; diff --git a/src/sagas/employee.sagas.js b/src/sagas/employee.sagas.js index 13db916..f08fa2c 100644 --- a/src/sagas/employee.sagas.js +++ b/src/sagas/employee.sagas.js @@ -10,7 +10,12 @@ import { setFormEmployeeNote } from "../actions/employee/reducer.actions"; import { getSelfUserRequest } from "../actions/user/saga.actions"; -import { addEmployee, getEmployee, deleteEmployee, updateEmployee } from "../api/employee.api"; +import { + addEmployee, + getEmployee, + deleteEmployee, + updateEmployee +} from "../api/employee.api"; function* addEmployeeCall(postBody) { yield effects.put(isSendingEmployeeRequest(true)); @@ -46,7 +51,7 @@ function* updateEmployeeCall(payload) { yield effects.put(setEmployeeRequestError(exception)); return false; } finally { - yield effects.put(isSendingEmployeeRequest(false)) + yield effects.put(isSendingEmployeeRequest(false)); } } @@ -78,9 +83,9 @@ export function* addEmployeeFlow(request) { export function* readEmployeeFlow(request) { const wasSuccessful = yield effects.call(readEmployeeCall, request.data); if (wasSuccessful) { - yield effects.put(setEmployeeUUID(wasSuccessful.uuid)) + yield effects.put(setEmployeeUUID(wasSuccessful.uuid)); yield effects.put(setFormEmployeeEmail(wasSuccessful.provider_email)); - yield effects.put(setFormEmployeeNote(wasSuccessful.note)) + yield effects.put(setFormEmployeeNote(wasSuccessful.note)); } } @@ -97,4 +102,4 @@ export function* updateEmployeeFlow(request) { export function* deleteEmployeeFlow(request) { yield effects.call(deleteEmployeeCall, request.data); yield effects.put(getSelfUserRequest()); -} \ No newline at end of file +} diff --git a/src/sagas/employer.sagas.js b/src/sagas/employer.sagas.js new file mode 100644 index 0000000..cbb1573 --- /dev/null +++ b/src/sagas/employer.sagas.js @@ -0,0 +1,34 @@ +import { effects } from "redux-saga"; +import { + isSendingEmployerRequest, + setEmployerRequestError, + setEmployerRequestSuccess, + clearEmployerRequestError, + clearEmployerRequestSuccess +} from "../actions/employer/reducer.actions"; +import { getSelfUserRequest } from "../actions/user/saga.actions"; +import { updateEmployer } from "../api/employer.api"; + +function* updateEmployerCall(payload) { + yield effects.put(isSendingEmployerRequest(true)); + const { uuid, approved } = payload; + try { + return yield effects.call(updateEmployer, uuid, approved); + } catch (exception) { + yield effects.put(setEmployerRequestError(exception)); + return false; + } finally { + yield effects.put(isSendingEmployerRequest(false)); + } +} + +export function* updateEmployerFlow(request) { + yield effects.put(clearEmployerRequestSuccess()); + yield effects.put(clearEmployerRequestError()); + const wasSuccessful = yield effects.call(updateEmployerCall, request.data); + if (wasSuccessful) { + yield effects.put(getSelfUserRequest()); + yield effects.put(setEmployerRequestSuccess(wasSuccessful)); + yield effects.put(clearEmployerRequestError()); + } +} diff --git a/src/sagas/index.js b/src/sagas/index.js index 76caf21..27cd98f 100644 --- a/src/sagas/index.js +++ b/src/sagas/index.js @@ -57,6 +57,8 @@ import { readEmployeeFlow, deleteEmployeeFlow } from "./employee.sagas"; +import { UPDATE_EMPLOYER_REQUEST } from "../constants/employer.constants"; +import { updateEmployerFlow } from "./employer.sagas"; export default function* rootSaga() { yield takeLatest(SEND_REGISTER_REQUEST, registerUserFlow); @@ -80,4 +82,5 @@ export default function* rootSaga() { yield takeLatest(CREATE_EMPLOYEE_REQUEST, addEmployeeFlow); yield takeLatest(READ_EMPLOYEE_REQUEST, readEmployeeFlow); yield takeLatest(DELETE_EMPLOYEE_REQUEST, deleteEmployeeFlow); + yield takeLatest(UPDATE_EMPLOYER_REQUEST, updateEmployerFlow); }