From 805f20e040338f49dfeec5a03096d54c214bce37 Mon Sep 17 00:00:00 2001 From: Alexander Wong Date: Mon, 23 Apr 2018 11:07:33 -0600 Subject: [PATCH] working details view, approve/reject --- src/actions/pShift/saga.actions.js | 20 +- src/api/pShift.api.js | 10 +- src/components/App.jsx | 5 + .../User/Client/ClientEditShiftForm.jsx | 7 +- src/components/User/Client/ClientShifts.jsx | 48 +++-- .../User/Provider/ProviderShift.jsx | 174 ++++++++++++++++++ .../User/Provider/ProviderShifts.jsx | 103 ++++++++--- src/constants/pShift.constants.js | 2 + src/sagas/index.js | 14 +- src/sagas/pShift.sagas.js | 53 +++++- 10 files changed, 389 insertions(+), 47 deletions(-) create mode 100644 src/components/User/Provider/ProviderShift.jsx diff --git a/src/actions/pShift/saga.actions.js b/src/actions/pShift/saga.actions.js index 3f081ac..550f99b 100644 --- a/src/actions/pShift/saga.actions.js +++ b/src/actions/pShift/saga.actions.js @@ -1,4 +1,8 @@ -import { GET_PSHIFTS_REQUEST } from "../../constants/pShift.constants"; +import { + GET_PSHIFTS_REQUEST, + GET_PSHIFT_REQUEST, + UPDATE_PSHIFT_REQUEST +} from "../../constants/pShift.constants"; export function getPShiftsRequest(params) { return { @@ -6,3 +10,17 @@ export function getPShiftsRequest(params) { data: params }; } + +export function getPShiftRequest(payload) { + return { + type: GET_PSHIFT_REQUEST, + data: payload + } +} + +export function updatePShiftRequest(payload) { + return { + type: UPDATE_PSHIFT_REQUEST, + data: payload + }; +} diff --git a/src/api/pShift.api.js b/src/api/pShift.api.js index bbd0a9b..8473931 100644 --- a/src/api/pShift.api.js +++ b/src/api/pShift.api.js @@ -1,5 +1,13 @@ -import { get } from "./baseApi"; +import { get, put } from "./baseApi"; export function getPShifts(params) { return get("/pshift/", params).then(resp => Promise.resolve(resp)); } + +export function getPShift(uuid) { + return get(`/pshift/${uuid}/`).then(resp => Promise.resolve(resp)); +} + +export function updatePShift(uuid, params) { + return put(`/pshift/${uuid}/`, params).then(resp => Promise.resolve(resp)); +} diff --git a/src/components/App.jsx b/src/components/App.jsx index 0e11d6c..3d9edd4 100644 --- a/src/components/App.jsx +++ b/src/components/App.jsx @@ -18,6 +18,7 @@ import ClientShifts from "./User/Client/ClientShifts"; import ClientAddShiftForm from "./User/Client/ClientAddShiftForm"; import ClientEditShiftForm from "./User/Client/ClientEditShiftForm"; import ProviderClients from "./User/Provider/ProviderClients"; +import ProviderShift from "./User/Provider/ProviderShift"; import ProviderShifts from "./User/Provider/ProviderShifts"; import CompleteRegistration from "./User/CompleteRegistration"; import EditProfile from "./User/EditProfile"; @@ -102,6 +103,10 @@ class App extends Component { path="/user/profile/provider/clients" component={ProviderClients} /> + ; + } else if (!cShiftRequestErrors.length > 0) { + return ; } else { - return ; + return ; } } } diff --git a/src/components/User/Client/ClientShifts.jsx b/src/components/User/Client/ClientShifts.jsx index 76cd261..feb866f 100644 --- a/src/components/User/Client/ClientShifts.jsx +++ b/src/components/User/Client/ClientShifts.jsx @@ -105,29 +105,33 @@ const ClientShiftsView = ({ Schedule a Shift - {!!isSendingCShiftRequest && } + {!!isSendingCShiftRequest && } {!isSendingCShiftRequest && results.length > 0 && ( {results.map(result => { - const employee = getEmployeeFromPrice(result.price, user); - const price = getPriceFromPrice(result.price, user); + const employee = getEmployeeFromPrice(result.price, user) || {}; + const provider = employee.provider || {}; + const price = getPriceFromPrice(result.price, user) || {}; const workType = price.work_type; const min = duration( utc(result.set_end, ISO_8601) - utc(result.set_start, ISO_8601), "milliseconds" ).as("minutes"); - let displayText = duration(min, "minutes").humanize(); + let displayDuration = duration(min, "minutes").humanize(); if (min % 60) { - displayText = duration( + displayDuration = duration( Math.floor(min / 60), "hours" ).humanize(); - displayText += ` and ${duration( + displayDuration += ` and ${duration( min % 60, "minutes" ).humanize()}`; } + const approved = !!result.approved; + const rejected = !result.approved && result.approved !== null; + const pending = result.approved === null; return ( @@ -142,24 +146,32 @@ const ClientShiftsView = ({ /> {workType.label} + + + {"At " + utc(result.set_start, ISO_8601) .local(false) - .format("dddd, MMMM Do YYYY, h:mm a Z") + - "; for " + - displayText + - "; rate $" + - price.amount + - "/hour"} + .format("dddd, MMMM Do YYYY, h:mm a Z")} - {result.description} + {displayDuration} + {`Rate $${price.amount}/hour`} + {/* {result.description} */} {/* {JSON.stringify(result, null, 2)} */} - - - {employee.provider.email} - - + + {`${provider.first_name} ${provider.last_name}`.trim() || + "No Name!"}{" "} + {provider.email} + {result.actual_start === null && ( diff --git a/src/components/User/Provider/ProviderShift.jsx b/src/components/User/Provider/ProviderShift.jsx new file mode 100644 index 0000000..84f4115 --- /dev/null +++ b/src/components/User/Provider/ProviderShift.jsx @@ -0,0 +1,174 @@ +import { utc, duration, ISO_8601 } from "moment"; +import React, { Component } from "react"; +import { connect } from "react-redux"; +import { Redirect } from "react-router-dom"; +import { + Button, + Container, + Header, + Label, + List, + Loader, + Message +} from "semantic-ui-react"; +import { setClearPShiftState } from "../../../actions/pShift/reducer.actions"; +import { + getPShiftRequest, + updatePShiftRequest +} from "../../../actions/pShift/saga.actions"; +import Error from "../../Shared/Error"; +import { + getEmployerFromPrice, + getWorkTypeFromPrice, + getPriceFromPrice +} from "./ProviderShiftsShared"; + +class ProviderShift extends Component { + handleChangePShiftApproval = (uuid, approved) => { + return () => { + this.props.dispatch( + updatePShiftRequest({ + uuid, + approved, + action: "", + chart: null, + single: true + }) + ); + }; + }; + + render() { + const { + isSendingPShiftRequest, + pShiftRequestError, + pShiftRequestSuccess, + selfUser + } = this.props; + + if (!selfUser.provider) { + return ; + } + return ( + + ); + } +} + +const ProviderShiftFormView = ({ + isSendingPShiftRequest, + pShiftRequestError, + shift, + user, + handleChangePShiftApproval +}) => { + const employer = getEmployerFromPrice(shift.price, user) || {}; + const client = employer.client || {}; + const workType = getWorkTypeFromPrice(shift.price, user) || {}; + const price = getPriceFromPrice(shift.price, user) || {}; + const min = duration( + utc(shift.set_end, ISO_8601) - utc(shift.set_start, ISO_8601), + "milliseconds" + ).as("minutes"); + let displayDuration = duration(min, "minutes").humanize(); + if (min % 60) { + displayDuration = duration(Math.floor(min / 60), "hours").humanize(); + displayDuration += ` and ${duration(min % 60, "minutes").humanize()}`; + } + const approved = !!shift.approved; + const rejected = !shift.approved && shift.approved !== null; + const pending = shift.approved === null; + return ( + +
Shift Details
+ + +
+ ); +}; + +function mapStateToProps(state) { + return { ...state.pShift, selfUser: state.user.selfUser }; +} + +class ProviderShiftWrapper extends Component { + constructor(props) { + super(props); + this.props.dispatch(setClearPShiftState()); + this.props.dispatch( + getPShiftRequest({ uuid: this.props.match.params.shiftUUID }) + ); + } + + render() { + const { pShiftRequestSuccess, pShiftRequestError } = this.props; + if (pShiftRequestSuccess.uuid) { + return ; + } else if (!pShiftRequestError) { + return ; + } else { + return ; + } + } +} + +export default connect(mapStateToProps)(ProviderShiftWrapper); diff --git a/src/components/User/Provider/ProviderShifts.jsx b/src/components/User/Provider/ProviderShifts.jsx index 8150180..0431d06 100644 --- a/src/components/User/Provider/ProviderShifts.jsx +++ b/src/components/User/Provider/ProviderShifts.jsx @@ -1,8 +1,9 @@ import { utc, ISO_8601, duration } from "moment"; import React, { Component } from "react"; import { connect } from "react-redux"; -import { Redirect } from "react-router-dom"; +import { Redirect, Link } from "react-router-dom"; import { + Button, Container, Header, Item, @@ -14,7 +15,10 @@ import { getEmployerFromPrice, getPriceFromPrice } from "./ProviderShiftsShared"; -import { getPShiftsRequest } from "../../../actions/pShift/saga.actions"; +import { + getPShiftsRequest, + updatePShiftRequest +} from "../../../actions/pShift/saga.actions"; class ProviderShifts extends Component { constructor(props) { @@ -44,6 +48,14 @@ class ProviderShifts extends Component { this.setState({ page: activePage }); }; + handleChangePShiftApproval = (uuid, approved) => { + return () => { + this.props.dispatch( + updatePShiftRequest({ uuid, approved, action: "", chart: null }) + ); + }; + }; + render() { const { isSendingPShiftRequest, @@ -60,6 +72,7 @@ class ProviderShifts extends Component { pageSize={pageSize} user={selfUser} handlePaginationChange={this.handlePaginationChange} + handleChangePShiftApproval={this.handleChangePShiftApproval} /> ); } else { @@ -78,35 +91,40 @@ const ProviderShiftsView = ({ user, page, pageSize, - handlePaginationChange + handlePaginationChange, + handleChangePShiftApproval }) => { const { count = 0, results = [] } = pShiftRequestSuccess; return (
Shifts
- {!!isSendingPShiftRequest && } + {!!isSendingPShiftRequest && } {!isSendingPShiftRequest && results.length > 0 && ( {results.map(result => { - const employer = getEmployerFromPrice(result.price, user); - const price = getPriceFromPrice(result.price, user); - const workType = price.work_type; + const employer = getEmployerFromPrice(result.price, user) || {}; + const client = employer.client || {}; + const price = getPriceFromPrice(result.price, user) || {}; + const workType = price.work_type || {}; const min = duration( utc(result.set_end, ISO_8601) - utc(result.set_start, ISO_8601), "milliseconds" ).as("minutes"); - let displayText = duration(min, "minutes").humanize(); + let displayDuration = duration(min, "minutes").humanize(); if (min % 60) { - displayText = duration( + displayDuration = duration( Math.floor(min / 60), "hours" ).humanize(); - displayText += ` and ${duration( + displayDuration += ` and ${duration( min % 60, "minutes" ).humanize()}`; } + const approved = !!result.approved; + const rejected = !result.approved && result.approved !== null; + const pending = result.approved === null; return ( @@ -121,24 +139,65 @@ const ProviderShiftsView = ({ /> {workType.label} + + + {"At " + utc(result.set_start, ISO_8601) .local(false) - .format("dddd, MMMM Do YYYY, h:mm a Z") + - "; for " + - displayText + - "; rate $" + - price.amount + - "/hour"} + .format("dddd, MMMM Do YYYY, h:mm a Z")} - {result.description} + {displayDuration} + {`Rate $${price.amount}/hour`} + {/* {result.description} */} {/* {JSON.stringify(result, null, 2)} */} - - - {employer.client.email} - - + + {`${client.first_name} ${client.last_name}`.trim() || + "No Name!"}{" "} + {client.email} + + + + {!approved && ( + + )} + {!rejected && ( + + )} + + + ); diff --git a/src/constants/pShift.constants.js b/src/constants/pShift.constants.js index c4de2a3..5b59f27 100644 --- a/src/constants/pShift.constants.js +++ b/src/constants/pShift.constants.js @@ -8,3 +8,5 @@ export const SET_CLEAR_PSHIFT_STATE = "SET_CLEAR_PSHIFT_STATE"; // Saga PShift Action Constants export const GET_PSHIFTS_REQUEST = "GET_PSHIFTS_REQUEST"; +export const GET_PSHIFT_REQUEST = "GET_PSHIFT_REQUEST"; +export const UPDATE_PSHIFT_REQUEST = "UPDATE_PSHIFT_REQUEST"; diff --git a/src/sagas/index.js b/src/sagas/index.js index f1404ac..b0df9eb 100644 --- a/src/sagas/index.js +++ b/src/sagas/index.js @@ -83,8 +83,16 @@ import { editCShiftFlow, deleteCShiftFlow } from "./cShift.sagas"; -import { GET_PSHIFTS_REQUEST } from "../constants/pShift.constants"; -import { getPShiftsFlow } from "./pShift.sagas"; +import { + GET_PSHIFTS_REQUEST, + GET_PSHIFT_REQUEST, + UPDATE_PSHIFT_REQUEST +} from "../constants/pShift.constants"; +import { + getPShiftsFlow, + getPShiftFlow, + updatePShiftFlow +} from "./pShift.sagas"; export default function* rootSaga() { yield takeLatest(SEND_REGISTER_REQUEST, registerUserFlow); @@ -118,4 +126,6 @@ export default function* rootSaga() { yield takeLatest(EDIT_CSHIFT_REQUEST, editCShiftFlow); yield takeLatest(DELETE_CSHIFT_REQUEST, deleteCShiftFlow); yield takeLatest(GET_PSHIFTS_REQUEST, getPShiftsFlow); + yield takeLatest(GET_PSHIFT_REQUEST, getPShiftFlow); + yield takeLatest(UPDATE_PSHIFT_REQUEST, updatePShiftFlow); } diff --git a/src/sagas/pShift.sagas.js b/src/sagas/pShift.sagas.js index ac38391..c2a0112 100644 --- a/src/sagas/pShift.sagas.js +++ b/src/sagas/pShift.sagas.js @@ -6,7 +6,11 @@ import { clearPShiftRequestError, clearPShiftRequestSuccess } from "../actions/pShift/reducer.actions"; -import { getPShifts } from "../api/pShift.api"; +import { getPShifts, getPShift, updatePShift } from "../api/pShift.api"; +import { + getPShiftsRequest, + getPShiftRequest +} from "../actions/pShift/saga.actions"; function* getPShiftsCall(params) { yield effects.put(isSendingPShiftRequest(true)); @@ -20,6 +24,30 @@ function* getPShiftsCall(params) { } } +function* getPShiftCall(payload) { + yield effects.put(isSendingPShiftRequest(true)); + try { + return yield effects.call(getPShift, payload.uuid); + } catch (exception) { + yield effects.put(setPShiftRequestError(exception)); + return false; + } finally { + yield effects.put(isSendingPShiftRequest(false)); + } +} + +function* updatePShiftCall(payload) { + yield effects.put(isSendingPShiftRequest(true)); + try { + return yield effects.call(updatePShift, payload.uuid, payload); + } catch (exception) { + yield effects.put(setPShiftRequestError(exception)); + return false; + } finally { + yield effects.put(isSendingPShiftRequest(false)); + } +} + export function* getPShiftsFlow(request) { yield effects.put(clearPShiftRequestSuccess()); yield effects.put(clearPShiftRequestError()); @@ -28,3 +56,26 @@ export function* getPShiftsFlow(request) { yield effects.put(setPShiftRequestSuccess(wasSuccessful)); } } + +export function* getPShiftFlow(request) { + yield effects.put(clearPShiftRequestSuccess()); + yield effects.put(clearPShiftRequestError()); + const wasSuccessful = yield effects.call(getPShiftCall, request.data); + if (wasSuccessful) { + yield effects.put(setPShiftRequestSuccess(wasSuccessful)); + } +} + +export function* updatePShiftFlow(request) { + yield effects.put(clearPShiftRequestSuccess()); + yield effects.put(clearPShiftRequestError()); + const wasSuccessful = yield effects.call(updatePShiftCall, request.data); + if (wasSuccessful) { + yield effects.put(setPShiftRequestSuccess(wasSuccessful)); + if (request.data.single) { + yield effects.put(getPShiftRequest({ uuid: request.data.uuid })); + } else { + yield effects.put(getPShiftsRequest({ page: 1 })); + } + } +}