added provider users approve clients functionality
This commit is contained in:
parent
bc0628bcb7
commit
e6ee51f481
42
src/actions/employer/reducer.actions.js
Normal file
42
src/actions/employer/reducer.actions.js
Normal file
|
@ -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
|
||||
};
|
||||
}
|
8
src/actions/employer/saga.actions.js
Normal file
8
src/actions/employer/saga.actions.js
Normal file
|
@ -0,0 +1,8 @@
|
|||
import { UPDATE_EMPLOYER_REQUEST } from "../../constants/employer.constants";
|
||||
|
||||
export function updateEmployerRequest(payload) {
|
||||
return {
|
||||
type: UPDATE_EMPLOYER_REQUEST,
|
||||
data: payload
|
||||
};
|
||||
}
|
12
src/api/employer.api.js
Normal file
12
src/api/employer.api.js
Normal file
|
@ -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)
|
||||
);
|
||||
}
|
|
@ -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}
|
||||
/>
|
||||
<PrivateRoute
|
||||
path="/user/profile/provider/clients"
|
||||
component={ProviderClients}
|
||||
/>
|
||||
<PrivateRoute path="/user/profile/edit" component={EditProfile} />
|
||||
<PrivateRoute path="/user/profile" component={Profile} />
|
||||
<Route path="/user/complete-registration" component={Profile} />
|
||||
|
|
|
@ -73,6 +73,11 @@ const NavbarView = ({ isAuthenticated, dispatchLogoutRequest, selfUser }) => (
|
|||
Providers
|
||||
</Dropdown.Item>
|
||||
)}
|
||||
{selfUser.provider && (
|
||||
<Dropdown.Item as={Link} to="/user/profile/provider/clients">
|
||||
Clients
|
||||
</Dropdown.Item>
|
||||
)}
|
||||
<Dropdown.Item as={Link} to="/auth/settings">
|
||||
Settings
|
||||
</Dropdown.Item>
|
||||
|
|
|
@ -111,13 +111,13 @@ const ClientAddProviderFormView = ({
|
|||
</Form.Field>
|
||||
<Error header="Add Provider failed!" error={employeeRequestError} />
|
||||
<Message success>
|
||||
<Message.Header>Create Worktype successful!</Message.Header>
|
||||
<p>Worktype successfully created.</p>
|
||||
<Message.Header>Create Provider successful!</Message.Header>
|
||||
<p>Provider successfully created.</p>
|
||||
{!!employeeRequestSuccess && (
|
||||
<Redirect to="/user/profile/client/providers" />
|
||||
)}
|
||||
</Message>
|
||||
<Form.Button>Submit Worktype</Form.Button>
|
||||
<Form.Button>Submit Provider</Form.Button>
|
||||
</Form>
|
||||
</Container>
|
||||
);
|
||||
|
|
|
@ -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) => (
|
||||
<Card key={index}>
|
||||
<Card.Content>
|
||||
<Card.Header as="h4">{employee.provider}</Card.Header>
|
||||
<Card.Description>{employee.note}</Card.Description>
|
||||
{(employee.approved === null ||
|
||||
employee.approved === false) && (
|
||||
<div>
|
||||
<Card.Header as="h4">{employee.provider}</Card.Header>
|
||||
<Card.Description>{employee.note}</Card.Description>
|
||||
</div>
|
||||
)}
|
||||
{employee.approved && (
|
||||
<div>
|
||||
<Card.Header as="h4">
|
||||
{`${employee.provider.first_name} ${
|
||||
employee.provider.last_name
|
||||
}`.trim() || "No Name!"}
|
||||
</Card.Header>
|
||||
<Card.Description>
|
||||
{employee.provider.userinfo && (
|
||||
<List>
|
||||
{employee.provider.userinfo.phone_number && (
|
||||
<List.Item>
|
||||
Phone Number:{" "}
|
||||
{employee.provider.userinfo.phone_number}
|
||||
</List.Item>
|
||||
)}
|
||||
</List>
|
||||
)}
|
||||
</Card.Description>
|
||||
</div>
|
||||
)}
|
||||
<Label
|
||||
attached="bottom right"
|
||||
color={
|
||||
employee.approved === null
|
||||
? "grey"
|
||||
: !!employee.approved ? "green" : "red"
|
||||
}
|
||||
>
|
||||
{employee.approved === null
|
||||
? "Pending"
|
||||
: !!employee.approved ? "Approved" : "Ended"}
|
||||
</Label>
|
||||
</Card.Content>
|
||||
<Card.Content extra>
|
||||
<Popup
|
||||
content={
|
||||
<div>
|
||||
|
|
133
src/components/User/Provider/ProviderClients.jsx
Normal file
133
src/components/User/Provider/ProviderClients.jsx
Normal file
|
@ -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 (
|
||||
<ProviderClientsView
|
||||
user={selfUser}
|
||||
updateEmployer={this.updateEmployer}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
return <Redirect to="/" />;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return { selfUser: state.user.selfUser };
|
||||
}
|
||||
|
||||
const ProviderClientsView = ({ user, updateEmployer }) => (
|
||||
<Container>
|
||||
<Header>Clients</Header>
|
||||
{(user.provider.employers || []).filter(employer => !employer.deleted)
|
||||
.length > 0 && (
|
||||
<Card.Group>
|
||||
{user.provider.employers
|
||||
.filter(employer => !employer.deleted)
|
||||
.map((employer, index) => (
|
||||
<Card key={index}>
|
||||
<Card.Content>
|
||||
{(employer.approved === null ||
|
||||
employer.approved === false) && (
|
||||
<div>
|
||||
<Card.Header as="h4">
|
||||
{employer.client.trim() || "No Name!"}
|
||||
</Card.Header>
|
||||
<Card.Description>{employer.note}</Card.Description>
|
||||
</div>
|
||||
)}
|
||||
{employer.approved && (
|
||||
<div>
|
||||
<Card.Header as="h4">
|
||||
{`${employer.client.first_name} ${
|
||||
employer.client.last_name
|
||||
}`.trim() || "No Name!"}
|
||||
</Card.Header>
|
||||
<Card.Description>
|
||||
{employer.client.userinfo && (
|
||||
<List>
|
||||
{employer.client.userinfo.phone_number && (
|
||||
<List.Item>
|
||||
Phone Number:{" "}
|
||||
{employer.client.userinfo.phone_number}
|
||||
</List.Item>
|
||||
)}
|
||||
</List>
|
||||
)}
|
||||
</Card.Description>
|
||||
</div>
|
||||
)}
|
||||
<Label
|
||||
attached="bottom right"
|
||||
color={
|
||||
employer.approved === null
|
||||
? "grey"
|
||||
: !!employer.approved ? "green" : "red"
|
||||
}
|
||||
>
|
||||
{employer.approved === null
|
||||
? "Pending"
|
||||
: !!employer.approved ? "Approved" : "Ended"}
|
||||
</Label>
|
||||
</Card.Content>
|
||||
<Card.Content extra>
|
||||
<Button.Group>
|
||||
{!employer.approved && (
|
||||
<Button
|
||||
basic
|
||||
color="green"
|
||||
size="small"
|
||||
onClick={() => updateEmployer(employer.uuid, true)}
|
||||
>
|
||||
Approve
|
||||
</Button>
|
||||
)}
|
||||
{employer.approved === null && (
|
||||
<Button
|
||||
basic
|
||||
color="red"
|
||||
size="small"
|
||||
onClick={() => updateEmployer(employer.uuid, false)}
|
||||
>
|
||||
Reject
|
||||
</Button>
|
||||
)}
|
||||
{employer.approved && (
|
||||
<Button
|
||||
basic
|
||||
color="red"
|
||||
size="small"
|
||||
onClick={() => updateEmployer(employer.uuid, false)}
|
||||
>
|
||||
End
|
||||
</Button>
|
||||
)}
|
||||
</Button.Group>
|
||||
</Card.Content>
|
||||
</Card>
|
||||
))}
|
||||
</Card.Group>
|
||||
)}
|
||||
</Container>
|
||||
);
|
||||
|
||||
export default connect(mapStateToProps)(ProviderClients);
|
|
@ -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";
|
||||
|
|
9
src/constants/employer.constants.js
Normal file
9
src/constants/employer.constants.js
Normal file
|
@ -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";
|
47
src/reducers/employerReducer.js
Normal file
47
src/reducers/employerReducer.js
Normal file
|
@ -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;
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
34
src/sagas/employer.sagas.js
Normal file
34
src/sagas/employer.sagas.js
Normal file
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user