parent
2b15495072
commit
0fc6ac31f5
13 changed files with 379 additions and 2 deletions
@ -0,0 +1,49 @@ |
|||||||
|
import { |
||||||
|
IS_SENDING_PSHIFT_REQUEST, |
||||||
|
SET_PSHIFT_REQUEST_SUCCESS, |
||||||
|
SET_PSHIFT_REQUEST_ERROR, |
||||||
|
CLEAR_PSHIFT_REQUEST_ERROR, |
||||||
|
CLEAR_PSHIFT_REQUEST_SUCCESS, |
||||||
|
SET_CLEAR_PSHIFT_STATE |
||||||
|
} from "../../constants/pShift.constants"; |
||||||
|
import { parseError } from "../common.actions"; |
||||||
|
|
||||||
|
export function isSendingPShiftRequest(sendingRequest) { |
||||||
|
return { |
||||||
|
type: IS_SENDING_PSHIFT_REQUEST, |
||||||
|
data: sendingRequest |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
export function setPShiftRequestSuccess(response) { |
||||||
|
return { |
||||||
|
type: SET_PSHIFT_REQUEST_SUCCESS, |
||||||
|
data: response.detail || response |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
export function setPShiftRequestError(exception) { |
||||||
|
let error = parseError(exception); |
||||||
|
return { |
||||||
|
type: SET_PSHIFT_REQUEST_ERROR, |
||||||
|
data: error |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
export function clearPShiftRequestError() { |
||||||
|
return { |
||||||
|
type: CLEAR_PSHIFT_REQUEST_ERROR |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
export function clearPShiftRequestSuccess() { |
||||||
|
return { |
||||||
|
type: CLEAR_PSHIFT_REQUEST_SUCCESS |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
export function setClearPShiftState() { |
||||||
|
return { |
||||||
|
type: SET_CLEAR_PSHIFT_STATE |
||||||
|
}; |
||||||
|
} |
@ -0,0 +1,8 @@ |
|||||||
|
import { GET_PSHIFTS_REQUEST } from "../../constants/pShift.constants"; |
||||||
|
|
||||||
|
export function getPShiftsRequest(params) { |
||||||
|
return { |
||||||
|
type: GET_PSHIFTS_REQUEST, |
||||||
|
data: params |
||||||
|
}; |
||||||
|
} |
@ -0,0 +1,5 @@ |
|||||||
|
import { get } from "./baseApi"; |
||||||
|
|
||||||
|
export function getPShifts(params) { |
||||||
|
return get("/pshift/", params).then(resp => Promise.resolve(resp)); |
||||||
|
} |
@ -0,0 +1,166 @@ |
|||||||
|
import { utc, ISO_8601, duration } from "moment"; |
||||||
|
import React, { Component } from "react"; |
||||||
|
import { connect } from "react-redux"; |
||||||
|
import { Redirect } from "react-router-dom"; |
||||||
|
import { |
||||||
|
Container, |
||||||
|
Header, |
||||||
|
Item, |
||||||
|
Pagination, |
||||||
|
Loader, |
||||||
|
Label |
||||||
|
} from "semantic-ui-react"; |
||||||
|
import { |
||||||
|
getEmployerFromPrice, |
||||||
|
getPriceFromPrice |
||||||
|
} from "./ProviderShiftsShared"; |
||||||
|
import { getPShiftsRequest } from "../../../actions/pShift/saga.actions"; |
||||||
|
|
||||||
|
class ProviderShifts extends Component { |
||||||
|
constructor(props) { |
||||||
|
super(props); |
||||||
|
this.state = { |
||||||
|
page: 1, |
||||||
|
pageSize: 10 // client can't control this, but set here just in case |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
componentWillMount = () => { |
||||||
|
this.props.dispatch( |
||||||
|
getPShiftsRequest({ |
||||||
|
page: this.state.page, |
||||||
|
page_size: this.state.pageSize |
||||||
|
}) |
||||||
|
); |
||||||
|
}; |
||||||
|
|
||||||
|
handlePaginationChange = (event, { activePage }) => { |
||||||
|
this.props.dispatch( |
||||||
|
getPShiftsRequest({ |
||||||
|
page: activePage, |
||||||
|
page_size: this.state.pageSize |
||||||
|
}) |
||||||
|
); |
||||||
|
this.setState({ page: activePage }); |
||||||
|
}; |
||||||
|
|
||||||
|
render() { |
||||||
|
const { |
||||||
|
isSendingPShiftRequest, |
||||||
|
pShiftRequestSuccess, |
||||||
|
selfUser |
||||||
|
} = this.props; |
||||||
|
const { page, pageSize } = this.state; |
||||||
|
if (selfUser.provider) { |
||||||
|
return ( |
||||||
|
<ProviderShiftsView |
||||||
|
isSendingPShiftRequest={isSendingPShiftRequest} |
||||||
|
pShiftRequestSuccess={pShiftRequestSuccess} |
||||||
|
page={page} |
||||||
|
pageSize={pageSize} |
||||||
|
user={selfUser} |
||||||
|
handlePaginationChange={this.handlePaginationChange} |
||||||
|
/> |
||||||
|
); |
||||||
|
} else { |
||||||
|
return <Redirect to="/" />; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function mapStateToProps(state) { |
||||||
|
return { ...state.pShift, selfUser: state.user.selfUser }; |
||||||
|
} |
||||||
|
|
||||||
|
const ProviderShiftsView = ({ |
||||||
|
isSendingPShiftRequest, |
||||||
|
pShiftRequestSuccess, |
||||||
|
user, |
||||||
|
page, |
||||||
|
pageSize, |
||||||
|
handlePaginationChange |
||||||
|
}) => { |
||||||
|
const { count = 0, results = [] } = pShiftRequestSuccess; |
||||||
|
return ( |
||||||
|
<Container> |
||||||
|
<Header>Shifts</Header> |
||||||
|
{!!isSendingPShiftRequest && <Loader content="Loading" />} |
||||||
|
{!isSendingPShiftRequest && |
||||||
|
results.length > 0 && ( |
||||||
|
<Item.Group divided> |
||||||
|
{results.map(result => { |
||||||
|
const employer = getEmployerFromPrice(result.price, user); |
||||||
|
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(); |
||||||
|
if (min % 60) { |
||||||
|
displayText = duration( |
||||||
|
Math.floor(min / 60), |
||||||
|
"hours" |
||||||
|
).humanize(); |
||||||
|
displayText += ` and ${duration( |
||||||
|
min % 60, |
||||||
|
"minutes" |
||||||
|
).humanize()}`; |
||||||
|
} |
||||||
|
return ( |
||||||
|
<Item key={result.uuid}> |
||||||
|
<Item.Content> |
||||||
|
<Item.Header> |
||||||
|
<Label |
||||||
|
circular |
||||||
|
empty |
||||||
|
style={{ |
||||||
|
backgroundColor: workType.color, |
||||||
|
borderColor: workType.color |
||||||
|
}} |
||||||
|
/> |
||||||
|
{workType.label} |
||||||
|
</Item.Header> |
||||||
|
<Item.Meta> |
||||||
|
{"At " + |
||||||
|
utc(result.set_start, ISO_8601) |
||||||
|
.local(false) |
||||||
|
.format("dddd, MMMM Do YYYY, h:mm a Z") + |
||||||
|
"; for " + |
||||||
|
displayText + |
||||||
|
"; rate $" + |
||||||
|
price.amount + |
||||||
|
"/hour"} |
||||||
|
</Item.Meta> |
||||||
|
<Item.Description>{result.description}</Item.Description> |
||||||
|
{/* <code>{JSON.stringify(result, null, 2)}</code> */} |
||||||
|
<Item.Meta> |
||||||
|
<a href={"mailto:" + employer.client.email}> |
||||||
|
{employer.client.email} |
||||||
|
</a> |
||||||
|
</Item.Meta> |
||||||
|
</Item.Content> |
||||||
|
</Item> |
||||||
|
); |
||||||
|
})} |
||||||
|
</Item.Group> |
||||||
|
)} |
||||||
|
<div style={{ textAlign: "center" }}> |
||||||
|
<Pagination |
||||||
|
activePage={page} |
||||||
|
onPageChange={handlePaginationChange} |
||||||
|
totalPages={Math.ceil(count / pageSize)} |
||||||
|
boundaryRange={1} |
||||||
|
siblingRange={1} |
||||||
|
size="mini" |
||||||
|
firstItem={undefined} |
||||||
|
lastItem={undefined} |
||||||
|
prevItem={null} |
||||||
|
nextItem={null} |
||||||
|
/> |
||||||
|
</div> |
||||||
|
</Container> |
||||||
|
); |
||||||
|
}; |
||||||
|
|
||||||
|
export default connect(mapStateToProps)(ProviderShifts); |
@ -0,0 +1,42 @@ |
|||||||
|
export const getEmployerFromPrice = (priceUUID, selfUser) => { |
||||||
|
const employers = |
||||||
|
selfUser && selfUser.provider && selfUser.provider.employers; |
||||||
|
let matchEmployer = null; |
||||||
|
employers.forEach(employer => { |
||||||
|
const priceMatch = employer.prices.filter(price => { |
||||||
|
return price.uuid === priceUUID; |
||||||
|
}); |
||||||
|
if (priceMatch.length > 0) { |
||||||
|
matchEmployer = employer; |
||||||
|
} |
||||||
|
}); |
||||||
|
return matchEmployer; |
||||||
|
}; |
||||||
|
|
||||||
|
export const getWorkTypeFromPrice = (priceUUID, selfUser) => { |
||||||
|
const employers = |
||||||
|
selfUser && selfUser.provider && selfUser.provider.employers; |
||||||
|
let matchWorkType = null; |
||||||
|
employers.forEach(employer => { |
||||||
|
employer.prices.forEach(price => { |
||||||
|
if (price.uuid === priceUUID) { |
||||||
|
matchWorkType = price.work_type; |
||||||
|
} |
||||||
|
}); |
||||||
|
}); |
||||||
|
return matchWorkType; |
||||||
|
}; |
||||||
|
|
||||||
|
export const getPriceFromPrice = (priceUUID, selfUser) => { |
||||||
|
const employers = |
||||||
|
selfUser && selfUser.provider && selfUser.provider.employers; |
||||||
|
let matchPrice = null; |
||||||
|
employers.forEach(employer => { |
||||||
|
employer.prices.forEach(price => { |
||||||
|
if (price.uuid === priceUUID) { |
||||||
|
matchPrice = price; |
||||||
|
} |
||||||
|
}); |
||||||
|
}); |
||||||
|
return matchPrice; |
||||||
|
}; |
@ -0,0 +1,10 @@ |
|||||||
|
// Reducer PShift Action Constants
|
||||||
|
export const IS_SENDING_PSHIFT_REQUEST = "IS_SENDING_PSHIFT_REQUEST"; |
||||||
|
export const SET_PSHIFT_REQUEST_ERROR = "SET_PSHIFT_REQUEST_ERROR"; |
||||||
|
export const CLEAR_PSHIFT_REQUEST_ERROR = "CLEAR_PSHIFT_REQUEST_ERROR"; |
||||||
|
export const SET_PSHIFT_REQUEST_SUCCESS = "SET_PSHIFT_REQUEST_SUCCESS"; |
||||||
|
export const CLEAR_PSHIFT_REQUEST_SUCCESS = "CLEAR_PSHIFT_REQUEST_SUCCESS"; |
||||||
|
export const SET_CLEAR_PSHIFT_STATE = "SET_CLEAR_PSHIFT_STATE"; |
||||||
|
|
||||||
|
// Saga PShift Action Constants
|
||||||
|
export const GET_PSHIFTS_REQUEST = "GET_PSHIFTS_REQUEST"; |
@ -0,0 +1,52 @@ |
|||||||
|
import { |
||||||
|
IS_SENDING_PSHIFT_REQUEST, |
||||||
|
SET_PSHIFT_REQUEST_ERROR, |
||||||
|
SET_PSHIFT_REQUEST_SUCCESS, |
||||||
|
CLEAR_PSHIFT_REQUEST_ERROR, |
||||||
|
CLEAR_PSHIFT_REQUEST_SUCCESS, |
||||||
|
SET_CLEAR_PSHIFT_STATE |
||||||
|
} from "../constants/pShift.constants"; |
||||||
|
|
||||||
|
const initialState = { |
||||||
|
isSendingPShiftRequest: false, |
||||||
|
pShiftRequestError: "", |
||||||
|
pShiftRequestSuccess: "" |
||||||
|
}; |
||||||
|
|
||||||
|
function pShiftReducer(state = initialState, action) { |
||||||
|
switch (action.type) { |
||||||
|
case IS_SENDING_PSHIFT_REQUEST: |
||||||
|
return { |
||||||
|
...state, |
||||||
|
isSendingPShiftRequest: action.data |
||||||
|
}; |
||||||
|
case SET_PSHIFT_REQUEST_ERROR: |
||||||
|
return { |
||||||
|
...state, |
||||||
|
pShiftRequestError: action.data |
||||||
|
}; |
||||||
|
case CLEAR_PSHIFT_REQUEST_ERROR: |
||||||
|
return { |
||||||
|
...state, |
||||||
|
pShiftRequestError: "" |
||||||
|
}; |
||||||
|
case SET_PSHIFT_REQUEST_SUCCESS: |
||||||
|
return { |
||||||
|
...state, |
||||||
|
pShiftRequestSuccess: action.data |
||||||
|
}; |
||||||
|
case CLEAR_PSHIFT_REQUEST_SUCCESS: |
||||||
|
return { |
||||||
|
...state, |
||||||
|
pShiftRequestSuccess: "" |
||||||
|
}; |
||||||
|
case SET_CLEAR_PSHIFT_STATE: |
||||||
|
return { |
||||||
|
...initialState |
||||||
|
}; |
||||||
|
default: |
||||||
|
return { ...state }; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
export default pShiftReducer; |
@ -0,0 +1,30 @@ |
|||||||
|
import { effects } from "redux-saga"; |
||||||
|
import { |
||||||
|
isSendingPShiftRequest, |
||||||
|
setPShiftRequestError, |
||||||
|
setPShiftRequestSuccess, |
||||||
|
clearPShiftRequestError, |
||||||
|
clearPShiftRequestSuccess |
||||||
|
} from "../actions/pShift/reducer.actions"; |
||||||
|
import { getPShifts } from "../api/pShift.api"; |
||||||
|
|
||||||
|
function* getPShiftsCall(params) { |
||||||
|
yield effects.put(isSendingPShiftRequest(true)); |
||||||
|
try { |
||||||
|
return yield effects.call(getPShifts, params); |
||||||
|
} 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()); |
||||||
|
const wasSuccessful = yield effects.call(getPShiftsCall, request.data); |
||||||
|
if (wasSuccessful) { |
||||||
|
yield effects.put(setPShiftRequestSuccess(wasSuccessful)); |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue