Initial commit
This commit is contained in:
34
client-wiaas/src/App.js
Normal file
34
client-wiaas/src/App.js
Normal file
@@ -0,0 +1,34 @@
|
||||
import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import ContentContainer from './containers/ContentContainer.jsx';
|
||||
import LogInContainer from './containers/login/LogInContainer.jsx';
|
||||
import './App.css';
|
||||
import './mainComponents/box/WiaasBox.css';
|
||||
import NotificationBox from './mainComponents/notification/NotificationBox.jsx';
|
||||
import DialogBox from './mainComponents/dialog/DialogBox.jsx';
|
||||
|
||||
class App extends Component {
|
||||
render() {
|
||||
const {isLoggedIn, updateMessages, isDialogOpen, dialogContent} = this.props;
|
||||
|
||||
return (<div className="App">
|
||||
|
||||
{
|
||||
!isLoggedIn
|
||||
? (<LogInContainer/>)
|
||||
: (<ContentContainer className="content"/>)
|
||||
}
|
||||
<NotificationBox messages={updateMessages}/>
|
||||
<DialogBox isDialogOpen={isDialogOpen} dialogContent={dialogContent}/>
|
||||
</div>);
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
isLoggedIn: state.auth.isLoggedIn,
|
||||
updateMessages: state.notificationReducer.updateMessages,
|
||||
isDialogOpen: state.dialogReducer.isDialogOpen,
|
||||
dialogContent: state.dialogReducer.dialogContent
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps)(App);
|
||||
6
client-wiaas/src/App.scss
Normal file
6
client-wiaas/src/App.scss
Normal file
@@ -0,0 +1,6 @@
|
||||
@import 'styleConstants.scss';
|
||||
|
||||
.App {
|
||||
text-align: left;
|
||||
height: 100%;
|
||||
}
|
||||
8
client-wiaas/src/App.test.js
Normal file
8
client-wiaas/src/App.test.js
Normal file
@@ -0,0 +1,8 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import App from './App';
|
||||
|
||||
it('renders without crashing', () => {
|
||||
const div = document.createElement('div');
|
||||
ReactDOM.render(<App />, div);
|
||||
});
|
||||
40
client-wiaas/src/actions/bids/bidsActions.js
Normal file
40
client-wiaas/src/actions/bids/bidsActions.js
Normal file
@@ -0,0 +1,40 @@
|
||||
import {
|
||||
API_SERVER
|
||||
} from '../../config';
|
||||
import HtmlClient from '../../helpers/HtmlClient';
|
||||
import {
|
||||
REQUEST_SET_BID,
|
||||
bidsTexts
|
||||
} from '../../constants/bidsConstants';
|
||||
import {fetchCartItems} from '../cart/cartActions';
|
||||
import {updateMessages} from '../notification/notificationActions';
|
||||
import {setDialogOpenFlag} from '../../actions/dialog/dialogActions';
|
||||
|
||||
const client = new HtmlClient();
|
||||
|
||||
const requestSetBid = () => ({
|
||||
type: REQUEST_SET_BID
|
||||
});
|
||||
|
||||
export const setBid = (idBid, idCart) => {
|
||||
return dispatch => {
|
||||
dispatch(requestSetBid());
|
||||
return client.fetch({
|
||||
url: `${API_SERVER}/cart/api/setBidForCart`,
|
||||
method: 'post',
|
||||
data: {idBid, idCart}
|
||||
})
|
||||
.then(response => {
|
||||
if(response.data && response.data.messages){
|
||||
dispatch(updateMessages(response.data.messages, bidsTexts.messages));
|
||||
if(response.data.messages[0].code === 'success'){
|
||||
dispatch(setDialogOpenFlag(false));
|
||||
dispatch(fetchCartItems(true));
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
client.onError(error, dispatch);
|
||||
});
|
||||
}
|
||||
};
|
||||
312
client-wiaas/src/actions/cart/cartActions.js
Normal file
312
client-wiaas/src/actions/cart/cartActions.js
Normal file
@@ -0,0 +1,312 @@
|
||||
import {API_SERVER} from '../../config';
|
||||
import HtmlClient from '../../helpers/HtmlClient';
|
||||
import {
|
||||
REQUEST_SHOP_CART_COUNT,
|
||||
RECEIVE_SHOP_CART_COUNT,
|
||||
REQUEST_SHOP_CART_ITEMS,
|
||||
RECEIVE_SHOP_CART_ITEMS,
|
||||
SET_CURRENT_STEP,
|
||||
RESET_STEPS,
|
||||
GO_TO_NEXT_STEP,
|
||||
GO_TO_PREVIOUS_STEP,
|
||||
LOAD_CART_STEPS,
|
||||
cartSteps,
|
||||
UPLOAD_DOCUMENT,
|
||||
REQUEST_CART_DOCUMENTS,
|
||||
RECEIVE_CART_DOCUMENTS,
|
||||
REQUEST_CUSTOMER_DETAILS,
|
||||
RECEIVE_CUSTOMER_DETAILS,
|
||||
SELECT_COUNTRY_DELIVERY,
|
||||
SELECT_COUNTRY_BILLING,
|
||||
SET_ORDER_INFO,
|
||||
IS_CART_ITEMS_DISABLED,
|
||||
RECEIVE_ORDER_TOTAL_PRICE,
|
||||
UPDATE_CART_ITEMS,
|
||||
SET_NEXT_STEP,
|
||||
SET_PREV_STEP,
|
||||
SET_ORDER_PLACED,
|
||||
SET_ORDER_PLACED_REDIRECT,
|
||||
cartMessages
|
||||
} from '../../constants/cartConstants';
|
||||
import {updateMessages} from '../notification/notificationActions';
|
||||
const client = new HtmlClient();
|
||||
|
||||
export const requestShopCartCount = () => ({type: REQUEST_SHOP_CART_COUNT});
|
||||
export const receiveShopCartCount = (json) => ({type: RECEIVE_SHOP_CART_COUNT, cartCount: json});
|
||||
|
||||
export const requestShopCartItems = () => ({
|
||||
type: REQUEST_SHOP_CART_ITEMS,
|
||||
isLoading: true
|
||||
});
|
||||
export const receiveShopCartItems = (json) => ({
|
||||
type: RECEIVE_SHOP_CART_ITEMS,
|
||||
isLoading: false,
|
||||
cartItems: json
|
||||
});
|
||||
|
||||
export const requestCustomerDetails = () => ({
|
||||
type: REQUEST_CUSTOMER_DETAILS,
|
||||
isLoading: true
|
||||
});
|
||||
export const receiveCustomerDetails = (json) => ({
|
||||
type: RECEIVE_CUSTOMER_DETAILS,
|
||||
isLoading: false,
|
||||
customerDetails: json
|
||||
});
|
||||
|
||||
export const fetchCartCount = () => {
|
||||
return dispatch => {
|
||||
dispatch(requestShopCartCount());
|
||||
return client.fetch({url: `${API_SERVER}/cart/api/getCartCount`}).then(response => {
|
||||
if (typeof response.data !== 'undefined' && 'cartItemsCount' in response.data) {
|
||||
dispatch(receiveShopCartCount(response.data.cartItemsCount));
|
||||
}
|
||||
}).catch(error => {
|
||||
client.onError(error, dispatch);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const fetchCartItems = (isForSteps = false) => {
|
||||
return dispatch => {
|
||||
dispatch(requestShopCartItems());
|
||||
return client.fetch({url: `${API_SERVER}/cart/api/getCartItems`}).then(response => {
|
||||
if (typeof response.data !== 'undefined' && 'cartItems' in response.data) {
|
||||
dispatch(receiveShopCartItems(response.data.cartItems));
|
||||
dispatch(fetchCartDocuments(response.data.cartItems.map((cartItem) => cartItem.idPackage), isForSteps));
|
||||
dispatch(updateOrderTotalPrice(response.data.cartItems));
|
||||
}
|
||||
}).catch(error => {
|
||||
client.onError(error, dispatch);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const updateOrderTotalPrice = (cartItems) => ({type: RECEIVE_ORDER_TOTAL_PRICE, cartItems});
|
||||
|
||||
const updateCartItems = (newItem)=>(
|
||||
{type: UPDATE_CART_ITEMS, newItem}
|
||||
);
|
||||
|
||||
export const updateQuantity = (cartItem, quantity, updateCartAllItems) => {
|
||||
const params = {
|
||||
idPackage: cartItem.idPackage || 0,
|
||||
idCustomerInstance: cartItem.idCustomerInstance || 0,
|
||||
idPrice: cartItem.idPrice || 0,
|
||||
quantity
|
||||
};
|
||||
|
||||
return dispatch => {
|
||||
return client.fetch({
|
||||
url: `${API_SERVER}/cart/api/updateQuantity`,
|
||||
method: 'post',
|
||||
data: params
|
||||
}).then(response => {
|
||||
if (typeof response.data !== 'undefined' && 'messages' in response.data) {
|
||||
const filteredMessages = response.data.messages.filter(message => {
|
||||
return message.code === 'error';
|
||||
});
|
||||
|
||||
if(filteredMessages.length > 0){
|
||||
dispatch(updateMessages(filteredMessages, cartMessages));
|
||||
}else{
|
||||
cartItem.quantity = quantity;
|
||||
dispatch(updateCartItems(cartItem));
|
||||
}
|
||||
}
|
||||
}).catch(error => {
|
||||
client.onError(error, dispatch);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const removeCartItem = (idCart) => {
|
||||
return dispatch => {
|
||||
return client.fetch({
|
||||
url: `${API_SERVER}/cart/api/removeFromCart`,
|
||||
method: 'post',
|
||||
data: {idCart}
|
||||
}).then(response => {
|
||||
if (typeof response.data !== 'undefined' && 'messages' in response.data) {
|
||||
dispatch(updateMessages(response.data.messages, cartMessages));
|
||||
response.data.messages.forEach(messageObject => {
|
||||
if (messageObject.code === 'success') {
|
||||
dispatch(fetchCartCount());
|
||||
dispatch(fetchCartItems(true));
|
||||
}
|
||||
})
|
||||
}
|
||||
}).catch(error => {
|
||||
client.onError(error, dispatch);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const getSteps = (whitoutUploadDoc) => {
|
||||
const newSteps = Object.assign({}, cartSteps());
|
||||
|
||||
if(whitoutUploadDoc) {
|
||||
delete newSteps.cartUploadDocuments;
|
||||
newSteps.cartCustomerDetails.previous = null;
|
||||
newSteps.cartCustomerDetails.status = 'active';
|
||||
}
|
||||
|
||||
return {
|
||||
type: LOAD_CART_STEPS,
|
||||
cartSteps: newSteps
|
||||
};
|
||||
};
|
||||
|
||||
export const loadSteps = (whitoutUploadDoc) => {
|
||||
const firstStep = whitoutUploadDoc ? 'cartCustomerDetails' : 'cartUploadDocuments';
|
||||
|
||||
return dispatch => {
|
||||
dispatch(getSteps(whitoutUploadDoc));
|
||||
dispatch(selectStep(firstStep));
|
||||
dispatch(resetSteps());
|
||||
dispatch(setCartItemsDisabled(false));
|
||||
}
|
||||
}
|
||||
|
||||
export const selectStep = (step, params={}) => {
|
||||
return {type: SET_CURRENT_STEP, currentStep: step, params};
|
||||
}
|
||||
|
||||
const resetSteps = () => ({type: RESET_STEPS});
|
||||
|
||||
export const getCustomerDetails = () => {
|
||||
return dispatch => {
|
||||
return client.fetch({url: `${API_SERVER}/cart/api/getCustomerDetails`})
|
||||
.then(response => {
|
||||
if (typeof response.data !== 'undefined' && response.data.customerDetails) {
|
||||
const customerDetails = response.data.customerDetails;
|
||||
dispatch(receiveCustomerDetails(customerDetails));
|
||||
}
|
||||
}).catch(error => {
|
||||
client.onError(error, dispatch);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const nextStep = (step) => ({type: GO_TO_NEXT_STEP});
|
||||
export const previousStep = (params) => ({type: GO_TO_PREVIOUS_STEP, params});
|
||||
|
||||
export const uploadDocumnet = () => ({type: UPLOAD_DOCUMENT});
|
||||
|
||||
export const uploadOrderDocument = (idPackage, idDocumentType, file, packages) => {
|
||||
return dispatch => {
|
||||
dispatch(uploadDocumnet());
|
||||
|
||||
return client.uploadFile(file, {
|
||||
url: `${API_SERVER}/cart/api/uploadOrderDocument`,
|
||||
data: {
|
||||
idDocumentType,
|
||||
idPackage
|
||||
}
|
||||
}).then(response => {
|
||||
if (typeof response.data !== 'undefined' && 'messages' in response.data) {
|
||||
dispatch(updateMessages(response.data.messages, cartMessages));
|
||||
dispatch(fetchCartDocuments(packages));
|
||||
}
|
||||
}).catch(error => {
|
||||
client.onError(error, dispatch);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const badFile = () =>{
|
||||
return dispatch => {
|
||||
dispatch(updateMessages([{code: 'warning', message: 'INVALID_FILE'}], cartMessages));
|
||||
}
|
||||
}
|
||||
|
||||
export const requestCartDocuments = () => ({
|
||||
type: REQUEST_CART_DOCUMENTS,
|
||||
isLoading: true
|
||||
});
|
||||
export const receiveCartDocuments = (json) => ({
|
||||
type: RECEIVE_CART_DOCUMENTS,
|
||||
isLoading: false,
|
||||
cartDocuments: json
|
||||
});
|
||||
|
||||
export const fetchCartDocuments = (packages, isForSteps = false) => {
|
||||
return dispatch => {
|
||||
dispatch(requestCartDocuments());
|
||||
|
||||
return client.fetch({
|
||||
url: `${API_SERVER}/cart/api/getCartDocuments`,
|
||||
method: 'post',
|
||||
data: {packages}
|
||||
}).then(response => {
|
||||
if (response.data) {
|
||||
dispatch(receiveCartDocuments(response.data));
|
||||
if(isForSteps) {
|
||||
const whitoutUploadDoc = response.data.templates.length === 0;
|
||||
dispatch(loadSteps(whitoutUploadDoc));
|
||||
}
|
||||
}
|
||||
}).catch(error => {
|
||||
client.onError(error, dispatch);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const selectCountryDelivery = (country) => ({type: SELECT_COUNTRY_DELIVERY, selectedCountryDelivery: country});
|
||||
export const selectCountryBilling = (country) => ({type: SELECT_COUNTRY_BILLING, selectedCountryBilling: country});
|
||||
|
||||
export const saveOrderDetails = (orderDetails, cartItems) => {
|
||||
const orderInfo = {orderDetails, cartItems};
|
||||
return dispatch => {
|
||||
return client.fetch({
|
||||
url: `${API_SERVER}/cart/api/saveOrderDetails`,
|
||||
method: 'post',
|
||||
data: {orderDetails, cartItems}
|
||||
}).then(response => {
|
||||
if (typeof response.data !== 'undefined' && 'messages' in response.data) {
|
||||
dispatch(getCustomerDetails());
|
||||
dispatch(setOrderInfo(orderInfo));
|
||||
}
|
||||
}).catch(error => {
|
||||
client.onError(error, dispatch);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const setOrderInfo = (info) => ({type: SET_ORDER_INFO, orderInfo: info});
|
||||
|
||||
export const setOrderPlacedFlag = (flag) => ({type: SET_ORDER_PLACED, orderPlaced: flag});
|
||||
export const setOrderPlacedRedirectFlag = (flag) => ({type: SET_ORDER_PLACED_REDIRECT, orderPlacedRedirect: flag});
|
||||
|
||||
export const placeOrder = (orderInfo) => {
|
||||
const {orderDetails, cartItems} = orderInfo;
|
||||
return dispatch => {
|
||||
return client.fetch({
|
||||
url: `${API_SERVER}/cart/api/placeOrder`,
|
||||
method: 'post',
|
||||
data: {orderDetails, cartItems}
|
||||
}).then(response => {
|
||||
if (typeof response.data !== 'undefined' && 'messages' in response.data) {
|
||||
dispatch(updateMessages(response.data.messages, cartMessages));
|
||||
if(!checkIfErrorMessageExists(response.data.messages)) {
|
||||
dispatch(fetchCartCount());
|
||||
dispatch(setOrderPlacedFlag(true));
|
||||
dispatch(setOrderPlacedRedirectFlag(true));
|
||||
}
|
||||
}
|
||||
}).catch(error => {
|
||||
client.onError(error, dispatch);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const checkIfErrorMessageExists = (messagesArray) => {
|
||||
return messagesArray.some(messageObj => {
|
||||
return messageObj.code === 'error';
|
||||
});
|
||||
}
|
||||
|
||||
export const setCartItemsDisabled = (flag) => ({type: IS_CART_ITEMS_DISABLED, isCartItemsDisabled: flag});
|
||||
|
||||
export const setNextActionFct = (fct) => ({type: SET_NEXT_STEP, nextStepAction: fct});
|
||||
export const setPrevActionFct = (fct) => ({type: SET_PREV_STEP, prevStepAction: fct});
|
||||
9
client-wiaas/src/actions/coMarket/coMarketActions.js
Normal file
9
client-wiaas/src/actions/coMarket/coMarketActions.js
Normal file
@@ -0,0 +1,9 @@
|
||||
|
||||
import {
|
||||
SET_PACKAGE_FROM_URL
|
||||
} from '../../constants/coMarketConstants';
|
||||
|
||||
export const setPackageFromUrl = (idPackage) => ({
|
||||
type: SET_PACKAGE_FROM_URL,
|
||||
idPackage
|
||||
});
|
||||
@@ -0,0 +1,166 @@
|
||||
import {
|
||||
API_SERVER
|
||||
} from '../../config';
|
||||
import HtmlClient from '../../helpers/HtmlClient';
|
||||
import PriceHelper from '../../helpers/coMarket/PriceHelper';
|
||||
import {
|
||||
REQUEST_PACKAGE_DETAILS,
|
||||
RECIEVE_PACKAGE_DETAILS,
|
||||
SELECT_OPTION,
|
||||
SELECT_AGREEMENT,
|
||||
SELECT_ADDITIONAL,
|
||||
REMOVE_ADDITIONAL,
|
||||
REQUEST_ADD_TO_CART,
|
||||
CLEAR_SELECTIONS,
|
||||
coMarketMessages
|
||||
} from '../../constants/coMarketConstants';
|
||||
import {updateMessages} from '../notification/notificationActions';
|
||||
import {fetchCartCount} from '../cart/cartActions';
|
||||
|
||||
const client = new HtmlClient();
|
||||
const priceHelper = new PriceHelper();
|
||||
|
||||
const requestPackageDetails = () => ({
|
||||
type: REQUEST_PACKAGE_DETAILS,
|
||||
isLoading: true
|
||||
});
|
||||
const recievePackageDetails = (json) => ({
|
||||
type: RECIEVE_PACKAGE_DETAILS,
|
||||
isLoading: false,
|
||||
selectedPackage: json
|
||||
});
|
||||
|
||||
const clearSelections = () => ({
|
||||
type: CLEAR_SELECTIONS,
|
||||
selectedOptions: null,
|
||||
selectedAdditionals: null,
|
||||
selectedAgreement: null
|
||||
})
|
||||
|
||||
export const fetchPackageDetails = (params) => {
|
||||
return dispatch => {
|
||||
dispatch(requestPackageDetails());
|
||||
return client.fetch({
|
||||
url: `${API_SERVER}/coMarket/api/getShopPackageDetails`,
|
||||
method: 'post',
|
||||
data: params
|
||||
})
|
||||
.then(response => {
|
||||
if(response.data){
|
||||
const jsonData = response.data;
|
||||
dispatch(clearSelections());
|
||||
if(jsonData.prices && jsonData.prices.length){
|
||||
dispatch(selectAgreement(jsonData.prices[0]));
|
||||
}
|
||||
|
||||
if(jsonData.groups){
|
||||
Object.keys(jsonData.groups).forEach((idGroup) => {
|
||||
const defaultOption = jsonData.groups[idGroup].options.find((option) => {return parseInt(option.isDefault, 10) === 1});
|
||||
if(defaultOption){
|
||||
dispatch(selectOption(idGroup, defaultOption));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
dispatch(recievePackageDetails(jsonData));
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
client.onError(error, dispatch);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const generateOptions = (selectedOptions, selectedAdditionals, selectedAgreement) => {
|
||||
const extraPackages = [];
|
||||
const unavailablePackages = [];
|
||||
if(selectedAdditionals && selectedAdditionals.length){
|
||||
selectedAdditionals.forEach(additional => {
|
||||
const selectedPrice = priceHelper.getSelectedPrice(additional, selectedAgreement);
|
||||
if(!selectedPrice){
|
||||
unavailablePackages.push(additional);
|
||||
}else{
|
||||
extraPackages.push(additional.idAdditionalPackage);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if(selectedOptions){
|
||||
Object.keys(selectedOptions).forEach(idGroup => {
|
||||
const selectedPrice = priceHelper.getSelectedPrice(selectedOptions[idGroup], selectedAgreement);
|
||||
if(!selectedPrice){
|
||||
unavailablePackages.push(selectedOptions[idGroup]);
|
||||
}else{
|
||||
extraPackages.push(selectedOptions[idGroup].idOptionPackage);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return {extraPackages, unavailablePackages};
|
||||
};
|
||||
|
||||
const requestAddToCart = () => ({
|
||||
type: REQUEST_ADD_TO_CART
|
||||
});
|
||||
|
||||
export const addToCart = (addParams) => {
|
||||
const options = generateOptions(addParams.selectedOptions, addParams.selectedAdditionals, addParams.selectedAgreement);
|
||||
|
||||
const params = {
|
||||
idPackage: addParams.selectedPackage.packageInfo.idPackage,
|
||||
idPrice: addParams.selectedAgreement.idPrice,
|
||||
options: options.extraPackages
|
||||
};
|
||||
|
||||
if(options.unavailablePackages.length){
|
||||
const unavailable = options.unavailablePackages.map((unavailable) =>{return unavailable.optionName || unavailable.packageName;});
|
||||
const message = coMarketMessages.UNAVAILABLE_PACKAGES + ' ' + unavailable.join();
|
||||
|
||||
return dispatch => {dispatch(updateMessages([{code: 'warning', message}], coMarketMessages))};
|
||||
}
|
||||
|
||||
return dispatch => {
|
||||
dispatch(requestAddToCart());
|
||||
return client.fetch({
|
||||
url: `${API_SERVER}/coMarket/api/addToCart`,
|
||||
method: 'post',
|
||||
data: params
|
||||
})
|
||||
.then(response => {
|
||||
if(response.data && response.data.messages){
|
||||
dispatch(updateMessages(response.data.messages, coMarketMessages));
|
||||
dispatch(fetchCartCount());
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
client.onError(error, dispatch);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export const selectAgreement = (agreement) => {
|
||||
return {
|
||||
type: SELECT_AGREEMENT,
|
||||
selectedAgreement: agreement,
|
||||
};
|
||||
};
|
||||
|
||||
export const selectOption = (idGroup, option) => {
|
||||
const selectedOption = {};
|
||||
selectedOption[idGroup] = option;
|
||||
|
||||
return {
|
||||
type: SELECT_OPTION,
|
||||
selectedOptions: selectedOption,
|
||||
};
|
||||
};
|
||||
|
||||
export const selectAdditional = (additional) => ({
|
||||
type: SELECT_ADDITIONAL,
|
||||
selectedAdditonal: additional,
|
||||
});
|
||||
|
||||
export const removetAdditional = (additional) => ({
|
||||
type: REMOVE_ADDITIONAL,
|
||||
selectedAdditonal: additional,
|
||||
});
|
||||
86
client-wiaas/src/actions/coMarket/coMarketPackagesActions.js
Normal file
86
client-wiaas/src/actions/coMarket/coMarketPackagesActions.js
Normal file
@@ -0,0 +1,86 @@
|
||||
import {
|
||||
API_SERVER
|
||||
} from '../../config';
|
||||
import HtmlClient from '../../helpers/HtmlClient';
|
||||
import {
|
||||
REQUEST_SHOP_PACKAGES,
|
||||
RECIEVE_SHOP_PACKAGES,
|
||||
REQUEST_SHOP_COMMERCIAL_LEADS,
|
||||
RECIEVE_SHOP_COMMERCIAL_LEADS,
|
||||
SELECT_SHOP_COMMERCIAL_LEAD
|
||||
} from '../../constants/coMarketConstants';
|
||||
const client = new HtmlClient();
|
||||
|
||||
const requestShopPackages = () => ({
|
||||
type: REQUEST_SHOP_PACKAGES,
|
||||
isLoading: true
|
||||
});
|
||||
const recieveShopPackages = (json) => ({
|
||||
type: RECIEVE_SHOP_PACKAGES,
|
||||
isLoading: false,
|
||||
shopPackages: json
|
||||
});
|
||||
|
||||
export const fetchShopPackages = (cl, search) => {
|
||||
return dispatch => {
|
||||
dispatch(requestShopPackages());
|
||||
return client.fetch({
|
||||
url: `${API_SERVER}/coMarket/api/getShopPackages`,
|
||||
method: 'post',
|
||||
data: {
|
||||
idCommercialLead: (cl && cl.value) || 0,
|
||||
search
|
||||
}
|
||||
})
|
||||
.then(response => {
|
||||
if(response.data && response.data.packages){
|
||||
dispatch(recieveShopPackages(response.data.packages))
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
client.onError(error, dispatch);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const requestShopCommercialLeads = () => ({
|
||||
type: REQUEST_SHOP_COMMERCIAL_LEADS
|
||||
});
|
||||
const recieveShopCommercialLeads = (json) => ({
|
||||
type: RECIEVE_SHOP_COMMERCIAL_LEADS,
|
||||
commercialLeads: json
|
||||
});
|
||||
|
||||
const generateClOptions = (commercialLeads) => {
|
||||
commercialLeads.forEach((cl) => {
|
||||
cl.value = cl.idCommercialLead;
|
||||
cl.label = cl.commercialLeadName;
|
||||
});
|
||||
|
||||
return commercialLeads;
|
||||
}
|
||||
|
||||
export const fetchShopCommercialLeads = () => {
|
||||
return dispatch => {
|
||||
dispatch(requestShopCommercialLeads());
|
||||
return client.fetch({url: `${API_SERVER}/coMarket/api/getAllCommercialLeads`})
|
||||
.then(response => {
|
||||
if(response.data && response.data.commercialLeads){
|
||||
const clOptions = generateClOptions(response.data.commercialLeads);
|
||||
dispatch(recieveShopCommercialLeads(clOptions));
|
||||
if (clOptions.length) {
|
||||
dispatch(selectCommercialLead(clOptions[0]));
|
||||
dispatch(fetchShopPackages(clOptions[0]));
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
client.onError(error, dispatch);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const selectCommercialLead = (cl) => ({
|
||||
type: SELECT_SHOP_COMMERCIAL_LEAD,
|
||||
selectedCommercialLead: cl
|
||||
});
|
||||
27
client-wiaas/src/actions/dashboard/dashboardActions.js
Normal file
27
client-wiaas/src/actions/dashboard/dashboardActions.js
Normal file
@@ -0,0 +1,27 @@
|
||||
import {API_SERVER} from '../../config';
|
||||
import HtmlClient from '../../helpers/HtmlClient';
|
||||
import {REQUEST_GADGETS, RECIEVE_GADGETS} from '../../constants/dashboardConstants';
|
||||
const htmlClient = new HtmlClient();
|
||||
|
||||
const requestGadgets = () => ({type: REQUEST_GADGETS});
|
||||
const recieveGadgets = (json) => ({
|
||||
type: RECIEVE_GADGETS,
|
||||
gadgets: json
|
||||
});
|
||||
|
||||
export const fetchGadgets = () => {
|
||||
return dispatch => {
|
||||
dispatch(requestGadgets());
|
||||
return htmlClient.fetch({
|
||||
url: `${API_SERVER}/dashboards/api/getMyDashboard`
|
||||
})
|
||||
.then(response => {
|
||||
if(response.data && response.data.gadgets){
|
||||
dispatch(recieveGadgets(response.data.gadgets))
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
htmlClient.onError(error, dispatch);
|
||||
});
|
||||
}
|
||||
}
|
||||
28
client-wiaas/src/actions/dashboard/nextActionsActions.js
Normal file
28
client-wiaas/src/actions/dashboard/nextActionsActions.js
Normal file
@@ -0,0 +1,28 @@
|
||||
import {API_SERVER} from '../../config';
|
||||
import HtmlClient from '../../helpers/HtmlClient';
|
||||
import {REQUEST_NEXT_ACTIONS, RECIEVE_NEXT_ACTIONS} from '../../constants/dashboardConstants';
|
||||
const client = new HtmlClient();
|
||||
|
||||
export const requestNextActions = () => ({
|
||||
type: REQUEST_NEXT_ACTIONS,
|
||||
isLoading: true
|
||||
});
|
||||
|
||||
export const recieveNextActions = (json) => ({
|
||||
type: RECIEVE_NEXT_ACTIONS,
|
||||
isLoading: false,
|
||||
nextActions: json
|
||||
});
|
||||
|
||||
export const fetchNextActions = () => {
|
||||
return dispatch => {
|
||||
dispatch(requestNextActions());
|
||||
return client.fetch({
|
||||
url: `${API_SERVER}/dashboards/api/getNextActionsInfo`
|
||||
})
|
||||
.then(response => dispatch(recieveNextActions(response.data)))
|
||||
.catch(error => {
|
||||
client.onError(error, dispatch);
|
||||
});
|
||||
}
|
||||
}
|
||||
35
client-wiaas/src/actions/dashboard/ordersActions.js
Normal file
35
client-wiaas/src/actions/dashboard/ordersActions.js
Normal file
@@ -0,0 +1,35 @@
|
||||
import {API_SERVER} from '../../config';
|
||||
import HtmlClient from '../../helpers/HtmlClient';
|
||||
import {
|
||||
REQUEST_ORDERS,
|
||||
RECEIVE_ORDERS
|
||||
} from '../../constants/dashboardConstants';
|
||||
const htmlClient = new HtmlClient();
|
||||
|
||||
export const requestOrders = () => ({
|
||||
type: REQUEST_ORDERS,
|
||||
isLoading: true
|
||||
});
|
||||
|
||||
export const recieveOrders = (json) => ({
|
||||
type: RECEIVE_ORDERS,
|
||||
isLoading: false,
|
||||
orders: json
|
||||
});
|
||||
|
||||
export const fetchOrders = (viewAllOrders) => {
|
||||
return dispatch => {
|
||||
dispatch(requestOrders());
|
||||
return htmlClient.fetch({
|
||||
url: `${API_SERVER}/dashboards/api/getOrderCentralInfo`,
|
||||
method: 'post',
|
||||
data: {
|
||||
viewAllOrders
|
||||
}
|
||||
})
|
||||
.then(response => dispatch(recieveOrders(response.data)))
|
||||
.catch(error => {
|
||||
htmlClient.onError(error, dispatch);
|
||||
});
|
||||
}
|
||||
}
|
||||
4
client-wiaas/src/actions/dialog/dialogActions.js
Normal file
4
client-wiaas/src/actions/dialog/dialogActions.js
Normal file
@@ -0,0 +1,4 @@
|
||||
import {CONTENT_MESSAGE, IS_OPENED} from '../../constants/dialogConstants';
|
||||
|
||||
export const setDialogContent = (json) => ({type: CONTENT_MESSAGE, dialogContent: json});
|
||||
export const setDialogOpenFlag = (flag) => ({type: IS_OPENED, isDialogOpen: flag});
|
||||
268
client-wiaas/src/actions/login/authActions.js
Normal file
268
client-wiaas/src/actions/login/authActions.js
Normal file
@@ -0,0 +1,268 @@
|
||||
import jwtDecode from 'jwt-decode';
|
||||
|
||||
import {
|
||||
API_SERVER
|
||||
} from '../../config';
|
||||
import {
|
||||
LOGIN,
|
||||
LOGOUT,
|
||||
LOGIN_SUCCESS,
|
||||
LOGIN_FAIL,
|
||||
VALIDATE_TOKEN,
|
||||
REQUEST_MODULES,
|
||||
RECIEVE_MODULES,
|
||||
REQUEST_FORGOT_PASSWORD,
|
||||
FORGOT_PASSWORD,
|
||||
REFRESH_TOKEN,
|
||||
REQUEST_CHANGE,
|
||||
PASSWORD_CHANGED,
|
||||
SET_COMPANY_ADMIN_FLAG,
|
||||
authActivity
|
||||
} from '../../constants/authConstants';
|
||||
import HtmlClient from '../../helpers/HtmlClient';
|
||||
|
||||
const htmlClient = new HtmlClient();
|
||||
let refreshToken = '';
|
||||
let refreshTimer = {};
|
||||
const REFRESH_TIME = 1000 * 60 * 50; //refresh 10 minutes before expired
|
||||
|
||||
export const login = () => ({
|
||||
type: LOGIN
|
||||
});
|
||||
|
||||
export const validateToken = () => ({
|
||||
type: VALIDATE_TOKEN
|
||||
});
|
||||
|
||||
export const validateAccessToken = (token) => {
|
||||
return dispatch => {
|
||||
dispatch(validateToken());
|
||||
return htmlClient.fetch({
|
||||
url: `${API_SERVER}/login/api/validateToken`
|
||||
})
|
||||
.then(response => {
|
||||
if (response.data && response.data.status === 'success') {
|
||||
const serverTime = response.data.serverTime || 1;
|
||||
|
||||
dispatch(loggedIn({
|
||||
accessToken: token,
|
||||
userInfo: response.data.userInfo
|
||||
}));
|
||||
refreshToken = response.data.refreshToken;
|
||||
startRefreshTimer(dispatch, serverTime);
|
||||
dispatch(setUserAsCompanyAdmin(response.data.userInfo.wiaas_is_company_admin));
|
||||
} else {
|
||||
dispatch(loginFail(response.data));
|
||||
}
|
||||
|
||||
})
|
||||
.catch(error => {
|
||||
htmlClient.onError(error, dispatch);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const setUserAsCompanyAdmin = (isCompanyAdmin) => ({type: SET_COMPANY_ADMIN_FLAG, isCompanyAdmin});
|
||||
|
||||
export const validateCredentials = (username, password) => {
|
||||
return dispatch => {
|
||||
dispatch(login());
|
||||
return htmlClient.fetch({
|
||||
url: `${API_SERVER}/login/api/getToken`,
|
||||
method: 'post',
|
||||
data: {
|
||||
username,
|
||||
password,
|
||||
login: true
|
||||
},
|
||||
header: {}
|
||||
})
|
||||
.then(response => {
|
||||
if (response.data.status === 'success') {
|
||||
const decodedAceessToken = jwtDecode(response.data.accessToken);
|
||||
if(decodedAceessToken.data.wiaas_user_type === 'customer'){
|
||||
localStorage.setItem('accessToken', response.data.accessToken);
|
||||
const serverTime = response.data.serverTime || 1;
|
||||
refreshToken = response.data.refreshToken;
|
||||
startRefreshTimer(dispatch, serverTime);
|
||||
dispatch(loggedIn(response.data));
|
||||
dispatch(setUserAsCompanyAdmin(response.data.userInfo.wiaas_is_company_admin));
|
||||
}else{
|
||||
dispatch(loginFail({status: 'fail', errorMessage: 'INVALID_USER_TYPE'}));
|
||||
}
|
||||
} else {
|
||||
dispatch(loginFail(response.data));
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
htmlClient.onError(error, dispatch);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const startRefreshTimer = (dispatch, serverTime) => {
|
||||
const decodedAceessToken = jwtDecode(localStorage.accessToken);
|
||||
const TEN_MINUTES = 600;
|
||||
const tokenTimeLeft = decodedAceessToken.exp - serverTime;
|
||||
const refreshTime = tokenTimeLeft ? (tokenTimeLeft - TEN_MINUTES) * 1000 : REFRESH_TIME;
|
||||
|
||||
if(refreshTime <= 0){
|
||||
dispatch(validateRefreshToken());
|
||||
}else{
|
||||
refreshTimer = setTimeout(()=>{
|
||||
dispatch(validateRefreshToken());
|
||||
}, refreshTime);
|
||||
}
|
||||
}
|
||||
|
||||
const requestRefreshToken = () => ({
|
||||
type: REFRESH_TOKEN
|
||||
});
|
||||
|
||||
const validateRefreshToken = () => {
|
||||
return dispatch => {
|
||||
dispatch(requestRefreshToken());
|
||||
return htmlClient.fetch({
|
||||
url: `${API_SERVER}/login/api/refreshToken`,
|
||||
method: 'post',
|
||||
data: {
|
||||
refreshToken,
|
||||
lastActivity: authActivity.lastActivity
|
||||
}
|
||||
})
|
||||
.then(response => {
|
||||
if (response.data.status === 'success') {
|
||||
localStorage.setItem('accessToken', response.data.accessToken);
|
||||
const serverTime = response.data.serverTime || 1;
|
||||
refreshToken = response.data.refreshToken;
|
||||
dispatch(setUserAsCompanyAdmin(response.data.userInfo.wiaas_is_company_admin));
|
||||
startRefreshTimer(dispatch, serverTime);
|
||||
} else {
|
||||
dispatch(logout(response.data));
|
||||
dispatch(loginFail(response.data));
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
htmlClient.onError(error, dispatch);
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
export const getModules = () => {
|
||||
return dispatch => {
|
||||
dispatch(requestModules());
|
||||
return htmlClient.fetch({
|
||||
url: `${API_SERVER}/login/api/getModules`,
|
||||
})
|
||||
.then(response => {
|
||||
dispatch(recieveModules(response.data));
|
||||
})
|
||||
.catch(error => {
|
||||
htmlClient.onError(error, dispatch);
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
const requestModules = () => ({
|
||||
type: REQUEST_MODULES
|
||||
});
|
||||
|
||||
const recieveModules = (json) => ({
|
||||
type: RECIEVE_MODULES,
|
||||
modules: json.modules
|
||||
});
|
||||
|
||||
export const logout = () => {
|
||||
localStorage.removeItem('accessToken');
|
||||
clearInterval(refreshTimer);
|
||||
return {
|
||||
type: LOGOUT,
|
||||
isLoggedIn: false,
|
||||
errorMessage: 'LOGGED_OUT'
|
||||
}
|
||||
}
|
||||
|
||||
export const loggedIn = (jsonData) => {
|
||||
return {
|
||||
type: LOGIN_SUCCESS,
|
||||
isLoggedIn: true,
|
||||
userInfo: jsonData.userInfo
|
||||
}
|
||||
}
|
||||
|
||||
export const loginFail = (jsonData) => {
|
||||
return {
|
||||
type: LOGIN_FAIL,
|
||||
isLoggedIn: false,
|
||||
errorMessage: jsonData.errorMessage
|
||||
}
|
||||
}
|
||||
|
||||
export const generatePassword = (mail) => {
|
||||
return dispatch => {
|
||||
dispatch(requestForgotPassword());
|
||||
return htmlClient.fetch({
|
||||
url: `${API_SERVER}/login/api/forgotPassword`,
|
||||
method: 'post',
|
||||
data: {mail},
|
||||
header: {}
|
||||
})
|
||||
.then(response => {
|
||||
if(typeof response.data !== 'undefined' && 'messages' in response.data) {
|
||||
dispatch(forgotPasswordMessage(response.data.messages[0]));
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
htmlClient.onError(error, dispatch);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const requestForgotPassword = () => ({
|
||||
type: REQUEST_FORGOT_PASSWORD,
|
||||
errorMessage: 'FORGOT_REQUEST_SENT'
|
||||
});
|
||||
const forgotPasswordMessage = (jsonData) => {
|
||||
return {
|
||||
type: FORGOT_PASSWORD,
|
||||
errorMessage: jsonData.message,
|
||||
messageColor: jsonData.code
|
||||
}
|
||||
}
|
||||
|
||||
const requestChange = () => ({
|
||||
type: REQUEST_CHANGE
|
||||
});
|
||||
|
||||
const passwordChanged = (messageObj) => {
|
||||
const code = messageObj.code === 'error' ? 'danger' : messageObj.code;
|
||||
const isPasswordChanged = messageObj.message === 'PASSWORD_GENERATED' ? true : false;
|
||||
return {
|
||||
type: PASSWORD_CHANGED,
|
||||
errorMessage: messageObj.message,
|
||||
messageColor: code,
|
||||
isPasswordChanged: isPasswordChanged
|
||||
}
|
||||
};
|
||||
|
||||
export const changePassword = (token, newPassword, confirmPassword) => {
|
||||
return dispatch => {
|
||||
dispatch(requestChange());
|
||||
return htmlClient.fetch({
|
||||
url: `${API_SERVER}/login/api/changePassword`,
|
||||
method: 'post',
|
||||
data: {token, newPassword, confirmPassword},
|
||||
header: {}
|
||||
})
|
||||
.then(response => {
|
||||
if(response.data.messages && response.data.messages.length > 0){
|
||||
dispatch(passwordChanged(response.data.messages[0]));
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
htmlClient.onError(error, dispatch);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
import {UPDATE_MESSAGES, DESTROY_MESSAGE} from '../../constants/notificationConstants';
|
||||
|
||||
export const destroyMessage = () => ({type: DESTROY_MESSAGE, messages: []});
|
||||
export const updateMessages = (json, messageObj) => ({type: UPDATE_MESSAGES, updateMessages: {messageJson: json, messageObj}});
|
||||
@@ -0,0 +1,77 @@
|
||||
import {API_SERVER} from '../../config';
|
||||
import HtmlClient from '../../helpers/HtmlClient';
|
||||
import {
|
||||
REQUEST_ORDER_PROJECTS,
|
||||
RECEIVE_ORDER_PROJECTS,
|
||||
REQUEST_ADD_PROJECT,
|
||||
orderProjectsTexts
|
||||
} from '../../constants/orderProjectsConstants';
|
||||
import {updateMessages} from '../notification/notificationActions';
|
||||
import {setDialogOpenFlag} from '../dialog/dialogActions';
|
||||
|
||||
const htmlClient = new HtmlClient();
|
||||
|
||||
const requestOrderProjects = () => ({
|
||||
type: REQUEST_ORDER_PROJECTS,
|
||||
isLoading: true
|
||||
});
|
||||
const recieveOrderProjects = (json) => ({
|
||||
type: RECEIVE_ORDER_PROJECTS,
|
||||
isLoading: false,
|
||||
orderProjects: json
|
||||
});
|
||||
|
||||
const generateOptions = (orderProjects) => {
|
||||
orderProjects.forEach((orderProject) => {
|
||||
orderProject.value = orderProject.idProject;
|
||||
orderProject.label = orderProject.projectName;
|
||||
});
|
||||
|
||||
return orderProjects;
|
||||
}
|
||||
|
||||
export const getOrderProjects = () => {
|
||||
return dispatch => {
|
||||
dispatch(requestOrderProjects());
|
||||
return htmlClient.fetch({
|
||||
url: `${API_SERVER}/orderProjects/api/getOrderProjects`
|
||||
})
|
||||
.then(response => {
|
||||
if (response.data) {
|
||||
const orderProjects = generateOptions(response.data);
|
||||
dispatch(recieveOrderProjects(orderProjects));
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
htmlClient.onError(error, dispatch);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const requestAddProject = () => ({
|
||||
type: REQUEST_ADD_PROJECT,
|
||||
isLoading: true
|
||||
});
|
||||
|
||||
export const addProject = (projectData) => {
|
||||
return dispatch => {
|
||||
dispatch(requestAddProject());
|
||||
return htmlClient.fetch({
|
||||
url: `${API_SERVER}/orderProjects/api/addOrderProject`,
|
||||
method: 'post',
|
||||
data: {projectData: JSON.stringify(projectData)}
|
||||
})
|
||||
.then(response => {
|
||||
if(response.data && response.data.messages){
|
||||
dispatch(updateMessages(response.data.messages, orderProjectsTexts.messages));
|
||||
if(response.data.messages[0].code === 'success'){
|
||||
dispatch(getOrderProjects());
|
||||
dispatch(setDialogOpenFlag(false));
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
htmlClient.onError(error, dispatch);
|
||||
});
|
||||
}
|
||||
}
|
||||
102
client-wiaas/src/actions/orders/customerAcceptanceActions.js
Normal file
102
client-wiaas/src/actions/orders/customerAcceptanceActions.js
Normal file
@@ -0,0 +1,102 @@
|
||||
import {
|
||||
API_SERVER
|
||||
} from '../../config';
|
||||
import {
|
||||
REQUEST_CUSTOMER_ACCEPTANCE,
|
||||
RECEIVE_CUSTOMER_ACCEPTANCE,
|
||||
UPLOAD_CUSTOMER_ACCEPTANCE,
|
||||
SEND_CUSTOMER_ACCEPTANCE,
|
||||
orderMessages
|
||||
} from '../../constants/ordersConstants';
|
||||
import {
|
||||
updateMessages
|
||||
} from '../notification/notificationActions';
|
||||
import HtmlClient from '../../helpers/HtmlClient';
|
||||
|
||||
const htmlClient = new HtmlClient();
|
||||
|
||||
const requestCustomerAcceptance = () => ({
|
||||
type: REQUEST_CUSTOMER_ACCEPTANCE
|
||||
});
|
||||
const recieveCustomerAcceptance = (json) => ({
|
||||
type: RECEIVE_CUSTOMER_ACCEPTANCE,
|
||||
customerAcceptance: json
|
||||
});
|
||||
|
||||
export const fetchCustomerAcceptance = (idOrder) => {
|
||||
return dispatch => {
|
||||
dispatch(requestCustomerAcceptance());
|
||||
return htmlClient.fetch({
|
||||
url: `${API_SERVER}/orders/api/getCustomerAcceptance`,
|
||||
method: 'post',
|
||||
data: {
|
||||
idOrder
|
||||
}
|
||||
})
|
||||
.then(response => {
|
||||
if (response.data) {
|
||||
dispatch(recieveCustomerAcceptance(response.data));
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
htmlClient.onError(error, dispatch);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const uploadAcceptanceAction = () => ({
|
||||
type: UPLOAD_CUSTOMER_ACCEPTANCE
|
||||
});
|
||||
|
||||
export const uploadAcceptance = (idOrder, file) => {
|
||||
return dispatch => {
|
||||
dispatch(uploadAcceptanceAction());
|
||||
return htmlClient.uploadFile(file, {
|
||||
url: `${API_SERVER}/orders/api/uploadAcceptanceDocument`,
|
||||
data: {
|
||||
idOrder
|
||||
}
|
||||
}).then(response => {
|
||||
if (typeof response.data !== 'undefined' && 'messages' in response.data) {
|
||||
dispatch(updateMessages(response.data.messages, orderMessages));
|
||||
dispatch(fetchCustomerAcceptance(idOrder));
|
||||
}
|
||||
}).catch(error => {
|
||||
htmlClient.onError(error, dispatch);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const badFile = () =>{
|
||||
return dispatch => {
|
||||
dispatch(updateMessages([{code: 'warning', message: 'INVALID_FILE_ACCEPTANCE'}], orderMessages));
|
||||
}
|
||||
}
|
||||
|
||||
const sendCustomerAcceptance = () => ({
|
||||
type: SEND_CUSTOMER_ACCEPTANCE
|
||||
});
|
||||
|
||||
export const acceptDeclineInstallation = (idOrder, actionType, declineReason) => {
|
||||
return dispatch => {
|
||||
dispatch(sendCustomerAcceptance());
|
||||
return htmlClient.fetch({
|
||||
url: `${API_SERVER}/orders/api/acceptDeclineInstallation`,
|
||||
method: 'post',
|
||||
data: {
|
||||
idOrder,
|
||||
actionType,
|
||||
declineReason
|
||||
}
|
||||
})
|
||||
.then(response => {
|
||||
if (response.data) {
|
||||
dispatch(updateMessages(response.data.messages, orderMessages));
|
||||
dispatch(fetchCustomerAcceptance(idOrder));
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
htmlClient.onError(error, dispatch);
|
||||
});
|
||||
}
|
||||
}
|
||||
66
client-wiaas/src/actions/orders/ordersActions.js
Normal file
66
client-wiaas/src/actions/orders/ordersActions.js
Normal file
@@ -0,0 +1,66 @@
|
||||
import {API_SERVER} from '../../config';
|
||||
import HtmlClient from '../../helpers/HtmlClient';
|
||||
import {
|
||||
REQUEST_ACTIVE_ORDERS,
|
||||
RECEIVE_ACTIVE_ORDERS,
|
||||
REQUEST_HISTORY_ORDERS,
|
||||
RECEIVE_HISTORY_ORDERS,
|
||||
SET_VIEW_ALL_ORDERS
|
||||
} from '../../constants/ordersConstants';
|
||||
const htmlClient = new HtmlClient();
|
||||
|
||||
const requestActiveOrders = () => ({
|
||||
type: REQUEST_ACTIVE_ORDERS,
|
||||
isLoading: true
|
||||
});
|
||||
const recieveActiveOrders = (json) => ({
|
||||
type: RECEIVE_ACTIVE_ORDERS,
|
||||
isLoading: false,
|
||||
activeOrders: json
|
||||
});
|
||||
|
||||
export const getActiveOrders = () => {
|
||||
return dispatch => {
|
||||
dispatch(requestActiveOrders());
|
||||
return htmlClient.fetch({
|
||||
url: `${API_SERVER}/orders/api/getActiveOrders`
|
||||
})
|
||||
.then(response => {
|
||||
if (typeof response.data !== 'undefined' && 'orders' in response.data) {
|
||||
dispatch(recieveActiveOrders(response.data.orders));
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
htmlClient.onError(error, dispatch);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const requestHistoryOrders = () => ({
|
||||
type: REQUEST_HISTORY_ORDERS,
|
||||
isLoading: true
|
||||
});
|
||||
const recieveHistoryOrders = (json) => ({
|
||||
type: RECEIVE_HISTORY_ORDERS,
|
||||
isLoading: false,
|
||||
historyOrders: json
|
||||
});
|
||||
|
||||
export const getHistoryOrders = () => {
|
||||
return dispatch => {
|
||||
dispatch(requestHistoryOrders());
|
||||
return htmlClient.fetch({
|
||||
url: `${API_SERVER}/orders/api/getHistoryOrders`
|
||||
})
|
||||
.then(response => {
|
||||
if (typeof response.data !== 'undefined' && 'orders' in response.data) {
|
||||
dispatch(recieveHistoryOrders(response.data.orders));
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
htmlClient.onError(error, dispatch);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const setViewAllOrdersFlag = (isViewAllOrdersChecked) => ({type: SET_VIEW_ALL_ORDERS, isViewAllOrdersChecked});
|
||||
344
client-wiaas/src/actions/orders/processActions.js
Normal file
344
client-wiaas/src/actions/orders/processActions.js
Normal file
@@ -0,0 +1,344 @@
|
||||
import {
|
||||
API_SERVER
|
||||
} from '../../config';
|
||||
import {
|
||||
orderMessages,
|
||||
REQUEST_ORDER_INFO,
|
||||
RECEIVE_ORDER_INFO,
|
||||
SEND_ORDER_COMMENT,
|
||||
REQUEST_CUSTOMER_DOCUMENTS,
|
||||
RECEIVE_CUSTOMER_DOCUMENTS,
|
||||
RE_UPLOAD_DOCUMENT,
|
||||
REQUEST_VALIDATION_COMMENTS,
|
||||
RECEIVE_VALIDATION_COMMENTS,
|
||||
REQUEST_IS_NEXT_STEP_WANTED,
|
||||
RECEIVE_IS_NEXT_STEP_WANTED,
|
||||
RECEIVE_IS_COMPONENT_DISABLED,
|
||||
SET_EARLIEST_INSTALLATION_DATE,
|
||||
SET_CONFIRMATION_DATES,
|
||||
REQUEST_INSTALLATION_COMPANIES,
|
||||
RECEIVE_INSTALLATION_COMPANIES,
|
||||
REQUEST_ALL_SHIPPING_DATES_CONFIRMED,
|
||||
RECEIVE_ALL_SHIPPING_DATES_CONFIRMED,
|
||||
SET_SUPPORT_MESSAGE,
|
||||
SET_SCHEDULING_DISABLED_FLAG
|
||||
} from '../../constants/ordersConstants';
|
||||
import HtmlClient from '../../helpers/HtmlClient';
|
||||
import {updateMessages} from '../notification/notificationActions';
|
||||
|
||||
const htmlClient = new HtmlClient();
|
||||
|
||||
const requestOrderInfo = () => ({
|
||||
type: REQUEST_ORDER_INFO,
|
||||
isLoading: true
|
||||
});
|
||||
const recieveOrderInfo = (json) => ({
|
||||
type: RECEIVE_ORDER_INFO,
|
||||
isLoading: false,
|
||||
orderInfo: json
|
||||
});
|
||||
|
||||
export const fetchOrderInfo = (idOrder) => {
|
||||
return dispatch => {
|
||||
dispatch(requestOrderInfo());
|
||||
return htmlClient.fetch({
|
||||
url: `${API_SERVER}/orders/api/getOrderInfo`,
|
||||
method: 'post',
|
||||
data: {
|
||||
idOrder
|
||||
}
|
||||
})
|
||||
.then(response => {
|
||||
if (response.data) {
|
||||
dispatch(recieveOrderInfo(response.data));
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
htmlClient.onError(error, dispatch);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const sendComment = () => ({
|
||||
type: SEND_ORDER_COMMENT
|
||||
})
|
||||
|
||||
export const addComment = (idOrder, comment) => {
|
||||
return dispatch => {
|
||||
dispatch(sendComment());
|
||||
return htmlClient.fetch({
|
||||
url: `${API_SERVER}/orders/api/addOrderComment`,
|
||||
method: 'post',
|
||||
data: {
|
||||
idOrder,
|
||||
comment
|
||||
}
|
||||
})
|
||||
.then(response => {
|
||||
if (response.data && response.data.messages) {
|
||||
dispatch(updateMessages(response.data.messages, orderMessages));
|
||||
dispatch(fetchOrderInfo(idOrder));
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
htmlClient.onError(error, dispatch);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const requestCustomerDocuments = () => ({
|
||||
type: REQUEST_CUSTOMER_DOCUMENTS
|
||||
});
|
||||
const recieveCustomerDocuments = (json) => ({
|
||||
type: RECEIVE_CUSTOMER_DOCUMENTS,
|
||||
customerDocuments: json
|
||||
});
|
||||
|
||||
export const fetchCustomerDocuments = (idOrder, documentType, idPackage = 0) => {
|
||||
return dispatch => {
|
||||
dispatch(requestCustomerDocuments());
|
||||
return htmlClient.fetch({
|
||||
url: `${API_SERVER}/orders/api/getOrderDocumentsPerType`,
|
||||
method: 'post',
|
||||
data: {
|
||||
idOrder,
|
||||
idPackage,
|
||||
documentType
|
||||
}
|
||||
})
|
||||
.then(response => {
|
||||
if (typeof response.data !== 'undefined' && 'documents' in response.data) {
|
||||
dispatch(recieveCustomerDocuments(response.data.documents));
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
htmlClient.onError(error, dispatch);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const requestValidationComments = () => ({
|
||||
type: REQUEST_VALIDATION_COMMENTS
|
||||
});
|
||||
const recieveValidationComments = (json) => ({
|
||||
type: RECEIVE_VALIDATION_COMMENTS,
|
||||
validationComments: json
|
||||
});
|
||||
|
||||
export const fetchValidationComments = (idOrder, idProcessStep, commentType) => {
|
||||
return dispatch => {
|
||||
dispatch(requestValidationComments());
|
||||
return htmlClient.fetch({
|
||||
url: `${API_SERVER}/orders/api/getCommentsByType`,
|
||||
method: 'post',
|
||||
data: {
|
||||
idOrder,
|
||||
idProcessStep,
|
||||
commentType
|
||||
}
|
||||
})
|
||||
.then(response => {
|
||||
if (response.data) {
|
||||
dispatch(recieveValidationComments(response.data));
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
htmlClient.onError(error, dispatch);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const reUploadDocumnet = () => ({
|
||||
type: RE_UPLOAD_DOCUMENT
|
||||
});
|
||||
|
||||
export const reUploadOrderDocument = (idPackage, idOrder, idDocument, file) => {
|
||||
return dispatch => {
|
||||
dispatch(reUploadDocumnet());
|
||||
return htmlClient.uploadFile(file, {
|
||||
url: `${API_SERVER}/orders/api/reUploadQuestionaire`,
|
||||
data: {
|
||||
idPackage,
|
||||
idOrder,
|
||||
idDocument
|
||||
}
|
||||
}).then(response => {
|
||||
if (typeof response.data !== 'undefined' && 'messages' in response.data) {
|
||||
dispatch(updateMessages(response.data.messages, orderMessages));
|
||||
dispatch(fetchCustomerDocuments(idOrder, 'orderQuestionaire', idPackage));
|
||||
}
|
||||
}).catch(error => {
|
||||
htmlClient.onError(error, dispatch);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const badFile = () =>{
|
||||
return dispatch => {
|
||||
dispatch(updateMessages([{code: 'warning', message: 'INVALID_FILE_QUESTIONNAINRE'}], orderMessages));
|
||||
}
|
||||
}
|
||||
|
||||
export const requestIsNextStepWanted = () => ({type: REQUEST_IS_NEXT_STEP_WANTED});
|
||||
export const receiveIsNextStepWanted = (json) => ({
|
||||
type: RECEIVE_IS_NEXT_STEP_WANTED,
|
||||
isNextStepWanted: json
|
||||
});
|
||||
|
||||
const receiveIsComponentDisabled = (isComponentDisabled) => ({
|
||||
type: RECEIVE_IS_COMPONENT_DISABLED,
|
||||
isComponentDisabled
|
||||
});
|
||||
|
||||
const setEarliestInstallationDate = (earliestInstallDate) => ({
|
||||
type: SET_EARLIEST_INSTALLATION_DATE,
|
||||
earliestInstallDate
|
||||
});
|
||||
|
||||
const setConfirmationDates = (json) => ({
|
||||
type: SET_CONFIRMATION_DATES,
|
||||
confirmationDates: json
|
||||
});
|
||||
export const getInstallationConfirmationDates = (idOrder, idPackage = 0) => {
|
||||
return dispatch => {
|
||||
return htmlClient.fetch({
|
||||
url: `${API_SERVER}/orders/api/getInstallationDates`,
|
||||
method: 'post',
|
||||
data: {idOrder, idPackage}
|
||||
})
|
||||
.then(response => {
|
||||
if (typeof response.data !== 'undefined' && 'confirmationDates' in response.data) {
|
||||
dispatch(setConfirmationDates(response.data.confirmationDates));
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
htmlClient.onError(error, dispatch);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const requestInstallationCompanies = () => ({type: REQUEST_INSTALLATION_COMPANIES});
|
||||
const recieveInstallationCompanies = (json) => ({
|
||||
type: RECEIVE_INSTALLATION_COMPANIES,
|
||||
installCompanies: json
|
||||
});
|
||||
|
||||
const requestAreAllShippingDatesConfirmed = ()=> ({type: REQUEST_ALL_SHIPPING_DATES_CONFIRMED});
|
||||
const receiveAreAllShippingDatesConfirmed = (json) => ({
|
||||
type: RECEIVE_ALL_SHIPPING_DATES_CONFIRMED,
|
||||
areAllShippingDatesConfirmed: json
|
||||
});
|
||||
|
||||
export const getAllDataForInstallation = (idOrder, usedForDirective, stepsNameForInstallation, fileType) => {
|
||||
const isNextStepTheOneWanted = {};
|
||||
return dispatch => {
|
||||
dispatch(requestInstallationCompanies());
|
||||
dispatch(requestIsNextStepWanted());
|
||||
dispatch(requestCustomerDocuments());
|
||||
dispatch(requestAreAllShippingDatesConfirmed());
|
||||
return htmlClient.fetch({
|
||||
url: `${API_SERVER}/orders/api/getAllDataForInstallation`,
|
||||
method: 'post',
|
||||
data: {idOrder, stepsNameForInstallation, fileType}
|
||||
})
|
||||
.then(response => {
|
||||
if (typeof response.data !== 'undefined') {
|
||||
if ('messages' in response.data) {
|
||||
dispatch(updateMessages(response.data.messages, orderMessages));
|
||||
}
|
||||
if('installCompanies' in response.data) {
|
||||
dispatch(recieveInstallationCompanies(response.data.installCompanies));
|
||||
}
|
||||
if('earliestInstallationDate' in response.data) {
|
||||
dispatch(setEarliestInstallationDate(response.data.earliestInstallationDate));
|
||||
}
|
||||
if ('installationDates' in response.data) {
|
||||
dispatch(setConfirmationDates(response.data.installationDates.confirmationDates));
|
||||
}
|
||||
if('isNextStepWanted' in response.data) {
|
||||
isNextStepTheOneWanted[usedForDirective] = response.data.isNextStepWanted;
|
||||
|
||||
dispatch(receiveIsNextStepWanted(isNextStepTheOneWanted));
|
||||
dispatch(receiveIsComponentDisabled(isNextStepTheOneWanted));
|
||||
}
|
||||
if('areAllShippingDatesConfirmed' in response.data) {
|
||||
dispatch(receiveAreAllShippingDatesConfirmed(response.data.areAllShippingDatesConfirmed));
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
htmlClient.onError(error, dispatch);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
export const updateInstallationDate = (idOrder, idPackage, installationDate, status, clearDateInput='') => {
|
||||
return dispatch => {
|
||||
return htmlClient.fetch({
|
||||
url: `${API_SERVER}/orders/api/updateInstallationDate`,
|
||||
method: 'post',
|
||||
data: {idOrder, idPackage, installationDate, status}
|
||||
})
|
||||
.then(response => {
|
||||
if (typeof response.data !== 'undefined' && 'messages' in response.data) {
|
||||
dispatch(updateMessages(response.data.messages, orderMessages));
|
||||
if(response.data.messages.find(messageObj => {return messageObj.code === 'success';})) {
|
||||
if(clearDateInput) {
|
||||
clearDateInput(undefined);
|
||||
}
|
||||
}
|
||||
}
|
||||
dispatch(getInstallationConfirmationDates(idOrder, idPackage));
|
||||
})
|
||||
.catch(error => {
|
||||
htmlClient.onError(error, dispatch);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const removeMyDate = (idOrder, idPackage, installationDate) => {
|
||||
return dispatch => {
|
||||
return htmlClient.fetch({
|
||||
url: `${API_SERVER}/orders/api/removeMyDate`,
|
||||
method: 'post',
|
||||
data: {idOrder, idPackage, installationDate}
|
||||
})
|
||||
.then(response => {
|
||||
if (typeof response.data !== 'undefined' && 'messages' in response.data) {
|
||||
dispatch(updateMessages(response.data.messages, orderMessages));
|
||||
}
|
||||
dispatch(getInstallationConfirmationDates(idOrder, idPackage));
|
||||
})
|
||||
.catch(error => {
|
||||
htmlClient.onError(error, dispatch);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const setSupportMessage = (message) => ({
|
||||
type: SET_SUPPORT_MESSAGE,
|
||||
supportText: message
|
||||
});
|
||||
|
||||
export const sendSupportMail = (orderInfo, orderPackages, supportText) => {
|
||||
return dispatch => {
|
||||
return htmlClient.fetch({
|
||||
url: `${API_SERVER}/orders/api/sendSupportMail`,
|
||||
method: 'post',
|
||||
data: {orderInfo, orderPackages, supportText}
|
||||
})
|
||||
.then(response => {
|
||||
if (typeof response.data !== 'undefined' && 'messages' in response.data) {
|
||||
dispatch(updateMessages(response.data.messages, orderMessages));
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
htmlClient.onError(error, dispatch);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const setSchedulingFlag = (flag) => ({
|
||||
type: SET_SCHEDULING_DISABLED_FLAG,
|
||||
isSchedulingDisabled: flag
|
||||
});
|
||||
30
client-wiaas/src/actions/page/pageActions.js
Normal file
30
client-wiaas/src/actions/page/pageActions.js
Normal file
@@ -0,0 +1,30 @@
|
||||
import {
|
||||
SET_PARAMS_FROM_URL,
|
||||
RESET_PARAMS,
|
||||
SET_ACTIVE_MODULE,
|
||||
SET_ACTIVE_SUB_MODULE,
|
||||
RESET_ACTIVE_SUB_MODULE
|
||||
} from '../../constants/pageConstants';
|
||||
|
||||
export const setParamsFromUrl = (params) => ({
|
||||
type: SET_PARAMS_FROM_URL,
|
||||
urlParams: params
|
||||
});
|
||||
|
||||
export const resetParamsFromUrl = () => ({
|
||||
type: RESET_PARAMS
|
||||
});
|
||||
|
||||
export const setActiveModule = (module) => ({
|
||||
type: SET_ACTIVE_MODULE,
|
||||
activeModule: module
|
||||
});
|
||||
|
||||
export const setActiveSubModule = (submodule) => ({
|
||||
type: SET_ACTIVE_SUB_MODULE,
|
||||
activeSubmodule: submodule
|
||||
});
|
||||
|
||||
export const resetActiveSubModule = () => ({
|
||||
type: RESET_ACTIVE_SUB_MODULE
|
||||
});
|
||||
118
client-wiaas/src/actions/profileSettings/addressActions.js
Normal file
118
client-wiaas/src/actions/profileSettings/addressActions.js
Normal file
@@ -0,0 +1,118 @@
|
||||
import {
|
||||
API_SERVER
|
||||
} from '../../config';
|
||||
import HtmlClient from '../../helpers/HtmlClient';
|
||||
import {
|
||||
REQUEST_SAVE_PROFILE_ADDRESS,
|
||||
REQUEST_REMOVE_PROFILE_ADDRESS,
|
||||
REQUEST_REMOVE_BILLING_ADDRESS,
|
||||
REQUEST_SAVE_BILLING_ADDRESS,
|
||||
profileTexts
|
||||
} from '../../constants/profileSettingsConstants';
|
||||
import {fetchProfileInfo} from './profileSettingsActions';
|
||||
import {updateMessages} from '../notification/notificationActions';
|
||||
import {setDialogOpenFlag} from '../dialog/dialogActions';
|
||||
|
||||
const client = new HtmlClient();
|
||||
|
||||
const requestSaveAddress = () => ({
|
||||
type: REQUEST_SAVE_PROFILE_ADDRESS
|
||||
});
|
||||
|
||||
export const saveProfileAddress = (idUser, profileAddress) => {
|
||||
return dispatch => {
|
||||
dispatch(requestSaveAddress());
|
||||
return client.fetch({
|
||||
url: `${API_SERVER}/profileSettings/api/saveProfileAddress`,
|
||||
method: 'post',
|
||||
data: {profileAddress: JSON.stringify(profileAddress)}
|
||||
})
|
||||
.then(response => {
|
||||
if(response.data && response.data.messages){
|
||||
dispatch(updateMessages(response.data.messages, profileTexts.messages));
|
||||
if(response.data.messages[0].code === 'success'){
|
||||
dispatch(fetchProfileInfo(idUser));
|
||||
dispatch(setDialogOpenFlag(false));
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
client.onError(error, dispatch);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const requestRemoveAddress = () => ({
|
||||
type: REQUEST_REMOVE_PROFILE_ADDRESS
|
||||
});
|
||||
|
||||
export const removeProfileAddress = (idUser, idProfileAddress) => {
|
||||
return dispatch => {
|
||||
dispatch(requestRemoveAddress());
|
||||
return client.fetch({
|
||||
url: `${API_SERVER}/profileSettings/api/removeProfileAddress`,
|
||||
method: 'post',
|
||||
data: {idProfileAddress}
|
||||
})
|
||||
.then(response => {
|
||||
if(response.data && response.data.messages){
|
||||
dispatch(updateMessages(response.data.messages, profileTexts.messages));
|
||||
dispatch(fetchProfileInfo(idUser));
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
client.onError(error, dispatch);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const requestSaveBillingAddress = () => ({
|
||||
type: REQUEST_SAVE_BILLING_ADDRESS
|
||||
});
|
||||
|
||||
export const saveBillingAddress = (idUser, idCompany, billingAddress) => {
|
||||
return dispatch => {
|
||||
dispatch(requestSaveBillingAddress());
|
||||
return client.fetch({
|
||||
url: `${API_SERVER}/profileSettings/api/saveBillingAddress`,
|
||||
method: 'post',
|
||||
data: {idCompany, billingAddress: JSON.stringify(billingAddress)}
|
||||
})
|
||||
.then(response => {
|
||||
if(response.data && response.data.messages){
|
||||
dispatch(updateMessages(response.data.messages, profileTexts.messages));
|
||||
if(response.data.messages[0].code === 'success'){
|
||||
dispatch(fetchProfileInfo(idUser));
|
||||
dispatch(setDialogOpenFlag(false));
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
client.onError(error, dispatch);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const requestRemoveBillingAddress = () => ({
|
||||
type: REQUEST_REMOVE_BILLING_ADDRESS
|
||||
});
|
||||
|
||||
export const removeBillingAddress = (idUser, idBillingAddress) => {
|
||||
return dispatch => {
|
||||
dispatch(requestRemoveBillingAddress());
|
||||
return client.fetch({
|
||||
url: `${API_SERVER}/profileSettings/api/removeBillingAddress`,
|
||||
method: 'post',
|
||||
data: {idBillingAddress}
|
||||
})
|
||||
.then(response => {
|
||||
if(response.data && response.data.messages){
|
||||
dispatch(updateMessages(response.data.messages, profileTexts.messages));
|
||||
dispatch(fetchProfileInfo(idUser));
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
client.onError(error, dispatch);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
import {
|
||||
API_SERVER
|
||||
} from '../../config';
|
||||
import HtmlClient from '../../helpers/HtmlClient';
|
||||
import {
|
||||
REQUEST_PROFILE_INFO,
|
||||
RECIEVE_PROFILE_INFO,
|
||||
REQUEST_SAVE_PROFILE,
|
||||
REQUEST_SAVE_COMPANY,
|
||||
REQUEST_COUNTRIES,
|
||||
RECIEVE_COUNTRIES,
|
||||
profileTexts
|
||||
} from '../../constants/profileSettingsConstants';
|
||||
import {updateMessages} from '../notification/notificationActions';
|
||||
|
||||
const client = new HtmlClient();
|
||||
|
||||
const requestProfileInfo = () => ({
|
||||
type: REQUEST_PROFILE_INFO,
|
||||
isLoading: true
|
||||
});
|
||||
|
||||
export const recieveProfileInfo = (json) => ({
|
||||
type: RECIEVE_PROFILE_INFO,
|
||||
isLoading: false,
|
||||
profileInfo: json
|
||||
});
|
||||
|
||||
export const fetchProfileInfo = (idUser) => {
|
||||
return dispatch => {
|
||||
dispatch(requestProfileInfo());
|
||||
return client.fetch({
|
||||
url: `${API_SERVER}/profileSettings/api/getProfileInfo`,
|
||||
method: 'post',
|
||||
data: {idUser}
|
||||
})
|
||||
.then(response => {
|
||||
if(response.data){
|
||||
dispatch(recieveProfileInfo(response.data));
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
client.onError(error, dispatch);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const requestSaveProfile = () => ({
|
||||
type: REQUEST_SAVE_PROFILE
|
||||
});
|
||||
|
||||
export const saveProfileInfo = (idUser, profile) => {
|
||||
return dispatch => {
|
||||
dispatch(requestSaveProfile());
|
||||
return client.fetch({
|
||||
url: `${API_SERVER}/profileSettings/api/saveProfileInfo`,
|
||||
method: 'post',
|
||||
data: {idUser, profile: JSON.stringify(profile)}
|
||||
})
|
||||
.then(response => {
|
||||
if(response.data && response.data.messages){
|
||||
dispatch(updateMessages(response.data.messages, profileTexts.messages));
|
||||
dispatch(fetchProfileInfo(idUser));
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
client.onError(error, dispatch);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const requestSaveCompany = () => ({
|
||||
type: REQUEST_SAVE_COMPANY
|
||||
});
|
||||
|
||||
export const saveCompanyInfo = (idUser, companyInfo) => {
|
||||
return dispatch => {
|
||||
dispatch(requestSaveCompany());
|
||||
return client.fetch({
|
||||
url: `${API_SERVER}/profileSettings/api/saveCompanyInfo`,
|
||||
method: 'post',
|
||||
data: {companyInfo: JSON.stringify(companyInfo)}
|
||||
})
|
||||
.then(response => {
|
||||
if(response.data && response.data.messages){
|
||||
dispatch(updateMessages(response.data.messages, profileTexts.messages));
|
||||
dispatch(fetchProfileInfo(idUser));
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
client.onError(error, dispatch);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const requestCountries = () => ({
|
||||
type: REQUEST_COUNTRIES,
|
||||
areCountriesLoading: true
|
||||
});
|
||||
|
||||
const recieveCountries = (json) => ({
|
||||
type: RECIEVE_COUNTRIES,
|
||||
areCountriesLoading: false,
|
||||
countries: json
|
||||
});
|
||||
|
||||
export const fetchCountries = () => {
|
||||
return dispatch => {
|
||||
dispatch(requestCountries());
|
||||
return client.fetch({
|
||||
url: `${API_SERVER}/profileSettings/api/getCoutnries`,
|
||||
method: 'get'
|
||||
})
|
||||
.then(response => {
|
||||
if(response.data){
|
||||
dispatch(recieveCountries(response.data));
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
client.onError(error, dispatch);
|
||||
});
|
||||
}
|
||||
};
|
||||
19
client-wiaas/src/config.js
Normal file
19
client-wiaas/src/config.js
Normal file
@@ -0,0 +1,19 @@
|
||||
const APPLICAITON_MODE = 'DEV';
|
||||
const APPLICATION_NAME = 'Co-Market';
|
||||
const API_VERSION = 'v2';
|
||||
|
||||
const API_SERVER_BASE = (() => {
|
||||
if(APPLICAITON_MODE === 'TEST'){
|
||||
return 'http://localhost/api-wiaas';
|
||||
}
|
||||
|
||||
if(APPLICAITON_MODE === 'PROD'){
|
||||
return 'http://localhost/api-wiaas';
|
||||
}
|
||||
|
||||
return 'http://localhost/api-wiaas';
|
||||
})();
|
||||
|
||||
const API_SERVER = API_SERVER_BASE + '/' + API_VERSION;
|
||||
|
||||
export {APPLICAITON_MODE, API_SERVER_BASE, API_SERVER, APPLICATION_NAME}
|
||||
31
client-wiaas/src/configureStore.js
Normal file
31
client-wiaas/src/configureStore.js
Normal file
@@ -0,0 +1,31 @@
|
||||
import {
|
||||
createStore,
|
||||
applyMiddleware
|
||||
} from 'redux';
|
||||
import thunkMiddleware from 'redux-thunk';
|
||||
import {
|
||||
createLogger
|
||||
} from 'redux-logger';
|
||||
import reduxCatch from 'redux-catch';
|
||||
import wiaasReducers from './reducers';
|
||||
|
||||
const loggerMiddleware = createLogger();
|
||||
const errorHandler = (error, getState, lastAction, dispatch) => {
|
||||
console.error(error);
|
||||
console.debug('current state', getState());
|
||||
console.debug('last action was', lastAction);
|
||||
};
|
||||
|
||||
function configureStore() {
|
||||
return createStore(
|
||||
wiaasReducers,
|
||||
applyMiddleware(
|
||||
reduxCatch(errorHandler),
|
||||
thunkMiddleware,
|
||||
loggerMiddleware
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
export let store = configureStore();
|
||||
33
client-wiaas/src/constants/appContainers.js
Normal file
33
client-wiaas/src/constants/appContainers.js
Normal file
@@ -0,0 +1,33 @@
|
||||
import DashboardsContainer from '../containers/dashboard/DashboardsContainer.jsx';
|
||||
import OrdersContainer from '../containers/orders/OrdersContainer.jsx';
|
||||
import CoMarketContainer from '../containers/coMarket/CoMarketContainer.jsx';
|
||||
import CartContainer from '../containers/cart/CartContainer.jsx';
|
||||
import TermsContainer from '../containers/terms/TermsContainer.jsx';
|
||||
import ProfileSettingsContainer from '../containers/profileSettings/ProfileSettingsContainer.jsx';
|
||||
|
||||
export const MainContainers = {
|
||||
Dashboards: {
|
||||
container: DashboardsContainer,
|
||||
params: []
|
||||
},
|
||||
Orders: {
|
||||
container: OrdersContainer,
|
||||
params: ['idOrder']
|
||||
},
|
||||
CoMarket: {
|
||||
container: CoMarketContainer,
|
||||
params: ['idCommercialLead', 'idPackage']
|
||||
},
|
||||
Cart: {
|
||||
container: CartContainer,
|
||||
params: []
|
||||
},
|
||||
Terms: {
|
||||
container: TermsContainer,
|
||||
params: []
|
||||
},
|
||||
ProfileSettings: {
|
||||
container: ProfileSettingsContainer,
|
||||
params: []
|
||||
}
|
||||
};
|
||||
68
client-wiaas/src/constants/authConstants.js
Normal file
68
client-wiaas/src/constants/authConstants.js
Normal file
@@ -0,0 +1,68 @@
|
||||
import {API_SERVER_BASE} from '../config.js';
|
||||
|
||||
const MODULE = 'AUTH_';
|
||||
|
||||
export const LOGIN = MODULE + 'LOGIN';
|
||||
export const LOGOUT = MODULE + 'LOGOUT';
|
||||
export const LOGIN_SUCCESS = MODULE + 'LOGIN_SUCCESS';
|
||||
export const LOGIN_FAIL = MODULE + 'LOGIN_FAIL';
|
||||
|
||||
export const REQUEST_FORGOT_PASSWORD = MODULE + 'REQUEST_FORGOT_PASSWORD';
|
||||
export const FORGOT_PASSWORD = MODULE + 'FORGOT_PASSWORD';
|
||||
|
||||
export const VALIDATE_TOKEN = MODULE + 'VALIDATE_TOKEN';
|
||||
|
||||
export const REQUEST_MODULES = MODULE + 'REQUEST_MODULES';
|
||||
export const RECIEVE_MODULES = MODULE + 'RECIEVE_MODULES';
|
||||
|
||||
export const REFRESH_TOKEN = MODULE + 'REFRESH_TOKEN';
|
||||
|
||||
export const REQUEST_CHANGE = MODULE + 'REQUEST_CHANGE';
|
||||
export const PASSWORD_CHANGED = MODULE + 'PASSWORD_CHANGED';
|
||||
|
||||
export const SET_COMPANY_ADMIN_FLAG = MODULE + 'SET_COMPANY_ADMIN_FLAG';
|
||||
|
||||
export const authActivity = {
|
||||
lastActivity : Date.now()
|
||||
};
|
||||
|
||||
|
||||
export const loginMessages = {
|
||||
INVALID_USERNAME_PASSWORD: 'Invalid username or password',
|
||||
EXPIRED_TOKEN: 'Your session has expired',
|
||||
LOGGED_OUT: 'You have been successfully logged out !',
|
||||
NO_USER: 'Please review the mail address and try again!',
|
||||
GENERATED_SUCCESSFULLY: 'An email was sent to you. Please check your inbox to change your password',
|
||||
CHANGE_LATER: 'You can change your password in 5 minutes!',
|
||||
INVALID_REFRESH_TOKEN: 'Your session has expired!',
|
||||
EXPIRED_SESSION : 'Your session has expired!',
|
||||
INVALID_USER_TYPE: 'Users with other roles than "customer" must use this url for login: ' + API_SERVER_BASE,
|
||||
INVALID_CHANGE_TOKEN: 'Invalid change token value!',
|
||||
PASSWORDS_MISSING: 'Password can not be empty',
|
||||
WRONG_USERNAME: 'Invalid username!',
|
||||
PASSWORD_GENERATED: 'Password has been changed!',
|
||||
ERROR_PASSWORD_GENERATED: 'There seems to be a problem and the password was not saved!',
|
||||
PASSWORD_SAME: 'The password cannot be the same with the old password!',
|
||||
PASSWORD_MISMATCH: 'The new password and the confirmation password are not the same!',
|
||||
PASSWORD_INCORRECT: 'The password must contain at least one lower case letter, one uppercaser letter, one number and one special character!',
|
||||
FORGOT_REQUEST_SENT: 'Sending request...'
|
||||
}
|
||||
|
||||
export const loginTexts = {
|
||||
labels: {
|
||||
CHANGE_PASSWORD: 'Change Password',
|
||||
NEW_PASSWORD: 'New password',
|
||||
CONFIRM_PASSWORD: 'Confirm password',
|
||||
WELCOME_TO: 'Welcome to',
|
||||
SIGN_IN: 'Sign In',
|
||||
USERNAME: 'Username',
|
||||
PASSWORD: 'Password',
|
||||
|
||||
},
|
||||
buttons: {
|
||||
CHANGE_PASSWORD: 'Change Password',
|
||||
SIGN_IN: 'Sign In',
|
||||
BACK_TO_SIGNIN: 'Back to Sign In',
|
||||
FORGOT_PASSWORD: 'Forgot password?'
|
||||
}
|
||||
};
|
||||
11
client-wiaas/src/constants/bidsConstants.js
Normal file
11
client-wiaas/src/constants/bidsConstants.js
Normal file
@@ -0,0 +1,11 @@
|
||||
const MODULE = 'BIDS_';
|
||||
|
||||
export const REQUEST_SET_BID = MODULE + 'REQUEST_SET_BID';
|
||||
|
||||
export const bidsTexts = {
|
||||
messages: {
|
||||
BID_SET: 'Bid set!',
|
||||
CART_REQUIRED: 'Invalid cart item!',
|
||||
BID_NOT_USED: 'There seems to be a problem and the bid was not set!'
|
||||
}
|
||||
}
|
||||
176
client-wiaas/src/constants/cartConstants.js
Normal file
176
client-wiaas/src/constants/cartConstants.js
Normal file
@@ -0,0 +1,176 @@
|
||||
import CartUploadDocumentsContainer from '../containers/cart/CartUploadDocumentsContainer.jsx';
|
||||
import CartCustomerDetailsContainer from '../containers/cart/CartCustomerDetailsContainer.jsx';
|
||||
import CartReviewOrderContainer from '../containers/cart/CartReviewOrderContainer.jsx';
|
||||
|
||||
const MODULE = 'CART_';
|
||||
export const REQUEST_SHOP_CART_COUNT = MODULE + 'REQUEST_SHOP_CART_COUNT';
|
||||
export const RECEIVE_SHOP_CART_COUNT = MODULE + 'RECEIVE_SHOP_CART_COUNT';
|
||||
export const REQUEST_SHOP_CART_ITEMS = MODULE + 'REQUEST_SHOP_CART_ITEMS';
|
||||
export const RECEIVE_SHOP_CART_ITEMS = MODULE + 'RECEIVE_SHOP_CART_ITEMS';
|
||||
export const REQUEST_CUSTOMER_DETAILS = MODULE + 'REQUEST_CUSTOMER_DETAILS';
|
||||
export const RECEIVE_CUSTOMER_DETAILS = MODULE + 'RECEIVE_CUSTOMER_DETAILS';
|
||||
export const SET_CURRENT_STEP = MODULE + 'SET_CURRENT_STEP';
|
||||
export const RESET_STEPS = MODULE + 'RESET_STEPS';
|
||||
export const GO_TO_NEXT_STEP = MODULE + 'GO_TO_NEXT_STEP';
|
||||
export const GO_TO_PREVIOUS_STEP = MODULE + 'GO_TO_PREVIOUS_STEP';
|
||||
export const LOAD_CART_STEPS = MODULE + 'LOAD_CART_STEPS';
|
||||
export const UPLOAD_DOCUMENT = MODULE + 'UPLOAD_DOCUMENT';
|
||||
export const REQUEST_CART_DOCUMENTS = MODULE + 'REQUEST_CART_DOCUMENTS';
|
||||
export const RECEIVE_CART_DOCUMENTS = MODULE + 'RECEIVE_CART_DOCUMENTS';
|
||||
export const SELECT_COUNTRY_DELIVERY = MODULE + 'SELECT_COUNTRY_DELIVERY';
|
||||
export const SELECT_COUNTRY_BILLING = MODULE + 'SELECT_COUNTRY_BILLING';
|
||||
export const REVIEW_ORDER = MODULE + 'REVIEW_ORDER';
|
||||
export const SET_ORDER_INFO = MODULE + 'SET_ORDER_INFO';
|
||||
export const IS_CART_ITEMS_DISABLED = MODULE + 'IS_CART_ITEMS_DISABLED';
|
||||
export const RECEIVE_ORDER_TOTAL_PRICE = MODULE + 'RECEIVE_ORDER_TOTAL_PRICE';
|
||||
export const UPDATE_CART_ITEMS = MODULE + 'UPDATE_CART_ITEMS';
|
||||
export const SET_NEXT_STEP = MODULE + 'SET_NEXT_STEP';
|
||||
export const SET_PREV_STEP = MODULE + 'SET_PREV_STEP';
|
||||
export const SET_ORDER_PLACED = MODULE + 'SET_ORDER_PLACED';
|
||||
export const SET_ORDER_PLACED_REDIRECT = MODULE + 'SET_ORDER_PLACED_REDIRECT';
|
||||
|
||||
export const cartSteps = () => ({
|
||||
cartUploadDocuments: {
|
||||
container: CartUploadDocumentsContainer,
|
||||
name: 'Upload documents',
|
||||
next: 'cartCustomerDetails',
|
||||
previous: '',
|
||||
status: 'active'
|
||||
},
|
||||
cartCustomerDetails: {
|
||||
container: CartCustomerDetailsContainer,
|
||||
name: 'Delivery and billing details',
|
||||
next: 'cartReviewOrder',
|
||||
previous: 'cartUploadDocuments',
|
||||
status: 'inactive'
|
||||
},
|
||||
cartReviewOrder: {
|
||||
container: CartReviewOrderContainer,
|
||||
name: 'Review and confirm',
|
||||
next: '',
|
||||
previous: 'cartCustomerDetails',
|
||||
status: 'inactive'
|
||||
}
|
||||
});
|
||||
|
||||
export const cartMessages = {
|
||||
NOT_AVAILABLE: "This package is no longer available!",
|
||||
NO_PACKAGES: "For the moment there are no packages available for your selection!",
|
||||
INVALID_SELECTION: "Invalid selection!",
|
||||
INVALID_USER: "This package is not available for this user!",
|
||||
ONLY_ONE_CL: "You already have products from another reseller in the cart! One order can contain packages from a single reseller!",
|
||||
PACKAGE_ALREADY_IN_CART: "This package is already in the cart!",
|
||||
PACKAGE_ADDED: "Package added to cart!",
|
||||
OPTIONS_ADDED: "Package options saved!",
|
||||
QUANTITY_UPDATED: "Quantity has been updated for the package!",
|
||||
INVALID_PACKAGE_FOR_REMOVE: "This package is not available in your cart! In case this error persists contact Co-Market!",
|
||||
PACKAGE_REMOVED_FROM_CART: "The package has been removed from the cart!",
|
||||
INVALID_QUANTITY: "The quantity can be a number between 1 and 100!",
|
||||
CART_EMPTY: "You must have at least one package in the cart!",
|
||||
NO_DELIVERY_ADDRESS: "No delivery address was added! Please fill the necessary info",
|
||||
INCOMPLETE_DELIVERY_ADDRESS: "Incomplete delivery address. Please review!",
|
||||
INCOMPLETE_BILLING_ADDRESS: "Incomplete billing address. Please review!",
|
||||
INVALID_LENGTH_DELIVERY_ADDRESS: "Delivery address must not exceed 500 characters",
|
||||
INVALID_LENGTH_BILLING_ADDRESS: "Billing detailed address must not exceed 500 characters",
|
||||
INVALID_LENGTH_COMPANY_NAME: "Company name is too long. Maximum 300 characters!",
|
||||
INVALID_LENGTH_FIRST_NAME: "First name is too long. Maximum 200 characters!",
|
||||
INVALID_LENGTH_LAST_NAME: "Last name is too long. Maximum 200 characters!",
|
||||
INVALID_LENGTH_CITY: "City name is too long. Maximum 100 characters",
|
||||
INVALID_LENGTH_ZIP: "Zip code is too long. Maximum 20 characters",
|
||||
LINK_CUSTOMER_CL: "There is no link between you and the reseller!",
|
||||
ORDER_PLACED: "Order was successfully placed!",
|
||||
ORDER_ERROR: "Something went wrong when placing the order!",
|
||||
NO_PACKAGES_IN_CART: "Go to Co-Market to add packages.",
|
||||
BROKER_MAIL_SENT: "A confirmation email was sent to Co-Market!",
|
||||
MAIL_SENT: "Confirmation mail was sent with the order details!",
|
||||
ERROR_MAIL_SENT: "Error when sending mail!",
|
||||
ERROR_ORDER_INSERT: "An error occured while placing the order!",
|
||||
ERROR_ORDER_PACK_RELATION: "An error occured while linking the packages to the order!",
|
||||
ERROR_ON_ADDING_DOCUMENTS: "An error occured while linking the required documents",
|
||||
ERROR_ORDER_DELIVERY_ADDRESS: "An error occured when adding the delivery address!",
|
||||
ERROR_ORDER_BILLING_ADDRESS: "An error occured when adding the billing address!",
|
||||
ADDRESS_INSERTED: "Delivery and billing addresses were saved!",
|
||||
PACKAGES_DELETED: "Your cart is now empty!",
|
||||
NOT_UPLOADED: "You need to upload all questionaires to go further!",
|
||||
NO_FILE: "File is not valid! Supported formats are .docx, .doc, .xlsx, .xls, .odt, .ods, .pdf, .png, .jpg, .jpeg",
|
||||
UPLOAD_ERROR: "There seems to be an error and the file is not uploaded",
|
||||
FILE_UPLOADED: "Questionaire has been uploaded!",
|
||||
NOT_LINKED_TO_CART: "Questionaire has not been linked and needs to be uploaded again!",
|
||||
NO_SUPPORT: "File Drag/Drop is not supported for this browser",
|
||||
NOT_ACCEPTED_TERMS: "You have to accept the terms and conditions for the order to be placed.",
|
||||
PACKAGE_UNAVIALABLE: "Package is no longer available!",
|
||||
CL_UNAVIALABLE: "This reseller is no longer available!",
|
||||
PRODUCT_NOT_AVAILABLE: "Please remove packages that are no longer available!",
|
||||
MAX_CHARACTERS: "Too many characters!",
|
||||
QUESIONNAIRE_NOT_REQUIRED: "This packages do not require a questionnaire to be filed!",
|
||||
AGREEMENT_NOT_REQUIRED: "This packages do not require an agreement to be filed!",
|
||||
EXTRA_NOT_AVAILABLE: "This selection is not available for the selected price type!",
|
||||
UNAVAILABLE_PACKAGES: "Unavailable packages:",
|
||||
OPTIONS_UNAVAILABLE: "Some options are no longer available!",
|
||||
ADDITIONAL_PACKAGES_UNAVAILABLE: "Some additional packages are no longer available",
|
||||
INSTALLATION_SAVED: "Installation company was saved.",
|
||||
INFO_INCOMPLETE: "Complete all the information for delivery and billing to continue!",
|
||||
DOCS_MISSING: "Upload all required documents before proceding!",
|
||||
NO_CHANGE: "No change has been found",
|
||||
INVALID_FILE : 'Invalid file format! Supported extensions: .pdf, .docx, .doc, .xlsx, .xls, .odt, .ods',
|
||||
UNAVAILABLE_PACKAGE_IN_CART: 'This package contains unavailable products. Remove from the cart to continue: ',
|
||||
PRICE_DIGITS_TOO_MANY: 'Price should have no more than 15 digits'
|
||||
}
|
||||
|
||||
export const cartTexts = {
|
||||
labels: {
|
||||
ON_DELIVERY: 'On delivery',
|
||||
MONTHLY: 'Monthly',
|
||||
EMPTY_CART: 'Your cart is empty. You can add packages from Co-Market.',
|
||||
VAT: 'VAT code',
|
||||
REFERENCE: 'Location details',
|
||||
BID: 'Invoice reference',
|
||||
DELIVERY_ADDRESS: 'Delivery address',
|
||||
ADDRESS: 'Address',
|
||||
CITY: 'City',
|
||||
ZIP: 'Zip code',
|
||||
COUNTRY: 'Country name',
|
||||
BILLING_ADDRESS: 'Billing details',
|
||||
COMPANY: 'Company name',
|
||||
FIRST_NAME: 'First name',
|
||||
LAST_NAME: 'Last name',
|
||||
SAME_BILLING: 'Use same billing address as for delivery',
|
||||
TOTAL_PRICE: 'Total price',
|
||||
CONFIRM: 'Confirm order',
|
||||
CONFIRM_TEXT: 'Are you sure you want to place the order?',
|
||||
ITEMS_IN_CART_ICON: 'items in cart',
|
||||
EMPTY_CART_ICON: 'Cart is empty',
|
||||
REMOVE_ITEM_HEADER: 'Remove item confirmation',
|
||||
REMOVE_ITEM_TEXT: 'Are you sure you want to remove ',
|
||||
REMOVE_FROM_CART: 'Remove from cart',
|
||||
ADDITIOONAL_PACKAGE: 'Additional package',
|
||||
DOC_NOT_REQUIRED: 'Document not required',
|
||||
FILE_UPLOADED_TEXT: 'File uploaded! Select or drop to replace ',
|
||||
FILE: 'file',
|
||||
NO_FILE_UPLOAD_TEXT_1: 'Click here to select',
|
||||
NO_FILE_UPLOAD_TEXT_2: 'or drag and drop file here',
|
||||
TEMPLATES: 'Templates',
|
||||
UPLOADED: 'Uploaded dcuments',
|
||||
PACKAGE_UNAVAILABLE: 'This package is no longer available. Remove it from the cart to place the order successfully',
|
||||
BID_AVAILABLE: 'Bids available!',
|
||||
AVAILABLE_BIDS: 'Available Bids',
|
||||
BID_NUMBER: 'Bid Number',
|
||||
START_DATE: 'Start Date',
|
||||
END_DATE: 'End Date',
|
||||
FIXED: 'Fixed',
|
||||
RECURRENT: 'Recurrent',
|
||||
SERVICES: 'Services',
|
||||
ACTIONS: 'Actions',
|
||||
PROJECT: 'Project',
|
||||
INVOICE_MAIL: 'Invoice mail'
|
||||
},
|
||||
buttons: {
|
||||
YES: 'Yes',
|
||||
CANCEL: 'Cancel',
|
||||
PREVIOUS: 'Previous',
|
||||
NEXT: 'Next',
|
||||
ADD_ADDRESS: 'Add address',
|
||||
USE: 'Use',
|
||||
REMOVE: 'Remove'
|
||||
}
|
||||
};
|
||||
110
client-wiaas/src/constants/coMarketConstants.js
Normal file
110
client-wiaas/src/constants/coMarketConstants.js
Normal file
@@ -0,0 +1,110 @@
|
||||
const MODULE = 'CO_MARKET_';
|
||||
export const REQUEST_SHOP_PACKAGES = MODULE + 'REQUEST_SHOP_PACKAGES';
|
||||
export const RECIEVE_SHOP_PACKAGES = MODULE + 'RECIEVE_SHOP_PACKAGES';
|
||||
|
||||
export const REQUEST_SHOP_COMMERCIAL_LEADS = MODULE + 'REQUEST_SHOP_COMMERCIAL_LEADS';
|
||||
export const RECIEVE_SHOP_COMMERCIAL_LEADS = MODULE + 'RECIEVE_SHOP_COMMERCIAL_LEADS';
|
||||
export const SELECT_SHOP_COMMERCIAL_LEAD = MODULE + 'SELECT_SHOP_COMMERCIAL_LEAD';
|
||||
|
||||
export const REQUEST_PACKAGE_DETAILS = MODULE + 'REQUEST_PACKAGE_DETAILS';
|
||||
export const RECIEVE_PACKAGE_DETAILS = MODULE + 'RECIEVE_PACKAGE_DETAILS';
|
||||
|
||||
export const SELECT_OPTION = MODULE + 'SELECT_OPTION';
|
||||
export const SELECT_ADDITIONAL = MODULE + 'SELECT_ADDITIONAL';
|
||||
export const REMOVE_ADDITIONAL = MODULE + 'REMOVE_ADDITIONAL';
|
||||
export const SELECT_AGREEMENT = MODULE + 'SELECT_AGREEMENT';
|
||||
export const CLEAR_SELECTIONS = MODULE + 'CLEAR_SELECTIONS';
|
||||
|
||||
export const REQUEST_ADD_TO_CART = MODULE + 'REQUEST_ADD_TO_CART';
|
||||
|
||||
export const SET_PACKAGE_FROM_URL = MODULE + 'SET_PACKAGE_FROM_URL';
|
||||
|
||||
export const coMarketMessages = {
|
||||
NOT_AVAILABLE: "This package is no longer available!",
|
||||
NO_PACKAGES: "For the moment there are no packages available for your selection!",
|
||||
INVALID_SELECTION: "Invalid selection!",
|
||||
INVALID_USER: "This package is not available for this user!",
|
||||
ONLY_ONE_CL: "You already have products from another reseller in the cart! One order can contain packages from a single reseller!",
|
||||
ONLY_ONE_COUNTRY: "You already have products from another country in the cart! One order can contain packages from a single country!",
|
||||
PACKAGE_ALREADY_IN_CART: "This package is already in the cart!",
|
||||
PACKAGE_ADDED: "Package added to cart!",
|
||||
OPTIONS_ADDED: "Package options saved!",
|
||||
QUANTITY_UPDATED: "Quantity has been updated for the package!",
|
||||
INVALID_PACKAGE_FOR_REMOVE: "This package is not available in your cart! In case this error persists contact the Co-Market!",
|
||||
PACKAGE_REMOVED_FROM_CART: "The package has been removed from the cart!",
|
||||
INVALID_QUANTITY: "The quantity can be a number between 1 and 100!",
|
||||
CART_EMPTY: "You must have at least one package in the cart!",
|
||||
NO_DELIVERY_ADDRESS: "No delivery address was added! Please fill the necessary info",
|
||||
INCOMPLETE_DELIVERY_ADDRESS: "Incomplete delivery address. Please review!",
|
||||
INCOMPLETE_BILLING_ADDRESS: "Incomplete billing address. Please review!",
|
||||
INVALID_LENGTH_DELIVERY_ADDRESS: "Delivery detailed address should be not bigger than 500 characters",
|
||||
INVALID_LENGTH_BILLING_ADDRESS: "Billing detailed address should be not bigger than 500 characters",
|
||||
INVALID_LENGTH_COMPANY_NAME: "Company name is too long. Maximum 300 characters!",
|
||||
INVALID_LENGTH_FIRST_NAME: "First name is too long. Maximum 200 characters!",
|
||||
INVALID_LENGTH_LAST_NAME: "Last name is too long. Maximum 200 characters!",
|
||||
INVALID_LENGTH_CITY: "City name is too long. Maximum 100 characters",
|
||||
INVALID_LENGTH_ZIP: "Zip code is too long. Maximum 20 characters",
|
||||
LINK_CUSTOMER_CL: "There is no link between you and the reseller!",
|
||||
ORDER_PLACED: "Order was successfully placed!",
|
||||
ORDER_ERROR: "Something went wrong when placing the order!",
|
||||
NO_PACKAGES_IN_CART: "Go to the Co-Market to add packages.",
|
||||
BROKER_MAIL_SENT: "A confirmation email was sent to the Co-Market!",
|
||||
MAIL_SENT: "Confirmation mail was sent with the order details!",
|
||||
ERROR_MAIL_SENT: "Error when sending mail!",
|
||||
ERROR_ORDER_INSERT: "An error occured while placing the order!",
|
||||
ERROR_ORDER_PACK_RELATION: "An error occured while linking the packages to the order!",
|
||||
ERROR_ON_ADDING_DOCUMENTS: "An error occured while linking the required documents",
|
||||
ERROR_ORDER_DELIVERY_ADDRESS: "An error occured when adding the delivery address!",
|
||||
ERROR_ORDER_BILLING_ADDRESS: "An error occured when adding the billing address!",
|
||||
ADDRESS_INSERTED: "Delivery and billing addresses were saved!",
|
||||
PACKAGES_DELETED: "Your cart is now empty!",
|
||||
NOT_UPLOADED: "You need to upload all questionaires to go further!",
|
||||
NO_FILE: "File is not valid! Supported formats are .docx, .doc, .xlsx, .xls, .odt, .ods, .pdf, .png, .jpg, .jpeg",
|
||||
UPLOAD_ERROR: "There seems to be an error and the file is not uploaded",
|
||||
FILE_UPLOADED: "Questionaire has been uploaded!",
|
||||
NOT_LINKED_TO_CART: "Questionaire has not been linked and needs to be uploaded again!",
|
||||
NO_SUPPORT: "File Drag/Drop is not supported for this browser",
|
||||
NOT_ACCEPTED_TERMS: "You have to accept the terms and conditions for the order to be placed.",
|
||||
PACKAGE_UNAVIALABLE: "Package is no longer available!",
|
||||
CL_UNAVIALABLE: "This reseller is no longer available!",
|
||||
PRODUCT_NOT_AVAILABLE: "Please remove packages that are no longer available!",
|
||||
MAX_CHARACTERS: "Too many characters!",
|
||||
QUESIONNAIRE_NOT_REQUIRED: "This packages do not require a questionnaire to be filed!",
|
||||
AGREEMENT_NOT_REQUIRED: "This packages do not require an agreement to be filed!",
|
||||
EXTRA_NOT_AVAILABLE: "This selection is not available for the selected price type!",
|
||||
UNAVAILABLE_PACKAGES: "Unavailable packages:",
|
||||
OPTIONS_UNAVAILABLE: "Some options are no longer available!",
|
||||
ADDITIONAL_PACKAGES_UNAVAILABLE: "Some additional packages are no longer available",
|
||||
INSTALLATION_SAVED: "Installation company was saved."
|
||||
};
|
||||
|
||||
|
||||
export const coMarketTexts = {
|
||||
labels : {
|
||||
ON_DELIVERY: 'On delivery',
|
||||
MONTHLY: 'Monthly',
|
||||
NOT_AVAILABLE: 'Not available',
|
||||
SELECTION_NOT_AVAILABLE: 'This selection is not available for the selected price type!',
|
||||
RECURRENT_PRICE: 'Package recurent price',
|
||||
SERVICE_PRICE: 'Services and support',
|
||||
EXTEND: 'with possibility to extend each',
|
||||
PACKAGE_OPTIONS: ' ',
|
||||
ADDITIONAL_PACKAGES: 'Add-ons',
|
||||
AGREEMENT_OPTIONS: 'Payment options',
|
||||
CATALOGUE: 'Catalogue',
|
||||
SELECT_CL: 'Select reseller...',
|
||||
AVAILABLE_IN: 'Available in',
|
||||
DOCUMENTS: 'Documents',
|
||||
NEW_PRODUCTS: 'New Products',
|
||||
SEARCH_PACKAGE: 'search package...',
|
||||
COMMERCIAL_HEADER_1: 'Next-generation Collaboration',
|
||||
COMMERCIAL_HEADER_2: `Ricoh is now launching Huddle Concept - a stylishly designed,
|
||||
multifunctional workspace that integrates video conferencing
|
||||
with interactive whiteboard and enables more creative and interactive meetings`,
|
||||
BY : 'by'
|
||||
},
|
||||
buttons: {
|
||||
ADD_TO_CART: 'Add to cart',
|
||||
DETAILS: 'Details'
|
||||
}
|
||||
}
|
||||
44
client-wiaas/src/constants/dashboardConstants.js
Normal file
44
client-wiaas/src/constants/dashboardConstants.js
Normal file
@@ -0,0 +1,44 @@
|
||||
const MODULE = 'DASHBOARD_';
|
||||
|
||||
export const REQUEST_GADGETS = MODULE + 'REQUEST_GADGETS';
|
||||
export const RECIEVE_GADGETS = MODULE + 'RECIEVE_GADGETS';
|
||||
|
||||
export const REQUEST_ORDERS = MODULE + 'REQUEST_ORDERS';
|
||||
export const RECEIVE_ORDERS = MODULE + 'RECEIVE_ORDERS';
|
||||
|
||||
export const REQUEST_NEXT_ACTIONS = MODULE + 'REQUEST_NEXT_ACTIONS';
|
||||
export const RECIEVE_NEXT_ACTIONS = MODULE + 'RECIEVE_NEXT_ACTIONS';
|
||||
|
||||
export const dashboardTexts = {
|
||||
labels : {
|
||||
ORDER_CENTRAL: 'Order Central',
|
||||
NEXT_ACTIONS: 'Next Actions',
|
||||
NO_ORDERS: 'For the moment you don\'t have any orders. Go to the Co-Market to add packages.',
|
||||
NO_ACTIONS: 'No actions available.'
|
||||
},
|
||||
tableHeaders: {
|
||||
ORDER: 'Order Number',
|
||||
ORDER_DATE: 'Order Date',
|
||||
PLACED_BY: 'Placed By',
|
||||
REFERENCE: 'Location Details',
|
||||
STATUS: 'Status',
|
||||
ON_DELIVERY: 'On Delivery',
|
||||
MONTHLY: 'Monthly'
|
||||
},
|
||||
buttons: {
|
||||
DETAILS: 'Details'
|
||||
},
|
||||
statuses: {
|
||||
open: 'Open',
|
||||
'in-progress': 'In Progress',
|
||||
production: 'Production',
|
||||
'end-of-life': 'End Of Life',
|
||||
canceled: 'Canceled',
|
||||
'not-accepted': 'Not Accepted',
|
||||
invalid: 'Invalid',
|
||||
pending: 'Pending'
|
||||
},
|
||||
messages: {
|
||||
ORDER_PLACED: 'Thank you for your order! You will be able to see the progress of it in the Details section of your order'
|
||||
}
|
||||
}
|
||||
4
client-wiaas/src/constants/dialogConstants.js
Normal file
4
client-wiaas/src/constants/dialogConstants.js
Normal file
@@ -0,0 +1,4 @@
|
||||
const MODULE = 'DIALOG_';
|
||||
|
||||
export const CONTENT_MESSAGE = MODULE + 'CONTENT_MESSAGE';
|
||||
export const IS_OPENED = MODULE + 'IS_OPENED';
|
||||
6
client-wiaas/src/constants/menuConstants.jsx
Normal file
6
client-wiaas/src/constants/menuConstants.jsx
Normal file
@@ -0,0 +1,6 @@
|
||||
export const menuTexts = {
|
||||
buttons : {
|
||||
Profile: 'Profile',
|
||||
Logout: 'Logout'
|
||||
}
|
||||
};
|
||||
8
client-wiaas/src/constants/notificationConstants.js
Normal file
8
client-wiaas/src/constants/notificationConstants.js
Normal file
@@ -0,0 +1,8 @@
|
||||
const MODULE = 'NOTIFICATION_';
|
||||
|
||||
export const UPDATE_MESSAGES = MODULE + 'UPDATE_MESSAGES';
|
||||
export const DESTROY_MESSAGE = MODULE + 'DESTROY_MESSAGE';
|
||||
|
||||
export const notificationMessages = {
|
||||
HTML_ERROR : 'There seems to be a problem and the data could not be retrieved!'
|
||||
};
|
||||
15
client-wiaas/src/constants/orderProjectsConstants.js
Normal file
15
client-wiaas/src/constants/orderProjectsConstants.js
Normal file
@@ -0,0 +1,15 @@
|
||||
const MODULE = 'ORDER_PROJECTS_';
|
||||
|
||||
export const REQUEST_ORDER_PROJECTS = MODULE + 'REQUEST_ORDER_PROJECTS';
|
||||
export const RECEIVE_ORDER_PROJECTS = MODULE + 'RECEIVE_ORDER_PROJECTS';
|
||||
|
||||
export const REQUEST_ADD_PROJECT = MODULE + 'REQUEST_ADD_PROJECT';
|
||||
|
||||
export const orderProjectsTexts = {
|
||||
messages : {
|
||||
'INVALID_DATA' : 'Invalid data!',
|
||||
'PROJECT_ADDED' : 'Project added!',
|
||||
'EMPTY_VALUE' : 'The field can not be empty:',
|
||||
'MAX_CHARACTERS' : 'The field can not be longer than 100 characters:'
|
||||
}
|
||||
}
|
||||
209
client-wiaas/src/constants/ordersConstants.js
Normal file
209
client-wiaas/src/constants/ordersConstants.js
Normal file
@@ -0,0 +1,209 @@
|
||||
const MODULE = 'ORDERS_';
|
||||
|
||||
export const REQUEST_ORDERS = MODULE + 'REQUEST_ORDERS';
|
||||
export const RECEIVE_ORDERS = MODULE + 'RECEIVE_ORDERS';
|
||||
|
||||
export const REQUEST_ACTIVE_ORDERS = MODULE + 'REQUEST_ACTIVE_ORDERS';
|
||||
export const RECEIVE_ACTIVE_ORDERS = MODULE + 'RECEIVE_ACTIVE_ORDERS';
|
||||
|
||||
export const REQUEST_HISTORY_ORDERS = MODULE + 'REQUEST_HISTORY_ORDERS';
|
||||
export const RECEIVE_HISTORY_ORDERS = MODULE + 'RECEIVE_HISTORY_ORDERS';
|
||||
|
||||
export const REQUEST_ORDER_INFO = MODULE + 'REQUEST_ORDER_INFO';
|
||||
export const RECEIVE_ORDER_INFO = MODULE + 'RECEIVE_ORDER_INFO';
|
||||
|
||||
export const SEND_ORDER_COMMENT = MODULE + 'SEND_ORDER_COMMENT';
|
||||
|
||||
export const REQUEST_CUSTOMER_DOCUMENTS = MODULE + 'REQUEST_CUSTOMER_DOCUMENTS';
|
||||
export const RECEIVE_CUSTOMER_DOCUMENTS = MODULE + 'RECEIVE_CUSTOMER_DOCUMENTS';
|
||||
|
||||
export const RE_UPLOAD_DOCUMENT = MODULE + 'RE_UPLOAD_DOCUMENT';
|
||||
|
||||
export const REQUEST_VALIDATION_COMMENTS = MODULE + 'REQUEST_VALIDATION_COMMENTS';
|
||||
export const RECEIVE_VALIDATION_COMMENTS = MODULE + 'RECEIVE_VALIDATION_COMMENTS';
|
||||
|
||||
export const REQUEST_CUSTOMER_ACCEPTANCE = MODULE + 'REQUEST_CUSTOMER_ACCEPTANCE';
|
||||
export const RECEIVE_CUSTOMER_ACCEPTANCE = MODULE + 'RECEIVE_CUSTOMER_ACCEPTANCE';
|
||||
|
||||
export const UPLOAD_CUSTOMER_ACCEPTANCE = MODULE + 'UPLOAD_CUSTOMER_ACCEPTANCE';
|
||||
export const SEND_CUSTOMER_ACCEPTANCE = MODULE + 'SEND_CUSTOMER_ACCEPTANCE';
|
||||
export const REQUEST_IS_NEXT_STEP_WANTED = MODULE + 'REQUEST_IS_NEXT_STEP_WANTED';
|
||||
export const RECEIVE_IS_NEXT_STEP_WANTED = MODULE + 'RECEIVE_IS_NEXT_STEP_WANTED';
|
||||
export const RECEIVE_IS_COMPONENT_DISABLED = MODULE + 'RECEIVE_IS_COMPONENT_DISABLED';
|
||||
|
||||
export const SET_EARLIEST_INSTALLATION_DATE = MODULE + 'SET_EARLIEST_INSTALLATION_DATE';
|
||||
export const SET_CONFIRMATION_DATES = MODULE + 'SET_CONFIRMATION_DATES';
|
||||
|
||||
export const REQUEST_INSTALLATION_COMPANIES = MODULE + 'REQUEST_INSTALLATION_COMPANIES';
|
||||
export const RECEIVE_INSTALLATION_COMPANIES = MODULE + 'RECEIVE_INSTALLATION_COMPANIES';
|
||||
|
||||
export const SET_SUPPORT_MESSAGE = MODULE + 'SET_SUPPORT_MESSAGE';
|
||||
|
||||
export const SET_SCHEDULING_DISABLED_FLAG = MODULE + 'SET_SCHEDULING_DISABLED_FLAG';
|
||||
|
||||
export const SET_VIEW_ALL_ORDERS = MODULE + 'SET_VIEW_ALL_ORDERS';
|
||||
|
||||
export const REQUEST_ALL_SHIPPING_DATES_CONFIRMED = MODULE + 'REQUEST_ALL_SHIPPING_DATES_CONFIRMED';
|
||||
export const RECEIVE_ALL_SHIPPING_DATES_CONFIRMED = MODULE + 'RECEIVE_ALL_SHIPPING_DATES_CONFIRMED';
|
||||
|
||||
export const orderMessages = {
|
||||
SYSTEM_ALLOWED_LANGUAGES_EMPTY: 'There are no languages added in the system.',
|
||||
ALLOWED_LANGUAGE: 'Allowed languages are:',
|
||||
ALLOWED_LANGUAGE_ERROR: 'There was an error while trying to detect the language:',
|
||||
SERVER_ERROR: 'There seems to be a problem and the comment was not added!',
|
||||
ORDER_COMMENT_ADDED: 'Order comment updated!',
|
||||
FILE_UPLOADED : 'File has been uploaded and needs to be validated!',
|
||||
NOT_UPLOADED : 'There seems to be a problem and the file was not uploaded!',
|
||||
RE_UPLOAD_MAIL : 'Notify mail has been sent!',
|
||||
ACCEPTANCE_NOT_UPDATED : 'Acceptance status not updated!',
|
||||
ACCEPTANCE_NOT_UPLOADED: 'You need to uploade the acceptance document before you can agree with the installation!',
|
||||
DECLINE_REASON_EMPTY : 'Please describe what is not to your satisfaction.',
|
||||
INSTALLATION_DECLINED : 'The implementation is not satisfactory.',
|
||||
ERROR_MAIL_SENT : 'Notify mail was not sent!',
|
||||
ORDER_UPDATE_MAIL_SENT: 'Order update email was successfully sent',
|
||||
INSTALLATION_DATE_EMPTY: 'Installation date cannot be empty.',
|
||||
INVALID_DATE_ESTIMATED: 'Estimated date is in incorrect format.',
|
||||
STATUS_NOT_SET: 'Status of the installation date is not set.',
|
||||
EID_NOT_SET: 'Earliest installation date is not set.',
|
||||
RELATION_NOT_FOUND: 'Relation between the order and installation company has not been set.',
|
||||
PAST_DATE: 'Installation date cannot be earlier than',
|
||||
PROPOSED_DATE_EXISTS: 'This date is already proposed',
|
||||
MAX_SLA_EXCEEDED: 'Maximum installation date regarding SLA is excedeed.',
|
||||
MAX_CHARACTERS: 'Too many characters for field: ',
|
||||
INSTALLATION_ALREADY_ACCEPTED: 'The accepted installation date has been changed.',
|
||||
INSTALLATION_DATE_UPDATED: 'Installation date was successfully updated.',
|
||||
INSTALLATION_DATE_NOT_REMOVED: 'This installation date cannot be removed. Please refresh the page.',
|
||||
INSTALLATION_DATE_REMOVED : 'My proposed installation date was successfully removed',
|
||||
INSTALLATION_DATE_REMOVE_ERROR : 'There was an error while trying to remove my installation date proposed',
|
||||
INSTALLATION_MAIL_SENT: 'Notification mail was sent',
|
||||
INVALID_FILE_QUESTIONNAINRE : 'Invalid file format! Supported extensions: .pdf, .docx, .doc, .xlsx, .xls, .odt, .ods',
|
||||
INVALID_FILE_ACCEPTANCE : 'Invalid file format! Supported extensions: .pdf, .docx, .doc, .xlsx, .xls, .odt, .ods, .jpg, .png, .jpeg',
|
||||
EMPTY_VALUE: 'Field required: ',
|
||||
INSTALLATION_ACCEPTED: 'The implementation has been accepted!',
|
||||
ID_ORDER_NOT_SET: 'The id of the order is not set',
|
||||
SUPPORT_MAIL_SENT: 'Support mail sent!'
|
||||
};
|
||||
|
||||
export const orderTexts = {
|
||||
labels: {
|
||||
NOT_ACCEPTED: 'Customer acceptance must be submitted no later than : ',
|
||||
ACCEPTED: 'Implementation accepted',
|
||||
DECLINED: 'Implementation not satisfactory',
|
||||
NOT_SET: 'not set',
|
||||
REASON: 'Reason',
|
||||
UPLOAD_ACCEPTANCE_LABEL: 'Select or drop acceptance file',
|
||||
NO_DOCUMENTS_UPLOADED: 'No documents uploaded!',
|
||||
ACCEPTANCE_LABEL: 'The system is implemented in a professional way and provides the agreed functionality.',
|
||||
ACCEPT_INSTALLATION_TEXT: 'We are pleased to hear you are satisfied. Please continue by pressing the button below.',
|
||||
DECLINE_REASON_TEXT: 'We are sorry to hear you are not satisfied with the implementation. Please describe why below, to help us get better.',
|
||||
REFERENCE: 'Location Details',
|
||||
LOCATION_DETAILS: 'Location details',
|
||||
BID: 'Invoice reference',
|
||||
ORDER_DATE: 'Order date',
|
||||
EST_DELIVERY: 'Est. delivery date',
|
||||
AMOUNT: 'Amount',
|
||||
STATUS: 'Status',
|
||||
SOLD_BY: 'Sold By',
|
||||
TOTAL_DELVIERY_PRICE: 'On Delivery',
|
||||
TOTAL_RECURRENT_PRICE: 'Monthly',
|
||||
ACCEPTANCE_HEADER: 'Installation acceptance',
|
||||
DELIVERY_DATE: 'Delivery date',
|
||||
INSTALLATION_SCHEDULE_HEADER: 'Installation scheduling',
|
||||
SUPPORT_MESSAGE_HEADER: 'Contact support',
|
||||
TERMS_AND_COND: 'Terms and conditions',
|
||||
DELIVERY_ADDRESS: 'Delivery address',
|
||||
PHONE_NUMBER: 'Phone number',
|
||||
MAIL: 'Mail address',
|
||||
EXTEND: 'with possibility to extend each',
|
||||
PACKAGE_PRICE: 'Package price',
|
||||
RECURRENT_PRICE: 'Package recurent price',
|
||||
SERVICES_PRICE: 'Services and support',
|
||||
OPTIONS: 'Options',
|
||||
ADDITIONAL_PACKAGES: 'Additional Packages',
|
||||
DOCUMENTS: 'Documents',
|
||||
NO_DOCUMENTS: 'No documents available',
|
||||
OTHER_DOCS: 'Other documents',
|
||||
PACKAGES: 'Packages',
|
||||
COMPLETED: 'Completed',
|
||||
WILL_BE_PROCESS: 'This order will be processed soon',
|
||||
INSTALL_COMPANY: 'Installation company',
|
||||
INSTALL_COMPANY_NOT_SET: 'Installation company has not yet been chosen by the broker',
|
||||
EARLIEST_INSTALLATION: 'Earliest installation date',
|
||||
PROPOSED_DATES: 'Proposed dates',
|
||||
INSTALLATION_PROTOCOL: 'Installation protocol',
|
||||
NO_PROTOCOL_UPLOADED: 'No documents uploaded yet',
|
||||
INSTALLATION_MAIL_SENT: 'Notification mail was sent',
|
||||
ERROR_MAIL_SENT: 'An error occured while trying to send a mail.',
|
||||
ORDER_DETAILS: 'Order details',
|
||||
ORDER_NUMBER: 'Order number',
|
||||
COMMERCIAL_LEAD: 'Catalogue',
|
||||
ORDER_ITEMS: 'Order items',
|
||||
PRICE: 'Price',
|
||||
SERVICES_AND_SUPPORT: 'Services and support',
|
||||
END_OF_LIFE: 'End of life',
|
||||
ENTER_TEXT: 'Enter your text here',
|
||||
SELECT_OR_DROP: 'Select or drop questionnaire',
|
||||
ACTIVE_ORDERS: ' Active Orders',
|
||||
ORDER_HISTORY: 'Orders History',
|
||||
NO_RECORDS: 'No records available',
|
||||
NOT_AVAILABLE: 'This order is not available',
|
||||
ORDER: 'Order',
|
||||
ORDER_INFO: 'Order Info',
|
||||
COMMENTS: 'Comments',
|
||||
SCHEDULE_INSTALLATION_ENABLED: 'Function to schedule the installation date',
|
||||
SCHEDULE_INSTALLATION_DISABLED: 'Scheduling will be available when the delivery date is set by supplier',
|
||||
SCHEDULE_INSTALLATION_NOT_EXIST: 'Installation is not required for this order',
|
||||
PRELIMINARY_INSTALLATION_DATE: 'The date is preliminary until all shipping dates are confirmed',
|
||||
INSTALLATION_DATE_ACCEPTED: 'The installation date is the final and will be performed at the accepted date',
|
||||
INSTALLATION_DATE_NOT_SET: 'The installation date is not set yet',
|
||||
PLACED_BY: 'Placed by',
|
||||
VIEW_ALL_ORDERS: 'View all orders',
|
||||
INSTALLATION_DATE: 'Installation date',
|
||||
INSTALLATION_NOT_REQUIRED:'Installation is not required for this package',
|
||||
PRELIMINARY_INSTALLATION_DATE_LABEL: 'Preliminary installation date',
|
||||
PROJECT: 'Project'
|
||||
},
|
||||
buttons: {
|
||||
ACCEPT_INSTALLATION: 'I agree',
|
||||
DECLINE_INSTALLATION: 'I disagree',
|
||||
DELIVERY_DETAILS: 'Delivery details',
|
||||
DETAILS: 'Details',
|
||||
SUPPORT: 'Support',
|
||||
SEND: 'Send',
|
||||
CANCEL: 'Cancel',
|
||||
CLOSE: 'Close',
|
||||
YES: 'Yes',
|
||||
NO: 'No',
|
||||
ACCEPT: 'Accept',
|
||||
DECLINE: 'Decline',
|
||||
REMOVE: 'Remove',
|
||||
ADD_COMMENT: 'Add order comment',
|
||||
SEND_MAIL_TO_SUPPORT: 'Send an email to support',
|
||||
SEE_DOCUMENTS: 'See documents',
|
||||
ALL: 'All',
|
||||
SCHEDULE_INSTALLATION: 'Schedule installation',
|
||||
ACTIONS: 'Actions'
|
||||
},
|
||||
statuses: {
|
||||
open: 'Open',
|
||||
'in-progress': 'In Progress',
|
||||
production: 'Completed',
|
||||
'end-of-life': 'Completed',
|
||||
canceled: 'Canceled',
|
||||
'not-accepted': 'Not Accepted',
|
||||
invalid: 'Invalid',
|
||||
pending: 'Pending'
|
||||
},
|
||||
headers: {
|
||||
ORDER: 'Order',
|
||||
REFERENCE: 'Location Details',
|
||||
ORDER_DATE: 'Order date',
|
||||
ESTIMATED_DATE: 'Est. delivery date',
|
||||
COMMERCIAL_LEAD: 'Catalogue',
|
||||
AMOUNT: 'Amount',
|
||||
STATUS: 'Status',
|
||||
DELIVERY_DATE: 'Delivery date',
|
||||
END_OF_LIFE: 'End of Life',
|
||||
PLACED_BY: 'Placed by'
|
||||
}
|
||||
};
|
||||
8
client-wiaas/src/constants/pageConstants.js
Normal file
8
client-wiaas/src/constants/pageConstants.js
Normal file
@@ -0,0 +1,8 @@
|
||||
const MODULE = 'PAGE_';
|
||||
|
||||
export const SET_PARAMS_FROM_URL = MODULE + 'SET_PARAMS_FROM_URL';
|
||||
export const RESET_PARAMS = MODULE + 'RESET_PARAMS';
|
||||
|
||||
export const SET_ACTIVE_MODULE = MODULE + 'SET_ACTIVE_MODULE';
|
||||
export const SET_ACTIVE_SUB_MODULE = MODULE + 'SET_ACTIVE_SUB_MODULE';
|
||||
export const RESET_ACTIVE_SUB_MODULE = MODULE + 'RESET_ACTIVE_SUB_MODULE';
|
||||
82
client-wiaas/src/constants/profileSettingsConstants.js
Normal file
82
client-wiaas/src/constants/profileSettingsConstants.js
Normal file
@@ -0,0 +1,82 @@
|
||||
const MODULE = 'PROFILE_SETTINGS_';
|
||||
export const REQUEST_PROFILE_INFO = MODULE + 'REQUEST_PROFILE_INFO';
|
||||
export const RECIEVE_PROFILE_INFO = MODULE + 'RECIEVE_PROFILE_INFO';
|
||||
export const REQUEST_SAVE_PROFILE = MODULE + 'REQUEST_SAVE_PROFILE';
|
||||
export const REQUEST_SAVE_COMPANY = MODULE + 'REQUEST_SAVE_COMPANY';
|
||||
export const REQUEST_SAVE_PROFILE_ADDRESS = MODULE + 'REQUEST_SAVE_PROFILE_ADDRESS';
|
||||
export const REQUEST_REMOVE_PROFILE_ADDRESS = MODULE + 'REQUEST_REMOVE_PROFILE_ADDRESS';
|
||||
export const REQUEST_COUNTRIES = MODULE + 'REQUEST_COUNTRIES';
|
||||
export const RECIEVE_COUNTRIES = MODULE + 'RECIEVE_COUNTRIES';
|
||||
export const REQUEST_REMOVE_BILLING_ADDRESS = MODULE + 'REQUEST_REMOVE_BILLING_ADDRESS';
|
||||
export const REQUEST_SAVE_BILLING_ADDRESS = MODULE + 'REQUEST_SAVE_BILLING_ADDRESS';
|
||||
|
||||
export const profileTexts = {
|
||||
labels: {
|
||||
PROFILE_EDIT_TITLE: 'Edit profile data',
|
||||
COMPANY_EDIT_TITLE: 'Edit company data',
|
||||
PROFILE_NAME: 'Name',
|
||||
PROFILE_PHONE: 'Phone',
|
||||
COMPANY_NAME: 'Company Name',
|
||||
VAT_CODE: 'VAT',
|
||||
CHANGE_PASSWORD: 'Change password',
|
||||
PROFILE_ADDRESSES: 'Delivery Addresses',
|
||||
ADD_PROFILE_ADDRESS: 'Add delivery address',
|
||||
EDIT_PROFILE_ADDRESS: 'Edit devliery address',
|
||||
REMOVE_PROFILE_ADDRESS: 'Remove delivery address',
|
||||
ADD_BILLING_ADDRESS: 'Add billing address',
|
||||
EDIT_BILLING_ADDRESS: 'Edit billing address',
|
||||
REMOVE_BILLING_ADDRESS: 'Remove billing address',
|
||||
REMOVE_CONFIRMATION: 'Are you sure you want to remove this address?',
|
||||
ADDRESS_COUNTRY: 'Country',
|
||||
ADDRESS_CITY: 'City',
|
||||
ADDRESS_DETAILS: 'Address',
|
||||
ADDRESS_ZIP: 'Zip',
|
||||
BILLING_ADDRESSES: 'Billing addresses',
|
||||
FIRST_NAME: 'First Name',
|
||||
LAST_NAME: 'Last Name',
|
||||
DELEGATE: 'Attention',
|
||||
INVOICE_MAIL: 'Invoice Mail'
|
||||
},
|
||||
buttons: {
|
||||
SAVE: 'Save',
|
||||
GENERATE_TOKEN: 'Send password change token by mail',
|
||||
ADD_ADDRESS: 'Add address',
|
||||
CANCEL: 'Cancel',
|
||||
YES: 'Yes',
|
||||
NO: 'No'
|
||||
},
|
||||
messages: {
|
||||
INVALID_USER: 'You are not allowed to change the informations for this user!',
|
||||
INVALID_PROFILE_DATA: 'The profile information provided is not valid!',
|
||||
ADD_NAME: 'The name can not be empty!',
|
||||
ADD_PHONE_NUMBER: 'The phone number can not be empty!',
|
||||
INVALID_PHONE_NUMBER: 'Invalid phone number format!',
|
||||
INVALID_USER_TYPE: 'Invalid user type!',
|
||||
PROFILE_UPDATED: 'Profile info updated!',
|
||||
PROFILE_NOT_CHANGED: 'No changes!',
|
||||
NOT_COMPANY_ADMIN: 'You are not allowed to change the company information! Contact your company admin user.',
|
||||
ADD_VAT: 'The vat code can not be empty!',
|
||||
ADD_COPMANY_NAME: 'The company name can not be empty!',
|
||||
COMPANY_UPDATED: 'Company info updated!',
|
||||
COMPANY_NOT_CHANGED: 'No changes!',
|
||||
ADD_COMPANY: 'Invalid company!',
|
||||
NO_ADDRESS_SELECTED: 'No address selected!',
|
||||
ADDRESS_REMOVED: 'Profile address removed!',
|
||||
BILLING_ADDRESS_REMOVED: 'Billing address removed!',
|
||||
ADDRESS_ERROR: 'There seems to be a problem and the address could not be removed!',
|
||||
NOT_ADDRESS_OWNER: 'You are not allowed to modify this address!',
|
||||
INVALID_PROFILE_ADDRESS: 'The address provided is not valid',
|
||||
PROFILE_ADDRESS_UPDATED: 'Delivery address saved!',
|
||||
PROFILE_ADDRESS_NOT_CHANGED: 'Delivery address not changed!',
|
||||
BILLING_ADDRESS_UPDATED: 'Billing address saved!',
|
||||
BILLING_ADDRESS_NOT_CHANGED: 'Billing address not changed!',
|
||||
ADD_COUNTRY: 'The country field can not be empty',
|
||||
ADD_CITY: 'The city field can not be empty',
|
||||
ADD_ADDRESS: 'The address field can not be empty',
|
||||
ADD_ZIP: 'The zip field can not be empty',
|
||||
ADD_FIRST_NAME: 'The first name field can not be empty',
|
||||
ADD_LAST_NAME: 'The last name field can not be empty',
|
||||
ADD_INVOICE_MAIL: 'The invoice mail field can not be empty',
|
||||
INVALID_INVOICE_MAIL: 'Invalid invoice mail address'
|
||||
}
|
||||
};
|
||||
5
client-wiaas/src/constants/termsConstants.js
Normal file
5
client-wiaas/src/constants/termsConstants.js
Normal file
@@ -0,0 +1,5 @@
|
||||
export const termsTexts = {
|
||||
labels: {
|
||||
TERMS_AND_CONDITIONS: 'Terms and conditions'
|
||||
}
|
||||
};
|
||||
47
client-wiaas/src/containers/ContentContainer.jsx
Normal file
47
client-wiaas/src/containers/ContentContainer.jsx
Normal file
@@ -0,0 +1,47 @@
|
||||
import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import {BrowserRouter} from 'react-router-dom';
|
||||
import {getModules} from '../actions/login/authActions';
|
||||
import {setActiveModule} from '../actions/page/pageActions';
|
||||
import Menu from '../mainComponents/menu/Menu.jsx';
|
||||
import WiaasRouter from '../mainComponents/wiaasRouter/WiaasRouter.jsx';
|
||||
import Footer from './footer/Footer.jsx';
|
||||
import './contentContainer.css';
|
||||
|
||||
class ContentContainer extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.addActiveClass = this.addActiveClass.bind(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.props.dispatch(getModules());
|
||||
}
|
||||
|
||||
addActiveClass(moduleName) {
|
||||
this.props.dispatch(setActiveModule(moduleName));
|
||||
|
||||
}
|
||||
|
||||
render() {
|
||||
const {activeModule} = this.props;
|
||||
return (
|
||||
<BrowserRouter>
|
||||
<div className="main-wrapper">
|
||||
<header className="App-header">
|
||||
<Menu addActiveClass={this.addActiveClass} activeModule={activeModule} />
|
||||
</header>
|
||||
<WiaasRouter addActiveClass={this.addActiveClass} />
|
||||
<Footer/>
|
||||
</div>
|
||||
</BrowserRouter>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
activeModule: state.pageReducer.activeModule
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps)(ContentContainer);
|
||||
44
client-wiaas/src/containers/cart/CartContainer.jsx
Normal file
44
client-wiaas/src/containers/cart/CartContainer.jsx
Normal file
@@ -0,0 +1,44 @@
|
||||
import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import {Link} from 'react-router-dom';
|
||||
import {Row, Col, Container, NavLink} from 'reactstrap';
|
||||
import CartStepsContainer from './CartStepsContainer.jsx';
|
||||
import CartItemsContainer from './CartItemsContainer.jsx';
|
||||
import {fetchCartCount} from '../../actions/cart/cartActions';
|
||||
import {cartTexts} from '../../constants/cartConstants';
|
||||
|
||||
class CartContainer extends Component {
|
||||
componentDidMount() {
|
||||
this.props.dispatch(fetchCartCount());
|
||||
}
|
||||
|
||||
render() {
|
||||
const {cartSteps, currentStep, cartCount} = this.props;
|
||||
const TagName = currentStep && cartSteps && cartSteps[currentStep] ? cartSteps[currentStep].container : null;
|
||||
|
||||
return (
|
||||
<Container fluid={true} id="cart-container">
|
||||
{ cartCount
|
||||
? <div>
|
||||
<CartStepsContainer/>
|
||||
<Row>
|
||||
<Col xl="5" lg="5" md="12" xs="12"><CartItemsContainer /></Col>
|
||||
<Col xl="7" lg="7" md="12" xs="12">{TagName && <TagName/>}</Col>
|
||||
</Row>
|
||||
</div>
|
||||
: <Row>
|
||||
<NavLink tag={Link} to='/co-market' id="go-to-co-market-text">{cartTexts.labels.EMPTY_CART}</NavLink>
|
||||
</Row>
|
||||
}
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
cartSteps: state.cartReducer.cartSteps,
|
||||
currentStep: state.cartReducer.currentStep,
|
||||
cartCount: state.cartReducer.cartCount
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps)(CartContainer);
|
||||
@@ -0,0 +1,229 @@
|
||||
import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import {Row, Col, Form, Input} from 'reactstrap';
|
||||
import {WiaasTable, WiaasTableBody} from '../../mainComponents/table/WiaasTable.jsx';
|
||||
import ProfileAddressesContainer from '../profileSettings/ProfileAddressesContainer.jsx';
|
||||
import BillingAddressesContainer from '../profileSettings/BillingAddressesContainer.jsx';
|
||||
import OrderProjectsSelect from './components/OrderProjectsSelect.jsx';
|
||||
import {getCustomerDetails,setCartItemsDisabled, nextStep, previousStep, saveOrderDetails, fetchCartItems, setNextActionFct, setPrevActionFct} from '../../actions/cart/cartActions';
|
||||
import {cartMessages} from '../../constants/cartConstants';
|
||||
import {updateMessages} from '../../actions/notification/notificationActions';
|
||||
import {fetchProfileInfo, fetchCountries} from '../../actions/profileSettings/profileSettingsActions';
|
||||
import {cartTexts} from '../../constants/cartConstants';
|
||||
import './style/Cart.css';
|
||||
|
||||
class CartCustomerDetailsContainer extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
vatCode: '',
|
||||
companyName: '',
|
||||
details: {
|
||||
refernce: '',
|
||||
tender: '',
|
||||
idProject: ''
|
||||
},
|
||||
delivery: {},
|
||||
billing: {},
|
||||
project: {},
|
||||
checked: false,
|
||||
billingCountry: {}
|
||||
};
|
||||
|
||||
this.handleDetailsChange = this.handleDetailsChange.bind(this);
|
||||
this.handleDeliveryChange = this.handleDeliveryChange.bind(this);
|
||||
this.handleBillingChange = this.handleBillingChange.bind(this);
|
||||
this.handleProjectChange = this.handleProjectChange.bind(this);
|
||||
this.setBillingAsDelivery = this.setBillingAsDelivery.bind(this);
|
||||
this.checkIfInfoCompleted = this.checkIfInfoCompleted.bind(this);
|
||||
this.handleNextAction = this.handleNextAction.bind(this);
|
||||
this.handlePrevAction = this.handlePrevAction.bind(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.props.dispatch(getCustomerDetails());
|
||||
this.props.dispatch(fetchCartItems());
|
||||
this.props.dispatch(setNextActionFct(this.handleNextAction));
|
||||
this.props.dispatch(setPrevActionFct(this.handlePrevAction));
|
||||
this.props.dispatch(fetchProfileInfo(this.props.userInfo.wiaas_id_user));
|
||||
this.props.dispatch(fetchCountries());
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if(nextProps.customerDetails && nextProps.profileInfo) {
|
||||
const selectedDeliveryAddress = nextProps.profileInfo.profileAddresses.find((address) => {
|
||||
return address.id === nextProps.customerDetails.details.idDeliveryAddress
|
||||
}) || nextProps.profileInfo.profileAddresses[0] || {};
|
||||
|
||||
const selectedBillingAddress = nextProps.profileInfo.billingAddresses.find((address) => {
|
||||
return address.id === nextProps.customerDetails.details.idBillingAddress
|
||||
}) || nextProps.profileInfo.billingAddresses[0] || {};
|
||||
|
||||
this.setState({
|
||||
delivery: selectedDeliveryAddress,
|
||||
billing: selectedBillingAddress,
|
||||
vatCode: nextProps.profileInfo.vatCode,
|
||||
companyName: nextProps.profileInfo.companyName,
|
||||
details: nextProps.customerDetails.details
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
handleDetailsChange(event) {
|
||||
const fieldName = event.target.name;
|
||||
const details = this.state.details;
|
||||
details[fieldName] = event.target.value;
|
||||
|
||||
return this.setState({details});
|
||||
}
|
||||
|
||||
handleDeliveryChange(deliveryAddress) {
|
||||
return this.setState({delivery: deliveryAddress});
|
||||
}
|
||||
|
||||
handleBillingChange(billingDetails) {
|
||||
return this.setState({billing: billingDetails});
|
||||
}
|
||||
|
||||
handleProjectChange(project){
|
||||
const newDetails = this.state.details;
|
||||
newDetails.idProject = project ? project.idProject : null;
|
||||
return this.setState({details: newDetails});
|
||||
}
|
||||
|
||||
setBillingAsDelivery(e) {
|
||||
this.setState({
|
||||
checked: !this.state.checked
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
if (this.state.checked) {
|
||||
var newBillingState = Object.assign({}, this.state.billing, this.state.delivery);
|
||||
this.props.dispatch(saveOrderDetails({delivery: this.state.delivery, billing: newBillingState, details: this.state.details}, this.props.cartItems));
|
||||
}
|
||||
}, 10);
|
||||
}
|
||||
|
||||
handleNextAction() {
|
||||
if(this.checkIfInfoCompleted()) {
|
||||
this.props.dispatch(nextStep());
|
||||
this.props.dispatch(setCartItemsDisabled(true));
|
||||
this.props.dispatch(saveOrderDetails(this.state, this.props.cartItems));
|
||||
}
|
||||
}
|
||||
|
||||
handlePrevAction() {
|
||||
if(this.checkIfInfoCompleted()) {
|
||||
this.props.dispatch(previousStep());
|
||||
this.props.dispatch(setCartItemsDisabled(false));
|
||||
this.props.dispatch(saveOrderDetails(this.state, this.props.cartItems));
|
||||
}
|
||||
}
|
||||
|
||||
checkIfInfoCompleted() {
|
||||
const {delivery, billing} = this.state;
|
||||
const isDeliveryAddressCompleted = Object.keys(delivery).length ? Object.keys(delivery).every(delivKey => {
|
||||
return delivery[delivKey] !== '';
|
||||
}) : false;
|
||||
const isBillingAddressCompleted = Object.keys(billing).length ? Object.keys(billing).every(billingKey => {
|
||||
return billing[billingKey] !== '' || billingKey === 'firstName' || billingKey === 'lastName' || billingKey === 'invoiceMail';
|
||||
}) : false;
|
||||
|
||||
if(isDeliveryAddressCompleted && isBillingAddressCompleted) {
|
||||
return true;
|
||||
} else {
|
||||
this.props.dispatch(updateMessages([
|
||||
{
|
||||
code: 'warning',
|
||||
message: 'INFO_INCOMPLETE'
|
||||
}
|
||||
], cartMessages));
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
uncheckSameBillingIfChangesAreMade() {
|
||||
if(this.state.checked) {
|
||||
this.setState({ checked: !this.state.checked });
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const {isLoading, profileInfo, isProfileLoading} = this.props;
|
||||
|
||||
return (
|
||||
<div id="cart-customer-details-container">
|
||||
<WiaasTable id="cart-customer-main-information-container">
|
||||
<WiaasTableBody>
|
||||
<Row className="cart-customer-main-info-row">
|
||||
<Col md="4">{cartTexts.labels.VAT}</Col>
|
||||
<Col md="4">{profileInfo && profileInfo.vatCode}</Col>
|
||||
</Row>
|
||||
<Row className="cart-customer-main-info-row">
|
||||
<Col md="4">{cartTexts.labels.COMPANY}</Col>
|
||||
<Col md="4">{profileInfo && profileInfo.companyName}</Col>
|
||||
</Row>
|
||||
<Row className="cart-customer-main-info-row">
|
||||
<Col md="4">{cartTexts.labels.REFERENCE}</Col>
|
||||
<Input className="col-md-4" id ="reference-nb" type="text" name="reference" value={this.state.details.reference || ''} onChange={this.handleDetailsChange} />
|
||||
</Row>
|
||||
<Row className="cart-customer-main-info-row">
|
||||
<Col md="4">{cartTexts.labels.BID}</Col>
|
||||
<Input className="col-md-4" id="tender-nb" type="text" name="tender" value={this.state.details.tender || ''} onChange={this.handleDetailsChange} />
|
||||
</Row>
|
||||
<Row className="cart-customer-main-info-row">
|
||||
<Col md="4">{cartTexts.labels.PROJECT}</Col>
|
||||
<OrderProjectsSelect handleChange={this.handleProjectChange} idProject={this.state.details.idProject}/>
|
||||
</Row>
|
||||
{
|
||||
isLoading &&
|
||||
<Row>
|
||||
<Col className="loader">
|
||||
<i className="fa fa-spinner fa-spin fa-3x" aria-hidden="true"></i>
|
||||
</Col>
|
||||
</Row>
|
||||
}
|
||||
{ !isLoading &&
|
||||
<div>
|
||||
<Form id="delivery-information" className="cart-address-box">
|
||||
{
|
||||
(profileInfo && !isProfileLoading) &&
|
||||
<ProfileAddressesContainer
|
||||
params={{location: 'cart', handleDeliveryChange: this.handleDeliveryChange, idSelectedDeliveryAddress: this.state.delivery.id}}
|
||||
idUser={this.props.userInfo.wiaas_id_user}/>
|
||||
}
|
||||
</Form>
|
||||
</div>
|
||||
}
|
||||
|
||||
{ !isLoading &&
|
||||
<div>
|
||||
<Form id="billing-information" className="cart-address-box">
|
||||
{
|
||||
(profileInfo && !isProfileLoading) &&
|
||||
<BillingAddressesContainer
|
||||
idCompany={profileInfo.idCompany}
|
||||
params={{location: 'cart', handleBillingChange: this.handleBillingChange, idSelectedBillingAddress: this.state.billing.id}}
|
||||
idUser={this.props.userInfo.wiaas_id_user}/>
|
||||
}
|
||||
</Form>
|
||||
</div>
|
||||
}
|
||||
</WiaasTableBody>
|
||||
</WiaasTable>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
cartItems: state.cartReducer.cartItems,
|
||||
customerDetails: state.cartReducer.customerDetails,
|
||||
isLoading: state.cartReducer.isLoading,
|
||||
isProfileLoading: state.profileSettingsReducer.isLoading,
|
||||
userInfo: state.auth.userInfo,
|
||||
profileInfo: state.profileSettingsReducer.profileInfo,
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps)(CartCustomerDetailsContainer);
|
||||
83
client-wiaas/src/containers/cart/CartItemsContainer.jsx
Normal file
83
client-wiaas/src/containers/cart/CartItemsContainer.jsx
Normal file
@@ -0,0 +1,83 @@
|
||||
import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import {Row, Col} from 'reactstrap';
|
||||
import {WiaasTable, WiaasTableBody} from '../../mainComponents/table/WiaasTable.jsx';
|
||||
import CartItem from './components/CartItem.jsx';
|
||||
import {cartTexts} from '../../constants/cartConstants';
|
||||
import './style/Cart.css';
|
||||
|
||||
class CartItemsContainer extends Component {
|
||||
getOrderCommercialLead() {
|
||||
return this.props.cartItems.length ? this.props.cartItems[0].commercialLead : '';
|
||||
}
|
||||
|
||||
render() {
|
||||
const {cartItems, isCartItemsDisabled, orderTotalPrice, isLoading} = this.props;
|
||||
|
||||
return (
|
||||
<WiaasTable>
|
||||
{
|
||||
isLoading &&
|
||||
<div className="loader">
|
||||
<i className="fa fa-spinner fa-spin fa-3x" aria-hidden="true"></i>
|
||||
</div>
|
||||
}
|
||||
{
|
||||
(cartItems && cartItems.length && !isLoading) &&
|
||||
<WiaasTableBody id="cart-items-container">
|
||||
|
||||
{cartItems.map((cartItem, mapKey) => <CartItem key={cartItem.idPackage}
|
||||
cartItem={cartItem}
|
||||
cartItemNo={mapKey}
|
||||
isFormDisabled={isCartItemsDisabled}/>)}
|
||||
|
||||
<div id="total-price-in-cart-container" className="cart-show-items">
|
||||
<Row className="cart-total-price">
|
||||
<Col lg="5" xs="5" className="item-name">
|
||||
{cartTexts.labels.TOTAL_PRICE}:
|
||||
</Col>
|
||||
{
|
||||
orderTotalPrice &&
|
||||
<Col id={"cart-total-price"}
|
||||
lg="7" xs="7"
|
||||
className="item-name">
|
||||
<table className="price-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{cartTexts.labels.ON_DELIVERY}</th>
|
||||
<th>{cartTexts.labels.MONTHLY}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
{orderTotalPrice.fixedPrice.toLocaleString()} {orderTotalPrice.currency} {' '}
|
||||
</td>
|
||||
<td>
|
||||
{
|
||||
orderTotalPrice.recurrentPrice && orderTotalPrice.recurrentPrice.toLocaleString() + ' ' + orderTotalPrice.currency
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</Col>
|
||||
}
|
||||
</Row>
|
||||
</div>
|
||||
</WiaasTableBody>
|
||||
}
|
||||
</WiaasTable>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
cartItems: state.cartReducer.cartItems,
|
||||
isCartItemsDisabled: state.cartReducer.isCartItemsDisabled,
|
||||
orderTotalPrice: state.cartReducer.orderTotalPrice,
|
||||
isLoading: state.cartReducer.isLoading
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps)(CartItemsContainer);
|
||||
177
client-wiaas/src/containers/cart/CartReviewOrderContainer.jsx
Normal file
177
client-wiaas/src/containers/cart/CartReviewOrderContainer.jsx
Normal file
@@ -0,0 +1,177 @@
|
||||
import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import {Redirect} from 'react-router-dom';
|
||||
import {Row, Col, Button} from 'reactstrap';
|
||||
import './style/Cart.css';
|
||||
import {WiaasTable, WiaasTableBody} from '../../mainComponents/table/WiaasTable.jsx';
|
||||
import {placeOrder, setCartItemsDisabled, previousStep, fetchCartItems, setPrevActionFct} from '../../actions/cart/cartActions';
|
||||
import {setDialogContent, setDialogOpenFlag} from '../../actions/dialog/dialogActions';
|
||||
import {cartTexts} from '../../constants/cartConstants';
|
||||
|
||||
class CartReviewOrderContainer extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.placeOrder = this.placeOrder.bind(this);
|
||||
this.handlePreviousBtn = this.handlePreviousBtn.bind(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.props.dispatch(fetchCartItems());
|
||||
this.props.dispatch(setPrevActionFct(this.handlePreviousBtn));
|
||||
}
|
||||
|
||||
setDialogParams(dialogContent) {
|
||||
this.props.dispatch(setDialogOpenFlag(true));
|
||||
this.props.dispatch(setDialogContent(dialogContent));
|
||||
}
|
||||
|
||||
placeOrder() {
|
||||
this.props.dispatch(placeOrder(this.props.orderInfo));
|
||||
}
|
||||
|
||||
handlePreviousBtn() {
|
||||
this.props.dispatch(previousStep());
|
||||
this.props.dispatch(setCartItemsDisabled(false));
|
||||
}
|
||||
|
||||
getProjectName(idProject){
|
||||
const selectedProject = this.props.orderProjects.find(orderProject => {
|
||||
return orderProject.idProject === idProject
|
||||
});
|
||||
|
||||
return selectedProject && selectedProject.projectName ? selectedProject.projectName : '-';
|
||||
}
|
||||
|
||||
render() {
|
||||
const {orderInfo, isLoading, orderPlaced, orderPlacedRedirect} = this.props;
|
||||
const customerDetails = orderInfo && orderInfo.orderDetails;
|
||||
const items = orderInfo && orderInfo.cartItems;
|
||||
const dialogContent = {
|
||||
buttons: [
|
||||
{
|
||||
color: 'success',
|
||||
action: this.placeOrder,
|
||||
name: cartTexts.buttons.YES,
|
||||
id: 'place-order-confirmation'
|
||||
}, {
|
||||
color: 'secondary',
|
||||
name: cartTexts.buttons.CANCEL,
|
||||
id: 'cancel-remove-item'
|
||||
}
|
||||
],
|
||||
header: cartTexts.labels.CONFIRM,
|
||||
body: cartTexts.labels.CONFIRM_TEXT
|
||||
};
|
||||
|
||||
return (
|
||||
<div id="cart-review-all-order-container">
|
||||
{ (customerDetails && items) &&
|
||||
<WiaasTable>
|
||||
<WiaasTableBody id="cart-review-order-container">
|
||||
{ isLoading
|
||||
? <Row>
|
||||
<Col className="loader">
|
||||
<i className="fa fa-spinner fa-spin fa-3x" aria-hidden="true"></i>
|
||||
</Col>
|
||||
</Row>
|
||||
: <span>
|
||||
<Row className="cart-customer-main-info-row">
|
||||
<Col md="4">{cartTexts.labels.VAT}</Col>
|
||||
<Col md="4" id="review-vatCode">{customerDetails.vatCode}</Col>
|
||||
</Row>
|
||||
<Row className="cart-customer-main-info-row">
|
||||
<Col md="4">{cartTexts.labels.REFERENCE}</Col>
|
||||
<Col md="4" id="review-reference">{customerDetails.details.reference ? customerDetails.details.reference : '-'}</Col>
|
||||
</Row>
|
||||
<Row className="cart-customer-main-info-row">
|
||||
<Col md="4">{cartTexts.labels.BID}</Col>
|
||||
<Col md="4" id="review-tender">{customerDetails.details.tender ? customerDetails.details.tender : '-'}</Col>
|
||||
</Row>
|
||||
<Row className="cart-customer-main-info-row">
|
||||
<Col md="4">{cartTexts.labels.PROJECT}</Col>
|
||||
<Col md="4" id="review-tender">{customerDetails.details.idProject ? this.getProjectName(customerDetails.details.idProject) : '-'}</Col>
|
||||
</Row>
|
||||
<div>
|
||||
<h4>{cartTexts.labels.DELIVERY_ADDRESS}</h4>
|
||||
<Row className="cart-customer-main-info-row">
|
||||
<Col md="4">{cartTexts.labels.ADDRESS}</Col>
|
||||
<Col md="4"id="review-delivery-address">{customerDetails.delivery.detailedAddress}</Col>
|
||||
</Row>
|
||||
<Row className="cart-customer-main-info-row">
|
||||
<Col md="4">{cartTexts.labels.CITY}</Col>
|
||||
<Col md="4" id="review-delivery-city">{customerDetails.delivery.city}</Col>
|
||||
</Row>
|
||||
<Row className="cart-customer-main-info-row">
|
||||
<Col md="4">{cartTexts.labels.ZIP}</Col>
|
||||
<Col md="4" id="review-zip">{customerDetails.delivery.zipCode}</Col>
|
||||
</Row>
|
||||
<Row className="cart-customer-main-info-row">
|
||||
<Col md="4">{cartTexts.labels.COUNTRY}</Col>
|
||||
<Col md="4" id="review-delivery-country">{customerDetails.delivery.countryName}</Col>
|
||||
</Row>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h4>{cartTexts.labels.BILLING_ADDRESS}</h4>
|
||||
<Row className="cart-customer-main-info-row">
|
||||
<Col md="4">{cartTexts.labels.COMPANY}</Col>
|
||||
<Col md="4" id="review-billing-company">{customerDetails.companyName}</Col>
|
||||
</Row>
|
||||
<Row className="cart-customer-main-info-row">
|
||||
<Col md="4">{cartTexts.labels.FIRST_NAME}</Col>
|
||||
<Col md="4" id="review-billing-first-name">{customerDetails.billing.firstName || '-'}</Col>
|
||||
</Row>
|
||||
<Row className="cart-customer-main-info-row">
|
||||
<Col md="4">{cartTexts.labels.LAST_NAME}</Col>
|
||||
<Col md="4" id="review-billing-last-name">{customerDetails.billing.lastName || '-'}</Col>
|
||||
</Row>
|
||||
<Row className="cart-customer-main-info-row">
|
||||
<Col md="4">{cartTexts.labels.INVOICE_MAIL}</Col>
|
||||
<Col md="4" id="review-billing-mail">{customerDetails.billing.invoiceMail || '-'}</Col>
|
||||
</Row>
|
||||
<Row className="cart-customer-main-info-row">
|
||||
<Col md="4">{cartTexts.labels.ADDRESS}</Col>
|
||||
<Col md="4" id="review-billing-address">{customerDetails.billing.detailedAddress}</Col>
|
||||
</Row>
|
||||
<Row className="cart-customer-main-info-row">
|
||||
<Col md="4">{cartTexts.labels.CITY}</Col>
|
||||
<Col md="4" id="review-billing-city">{customerDetails.billing.city}</Col>
|
||||
</Row>
|
||||
<Row className="cart-customer-main-info-row">
|
||||
<Col md="4">{cartTexts.labels.ZIP}</Col>
|
||||
<Col md="4" id="review-billing-zip">{customerDetails.billing.zipCode}</Col>
|
||||
</Row>
|
||||
<Row className="cart-customer-main-info-row">
|
||||
<Col md="4">{cartTexts.labels.COUNTRY}</Col>
|
||||
<Col md="4" id="review-billing-country">{customerDetails.billing.countryName}</Col>
|
||||
</Row>
|
||||
</div>
|
||||
</span>
|
||||
}
|
||||
<Row>
|
||||
<Col xl={{size:3, offset:9}} sm="12" xs="12" className="button-cart">
|
||||
{
|
||||
(customerDetails && !isLoading) &&
|
||||
<Button className="place-order-btn" onClick={()=>{this.setDialogParams(dialogContent)}}>Confirm order</Button>
|
||||
}
|
||||
</Col>
|
||||
</Row>
|
||||
{orderPlaced && orderPlacedRedirect && <Redirect push to="/" />}
|
||||
</WiaasTableBody>
|
||||
</WiaasTable>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
orderInfo: state.cartReducer.orderInfo,
|
||||
isLoading: state.cartReducer.isLoading,
|
||||
orderPlaced: state.cartReducer.orderPlaced,
|
||||
orderPlacedRedirect: state.cartReducer.orderPlacedRedirect,
|
||||
orderProjects: state.orderProjectsReducer.orderProjects
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps)(CartReviewOrderContainer);
|
||||
75
client-wiaas/src/containers/cart/CartStepsContainer.jsx
Normal file
75
client-wiaas/src/containers/cart/CartStepsContainer.jsx
Normal file
@@ -0,0 +1,75 @@
|
||||
import React, {Component} from 'react';
|
||||
import {Col} from 'reactstrap';
|
||||
import {connect} from 'react-redux';
|
||||
import './style/CartStepsContainer.css';
|
||||
import {fetchCartItems} from '../../actions/cart/cartActions';
|
||||
import {cartTexts} from '../../constants/cartConstants';
|
||||
|
||||
class CartStepsContainer extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.handleStepChange = this.handleStepChange.bind(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const isForSteps = true;
|
||||
this.props.dispatch(fetchCartItems(isForSteps));
|
||||
}
|
||||
|
||||
handleStepChange(stepDirection) {
|
||||
if(stepDirection === 'next') {
|
||||
if(this.props.nextStepAction) {
|
||||
this.props.nextStepAction();
|
||||
}
|
||||
} else {
|
||||
if(this.props.prevStepAction) {
|
||||
this.props.prevStepAction();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const {cartSteps, currentStep, isLoading} = this.props;
|
||||
const stepsLength = cartSteps && Object.keys(cartSteps).length - 1;
|
||||
|
||||
return (
|
||||
<Col id="cart-steps-container" xl="12" lg="12" md="12" xs="12" sm="12">
|
||||
{(cartSteps && cartSteps[currentStep] && cartSteps[currentStep].previous && !isLoading) &&
|
||||
<span onClick={()=>{this.handleStepChange('previous')}} className="prev-btn">
|
||||
<Col sm="12" xs="12">
|
||||
{cartTexts.buttons.PREVIOUS}
|
||||
</Col>
|
||||
</span>
|
||||
}
|
||||
{cartSteps && Object.keys(cartSteps).map((stepKey, index) =>
|
||||
<span key={'cart-step-' + stepKey}>
|
||||
<Col xl="3" sm="12" xs="12" className={'step-name ' + cartSteps[stepKey].status}>
|
||||
{(index + 1) + ' . ' + cartSteps[stepKey].name}
|
||||
</Col>
|
||||
{stepsLength !== index && <div className="steps-link"><div className="step-link"></div></div>}
|
||||
</span>
|
||||
)}
|
||||
{(cartSteps && cartSteps[currentStep] && cartSteps[currentStep].next && !isLoading) &&
|
||||
<span onClick={()=>{this.handleStepChange('next')}} className="next-btn">
|
||||
<Col sm="12" xs="12" >
|
||||
{cartTexts.buttons.NEXT}
|
||||
</Col>
|
||||
</span>
|
||||
}
|
||||
</Col>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
cartItems: state.cartReducer.cartItems,
|
||||
cartSteps: state.cartReducer.cartSteps,
|
||||
currentStep: state.cartReducer.currentStep,
|
||||
cartDocuments: state.cartReducer.cartDocuments,
|
||||
nextStepAction: state.cartReducer.nextStepAction,
|
||||
prevStepAction: state.cartReducer.prevStepAction,
|
||||
isLoading: state.cartReducer.isLoading
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps)(CartStepsContainer);
|
||||
@@ -0,0 +1,99 @@
|
||||
import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import {Row, Col, Container} from 'reactstrap';
|
||||
import WiaasBox from '../../mainComponents/box/WiaasBox.jsx';
|
||||
import CartUploadDocument from './components/CartUploadDocument.jsx';
|
||||
import './style/CartUploadDocumentsContainer.css';
|
||||
import {cartMessages} from '../../constants/cartConstants';
|
||||
import {updateMessages} from '../../actions/notification/notificationActions';
|
||||
import {nextStep, setNextActionFct} from '../../actions/cart/cartActions';
|
||||
|
||||
const DOCUMENT_TYPES = {
|
||||
TEMPLATE_QUESTINNAIRE: 1,
|
||||
QUESTIONNAIRE: 2,
|
||||
TEMPLATE_AGREEMENT: 6,
|
||||
AGREEMENT: 7
|
||||
};
|
||||
|
||||
class CartCustomerQuestionnaireContainer extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.getDocument = this.getDocument.bind(this);
|
||||
this.handleStepChange = this.handleStepChange.bind(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.props.dispatch(setNextActionFct(this.handleStepChange));
|
||||
}
|
||||
|
||||
getDocument(idDocumentType, idPackage, documents) {
|
||||
return documents[idDocumentType] && documents[idDocumentType][idPackage]
|
||||
? documents[idDocumentType][idPackage]
|
||||
: null;
|
||||
}
|
||||
|
||||
handleStepChange() {
|
||||
if(this.props.cartDocuments && this.props.cartDocuments.areFilesUploaded) {
|
||||
this.props.dispatch(nextStep());
|
||||
} else {
|
||||
this.props.dispatch(updateMessages([{code:'warning', message: 'DOCS_MISSING'}], cartMessages));
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const {cartItems, cartDocuments, isLoading} = this.props;
|
||||
const packages = cartItems ? cartItems.map((cartItem) => cartItem.idPackage) : [];
|
||||
|
||||
return (
|
||||
<div id="cart-upload-documents-container">
|
||||
<Container fluid={true}>
|
||||
<Row>
|
||||
<Col lg="12" xs="12">
|
||||
{
|
||||
isLoading &&
|
||||
<div className="loader">
|
||||
<i className="fa fa-spinner fa-spin fa-3x" aria-hidden="true"></i>
|
||||
</div>
|
||||
}
|
||||
{
|
||||
(cartItems && cartDocuments && !isLoading) &&
|
||||
cartItems.map((cartItem, mapKey) =>
|
||||
<div key={'cart-upload-' + mapKey}>
|
||||
<WiaasBox mainTitle={cartItem.packageName} className="no-margin-box">
|
||||
<div className="upload-layer">
|
||||
<Row>
|
||||
<CartUploadDocument
|
||||
idDocumentType={DOCUMENT_TYPES.QUESTIONNAIRE}
|
||||
packages={packages}
|
||||
cartItem={cartItem}
|
||||
templateDocument={this.getDocument(DOCUMENT_TYPES.TEMPLATE_QUESTINNAIRE, cartItem.idPackage, cartDocuments['templates'])}
|
||||
uploadedDocument={this.getDocument(DOCUMENT_TYPES.QUESTIONNAIRE, cartItem.idPackage, cartDocuments['uploaded'])}
|
||||
/>
|
||||
<CartUploadDocument
|
||||
idDocumentType={DOCUMENT_TYPES.AGREEMENT}
|
||||
packages={packages}
|
||||
cartItem={cartItem}
|
||||
templateDocument={this.getDocument(DOCUMENT_TYPES.TEMPLATE_AGREEMENT, cartItem.idPackage, cartDocuments['templates'])}
|
||||
uploadedDocument={this.getDocument(DOCUMENT_TYPES.AGREEMENT, cartItem.idPackage, cartDocuments['uploaded'])}
|
||||
/>
|
||||
</Row>
|
||||
</div>
|
||||
</WiaasBox>
|
||||
</div>)
|
||||
}
|
||||
</Col>
|
||||
</Row>
|
||||
</Container>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
cartItems: state.cartReducer.cartItems,
|
||||
cartDocuments: state.cartReducer.cartDocuments,
|
||||
isLoading: state.cartReducer.isLoading
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps)(CartCustomerQuestionnaireContainer);
|
||||
@@ -0,0 +1,49 @@
|
||||
import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import {Form, FormGroup, Label, Input, Button} from 'reactstrap';
|
||||
import {addProject} from '../../../actions/orderProjects/orderProjectsActions';
|
||||
|
||||
class AddOrderProject extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
projectName: ''
|
||||
}
|
||||
|
||||
this.onProjectAdd = this.onProjectAdd.bind(this);
|
||||
this.handleChange = this.handleChange.bind(this);
|
||||
}
|
||||
|
||||
handleChange(event) {
|
||||
const field = event.target.name;
|
||||
const newProjectData = Object.assign({}, this.state);
|
||||
newProjectData[field] = event.target.value;
|
||||
this.setState(newProjectData);
|
||||
}
|
||||
|
||||
onProjectAdd(){
|
||||
this.props.dispatch(addProject(this.state));
|
||||
}
|
||||
|
||||
render() {
|
||||
return (<Form>
|
||||
<FormGroup>
|
||||
<Label for="projectName">Project Name <span className="required-icon">*</span></Label>
|
||||
<Input
|
||||
type="text"
|
||||
onChange={this.handleChange}
|
||||
name="projectName"
|
||||
id="projectName"
|
||||
value={this.state.projectName}
|
||||
placeholder="Project Name"/>
|
||||
</FormGroup>
|
||||
<FormGroup>
|
||||
<Button onClick={this.onProjectAdd}>Add Project</Button>
|
||||
</FormGroup>
|
||||
</Form>);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default connect()(AddOrderProject);
|
||||
40
client-wiaas/src/containers/cart/components/BidItem.jsx
Normal file
40
client-wiaas/src/containers/cart/components/BidItem.jsx
Normal file
@@ -0,0 +1,40 @@
|
||||
import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import {Button} from 'reactstrap';
|
||||
import { WiaasTableRow, WiaasTableCol} from '../../../mainComponents/table/WiaasTable.jsx';
|
||||
import {setBid} from '../../../actions/bids/bidsActions';
|
||||
import {cartTexts} from '../../../constants/cartConstants';
|
||||
|
||||
class BidItem extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.onBidSelect = this.onBidSelect.bind(this);
|
||||
}
|
||||
onBidSelect(idBid){
|
||||
this.props.dispatch(setBid(idBid, this.props.idCart));
|
||||
}
|
||||
|
||||
render() {
|
||||
const {bid, idSelectedBid} = this.props;
|
||||
return (
|
||||
<WiaasTableRow className="bid-item">
|
||||
<WiaasTableCol header={cartTexts.labels.BID_NUMBER}>{bid.bidNumber}</WiaasTableCol>
|
||||
<WiaasTableCol header={cartTexts.labels.START_DATE}>{bid.startDate}</WiaasTableCol>
|
||||
<WiaasTableCol header={cartTexts.labels.END_DATE}>{bid.endDate}</WiaasTableCol>
|
||||
<WiaasTableCol header={cartTexts.labels.FIXED}>{bid.fixedPrice}</WiaasTableCol>
|
||||
<WiaasTableCol header={cartTexts.labels.RECURRENT}>{bid.recurrentPrice}</WiaasTableCol>
|
||||
<WiaasTableCol header={cartTexts.labels.SERVICES}>{bid.servicesPrice}</WiaasTableCol>
|
||||
<WiaasTableCol header={cartTexts.labels.ACTIONS}>
|
||||
{
|
||||
idSelectedBid === bid.idBid
|
||||
? <Button onClick={()=>{this.onBidSelect(null)}}><span className="fa fa-times remove-item"></span> {cartTexts.buttons.REMOVE}</Button>
|
||||
: <Button onClick={()=>{this.onBidSelect(bid.idBid)}}>{cartTexts.buttons.USE}</Button>
|
||||
}
|
||||
</WiaasTableCol>
|
||||
</WiaasTableRow>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default connect()(BidItem);
|
||||
34
client-wiaas/src/containers/cart/components/BidsList.jsx
Normal file
34
client-wiaas/src/containers/cart/components/BidsList.jsx
Normal file
@@ -0,0 +1,34 @@
|
||||
import React, {Component} from 'react';
|
||||
import BidItem from './BidItem.jsx';
|
||||
import {cartTexts} from '../../../constants/cartConstants';
|
||||
import {WiaasTable, WiaasTableHeader, WiaasTableBody} from '../../../mainComponents/table/WiaasTable.jsx';
|
||||
|
||||
class BidsList extends Component {
|
||||
getHeaders(){
|
||||
return [
|
||||
cartTexts.labels.BID_NUMBER,
|
||||
cartTexts.labels.START_DATE,
|
||||
cartTexts.labels.END_DATE,
|
||||
cartTexts.labels.FIXED,
|
||||
cartTexts.labels.RECURRENT,
|
||||
cartTexts.labels.SERVICES,
|
||||
cartTexts.labels.ACTIONS
|
||||
];
|
||||
}
|
||||
|
||||
render() {
|
||||
const {bids, idCart, idSelectedBid} = this.props.params;
|
||||
return (
|
||||
<WiaasTable id="bids-list">
|
||||
<WiaasTableHeader headers={this.getHeaders()}/>
|
||||
<WiaasTableBody>
|
||||
{
|
||||
bids.map(bid => <BidItem key={'bid-' + bid.idBid} idSelectedBid={idSelectedBid} idCart={idCart} bid={bid}/>)
|
||||
}
|
||||
</WiaasTableBody>
|
||||
</WiaasTable>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default BidsList;
|
||||
23
client-wiaas/src/containers/cart/components/CartIcon.jsx
Normal file
23
client-wiaas/src/containers/cart/components/CartIcon.jsx
Normal file
@@ -0,0 +1,23 @@
|
||||
import React, {Component} from 'react';
|
||||
import {cartTexts} from '../../../constants/cartConstants';
|
||||
|
||||
class CartIcon extends Component {
|
||||
render() {
|
||||
let {cartCount} = this.props;
|
||||
cartCount = parseInt(cartCount, 10);
|
||||
|
||||
return (
|
||||
<span id="cart-count" className="items-cart-count">
|
||||
{ cartCount === 0
|
||||
? <span>{cartTexts.labels.EMPTY_CART_ICON}</span>
|
||||
: cartCount === 1
|
||||
? <span>1 item in cart</span>
|
||||
: <span>{cartCount} {cartTexts.labels.ITEMS_IN_CART_ICON}</span>
|
||||
}
|
||||
|
||||
</span>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default CartIcon;
|
||||
272
client-wiaas/src/containers/cart/components/CartItem.jsx
Normal file
272
client-wiaas/src/containers/cart/components/CartItem.jsx
Normal file
@@ -0,0 +1,272 @@
|
||||
import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import {Input, Tooltip, Row, Col} from 'reactstrap';
|
||||
import '../style/Cart.css';
|
||||
import {updateMessages} from '../../../actions/notification/notificationActions';
|
||||
import {updateQuantity, removeCartItem} from '../../../actions/cart/cartActions';
|
||||
import {setDialogContent, setDialogOpenFlag} from '../../../actions/dialog/dialogActions';
|
||||
import {cartMessages, cartTexts} from '../../../constants/cartConstants';
|
||||
import PackageBids from './PackageBids.jsx';
|
||||
|
||||
class CartItem extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
tooltipOpen: false,
|
||||
itemQuantity: 1,
|
||||
idCart: 0
|
||||
};
|
||||
|
||||
this.toggleTooltip = this.toggleTooltip.bind(this);
|
||||
this.removeItemFromCart = this.removeItemFromCart.bind(this);
|
||||
this.resetQuantity = this.resetQuantity.bind(this);
|
||||
this.sumPrices = this.sumPrices.bind(this);
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
this.setState({itemQuantity: nextProps.cartItem.quantity});
|
||||
this.sumPrices(nextProps.cartItem, nextProps.cartItem.quantity);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.setState({itemQuantity: this.props.cartItem.quantity});
|
||||
this.sumPrices(this.props.cartItem, this.props.cartItem.quantity);
|
||||
}
|
||||
|
||||
isQuantityValid(quantity) {
|
||||
return quantity > 0 && quantity <= 100;
|
||||
}
|
||||
|
||||
updateQuantity(cartItem, quantity) {
|
||||
if(quantity) {
|
||||
this.setState({itemQuantity: quantity});
|
||||
if(this.isQuantityValid(quantity)) {
|
||||
this.sumPrices(cartItem, quantity);
|
||||
this.props.dispatch(updateQuantity(cartItem, quantity));
|
||||
} else {
|
||||
this.props.dispatch(updateMessages([{code: 'error', message: 'INVALID_QUANTITY'}], cartMessages));
|
||||
}
|
||||
} else {
|
||||
this.setState({itemQuantity: ''});
|
||||
}
|
||||
}
|
||||
|
||||
resetQuantity(cartItem) {
|
||||
if(!this.state.itemQuantity || !this.isQuantityValid(this.state.itemQuantity)) {
|
||||
this.updateQuantity(cartItem, 1);
|
||||
}
|
||||
}
|
||||
|
||||
removeItemFromCart() {
|
||||
this.props.dispatch(removeCartItem(this.state.idCart));
|
||||
}
|
||||
|
||||
setDialogParams(cartItem, dialogContent) {
|
||||
this.setState({idCart: cartItem.idCart});
|
||||
this.props.dispatch(setDialogOpenFlag(true));
|
||||
dialogContent.bodyVariable = cartItem.packageName;
|
||||
this.props.dispatch(setDialogContent(dialogContent));
|
||||
}
|
||||
|
||||
toggleTooltip() {
|
||||
this.setState({
|
||||
tooltipOpen: !this.state.tooltipOpen
|
||||
});
|
||||
}
|
||||
|
||||
sumPrices(cartItem, quantity) {
|
||||
let total = 0;
|
||||
let oldTotal = null;
|
||||
let totalRecurrent = 0;
|
||||
let oldTotalRecurrent = null;
|
||||
const selectedBid = cartItem.bids.find((bid) => {
|
||||
return cartItem.idSelectedBid === bid.idBid;
|
||||
});
|
||||
|
||||
if(selectedBid){
|
||||
total += selectedBid.fixedPrice;
|
||||
totalRecurrent += selectedBid.servicesPrice + selectedBid.recurrentPrice;
|
||||
|
||||
oldTotal = cartItem.fixedPrice;
|
||||
oldTotalRecurrent = cartItem.servicesPrice + cartItem.recurentPrice;
|
||||
}else{
|
||||
total += cartItem.fixedPrice;
|
||||
totalRecurrent += cartItem.servicesPrice + cartItem.recurentPrice;
|
||||
}
|
||||
|
||||
if(cartItem.options.length) {
|
||||
cartItem.options.forEach((packageOption) => {
|
||||
if(Object.keys(packageOption.prices).length) {
|
||||
total += parseFloat(packageOption.prices.fixedExtra);
|
||||
totalRecurrent += parseFloat(packageOption.prices.recurentExtra) + parseFloat(packageOption.prices.servicesExtra);
|
||||
}
|
||||
});
|
||||
}
|
||||
if(cartItem.additionalPackages.length) {
|
||||
cartItem.additionalPackages.forEach((additionalPackage) => {
|
||||
if(Object.keys(additionalPackage).length) {
|
||||
total += parseFloat(additionalPackage.prices.fixedExtra);
|
||||
totalRecurrent += parseFloat(additionalPackage.prices.recurentExtra) + parseFloat(additionalPackage.prices.servicesExtra);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this.setState({
|
||||
fixedPrice: total * quantity,
|
||||
recurrentPrice: totalRecurrent * quantity,
|
||||
fixedOldPrice: oldTotal !== null ? oldTotal * quantity : null,
|
||||
recurrentOldPrice: oldTotalRecurrent !== null ? oldTotalRecurrent * quantity: null
|
||||
});
|
||||
}
|
||||
|
||||
getPriceClass(price){
|
||||
return price !== null ? 'new-price' : 'price';
|
||||
}
|
||||
|
||||
render() {
|
||||
const dialogContent = {
|
||||
buttons: [
|
||||
{
|
||||
color: 'success',
|
||||
action: this.removeItemFromCart,
|
||||
name: cartTexts.buttons.YES,
|
||||
id: 'remove-item-confirmation'
|
||||
}, {
|
||||
color: 'secondary',
|
||||
name: cartTexts.buttons.CANCEL,
|
||||
id: 'cancel-remove-item'
|
||||
}
|
||||
],
|
||||
header: cartTexts.labels.REMOVE_ITEM_HEADER,
|
||||
body: cartTexts.labels.REMOVE_ITEM_TEXT
|
||||
};
|
||||
const {cartItem, isFormDisabled} = this.props;
|
||||
const cartItemNo = this.props.cartItemNo ? this.props.cartItemNo + 1 : 1;
|
||||
|
||||
return (
|
||||
<div id={"item-row-in-cart-" + cartItem.idCart} className="cart-show-items">
|
||||
<Row className="cart-item-details">
|
||||
<Col id={"item-package-name-" + cartItem.idCart}
|
||||
xl="8" lg="8" md="7" sm="12" xs="12"
|
||||
className="item-name">
|
||||
{cartItemNo}. {cartItem.packageName}
|
||||
<PackageBids idSelectedBid={cartItem.idSelectedBid} idCart={cartItem.idCart} bids={cartItem.bids}/>
|
||||
</Col>
|
||||
<Col xl="3" lg="3" md="3" sm="9" xs="9" id={"item-quantity-" + cartItem.idCart}>
|
||||
{ isFormDisabled
|
||||
? cartItem.quantity === 1
|
||||
? cartItem.quantity + ' pc'
|
||||
: cartItem.quantity + ' pcs'
|
||||
: <Input className="quantity-field"
|
||||
value={this.state.itemQuantity}
|
||||
type="number"
|
||||
step="1"
|
||||
onChange={e => this.updateQuantity(cartItem, e.target.value)}
|
||||
onBlur={e => this.resetQuantity(cartItem, e.target.value)}
|
||||
/>
|
||||
}
|
||||
</Col>
|
||||
<Col id={"item-remove-btn-" + cartItem.idCart} xl="1" lg="1" md="1" sm="1" xs="1">
|
||||
<i id={'remove-item-' + cartItem.idCart + '-' + cartItem.idPackage}
|
||||
className="fa fa-times remove-item"
|
||||
aria-hidden="true"
|
||||
onClick={() => this.setDialogParams(cartItem, dialogContent) }></i>
|
||||
<Tooltip target={'remove-item-' + cartItem.idCart + '-' + cartItem.idPackage}
|
||||
placement="bottom"
|
||||
isOpen={this.state.tooltipOpen}
|
||||
toggle={this.toggleTooltip}>
|
||||
{cartTexts.labels.REMOVE_FROM_CART}
|
||||
</Tooltip>
|
||||
</Col>
|
||||
</Row>
|
||||
{ (!cartItem.areAdditionalAvailable || !cartItem.areOptionsAvailable || cartItem.status === 'not-available') &&
|
||||
<Row className="cart-item-small-details">
|
||||
<Col id={"item-warning-sign-remove-package-name-" + cartItem.idPackage}
|
||||
xl="12" lg="12" md="12" sm="12" xs="12"
|
||||
className="not-available">
|
||||
{cartTexts.labels.PACKAGE_UNAVAILABLE}
|
||||
</Col>
|
||||
</Row>
|
||||
}
|
||||
{cartItem.options.length > 0 &&
|
||||
cartItem.options.map((packageOption) =>
|
||||
<Row className="cart-item-small-details" key={"package-option-" + cartItem.idCart + "-" + packageOption.idOptionPackage}>
|
||||
<Col lg={{offset: 1, size: 4}} xs={{offset: 1, size: 4}}>
|
||||
{packageOption.groupName}:
|
||||
</Col>
|
||||
<Col lg="7" xs="7" id={"item-option-" + cartItem.idCart + "-" + packageOption.idOptionPackage}>
|
||||
{packageOption.packageName}
|
||||
</Col>
|
||||
</Row>
|
||||
)
|
||||
}
|
||||
{cartItem.additionalPackages.length > 0 &&
|
||||
cartItem.additionalPackages.map((additionalPackage) =>
|
||||
<Row className="cart-item-small-details" key={"additional-package-" + cartItem.idCart + "-" + additionalPackage.idAdditionalPackage}>
|
||||
<Col lg={{offset: 1, size: 4}} xs={{offset:1, size: 4}}>
|
||||
{cartTexts.labels.ADDITIOONAL_PACKAGE}:
|
||||
</Col>
|
||||
<Col lg="7" xs="7" id={"item-additional-" + cartItem.idCart + "-" + additionalPackage.idAdditionalPackage}>
|
||||
{additionalPackage.packageName}
|
||||
</Col>
|
||||
</Row>
|
||||
)
|
||||
}
|
||||
<Row className="cart-item-small-details">
|
||||
<Col lg={{offset: 1, size: 4}} xs={{offset:1, size: 4}}>Payment type:</Col>
|
||||
<Col lg="7" xs="7" id={"item-payment-type-" + cartItem.idCart}>
|
||||
{cartItem.payType}
|
||||
</Col>
|
||||
</Row>
|
||||
<Row className="cart-item-small-details">
|
||||
<Col lg={{offset: 1, size: 4}} xs={{offset:1, size: 4}}>Price:</Col>
|
||||
<Col lg="7" xs="7" id={"item-price-" + cartItem.idCart}>
|
||||
<table className="price-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{cartTexts.labels.ON_DELIVERY}</th>
|
||||
<th>{cartTexts.labels.MONTHLY}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
{
|
||||
this.state.fixedPrice &&
|
||||
<div>
|
||||
{
|
||||
this.state.fixedOldPrice !== null &&
|
||||
<div className="old-price">{this.state.fixedOldPrice}</div>
|
||||
}
|
||||
<div className={this.getPriceClass(this.state.fixedOldPrice)}>
|
||||
{this.state.fixedPrice.toLocaleString() + ' ' + cartItem.country.currency}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
}
|
||||
</td>
|
||||
<td>
|
||||
{
|
||||
this.state.recurrentPrice &&
|
||||
<div>
|
||||
{
|
||||
this.state.recurrentOldPrice !== null &&
|
||||
<div className="old-price">{this.state.recurrentOldPrice}</div>
|
||||
}
|
||||
<div className={this.getPriceClass(this.state.recurrentOldPrice)}>
|
||||
{this.state.recurrentPrice.toLocaleString() + ' ' + cartItem.country.currency}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default connect()(CartItem);
|
||||
@@ -0,0 +1,79 @@
|
||||
import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import {Col} from 'reactstrap';
|
||||
import {uploadOrderDocument, badFile} from '../../../actions/cart/cartActions';
|
||||
import Dropzone from 'react-dropzone';
|
||||
import {API_SERVER} from '../../../config';
|
||||
import FileDownloader from '../../../helpers/FileDownloader';
|
||||
import {cartTexts} from '../../../constants/cartConstants';
|
||||
|
||||
const fileHandler = new FileDownloader();
|
||||
const documentTypes = {
|
||||
2 : 'Customer Questionnaire',
|
||||
7 : 'Customer Agreement'
|
||||
};
|
||||
|
||||
class CartUploadDocument extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.uploadFile = this.uploadFile.bind(this);
|
||||
}
|
||||
|
||||
uploadFile(idPackage, idDocumentType,acceptedFiles, rejectedFiles, packages){
|
||||
const self = this;
|
||||
|
||||
acceptedFiles.forEach(file => {
|
||||
self.props.dispatch(uploadOrderDocument(idPackage, idDocumentType, file, packages));
|
||||
});
|
||||
|
||||
if(rejectedFiles && rejectedFiles.length) {
|
||||
this.props.dispatch(badFile());
|
||||
}
|
||||
}
|
||||
|
||||
downloadDocument(document){
|
||||
const fileUrl = `${API_SERVER}/utils/api/downloadFile?idDocument=${document.idDocument}&fileName=${document.documentName}.${document.extension}`
|
||||
const fileName = document.documentName + '.' + document.extension;
|
||||
fileHandler.download(fileUrl, fileName);
|
||||
}
|
||||
|
||||
render() {
|
||||
const {idDocumentType, cartItem, uploadedDocument, templateDocument, packages} = this.props;
|
||||
|
||||
return (<Col lg="6">
|
||||
{
|
||||
templateDocument &&
|
||||
<div>
|
||||
<Dropzone className="upload-file-drop-zone"
|
||||
accept=".pdf,.docx,.doc,.xlsx,.xls,.odt,.ods"
|
||||
onDrop={(acceptedFiles, rejectedFiles)=>{this.uploadFile(cartItem.idPackage, idDocumentType, acceptedFiles, rejectedFiles, packages)}}>
|
||||
{
|
||||
uploadedDocument
|
||||
? <h6 className="drop-zone-text uploaded">{cartTexts.labels.FILE_UPLOADED_TEXT} {documentTypes[idDocumentType]} {cartTexts.labels.FILE}</h6>
|
||||
: <h6 className="drop-zone-text">{cartTexts.labels.NO_FILE_UPLOAD_TEXT_1} {documentTypes[idDocumentType]} {cartTexts.labels.NO_FILE_UPLOAD_TEXT_2}</h6>
|
||||
}
|
||||
</Dropzone>
|
||||
{
|
||||
uploadedDocument &&
|
||||
<div>
|
||||
<div className="cart-subtitle">{cartTexts.labels.UPLOADED}:</div>
|
||||
<div className="document-link" onClick={() => {this.downloadDocument(uploadedDocument)}}>
|
||||
<i className="fa fa-file" aria-hidden="true"></i>
|
||||
{' ' + uploadedDocument.documentName + ' (' + uploadedDocument.extension + ')'}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
<div className="cart-subtitle">{cartTexts.labels.TEMPLATES}:</div>
|
||||
<div className="document-link" onClick={() => {this.downloadDocument(templateDocument)}}>
|
||||
<i className="fa fa-file" aria-hidden="true"></i>
|
||||
{' ' + templateDocument.documentName + ' (' + templateDocument.extension + ')'}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
</Col>);
|
||||
}
|
||||
}
|
||||
|
||||
export default connect()(CartUploadDocument);
|
||||
@@ -0,0 +1,71 @@
|
||||
import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import {Button, Row, Col} from 'reactstrap';
|
||||
import Select from 'react-select';
|
||||
import AddOrderProject from './AddOrderProject.jsx';
|
||||
import {getOrderProjects} from '../../../actions/orderProjects/orderProjectsActions';
|
||||
import {setDialogOpenFlag, setDialogContent} from '../../../actions/dialog/dialogActions';
|
||||
import '../style/OrderProjects.css';
|
||||
|
||||
class OrderProjectsSelect extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.openDialog = this.openDialog.bind(this);
|
||||
}
|
||||
|
||||
componentDidMount(){
|
||||
this.props.dispatch(getOrderProjects());
|
||||
}
|
||||
|
||||
openDialog(){
|
||||
const dialogContent = {
|
||||
header: 'Add Project',
|
||||
TagName: AddOrderProject,
|
||||
class: 'user-dialog',
|
||||
hasCloseIcon: true
|
||||
};
|
||||
|
||||
this.props.dispatch(setDialogOpenFlag(true));
|
||||
this.props.dispatch(setDialogContent(dialogContent));
|
||||
}
|
||||
|
||||
render() {
|
||||
const {orderProjects, isLoading, idProject, handleChange} = this.props;
|
||||
|
||||
return (<Col md={4} id="order-projects">
|
||||
{
|
||||
isLoading &&
|
||||
<div className="loader">
|
||||
<i className="fa fa-spinner fa-spin fa-3x" aria-hidden="true"></i>
|
||||
</div>
|
||||
}
|
||||
{orderProjects && !isLoading &&
|
||||
<Row>
|
||||
<Col md={10}>
|
||||
<Select value={idProject}
|
||||
name="idProject"
|
||||
className="order-project-select"
|
||||
placeholder="Project..."
|
||||
options={orderProjects}
|
||||
clearable={true}
|
||||
onChange={(project) => {handleChange(project)}}/>
|
||||
|
||||
</Col>
|
||||
<Col md={2}>
|
||||
<Button onClick={this.openDialog} className="actions-button">
|
||||
<i className="fa fa-plus" aria-hidden="true"></i>
|
||||
</Button>
|
||||
</Col>
|
||||
</Row>
|
||||
}
|
||||
</Col>);
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
orderProjects: state.orderProjectsReducer.orderProjects,
|
||||
isLoading: state.orderProjectsReducer.isLoading
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps)(OrderProjectsSelect);
|
||||
47
client-wiaas/src/containers/cart/components/PackageBids.jsx
Normal file
47
client-wiaas/src/containers/cart/components/PackageBids.jsx
Normal file
@@ -0,0 +1,47 @@
|
||||
import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import {cartTexts} from '../../../constants/cartConstants';
|
||||
import {setDialogOpenFlag, setDialogContent} from '../../../actions/dialog/dialogActions';
|
||||
import BidsList from './BidsList.jsx';
|
||||
import '../style/PacakgeBids.css';
|
||||
|
||||
class PackageBids extends Component {
|
||||
constructor(props){
|
||||
super(props);
|
||||
|
||||
this.openDialog = this.openDialog.bind(this);
|
||||
}
|
||||
|
||||
openDialog(){
|
||||
const dialogContent = {
|
||||
header: cartTexts.labels.AVAILABLE_BIDS,
|
||||
TagName: BidsList,
|
||||
class: 'bid-dialog',
|
||||
hasCloseIcon: true,
|
||||
params: {
|
||||
bids: this.props.bids,
|
||||
idCart: this.props.idCart,
|
||||
idSelectedBid: this.props.idSelectedBid
|
||||
}
|
||||
};
|
||||
|
||||
this.props.dispatch(setDialogOpenFlag(true));
|
||||
this.props.dispatch(setDialogContent(dialogContent));
|
||||
}
|
||||
|
||||
render() {
|
||||
const {bids} = this.props;
|
||||
return (
|
||||
<div id="cart-bids" className="cart-bids ">
|
||||
{
|
||||
bids && bids.length > 0 &&
|
||||
<span onClick={this.openDialog} className="cart-bids-text">
|
||||
{cartTexts.labels.BID_AVAILABLE}
|
||||
{' '}<span className="fa fa-arrow-circle-left"></span>
|
||||
</span>
|
||||
}
|
||||
</div>);
|
||||
}
|
||||
}
|
||||
|
||||
export default connect()(PackageBids);
|
||||
@@ -0,0 +1,50 @@
|
||||
import React, {Component} from 'react';
|
||||
import {FormGroup, Input} from 'reactstrap';
|
||||
|
||||
class SelectBillingAddress extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.handleOptionChange = this.handleOptionChange.bind(this);
|
||||
}
|
||||
|
||||
handleOptionChange(){
|
||||
this.props.handleBillingChange(this.props.billingAddress);
|
||||
}
|
||||
|
||||
render() {
|
||||
const {billingAddress, openAddressDialog, idSelectedBillingAddress} = this.props;
|
||||
|
||||
return (
|
||||
<div className="address-row">
|
||||
<FormGroup check>
|
||||
<div>
|
||||
<div className="address-text">
|
||||
<Input id={'billing-addres-check-' + billingAddress.id} checked={idSelectedBillingAddress === billingAddress.id} type="radio" onChange={this.handleOptionChange} name="billingAddress" />
|
||||
<div className="small-address-title">
|
||||
{billingAddress.firstName} {billingAddress.lastName}
|
||||
{
|
||||
billingAddress.invoiceMail &&
|
||||
<span>( {billingAddress.invoiceMail} )</span>
|
||||
}
|
||||
</div>
|
||||
<div>
|
||||
{billingAddress.countryName}, {billingAddress.city}, {billingAddress.detailedAddress}, {billingAddress.zipCode}
|
||||
</div>
|
||||
</div>
|
||||
<div className="address-icons">
|
||||
<i className="fa fa-pencil control-icon edit-address-btn"
|
||||
onClick={()=> {openAddressDialog('edit', billingAddress)}}
|
||||
id="edit-address-btn"
|
||||
aria-hidden="true"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</FormGroup>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default SelectBillingAddress;
|
||||
@@ -0,0 +1,41 @@
|
||||
import React, {Component} from 'react';
|
||||
import {FormGroup, Input} from 'reactstrap';
|
||||
|
||||
class SelectDeliveryAddress extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.handleOptionChange = this.handleOptionChange.bind(this);
|
||||
}
|
||||
|
||||
handleOptionChange(){
|
||||
this.props.handleDeliveryChange(this.props.profileAddress);
|
||||
}
|
||||
|
||||
render() {
|
||||
const {profileAddress, openAddressDialog, idSelectedDeliveryAddress} = this.props;
|
||||
|
||||
return (
|
||||
<div className="address-row">
|
||||
<FormGroup check>
|
||||
<div>
|
||||
<div className="address-text">
|
||||
<Input id={'delivery-addres-check-' + profileAddress.id} checked={idSelectedDeliveryAddress === profileAddress.id} type="radio" onChange={this.handleOptionChange} name="deliveryAddress" />
|
||||
{profileAddress.countryName}, {profileAddress.city}, {profileAddress.detailedAddress}, {profileAddress.zipCode}
|
||||
</div>
|
||||
<div className="address-icons">
|
||||
<i className="fa fa-pencil control-icon edit-address-btn"
|
||||
onClick={()=> {openAddressDialog('edit', profileAddress)}}
|
||||
id="edit-address-btn"
|
||||
aria-hidden="true"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</FormGroup>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default SelectDeliveryAddress;
|
||||
170
client-wiaas/src/containers/cart/style/Cart.scss
Normal file
170
client-wiaas/src/containers/cart/style/Cart.scss
Normal file
@@ -0,0 +1,170 @@
|
||||
@import '../../../styleConstants.scss';
|
||||
|
||||
#cart-count {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
#cart-container {
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
#cart-items-container {
|
||||
border-radius: $box-radius;
|
||||
|
||||
.cart-show-items {
|
||||
padding-top: 1rem;
|
||||
}
|
||||
|
||||
.quantity-field {
|
||||
margin-left: 2%;
|
||||
display: inline-block;
|
||||
max-width: 5rem;
|
||||
}
|
||||
|
||||
.remove-item {
|
||||
color: $redColor;
|
||||
cursor: pointer;
|
||||
font-size: 1.3rem;
|
||||
padding-top: 0.375rem;
|
||||
line-height: 1.5rem;
|
||||
}
|
||||
|
||||
.cart-item-details {
|
||||
padding-top: 0.5rem;
|
||||
}
|
||||
|
||||
.cart-item-small-details {
|
||||
padding-top: 0.5rem;
|
||||
font-size: $font-size-msmall;
|
||||
}
|
||||
|
||||
.item-name {
|
||||
font-weight: $font-weight;
|
||||
}
|
||||
|
||||
.cart-total-price {
|
||||
padding: 1rem 0;
|
||||
font-size: $font-size-big;
|
||||
}
|
||||
|
||||
.price-table th{
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.price-table td{
|
||||
border-top: 1px solid $darkGreyColor;
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.not-available {
|
||||
margin-left: 0.2rem;
|
||||
color: $not-available-status-color;
|
||||
font-weight: $font-weight;
|
||||
font-size: $font-size-msmall;
|
||||
}
|
||||
|
||||
.old-price{
|
||||
text-decoration: line-through;
|
||||
font-size: $font-size-msmall;
|
||||
}
|
||||
|
||||
.new-price{
|
||||
color: $redColor;
|
||||
font-weight: $font-weight;
|
||||
}
|
||||
}
|
||||
|
||||
#cart-review-order-container {
|
||||
border-radius: $box-radius;
|
||||
|
||||
.cart-customer-main-info-row {
|
||||
padding: 0.5rem;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.place-order-btn {
|
||||
cursor: pointer;
|
||||
background-color: $done-status-color;
|
||||
width: 100%;
|
||||
float: right;
|
||||
font-weight: $font-weight;
|
||||
}
|
||||
|
||||
.button-cart {
|
||||
text-align: right;
|
||||
padding: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
#go-to-co-market-text {
|
||||
color: $warmGreyColor;
|
||||
}
|
||||
|
||||
#cart-add-new-delivery-address {
|
||||
margin: 1rem;
|
||||
}
|
||||
|
||||
#cart-customer-details-container {
|
||||
.cart-customer-main-info-row {
|
||||
padding: 0.5rem;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.country-address {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.next-btn, .prev-btn {
|
||||
cursor: pointer;
|
||||
background-color: $whiteColor;
|
||||
color: $darkGreyColor;
|
||||
}
|
||||
|
||||
.next-btn {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.prev-btn {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.address-row {
|
||||
position: relative;
|
||||
border-bottom: 1px solid $divider-color;
|
||||
padding: 0.5rem 0;
|
||||
}
|
||||
|
||||
.address-text {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
margin-left: 2rem;
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
.address-icons{
|
||||
position: absolute;
|
||||
min-width: 3rem;
|
||||
display: inline-block;
|
||||
text-align: right;
|
||||
width: 15%;
|
||||
}
|
||||
|
||||
.control-icon {
|
||||
margin-right: 2rem;
|
||||
font-size: $font-size-big;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.add-address-btn{
|
||||
cursor: pointer;
|
||||
margin: 1rem 0;
|
||||
}
|
||||
|
||||
.cart-address-box {
|
||||
margin-top: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
#cart-customer-main-information-container {
|
||||
border-radius: $box-radius;
|
||||
}
|
||||
165
client-wiaas/src/containers/cart/style/CartStepsContainer.scss
Normal file
165
client-wiaas/src/containers/cart/style/CartStepsContainer.scss
Normal file
@@ -0,0 +1,165 @@
|
||||
@import '../../../styleConstants.scss';
|
||||
|
||||
#cart-steps-container {
|
||||
padding: 1rem 1rem 2rem;
|
||||
text-align: center;
|
||||
|
||||
.step-name {
|
||||
cursor: default;
|
||||
padding: 1rem;
|
||||
display: inline-block;
|
||||
border-radius: 4px;
|
||||
color: $whiteColor;
|
||||
}
|
||||
|
||||
.steps-link {
|
||||
display: inline;
|
||||
width: 2rem;
|
||||
height: 0.15rem;
|
||||
position: unset;
|
||||
}
|
||||
|
||||
.step-link {
|
||||
display: inline-block;
|
||||
background: $borderColor;
|
||||
height: 0.15rem;
|
||||
width: 2rem;
|
||||
}
|
||||
|
||||
.active {
|
||||
background: $lightGreenColor;
|
||||
}
|
||||
|
||||
.inactive {
|
||||
background: $lightGreyColor;
|
||||
}
|
||||
|
||||
.completed {
|
||||
background: $blueColor;
|
||||
}
|
||||
|
||||
.progress-main-bar {
|
||||
background: none;
|
||||
height: 1.5rem;
|
||||
font-size: $font-size-small;
|
||||
}
|
||||
|
||||
.progress-bar-item {
|
||||
border-radius: 0 15px 15px 0;
|
||||
overflow: hidden;
|
||||
margin-right: 0.5rem;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.next-btn,
|
||||
.prev-btn {
|
||||
cursor: pointer;
|
||||
background-color: $whiteColor;
|
||||
color: $darkGreyColor;
|
||||
border: 0.1rem $border-grey solid;
|
||||
padding: 0.95rem;
|
||||
display: inline-block;
|
||||
border-radius: $box-radius;
|
||||
font-weight: $font-weight;
|
||||
}
|
||||
|
||||
.next-btn {
|
||||
margin-left: 2rem;
|
||||
}
|
||||
|
||||
.prev-btn {
|
||||
margin-right: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
#cart-items-container {
|
||||
padding-top: 1rem;
|
||||
}
|
||||
@media all and (max-width: 1494px) {
|
||||
#cart-steps-container {
|
||||
.steps-link {
|
||||
position: relative;
|
||||
height: 1.5rem;
|
||||
display: block;
|
||||
width: 2rem;
|
||||
height: 1.5rem;
|
||||
top: 0;
|
||||
left: 49%;
|
||||
}
|
||||
|
||||
.step-link {
|
||||
background: $borderColor;
|
||||
width: 3px;
|
||||
height: 1.5rem;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.next-btn {
|
||||
display: block;
|
||||
width: fit-content;
|
||||
margin-top: 1rem;
|
||||
margin-left: 45%;
|
||||
}
|
||||
|
||||
.prev-btn {
|
||||
display: block;
|
||||
width: fit-content;
|
||||
margin-bottom: 1rem;
|
||||
margin-left: 44%;
|
||||
}
|
||||
}
|
||||
}
|
||||
@media all and (min-width: 992px) and (max-width: 1200px) {
|
||||
#cart-steps-container {
|
||||
.step-name {
|
||||
width: 30%;
|
||||
}
|
||||
|
||||
.steps-link {
|
||||
position: relative;
|
||||
height: 1.5rem;
|
||||
display: block;
|
||||
width: 2rem;
|
||||
height: 1.5rem;
|
||||
top: 0;
|
||||
left: 49%;
|
||||
}
|
||||
|
||||
.step-link {
|
||||
background: $borderColor;
|
||||
width: 3px;
|
||||
height: 1.5rem;
|
||||
z-index: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@media all and (max-width: 992px) {
|
||||
#cart-steps-container {
|
||||
.next-btn {
|
||||
display: block;
|
||||
margin-top: 1rem;
|
||||
margin-left: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.prev-btn {
|
||||
display: block;
|
||||
margin-bottom: 1rem;
|
||||
margin-left: 0;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
#cart-customer-details-container,
|
||||
#cart-review-all-order-container,
|
||||
#cart-upload-documents-container {
|
||||
border-top: 0.2rem solid $borderColor;
|
||||
}
|
||||
}
|
||||
@media all and (max-width: 768px) {
|
||||
#cart-steps-container {
|
||||
.step-name {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
@import '../../../styleConstants.scss';
|
||||
|
||||
#cart-upload-documents-container{
|
||||
border-radius: $box-radius;
|
||||
background: $whiteColor;
|
||||
|
||||
.upload-file-drop-zone {
|
||||
width: 100%;
|
||||
border: 3px dashed $borderColor;
|
||||
margin-top: 1rem;
|
||||
height: 5rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.drop-zone-text {
|
||||
text-align: center;
|
||||
padding: 1.3rem 0.5rem;
|
||||
}
|
||||
|
||||
.uploaded {
|
||||
color: #155724;
|
||||
}
|
||||
|
||||
.next-btn {
|
||||
float: right;
|
||||
cursor: pointer;
|
||||
background-color: $whiteColor;
|
||||
color: $darkGreyColor;
|
||||
}
|
||||
|
||||
.cart-subtitle {
|
||||
font-weight: $font-weight;
|
||||
padding-top: 0.3rem;
|
||||
}
|
||||
}
|
||||
|
||||
.upload-layer{
|
||||
background: $whiteColor;
|
||||
padding-bottom: 1rem;
|
||||
|
||||
.document-link{
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (max-width: 480px) {
|
||||
#cart-upload-documents-container {
|
||||
margin-top: 1rem;
|
||||
|
||||
.upload-file-drop-zone {
|
||||
height: 8rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
20
client-wiaas/src/containers/cart/style/OrderProjects.scss
Normal file
20
client-wiaas/src/containers/cart/style/OrderProjects.scss
Normal file
@@ -0,0 +1,20 @@
|
||||
@import '../../../styleConstants.scss';
|
||||
|
||||
#order-projects{
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
|
||||
.order-project-select{
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
.actions-button {
|
||||
background-color: $whiteColor;
|
||||
color: $darkGreyColor;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.actions-button:hover{
|
||||
background: rgba(113, 194, 191, 0.5);
|
||||
}
|
||||
}
|
||||
13
client-wiaas/src/containers/cart/style/PacakgeBids.scss
Normal file
13
client-wiaas/src/containers/cart/style/PacakgeBids.scss
Normal file
@@ -0,0 +1,13 @@
|
||||
@import '../../../styleConstants.scss';
|
||||
|
||||
#cart-bids{
|
||||
.cart-bids-text {
|
||||
color: $redColor;
|
||||
font-size: $font-size-msmall;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.bid-dialog{
|
||||
width: 70%;
|
||||
}
|
||||
27
client-wiaas/src/containers/coMarket/CoMarketContainer.jsx
Normal file
27
client-wiaas/src/containers/coMarket/CoMarketContainer.jsx
Normal file
@@ -0,0 +1,27 @@
|
||||
import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import {Container} from 'reactstrap';
|
||||
import CoMarketPackagesContainer from './CoMarketPackagesContainer.jsx';
|
||||
import CoMarketPackageDetailsContainer from './CoMarketPackageDetailsContainer.jsx';
|
||||
import {setPackageFromUrl} from '../../actions/coMarket/coMarketActions';
|
||||
import './style/CoMarket.css'
|
||||
|
||||
class CoMarketContainer extends Component {
|
||||
componentDidMount(){
|
||||
this.props.dispatch(setPackageFromUrl(this.props.match.params.idPackage));
|
||||
}
|
||||
|
||||
render() {
|
||||
const urlParams = this.props.match.params;
|
||||
|
||||
return (<Container fluid={true} id="co-market-container">
|
||||
{
|
||||
urlParams.idPackage ?
|
||||
<CoMarketPackageDetailsContainer idPackage={urlParams.idPackage} idCommercialLead={urlParams.idCommercialLead}/> :
|
||||
<CoMarketPackagesContainer/>
|
||||
}
|
||||
</Container>);
|
||||
}
|
||||
}
|
||||
|
||||
export default connect()(CoMarketContainer);
|
||||
@@ -0,0 +1,45 @@
|
||||
import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import {Row, Col, Input} from 'reactstrap';
|
||||
import {fetchShopPackages} from '../../actions/coMarket/coMarketPackagesActions';
|
||||
import {coMarketTexts} from '../../constants/coMarketConstants';
|
||||
|
||||
class CoMarketNavContainer extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.handleSearchChange = this.handleSearchChange.bind(this);
|
||||
this.state = {
|
||||
searchValue : ''
|
||||
};
|
||||
}
|
||||
|
||||
handleSearchChange(event) {
|
||||
this.setState({searchValue: event.target.value});
|
||||
this.props.dispatch(fetchShopPackages(this.props.selectedCommercialLead, event.target.value));
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Row className="co-market-nav">
|
||||
<Col xl="4" lg="3" md="3" sm="12" xs="12" className="co-market-nav-buttons">
|
||||
<div className="co-market-nav-div">
|
||||
{coMarketTexts.labels.NEW_PRODUCTS}
|
||||
</div>
|
||||
</Col>
|
||||
<Col xl="4" lg="4" md="4" xs="12" className="search-layer">
|
||||
<div className="co-market-nav-div">
|
||||
<i className="search-package-icon fa fa-search" aria-hidden="true"></i>
|
||||
<Input className="wiaas-input" onChange={this.handleSearchChange} value={this.state.searchValue} placeholder={coMarketTexts.labels.SEARCH_PACKAGE}/>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
selectedCommercialLead: state.coMarketPackagesReducer.selectedCommercialLead
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps)(CoMarketNavContainer);
|
||||
@@ -0,0 +1,109 @@
|
||||
import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import {Row, Col, Button} from 'reactstrap';
|
||||
import WiaasBox from '../../mainComponents/box/WiaasBox.jsx';
|
||||
import {fetchPackageDetails, addToCart} from '../../actions/coMarket/coMarketPackageDetailsActions';
|
||||
import PackageInfo from './components/PackageInfo.jsx';
|
||||
import PackagePrice from './components/PackagePrice.jsx';
|
||||
import PackageOptions from './components/PackageOptions.jsx';
|
||||
import AdditionalPackages from './components/AdditionalPackages.jsx';
|
||||
import AgreementOptions from './components/AgreementOptions.jsx';
|
||||
import {coMarketTexts} from '../../constants/coMarketConstants';
|
||||
import './style/CoMarketPackageDetailsContainer.css';
|
||||
|
||||
class CoMarketPackageDetailsContainer extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.handleAddToCart = this.handleAddToCart.bind(this);
|
||||
this.state = {
|
||||
selectedOptions: {}
|
||||
};
|
||||
}
|
||||
|
||||
handleAddToCart() {
|
||||
const addParams = {
|
||||
selectedPackage: this.props.selectedPackage,
|
||||
selectedAgreement: this.props.selectedAgreement,
|
||||
selectedOptions: this.props.selectedOptions,
|
||||
selectedAdditionals: this.props.selectedAdditionals
|
||||
};
|
||||
this.props.dispatch(addToCart(addParams));
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const {idPackage, idCommercialLead} = this.props;
|
||||
this.props.dispatch(fetchPackageDetails({idPackage, idCommercialLead}));
|
||||
}
|
||||
|
||||
render() {
|
||||
const {selectedPackage, selectedAgreement, messages, isLoading} = this.props;
|
||||
return(
|
||||
<div id="co-market-package-details">
|
||||
<Row>
|
||||
<Col xl="12" lg="12">
|
||||
<WiaasBox>
|
||||
{
|
||||
isLoading &&
|
||||
<div className="loader">
|
||||
<i className="fa fa-spinner fa-spin fa-3x" aria-hidden="true"></i>
|
||||
</div>
|
||||
}
|
||||
{
|
||||
(selectedPackage && !isLoading) &&
|
||||
<Row>
|
||||
<Col xl="6" lg="5" md="12" xs="12">
|
||||
<PackageInfo
|
||||
packageInfo={selectedPackage.packageInfo}
|
||||
documents={selectedPackage.documents} />
|
||||
</Col>
|
||||
|
||||
<Col xl="6" lg="7" md="12" xs="12">
|
||||
<div id="shop-package-buy-info">
|
||||
<PackagePrice
|
||||
country={selectedPackage.country} />
|
||||
{
|
||||
selectedPackage.groups && Object.keys(selectedPackage.groups).length > 0 && selectedAgreement &&
|
||||
<PackageOptions
|
||||
groups={selectedPackage.groups}
|
||||
country={selectedPackage.country}/>
|
||||
}
|
||||
{
|
||||
selectedPackage.additionalPackages && selectedPackage.additionalPackages.length > 0 && selectedAgreement &&
|
||||
<AdditionalPackages
|
||||
additionalPackages={selectedPackage.additionalPackages}
|
||||
country={selectedPackage.country}/>
|
||||
}
|
||||
<AgreementOptions
|
||||
prices={selectedPackage.prices}
|
||||
country={selectedPackage.country}/>
|
||||
<Button id="add-to-cart-btn"
|
||||
className="add-to-cart-btn"
|
||||
onClick={this.handleAddToCart}
|
||||
color="secondary">
|
||||
<i className="fa fa-shopping-cart" aria-hidden="true"></i>
|
||||
{' '}{coMarketTexts.buttons.ADD_TO_CART}
|
||||
</Button>
|
||||
{messages && <span>{messages[0].message}</span>}
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
}
|
||||
</WiaasBox>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
selectedPackage: state.coMarketPackageDetailsReducer.selectedPackage,
|
||||
selectedAgreement: state.coMarketPackageDetailsReducer.selectedAgreement,
|
||||
selectedOptions: state.coMarketPackageDetailsReducer.selectedOptions,
|
||||
selectedAdditionals: state.coMarketPackageDetailsReducer.selectedAdditionals,
|
||||
messages: state.coMarketPackageDetailsReducer.messages,
|
||||
isLoading: state.coMarketPackageDetailsReducer.isLoading
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps)(CoMarketPackageDetailsContainer);
|
||||
@@ -0,0 +1,62 @@
|
||||
import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import {Row, Col} from 'reactstrap';
|
||||
import ShopItem from './components/ShopItem.jsx';
|
||||
import WiaasBox from '../../mainComponents/box/WiaasBox.jsx';
|
||||
import CoMarketNavContainer from './CoMarketNavContainer.jsx';
|
||||
import {fetchShopPackages} from '../../actions/coMarket/coMarketPackagesActions';
|
||||
|
||||
class CoMarketPackagesContainer extends Component {
|
||||
componentDidMount() {
|
||||
this.props.dispatch(fetchShopPackages(this.props.selectedCommercialLead));
|
||||
}
|
||||
|
||||
render() {
|
||||
const {shopPackages, selectedCommercialLead, isLoading} = this.props;
|
||||
|
||||
return (
|
||||
<div id="co-market-shop">
|
||||
<Row>
|
||||
<Col xl="8" lg="8" md="8" sm="12" xs="12">
|
||||
<WiaasBox id="co-market-big-commercial">
|
||||
<img className="description-photo" src="https://res.cloudinary.com/co-market/image/upload/v1524472688/Co-Market/CoMarketStartsida_MAIN.jpg" alt="big-commercial"/>
|
||||
</WiaasBox>
|
||||
</Col>
|
||||
<Col xl="4" lg="4" md="4" sm="12" xs="12">
|
||||
<WiaasBox id="co-market-commercials">
|
||||
<img alt="wiaas commercial" src="https://res.cloudinary.com/co-market/image/upload/v1524472688/Co-Market/CoMarketStartsida_OFFERCoor.jpg" className="commercial-photo"/>
|
||||
</WiaasBox>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
<Col xl="8" lg="12" md="12">
|
||||
<WiaasBox id="co-market-packages" customHeader={CoMarketNavContainer}>
|
||||
<Row>
|
||||
{
|
||||
isLoading &&
|
||||
<Col xl="12" className="loader">
|
||||
<i className="fa fa-spinner fa-spin fa-3x" aria-hidden="true"></i>
|
||||
</Col>
|
||||
}
|
||||
{
|
||||
(shopPackages && !isLoading) &&
|
||||
shopPackages.map((shopPackage, mapKey) => <ShopItem key={shopPackage.idPackage}
|
||||
idCommercialLead={selectedCommercialLead.value}
|
||||
shopPackage={shopPackage}/>)
|
||||
}
|
||||
</Row>
|
||||
</WiaasBox>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
shopPackages: state.coMarketPackagesReducer.shopPackages,
|
||||
selectedCommercialLead: state.coMarketPackagesReducer.selectedCommercialLead,
|
||||
isLoading: state.coMarketPackagesReducer.isLoading
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps)(CoMarketPackagesContainer);
|
||||
@@ -0,0 +1,131 @@
|
||||
import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import {Label, Popover, PopoverBody, Input, Col} from 'reactstrap';
|
||||
import {selectAdditional, removetAdditional} from '../../../actions/coMarket/coMarketPackageDetailsActions';
|
||||
import PriceHelper from '../../../helpers/coMarket/PriceHelper';
|
||||
import {coMarketTexts} from '../../../constants/coMarketConstants';
|
||||
|
||||
const priceHelper = new PriceHelper();
|
||||
|
||||
class AdditionalPackageItem extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.toggle = this.toggle.bind(this);
|
||||
this.handleOptionChange = this.handleOptionChange.bind(this);
|
||||
this.isChecked = this.isChecked.bind(this);
|
||||
this.state = {
|
||||
popoverOpen: false
|
||||
};
|
||||
}
|
||||
|
||||
toggle() {
|
||||
this.setState({
|
||||
popoverOpen: !this.state.popoverOpen
|
||||
});
|
||||
}
|
||||
|
||||
handleOptionChange() {
|
||||
if(!this.isChecked()){
|
||||
this.props.dispatch(selectAdditional(this.props.additionalPackage))
|
||||
}else{
|
||||
this.props.dispatch(removetAdditional(this.props.additionalPackage));
|
||||
}
|
||||
}
|
||||
|
||||
isChecked() {
|
||||
return this.props.selectedAdditionals
|
||||
&& this.props.selectedAdditionals.includes(this.props.additionalPackage);
|
||||
}
|
||||
|
||||
isAvailable() {
|
||||
return this.props.additionalPackage.prices.find(price => {
|
||||
return price.idPaymentType === this.props.selectedAgreement.idPaymentType;
|
||||
});
|
||||
}
|
||||
|
||||
getClass(isChecked) {
|
||||
return isChecked ?
|
||||
'selected-option' :
|
||||
'';
|
||||
}
|
||||
|
||||
formatName(name) {
|
||||
return name.length > 39 ? name.substring(0, 40) + '...' : name;
|
||||
}
|
||||
|
||||
render() {
|
||||
const {additionalPackage, country} = this.props;
|
||||
const isAvailable = this.isAvailable();
|
||||
const selectedPrice = priceHelper.getSelectedPrice(additionalPackage, this.props.selectedAgreement);
|
||||
const isChecked = this.isChecked();
|
||||
|
||||
return (
|
||||
<Col xl="4" lg="4" md="6" xs="6" className="option-value">
|
||||
<div className={'option-selection ' + this.getClass(isChecked)}>
|
||||
<Label check>
|
||||
<Input type="checkbox"
|
||||
onChange={this.handleOptionChange}
|
||||
name={'package-option-'+ additionalPackage.idAdditionalPackage}
|
||||
className="package-option-input"/>
|
||||
<div className="option-name">{this.formatName(additionalPackage.packageName)}</div>
|
||||
<div className="option-description" dangerouslySetInnerHTML={{__html: additionalPackage.shortDescription}}></div>
|
||||
{
|
||||
priceHelper.hasFixedPrice(selectedPrice) &&
|
||||
<div className="option-prices">
|
||||
<table className="price-table option-price-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{coMarketTexts.labels.ON_DELIVERY}</th>
|
||||
<th>{coMarketTexts.labels.MONTHLY}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>{selectedPrice.fixedExtra > 0 ? selectedPrice.fixedExtra.toLocaleString() : 0} {country.currency}</td>
|
||||
<td>
|
||||
<div className="option-value-text monthly-price">
|
||||
{
|
||||
priceHelper.hasRecurrentPrice(selectedPrice)
|
||||
? priceHelper.sumPrices([selectedPrice.recurentExtra, selectedPrice.servicesExtra]).toLocaleString() + ' '
|
||||
: 0
|
||||
} {country.currency}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
}
|
||||
|
||||
</Label>
|
||||
{
|
||||
!isAvailable &&
|
||||
<span className="not-available">
|
||||
({coMarketTexts.labels.NOT_AVAILABLE})
|
||||
<i className="price-info-btn fa fa-info-circle"
|
||||
aria-hidden="true"
|
||||
id={'info-additonal-' + additionalPackage.idAdditionalPackage}
|
||||
onClick={this.toggle}></i>
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
|
||||
<Popover placement="bottom"
|
||||
isOpen={this.state.popoverOpen}
|
||||
target={'info-additonal-' + additionalPackage.idAdditionalPackage}
|
||||
toggle={this.toggle}>
|
||||
<PopoverBody>
|
||||
{coMarketTexts.labels.SELECTION_NOT_AVAILABLE}
|
||||
</PopoverBody>
|
||||
</Popover>
|
||||
</Col>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
selectedAgreement: state.coMarketPackageDetailsReducer.selectedAgreement,
|
||||
selectedAdditionals: state.coMarketPackageDetailsReducer.selectedAdditionals
|
||||
});
|
||||
export default connect(mapStateToProps)(AdditionalPackageItem);
|
||||
@@ -0,0 +1,26 @@
|
||||
import React, {Component} from 'react';
|
||||
import {Row} from 'reactstrap';
|
||||
import AdditionalPackageItemContainer from './AdditionalPackageItemContainer.jsx';
|
||||
import {coMarketTexts} from '../../../constants/coMarketConstants';
|
||||
|
||||
class AdditionalPackages extends Component {
|
||||
render() {
|
||||
const {additionalPackages, country} = this.props;
|
||||
return (
|
||||
<div className="shop-package-options">
|
||||
<h6 className="shop-package-label options-header">{coMarketTexts.labels.ADDITIONAL_PACKAGES}:</h6>
|
||||
<Row>
|
||||
{
|
||||
additionalPackages.map(additionalPackage => {
|
||||
return <AdditionalPackageItemContainer key={'additonal-' + additionalPackage.idAdditionalPackage}
|
||||
country={country}
|
||||
additionalPackage={additionalPackage}/>
|
||||
})
|
||||
}
|
||||
</Row>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default AdditionalPackages;
|
||||
@@ -0,0 +1,127 @@
|
||||
import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import {Label, Popover, PopoverBody, Input, Col} from 'reactstrap';
|
||||
import {selectAgreement} from '../../../actions/coMarket/coMarketPackageDetailsActions';
|
||||
import PriceHelper from '../../../helpers/coMarket/PriceHelper';
|
||||
import {coMarketTexts} from '../../../constants/coMarketConstants';
|
||||
|
||||
const priceHelper = new PriceHelper();
|
||||
|
||||
class AgreementOptionItem extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.toggle = this.toggle.bind(this);
|
||||
this.handleOptionChange = this.handleOptionChange.bind(this);
|
||||
this.state = {
|
||||
popoverOpen: false
|
||||
};
|
||||
}
|
||||
|
||||
toggle() {
|
||||
this.setState({
|
||||
popoverOpen: !this.state.popoverOpen
|
||||
});
|
||||
}
|
||||
|
||||
handleOptionChange() {
|
||||
this.props.dispatch(selectAgreement(this.props.price));
|
||||
}
|
||||
|
||||
getClass(selectedAgreement, price) {
|
||||
return selectedAgreement.idPaymentType === price.idPaymentType ?
|
||||
'selected-option' :
|
||||
'';
|
||||
}
|
||||
|
||||
render() {
|
||||
const {price, selectedAgreement, country} = this.props;
|
||||
|
||||
return (
|
||||
<Col xl="4" lg="4" md="6" xs="6" className="option-value">
|
||||
<div className={'option-selection ' + this.getClass(selectedAgreement, price)}>
|
||||
<Label check>
|
||||
<Input type="radio"
|
||||
name="price-type"
|
||||
onChange={this.handleOptionChange}
|
||||
checked={selectedAgreement.idPaymentType === price.idPaymentType}
|
||||
value={price.idPaymentType}
|
||||
className="price-type-option"/>
|
||||
<div className="option-name">{price.payType}</div>
|
||||
<div className="option-prices">
|
||||
<table className="price-table option-price-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{coMarketTexts.labels.ON_DELIVERY}</th>
|
||||
<th>{coMarketTexts.labels.MONTHLY}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>{price.fixedExtra.toLocaleString()} {country.currency}</td>
|
||||
<td>
|
||||
{
|
||||
priceHelper.hasRecurrentPrice(price)
|
||||
? <div className="option-value-text monthly-price">
|
||||
{priceHelper.sumPrices([price.recurentExtra, price.servicesExtra]).toLocaleString()} {country.currency}
|
||||
</div>
|
||||
: <div className="option-value-text monthly-price"> 0 </div>
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</Label>
|
||||
<i className="price-info-btn fa fa-info-circle"
|
||||
aria-hidden="true"
|
||||
id={'info-additonal-' + price.idPaymentType}
|
||||
onClick={this.toggle}></i>
|
||||
</div>
|
||||
<Popover placement="bottom"
|
||||
isOpen={this.state.popoverOpen}
|
||||
target={'info-additonal-' + price.idPaymentType}
|
||||
className="price-info-popover"
|
||||
container="shop-package-buy-info"
|
||||
toggle={this.toggle}>
|
||||
<PopoverBody>
|
||||
<div>
|
||||
{
|
||||
price.recurentExtra > 0 &&
|
||||
<div className="package-price-recurrent">
|
||||
<span className="price-info-title">{coMarketTexts.labels.RECURRENT_PRICE}: </span>
|
||||
{(price.recurentExtra).toLocaleString()} {country.currency} / {price.periodUnit}
|
||||
{
|
||||
price.packagePayPeriod > 0 &&
|
||||
<span>
|
||||
{' '} for {price.packagePayPeriod} {price.periodUnit}
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
{
|
||||
price.servicesExtra > 0 &&
|
||||
<div className="services-price-recurrent">
|
||||
<span className="price-info-title">{coMarketTexts.labels.SERVICE_PRICE}: </span>
|
||||
{(price.servicesExtra).toLocaleString()} {country.currency} / {price.periodUnit}
|
||||
{
|
||||
price.servicesContractPeriod > 0 &&
|
||||
<span>
|
||||
{' '} for {price.servicesContractPeriod} {price.periodUnit} {coMarketTexts.labels.EXTEND} {price.periodUnit} (Max {price.maxContractPeriod} {price.periodUnit})
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</PopoverBody>
|
||||
</Popover>
|
||||
</Col>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
selectedAgreement: state.coMarketPackageDetailsReducer.selectedAgreement
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps)(AgreementOptionItem);
|
||||
@@ -0,0 +1,24 @@
|
||||
import React, {Component} from 'react';
|
||||
import {Row} from 'reactstrap';
|
||||
import AgreementOptionItemContainer from './AgreementOptionItemContainer.jsx';
|
||||
import {coMarketTexts} from '../../../constants/coMarketConstants';
|
||||
|
||||
class AgreementOptions extends Component {
|
||||
render() {
|
||||
const {prices, country} = this.props;
|
||||
return (
|
||||
<div className="shop-package-options">
|
||||
<h6 className="shop-package-label options-header">{coMarketTexts.labels.AGREEMENT_OPTIONS}:</h6>
|
||||
<Row>
|
||||
{
|
||||
prices && prices.map((price) => {
|
||||
return <AgreementOptionItemContainer key={'agreement-' + price.idPaymentType} country={country} price={price}/>
|
||||
})
|
||||
}
|
||||
</Row>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default AgreementOptions;
|
||||
20
client-wiaas/src/containers/coMarket/components/CartIcon.jsx
Normal file
20
client-wiaas/src/containers/coMarket/components/CartIcon.jsx
Normal file
@@ -0,0 +1,20 @@
|
||||
import React, {Component} from 'react';
|
||||
|
||||
class CartIcon extends Component {
|
||||
render() {
|
||||
const cartCount = parseInt(this.props.cartCount, 10);
|
||||
|
||||
return (
|
||||
<span className="items-cart-count">
|
||||
{ cartCount === 0
|
||||
? <span>Cart is empty</span>
|
||||
: cartCount === 1
|
||||
? <span>1 item in cart</span>
|
||||
: <span>{cartCount} items in cart</span>
|
||||
}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default CartIcon;
|
||||
@@ -0,0 +1,83 @@
|
||||
import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import Select from 'react-select';
|
||||
import {fetchShopPackages, fetchShopCommercialLeads, selectCommercialLead} from '../../../actions/coMarket/coMarketPackagesActions';
|
||||
import {coMarketTexts} from '../../../constants/coMarketConstants';
|
||||
|
||||
class CoMarketCatalogSelect extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.handleClChange = this.handleClChange.bind(this);
|
||||
this.handleSearchChange = this.handleSearchChange.bind(this);
|
||||
this.state = {
|
||||
searchValue : ''
|
||||
};
|
||||
|
||||
}
|
||||
componentDidMount() {
|
||||
this.props.dispatch(fetchShopCommercialLeads());
|
||||
|
||||
if(this.props.commercialLeads && this.props.cartItems && this.props.activeModule==='cart'){
|
||||
const cl = this.props.commercialLeads.find((cl) => {return cl.idCommercialLead===this.props.cartItems[0].idCommercialLead});
|
||||
this.props.dispatch(selectCommercialLead(cl));
|
||||
}
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps){
|
||||
if(nextProps.activeModule==='cart' && nextProps.commercialLeads && nextProps.cartItems && nextProps.cartItems.length > 0){
|
||||
const cl = nextProps.commercialLeads.find((cl) => {return cl.idCommercialLead===nextProps.cartItems[0].idCommercialLead});
|
||||
nextProps.dispatch(selectCommercialLead(cl));
|
||||
}
|
||||
|
||||
if(nextProps.commercialLeads && nextProps.idCommercialLead && nextProps.activeModule === 'co-market'){
|
||||
const cl = nextProps.commercialLeads.find((cl) => {return cl.idCommercialLead===nextProps.idCommercialLead});
|
||||
nextProps.dispatch(selectCommercialLead(cl));
|
||||
}
|
||||
}
|
||||
|
||||
handleClChange(cl) {
|
||||
this.props.dispatch(selectCommercialLead(cl));
|
||||
this.props.dispatch(fetchShopPackages(cl));
|
||||
}
|
||||
|
||||
handleSearchChange(event) {
|
||||
this.setState({searchValue: event.target.value});
|
||||
this.props.dispatch(fetchShopPackages(this.props.selectedCommercialLead, event.target.value));
|
||||
}
|
||||
|
||||
render() {
|
||||
const {commercialLeads, selectedCommercialLead, idPackage, activeSubmodule} = this.props;
|
||||
const isDisabled = (idPackage || this.props.activeModule === 'cart') ? true : false;
|
||||
|
||||
return (
|
||||
<div id="co-market-catalog">
|
||||
{
|
||||
commercialLeads && activeSubmodule !== 'orders' &&
|
||||
<div className="filters co-market-nav-div">
|
||||
<div className="filter-name">{coMarketTexts.labels.CATALOGUE}:</div>
|
||||
<Select value={selectedCommercialLead}
|
||||
name="commercialLead"
|
||||
className="filter-select"
|
||||
placeholder={coMarketTexts.labels.SELECT_CL}
|
||||
options={commercialLeads}
|
||||
disabled={isDisabled}
|
||||
clearable={false}
|
||||
onChange={(cl) => {this.handleClChange(cl)}}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
commercialLeads: state.coMarketPackagesReducer.commercialLeads,
|
||||
selectedCommercialLead: state.coMarketPackagesReducer.selectedCommercialLead,
|
||||
idPackage: state.coMarketReducer.idPackage,
|
||||
cartItems: state.cartReducer.cartItems,
|
||||
activeSubmodule: state.pageReducer.activeSubmodule
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps)(CoMarketCatalogSelect);
|
||||
@@ -0,0 +1,61 @@
|
||||
import React, {Component} from 'react';
|
||||
import {Col} from 'reactstrap';
|
||||
import {API_SERVER} from '../../../config';
|
||||
import FileDownloader from '../../../helpers/FileDownloader';
|
||||
import {coMarketTexts} from '../../../constants/coMarketConstants';
|
||||
|
||||
const fileHandler = new FileDownloader();
|
||||
|
||||
class PackageInfo extends Component {
|
||||
downloadDocument(document){
|
||||
const fileUrl = `${API_SERVER}/utils/api/downloadFile?idDocument=${document.idDocument}&fileName=${document.documentName}.${document.extension}`
|
||||
const fileName = document.documentName + '.' + document.extension;
|
||||
fileHandler.download(fileUrl, fileName);
|
||||
}
|
||||
|
||||
render() {
|
||||
const {packageInfo, documents} = this.props;
|
||||
|
||||
return (
|
||||
<div id="shop-package-general-info" className="shop-package-general-info">
|
||||
{ packageInfo &&
|
||||
<span>
|
||||
<Col lg="12"
|
||||
className="shop-package-title"><h4>{packageInfo.name}</h4></Col>
|
||||
<Col lg="12"
|
||||
className="shop-package-reference"><h6>{packageInfo.reference}</h6></Col>
|
||||
<Col lg="12"
|
||||
dangerouslySetInnerHTML={{__html: packageInfo.shortDescription}}
|
||||
className="shop-package-full-description"></Col>
|
||||
<Col lg="12"
|
||||
className="shop-package-details-country">
|
||||
<div className="shop-package-label">{coMarketTexts.labels.AVAILABLE_IN}:</div>
|
||||
<div className="shop-package-text">
|
||||
{packageInfo.country} <span className={'flag-icon flag-icon-' + packageInfo.countryCode}></span>
|
||||
</div>
|
||||
</Col>
|
||||
</span>
|
||||
}
|
||||
{
|
||||
documents && documents.length > 0 &&
|
||||
<Col lg="12"
|
||||
className="shop-package-details-documents">
|
||||
<div className="shop-package-label">{coMarketTexts.labels.DOCUMENTS}:</div>
|
||||
{
|
||||
documents.map((document) =>
|
||||
<div key={document.idDocument}>
|
||||
<span className="document-link"
|
||||
onClick={() => {this.downloadDocument(document)}}>
|
||||
<i className="fa fa-file" aria-hidden="true"></i> {document.documentName} ({document.extension})
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</Col>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default PackageInfo;
|
||||
@@ -0,0 +1,123 @@
|
||||
import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import {Label, Popover, PopoverBody, Input, Col} from 'reactstrap';
|
||||
import {selectOption} from '../../../actions/coMarket/coMarketPackageDetailsActions';
|
||||
import PriceHelper from '../../../helpers/coMarket/PriceHelper';
|
||||
import {coMarketTexts} from '../../../constants/coMarketConstants';
|
||||
|
||||
const priceHelper = new PriceHelper();
|
||||
|
||||
class PackageOptionItem extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.toggle = this.toggle.bind(this);
|
||||
this.handleOptionChange = this.handleOptionChange.bind(this);
|
||||
|
||||
this.state = {
|
||||
popoverOpen: false
|
||||
};
|
||||
}
|
||||
|
||||
toggle() {
|
||||
this.setState({
|
||||
popoverOpen: !this.state.popoverOpen
|
||||
});
|
||||
}
|
||||
|
||||
handleOptionChange() {
|
||||
this.props.dispatch(selectOption(this.props.idGroup, this.props.option));
|
||||
}
|
||||
|
||||
isChecked() {
|
||||
return this.props.selectedOptions
|
||||
&& this.props.selectedOptions[this.props.idGroup]
|
||||
&& this.props.selectedOptions[this.props.idGroup].idOptionPackage === this.props.option.idOptionPackage;
|
||||
}
|
||||
|
||||
getClass(isChecked) {
|
||||
return isChecked ?
|
||||
'selected-option' :
|
||||
'';
|
||||
}
|
||||
|
||||
formatName(name) {
|
||||
return name.length > 39 ? name.substring(0, 40) + '...' : name;
|
||||
}
|
||||
|
||||
render() {
|
||||
const {idGroup, option, country} = this.props;
|
||||
const selectedPrice = this.props.selectedAgreement ? priceHelper.getSelectedPrice(option, this.props.selectedAgreement) : null;
|
||||
const isChecked = this.isChecked();
|
||||
|
||||
return (
|
||||
<Col xl="4" lg="4" md="6" xs="6" className="option-value">
|
||||
<div className={'form-check-inline option-selection ' + this.getClass(isChecked)}>
|
||||
<Label check>
|
||||
<Input type="radio"
|
||||
name={'package-option-'+ idGroup}
|
||||
className="package-option-input"
|
||||
onChange={this.handleOptionChange}
|
||||
checked={isChecked}
|
||||
value={option.idOptionPackage}/>
|
||||
<div className="option-name">{this.formatName(option.optionName)}</div>
|
||||
<div className="option-description" dangerouslySetInnerHTML={{__html: option.shortDescription}}></div>
|
||||
{
|
||||
priceHelper.hasFixedPrice(selectedPrice) &&
|
||||
<div className="option-prices">
|
||||
<table className="price-table option-price-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{coMarketTexts.labels.ON_DELIVERY}</th>
|
||||
<th>{coMarketTexts.labels.MONTHLY}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>{selectedPrice.fixedExtra && selectedPrice.fixedExtra.toLocaleString() + ' ' + country.currency} </td>
|
||||
<td>
|
||||
{
|
||||
priceHelper.hasRecurrentPrice(selectedPrice) ?
|
||||
<div className="option-value-text monthly-price">
|
||||
{priceHelper.sumPrices([selectedPrice.recurentExtra, selectedPrice.servicesExtra]).toLocaleString()} {country.currency}
|
||||
</div>
|
||||
: <div className="option-value-text monthly-price"> 0 </div>
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
}
|
||||
</Label>
|
||||
{
|
||||
!selectedPrice &&
|
||||
<Label>
|
||||
<div className="not-available">
|
||||
({coMarketTexts.labels.NOT_AVAILABLE})
|
||||
<i className="price-info-btn fa fa-info-circle"
|
||||
aria-hidden="true"
|
||||
id={'info-option-' + idGroup + '-' + option.idOptionPackage}
|
||||
onClick={this.toggle}></i>
|
||||
</div>
|
||||
</Label>
|
||||
}
|
||||
</div>
|
||||
<Popover placement="bottom"
|
||||
isOpen={this.state.popoverOpen}
|
||||
target={'info-option-' + idGroup + '-' + option.idOptionPackage}
|
||||
toggle={this.toggle}>
|
||||
<PopoverBody>
|
||||
{coMarketTexts.labels.SELECTION_NOT_AVAILABLE}
|
||||
</PopoverBody>
|
||||
</Popover>
|
||||
</Col>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
selectedAgreement: state.coMarketPackageDetailsReducer.selectedAgreement,
|
||||
selectedOptions: state.coMarketPackageDetailsReducer.selectedOptions
|
||||
});
|
||||
export default connect(mapStateToProps)(PackageOptionItem);
|
||||
@@ -0,0 +1,35 @@
|
||||
import React, {Component} from 'react';
|
||||
import {Row} from 'reactstrap';
|
||||
import PackageOptionItemContainer from './PackageOptionItemContainer.jsx';
|
||||
import {coMarketTexts} from '../../../constants/coMarketConstants';
|
||||
|
||||
class PackageOptions extends Component {
|
||||
render() {
|
||||
const {groups, country} = this.props;
|
||||
return (
|
||||
<div className="shop-package-options">
|
||||
<h6 className="shop-package-label options-header">{coMarketTexts.labels.PACKAGE_OPTIONS}</h6>
|
||||
{
|
||||
Object.keys(groups).map(groupKey => {
|
||||
const group = groups[groupKey];
|
||||
return <div key={'group-' + group.idGroup} className="package-option">
|
||||
<h6 className="shop-package-label"> {group.groupName}:</h6>
|
||||
<Row>
|
||||
{
|
||||
group.options.map(option => {
|
||||
return <PackageOptionItemContainer key={'option-' + group.idGroup + option.idOptionPackage}
|
||||
option={option}
|
||||
country={country}
|
||||
idGroup={group.idGroup}/>
|
||||
})
|
||||
}
|
||||
</Row>
|
||||
</div>
|
||||
})
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default PackageOptions;
|
||||
@@ -0,0 +1,80 @@
|
||||
import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import {coMarketTexts} from '../../../constants/coMarketConstants';
|
||||
|
||||
class PackagePrice extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.getFinalPrice = this.getFinalPrice.bind(this);
|
||||
this.filterByAgreement = this.filterByAgreement.bind(this);
|
||||
}
|
||||
|
||||
filterByAgreement(price) {
|
||||
return price.idPaymentType === this.props.selectedAgreement.idPaymentType;
|
||||
}
|
||||
|
||||
getExtra(selected, priceType) {
|
||||
const extraPriceObj = selected.prices.find(this.filterByAgreement);
|
||||
const extraPrice = extraPriceObj ? extraPriceObj[priceType] : 0;
|
||||
|
||||
return extraPrice;
|
||||
}
|
||||
|
||||
getFinalPrice(selectedAgreement, selectedOptions, selectedAdditionals, priceType) {
|
||||
let price = selectedAgreement ? selectedAgreement[priceType] : 0;
|
||||
|
||||
if(selectedAgreement && selectedOptions) {
|
||||
Object.keys(selectedOptions).forEach((idGroup) => {
|
||||
price += this.getExtra(selectedOptions[idGroup], priceType);
|
||||
});
|
||||
}
|
||||
if(selectedAgreement && selectedAdditionals) {
|
||||
selectedAdditionals.forEach((additional) => {
|
||||
price += this.getExtra(additional, priceType);
|
||||
});
|
||||
}
|
||||
|
||||
return price;
|
||||
}
|
||||
|
||||
render() {
|
||||
const {country, selectedAgreement, selectedOptions, selectedAdditionals} = this.props;
|
||||
|
||||
return (
|
||||
<div className="selection-price">
|
||||
{
|
||||
selectedAgreement &&
|
||||
<table className="price-table main-price">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{coMarketTexts.labels.ON_DELIVERY}</th>
|
||||
<th>{coMarketTexts.labels.MONTHLY}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
{this.getFinalPrice(selectedAgreement, selectedOptions, selectedAdditionals, 'fixedExtra').toLocaleString()} {country.currency}
|
||||
</td>
|
||||
<td>
|
||||
{(this.getFinalPrice(selectedAgreement, selectedOptions, selectedAdditionals, 'recurentExtra')
|
||||
+ this.getFinalPrice(selectedAgreement, selectedOptions, selectedAdditionals, 'servicesExtra')).toLocaleString()}
|
||||
{' '}{country.currency}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
selectedAgreement: state.coMarketPackageDetailsReducer.selectedAgreement,
|
||||
selectedOptions: state.coMarketPackageDetailsReducer.selectedOptions,
|
||||
selectedAdditionals: state.coMarketPackageDetailsReducer.selectedAdditionals
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps)(PackagePrice);
|
||||
45
client-wiaas/src/containers/coMarket/components/ShopItem.jsx
Normal file
45
client-wiaas/src/containers/coMarket/components/ShopItem.jsx
Normal file
@@ -0,0 +1,45 @@
|
||||
import React, {Component} from 'react';
|
||||
import {Link} from 'react-router-dom';
|
||||
import { Col, Card, CardBody, CardTitle, CardSubtitle, Button} from 'reactstrap';
|
||||
import {coMarketTexts} from '../../../constants/coMarketConstants';
|
||||
|
||||
class ShopItem extends Component {
|
||||
getShopItemPackageTitle(name) {
|
||||
return name.length > 40 ? name.substring(0, 40) + '...' : name;
|
||||
}
|
||||
|
||||
render() {
|
||||
const {shopPackage, idCommercialLead} = this.props;
|
||||
|
||||
return (
|
||||
<Col xl="3" lg="4" md="6" sm="12" xs="12">
|
||||
<Card className="shop-package-item">
|
||||
<div className="shop-image-photo" style={{'background-image': 'url("'+(shopPackage.photo || 'static/img/no-photo-package.jpg') +'")'}}></div>
|
||||
<CardBody>
|
||||
<CardTitle className="shop-package-title">
|
||||
<Link to={`/co-market/${idCommercialLead}/${shopPackage.idPackage}`}>
|
||||
{this.getShopItemPackageTitle(shopPackage.name)}
|
||||
</Link>
|
||||
</CardTitle>
|
||||
<CardSubtitle className="shop-package-reference">
|
||||
{shopPackage.reference}
|
||||
</CardSubtitle>
|
||||
|
||||
<div className="shop-package-country">
|
||||
{coMarketTexts.labels.AVAILABLE_IN}: {shopPackage.country}
|
||||
<span className={'flag-icon flag-icon-' + shopPackage.countryCode}></span>
|
||||
</div>
|
||||
<div className="shop-package-details-btn-layer">
|
||||
<Link id={'shop-package-details-' + shopPackage.idPackage} to={`/co-market/${idCommercialLead}/${shopPackage.idPackage}`}>
|
||||
<Button className="shop-package-details-btn">{coMarketTexts.buttons.DETAILS}</Button>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
</CardBody>
|
||||
</Card>
|
||||
</Col>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default ShopItem;
|
||||
175
client-wiaas/src/containers/coMarket/style/CoMarket.scss
Normal file
175
client-wiaas/src/containers/coMarket/style/CoMarket.scss
Normal file
@@ -0,0 +1,175 @@
|
||||
@import '../../../styleConstants.scss';
|
||||
|
||||
#co-market-shop {
|
||||
.shop-package-title {
|
||||
font-size: 1rem;
|
||||
height: 2rem;
|
||||
}
|
||||
|
||||
.shop-package-title a {
|
||||
font-size: $font-size-msmall;
|
||||
font-weight: $font-weight;
|
||||
text-align: left;
|
||||
color: $header-background;
|
||||
}
|
||||
|
||||
.shop-package-reference {
|
||||
font-size: $font-size-xsmal;
|
||||
font-weight: $font-weight;
|
||||
text-align: left;
|
||||
color: $warmGreyColor;
|
||||
}
|
||||
|
||||
.shop-package-country {
|
||||
display: inline-block;
|
||||
width: 50%;
|
||||
font-size: $font-size-xsmal;
|
||||
text-align: left;
|
||||
color: $warmGreyColor;
|
||||
}
|
||||
|
||||
.shop-package-details-btn-layer{
|
||||
display: inline-block;
|
||||
width: 50%;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.shop-package-details-btn{
|
||||
border-radius: 50px;
|
||||
background-color: $whiteColor;
|
||||
border: solid 0.7px $borderColor;
|
||||
color: $darkBlue;
|
||||
font-weight: $font-weight;
|
||||
font-size: $font-size-xsmal;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.shop-package-item{
|
||||
margin-top: 1rem;
|
||||
border-radius: 4px;
|
||||
background-color: $whiteColor;
|
||||
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.flag-icon{
|
||||
border-radius: 2px;
|
||||
margin-left: 0.2rem;
|
||||
}
|
||||
|
||||
.co-market-nav {
|
||||
font-size: $font-size-msmall;
|
||||
text-align: left;
|
||||
color: $warmGreyColor;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.co-market-nav-buttons{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: $header-background;
|
||||
font-weight: $font-weight;
|
||||
}
|
||||
|
||||
.search-layer{
|
||||
display:flex;
|
||||
align-items:center;
|
||||
}
|
||||
|
||||
.search-layer div{
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.wiaas-input {
|
||||
border-radius: 3.125rem;
|
||||
background-color: $whiteColor;
|
||||
border: solid 1px $borderColor;
|
||||
padding: 0.2rem 1.4rem;
|
||||
font-size: $font-size-xsmal;
|
||||
font-weight: 300;
|
||||
text-align: left;
|
||||
color: $warmGreyColor;
|
||||
}
|
||||
|
||||
input:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.search-package-icon {
|
||||
position: absolute;
|
||||
font-size: $font-size-xsmal;
|
||||
left: 0.4rem;
|
||||
top: 0.3rem;
|
||||
color: $warmGreyColor;
|
||||
}
|
||||
|
||||
.shop-image-photo{
|
||||
width:100%;
|
||||
height:129px;
|
||||
background-size: cover;
|
||||
}
|
||||
}
|
||||
|
||||
#co-market-big-commercial{
|
||||
background: $whiteColor;
|
||||
text-align: center;
|
||||
|
||||
.ricoh-text {
|
||||
color: $ricohRed;
|
||||
}
|
||||
|
||||
.description-photo{
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
#co-market-commercials {
|
||||
background: $whiteColor;
|
||||
|
||||
.commercial-photo {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
#co-market-catalog {
|
||||
.filter-name {
|
||||
margin-top: 0.4rem;
|
||||
font-size: $font-size-normal;
|
||||
display: inline-block;
|
||||
margin-right: 0.2rem;
|
||||
font-weight: $font-weight;
|
||||
}
|
||||
|
||||
.filter-select{
|
||||
display: inline-block;
|
||||
width: 21rem;
|
||||
vertical-align: top;
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (max-width: 767px) {
|
||||
.co-market-nav-div {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
margin: 0.5rem 0;
|
||||
font-size: $font-size-normal;
|
||||
}
|
||||
|
||||
.wiaas-input {
|
||||
font-size: $font-size-normal;
|
||||
}
|
||||
|
||||
#co-market-shop {
|
||||
.shop-package-title a {
|
||||
font-size: $font-size-big;
|
||||
}
|
||||
|
||||
.shop-package-reference, .shop-package-country{
|
||||
font-size: $font-size-normal;
|
||||
}
|
||||
|
||||
.shop-package-details-btn{
|
||||
font-size: $font-size-xbig;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
@import '../../../styleConstants.scss';
|
||||
|
||||
#co-market-package-details{
|
||||
background: $whiteColor;
|
||||
border-radius: $box-radius;
|
||||
}
|
||||
|
||||
#shop-package-general-info {
|
||||
padding: 2rem;
|
||||
|
||||
.shop-package-title {
|
||||
font-size: $font-size-big;
|
||||
text-align: center;
|
||||
font-weight: $font-weight;
|
||||
}
|
||||
|
||||
.shop-package-reference {
|
||||
margin-bottom: 5%;
|
||||
text-align: center;
|
||||
font-weight: $font-weight;
|
||||
font-size: $font-size-normal;
|
||||
color: $darkGreyColor;
|
||||
}
|
||||
|
||||
.shop-package-full-description {
|
||||
font-size: $font-size-normal;
|
||||
overflow: auto;
|
||||
min-height: 15rem;
|
||||
max-height: 30rem;
|
||||
}
|
||||
|
||||
.shop-package-label{
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.shop-package-text {
|
||||
display: inline-block;
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
.shop-package-details-country{
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.shop-package-details-documents{
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.document-link{
|
||||
color: #33425b;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
#shop-package-buy-info{
|
||||
padding: 2rem;
|
||||
|
||||
.shop-package-options{
|
||||
margin: 1rem 0;
|
||||
border-bottom: 2px solid $title-color;
|
||||
}
|
||||
|
||||
.not-available {
|
||||
margin-top: 1rem;
|
||||
margin-left: 0.2rem;
|
||||
color: $not-available-status-color;
|
||||
font-weight: $font-weight;
|
||||
font-size: $font-size-msmall;
|
||||
}
|
||||
|
||||
.price-info-btn {
|
||||
color: $info-color;
|
||||
cursor: pointer;
|
||||
margin-left: 0.2rem;
|
||||
}
|
||||
|
||||
.add-to-cart-btn {
|
||||
cursor: pointer;
|
||||
color: $darkGreyColor;
|
||||
background-color: $whiteColor;
|
||||
border-color:$warmGreyColor;
|
||||
|
||||
}
|
||||
|
||||
.selected-option {
|
||||
font-weight: $font-weight;
|
||||
background: $hoverColor;
|
||||
border-radius: $box-radius;
|
||||
}
|
||||
|
||||
.option-selection {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.option-selection:hover {
|
||||
background: $footer-background;
|
||||
color: $whiteColor;
|
||||
border-radius: $box-radius;
|
||||
}
|
||||
|
||||
.option-selection:hover .price-info-btn {
|
||||
color: $whiteColor;
|
||||
}
|
||||
|
||||
.option-name {
|
||||
font-size: $font-size-msmall;
|
||||
height: 2rem;
|
||||
}
|
||||
|
||||
.option-description {
|
||||
padding-top: 0.5rem;
|
||||
font-size: $font-size-msmall;
|
||||
height: 2rem;
|
||||
}
|
||||
|
||||
.price-info-popover {
|
||||
max-width: 50rem;
|
||||
}
|
||||
|
||||
.recurent-total-price{
|
||||
font-size: $font-size-msmall;
|
||||
}
|
||||
|
||||
.selection-price{
|
||||
background: $hoverColor;
|
||||
display: inline-block;
|
||||
border-radius: $box-radius;
|
||||
font-size: $font-size-big;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.option-prices {
|
||||
margin-top: 0.5rem;
|
||||
border-radius: $box-radius;
|
||||
}
|
||||
|
||||
.price-table {
|
||||
width: 8rem;
|
||||
}
|
||||
|
||||
.main-price {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.price-table th{
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.price-table td{
|
||||
border-top: 1px solid $darkGreyColor;
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.option-price-table{
|
||||
font-size: $font-size-xsmal;
|
||||
}
|
||||
}
|
||||
42
client-wiaas/src/containers/contentContainer.scss
Normal file
42
client-wiaas/src/containers/contentContainer.scss
Normal file
@@ -0,0 +1,42 @@
|
||||
@import '../styleConstants.scss';
|
||||
|
||||
.App-header {
|
||||
min-height: 7.2rem;
|
||||
}
|
||||
|
||||
.wiaas-button{
|
||||
background-color: $whiteColor;
|
||||
color: $darkGreyColor;
|
||||
font-size: $font-size-small;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.main-wrapper {
|
||||
position: relative;
|
||||
padding: 7.5rem 0 5rem 0;
|
||||
}
|
||||
|
||||
.loader{
|
||||
padding-top: 1rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.schedule-installation-btn {
|
||||
cursor: pointer;
|
||||
background-color: $whiteColor;
|
||||
color: $darkGreyColor;
|
||||
border: 0.1rem $border-grey solid;
|
||||
display: inline-block;
|
||||
border-radius: $box-radius;
|
||||
font-weight: $font-weight;
|
||||
}
|
||||
|
||||
@media all and (max-width: 992px) {
|
||||
.main-wrapper {
|
||||
padding: 0 0 5rem 0;
|
||||
}
|
||||
|
||||
.app-content{
|
||||
min-height: 400px;
|
||||
}
|
||||
}
|
||||
19
client-wiaas/src/containers/dashboard/Dashboards.scss
Normal file
19
client-wiaas/src/containers/dashboard/Dashboards.scss
Normal file
@@ -0,0 +1,19 @@
|
||||
@import '../../styleConstants.scss';
|
||||
|
||||
.order-placed-message {
|
||||
padding: 0.5rem 1rem;
|
||||
}
|
||||
|
||||
#dashboard-container {
|
||||
.dashborad-message {
|
||||
padding: 2rem;
|
||||
background: $whiteColor;
|
||||
color: $darkGreyColor;
|
||||
font-weight: $font-weight;
|
||||
}
|
||||
|
||||
.dashborad-message a {
|
||||
color: $darkGreyColor;
|
||||
font-weight: $font-weight;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import {Container, Row, Alert, Col} from 'reactstrap';
|
||||
import OrderCentralContainer from './OrderCentralContainer.jsx';
|
||||
import NextActionsContainer from './NextActionsContainer.jsx';
|
||||
import {fetchGadgets} from '../../actions/dashboard/dashboardActions';
|
||||
import {setOrderPlacedFlag, setOrderPlacedRedirectFlag} from '../../actions/cart/cartActions';
|
||||
import {dashboardTexts} from '../../constants/dashboardConstants';
|
||||
import './Dashboards.css';
|
||||
|
||||
const gadgetContainers = {
|
||||
CustomerOrderCentral : OrderCentralContainer,
|
||||
CustomerNextActions: NextActionsContainer
|
||||
}
|
||||
|
||||
class DashboardsContainer extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
orderPlaced: this.props.orderPlaced || false,
|
||||
redirect: this.props.orderPlacedRedirect || true
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.props.dispatch(fetchGadgets());
|
||||
if(this.state.orderPlaced && this.state.redirect) {
|
||||
this.setState({redirect: false});
|
||||
this.props.dispatch(setOrderPlacedRedirectFlag(false));
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const {gadgets} = this.props;
|
||||
|
||||
if(this.state.orderPlaced) {
|
||||
setTimeout(() => {
|
||||
this.setState({orderPlaced: false});
|
||||
this.props.dispatch(setOrderPlacedFlag(false));
|
||||
}, 15000);
|
||||
}
|
||||
|
||||
return (
|
||||
<div id="dashboard-container">
|
||||
<Container fluid={true} id="dashborad-gadgets">
|
||||
<Row>
|
||||
{
|
||||
this.state.orderPlaced &&
|
||||
<Col>
|
||||
<Alert color="success" className="order-placed-message">
|
||||
{dashboardTexts.messages.ORDER_PLACED}
|
||||
</Alert>
|
||||
</Col>
|
||||
}
|
||||
</Row>
|
||||
<Row>
|
||||
{
|
||||
gadgets &&
|
||||
gadgets.map((gadget, Key) => {
|
||||
const containerKey = gadget.name.replace(/\s/g, '');
|
||||
if(gadgetContainers[containerKey]){
|
||||
const TagName = gadgetContainers[containerKey];
|
||||
return <TagName key={gadget.idGadget} gadget={gadget}/>;
|
||||
}
|
||||
|
||||
return '';
|
||||
})
|
||||
}
|
||||
</Row>
|
||||
</Container>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
gadgets: state.dashboardReducer.gadgets,
|
||||
orderPlaced: state.cartReducer.orderPlaced,
|
||||
orderPlacedRedirect: state.cartReducer.orderPlacedRedirect
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps)(DashboardsContainer);
|
||||
46
client-wiaas/src/containers/dashboard/NextActions.scss
Normal file
46
client-wiaas/src/containers/dashboard/NextActions.scss
Normal file
@@ -0,0 +1,46 @@
|
||||
@import '../../styleConstants.scss';
|
||||
|
||||
#next-actions-gadget{
|
||||
.next-actions-row {
|
||||
font-size: $font-size-small;
|
||||
font-weight: $font-weight;
|
||||
text-align: left;
|
||||
color: $darkGreyColor;
|
||||
padding: 1rem 0;
|
||||
}
|
||||
|
||||
.next-actions-status {
|
||||
display: inline-block;
|
||||
border-radius: $box-radius;
|
||||
margin-left: 0.5rem;
|
||||
font-size: $font-size-xsmal;
|
||||
padding: 0.1rem 0.3rem;
|
||||
color: $whiteColor;
|
||||
cursor: pointer;
|
||||
border: 1px solid $whiteColor;
|
||||
}
|
||||
|
||||
.next-actions-status:hover{
|
||||
border: 1px solid $darkGreyColor;
|
||||
}
|
||||
|
||||
.invalid {
|
||||
background: $invalid-status-color;
|
||||
}
|
||||
|
||||
.pending {
|
||||
background: $pending-status-color;
|
||||
}
|
||||
|
||||
.not-accepted {
|
||||
background: $not-accepted-status-color;
|
||||
}
|
||||
|
||||
.in-progress {
|
||||
background: $in-progress-status-color;
|
||||
}
|
||||
|
||||
.next-action-details{
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import {Col} from 'reactstrap';
|
||||
import {fetchNextActions} from '../../actions/dashboard/nextActionsActions';
|
||||
import WiaasBox from '../../mainComponents/box/WiaasBox.jsx';
|
||||
import NextActionsList from './components/NextActionsList.jsx';
|
||||
import {dashboardTexts} from '../../constants/dashboardConstants';
|
||||
import './NextActions.css';
|
||||
|
||||
class NextActionsContainer extends Component {
|
||||
componentDidMount() {
|
||||
this.props.dispatch(fetchNextActions());
|
||||
}
|
||||
|
||||
render() {
|
||||
const {nextActions, isLoading} = this.props;
|
||||
|
||||
return (<Col xl="4" lg="4" md="12" sm="12" xs="12">
|
||||
<WiaasBox id="next-actions-gadget" mainTitle={dashboardTexts.labels.NEXT_ACTIONS}>
|
||||
{
|
||||
isLoading &&
|
||||
<div className="loader">
|
||||
<i className="fa fa-spinner fa-spin fa-3x" aria-hidden="true"></i>
|
||||
</div>
|
||||
}
|
||||
{
|
||||
(nextActions && nextActions.length > 0 && !isLoading) ?
|
||||
<NextActionsList nextActions={nextActions}/> :
|
||||
<div className="dashborad-message">{dashboardTexts.labels.NO_ACTIONS}</div>
|
||||
}
|
||||
</WiaasBox>
|
||||
</Col>);
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
nextActions: state.nextActionsReducer.nextActions,
|
||||
isLoading: state.nextActionsReducer.isLoading
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps)(NextActionsContainer);
|
||||
45
client-wiaas/src/containers/dashboard/OrderCentral.scss
Normal file
45
client-wiaas/src/containers/dashboard/OrderCentral.scss
Normal file
@@ -0,0 +1,45 @@
|
||||
@import '../../styleConstants.scss';
|
||||
|
||||
#order-central-gadget {
|
||||
.order-central-row {
|
||||
border-radius: 1.5px;
|
||||
}
|
||||
|
||||
.package-photo{
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
.orderNumber{
|
||||
display: inline-block;
|
||||
bottom: 0;
|
||||
font-size: $font-size-msmall;
|
||||
|
||||
a {
|
||||
color: $darkGreyColor;
|
||||
}
|
||||
}
|
||||
|
||||
.status-icon {
|
||||
width: $font-size-xsmal;
|
||||
height: $font-size-xsmal;
|
||||
display: inline-block;
|
||||
border-radius: 50%;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
.open {
|
||||
background: $open-status-color;
|
||||
}
|
||||
|
||||
.in-progress {
|
||||
background: $in-progress-status-color;
|
||||
}
|
||||
|
||||
.line-open {
|
||||
border-left: 3px $open-status-color solid;
|
||||
}
|
||||
|
||||
.line-in-progress {
|
||||
border-left: 3px $in-progress-status-color solid;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import {Col} from 'reactstrap';
|
||||
import {Link} from 'react-router-dom';
|
||||
import {fetchOrders} from '../../actions/dashboard/ordersActions';
|
||||
import WiaasBox from '../../mainComponents/box/WiaasBox.jsx';
|
||||
import OrdersList from './components/OrdersList.jsx';
|
||||
import OrderListHeader from '../orders/components/OrderListHeader.jsx';
|
||||
import {dashboardTexts} from '../../constants/dashboardConstants';
|
||||
import './OrderCentral.css';
|
||||
|
||||
const type = 'overview';
|
||||
|
||||
class OrderCentralContainer extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
orders: [],
|
||||
isViewAllOrdersChecked: false
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.props.dispatch(fetchOrders());
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if(nextProps.isViewAllOrdersChecked[type] !== this.state.isViewAllOrdersChecked) {
|
||||
this.setState({
|
||||
isViewAllOrdersChecked: nextProps.isViewAllOrdersChecked[type] || false
|
||||
});
|
||||
this.props.dispatch(fetchOrders(nextProps.isViewAllOrdersChecked[type]));
|
||||
}
|
||||
this.setState({
|
||||
orders: nextProps.orders
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const {isLoading} = this.props;
|
||||
|
||||
return (<Col xl="8" lg="8" md="12" sm="12" xs="12">
|
||||
<WiaasBox id="order-central-gadget" mainTitle={dashboardTexts.labels.ORDER_CENTRAL} customHeader={OrderListHeader} customHeaderParams={type}>
|
||||
{
|
||||
isLoading &&
|
||||
<div className="loader">
|
||||
<i className="fa fa-spinner fa-spin fa-3x" aria-hidden="true"></i>
|
||||
</div>
|
||||
}
|
||||
{
|
||||
(this.state.orders && this.state.orders.length > 0 && !isLoading) ?
|
||||
<OrdersList orders={this.state.orders} isViewAllOrdersChecked={this.props.isViewAllOrdersChecked[type]}/> :
|
||||
<div className="dashborad-message">
|
||||
<Link to='/co-market'>{dashboardTexts.labels.NO_ORDERS}</Link>
|
||||
</div>
|
||||
}
|
||||
</WiaasBox>
|
||||
</Col>);
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
orders: state.ordersCentralReducer.orders,
|
||||
isLoading: state.ordersCentralReducer.isLoading,
|
||||
isViewAllOrdersChecked: state.ordersReducer.isViewAllOrdersChecked
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps)(OrderCentralContainer);
|
||||
@@ -0,0 +1,25 @@
|
||||
import React, {Component} from 'react';
|
||||
import {Link} from 'react-router-dom';
|
||||
import {Col, Row} from 'reactstrap';
|
||||
import {dashboardTexts} from '../../../constants/dashboardConstants';
|
||||
|
||||
class NextActionItem extends Component {
|
||||
render() {
|
||||
const {nextAction} = this.props;
|
||||
|
||||
return (
|
||||
<Row className="next-actions-row">
|
||||
<Col xl="8">
|
||||
{nextAction.stepAction}
|
||||
</Col>
|
||||
<Col xl="4">
|
||||
<Link to={'orders/'+ nextAction.idOrder}>
|
||||
<div className={'next-actions-status ' + nextAction.status}>{dashboardTexts.statuses[nextAction.status]}</div>
|
||||
</Link>
|
||||
</Col>
|
||||
</Row>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default NextActionItem;
|
||||
@@ -0,0 +1,27 @@
|
||||
import React, {Component} from 'react';
|
||||
import NextActionItem from './NextActionItem';
|
||||
import {WiaasTable, WiaasTableBody} from '../../../mainComponents/table/WiaasTable.jsx';
|
||||
|
||||
class NextActionsList extends Component {
|
||||
|
||||
render() {
|
||||
const {nextActions} = this.props;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<WiaasTable>
|
||||
<WiaasTableBody>
|
||||
{
|
||||
nextActions &&
|
||||
nextActions.map((nextAction, index) =>
|
||||
<NextActionItem key={'action-' + nextAction.orderNumber + index} nextAction={nextAction}/>
|
||||
)
|
||||
}
|
||||
</WiaasTableBody>
|
||||
</WiaasTable>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default NextActionsList;
|
||||
@@ -0,0 +1,34 @@
|
||||
import React, {Component} from 'react';
|
||||
import {Link} from 'react-router-dom';
|
||||
import {Button} from 'reactstrap';
|
||||
import { WiaasTableRow, WiaasTableCol} from '../../../mainComponents/table/WiaasTable.jsx';
|
||||
import {dashboardTexts} from '../../../constants/dashboardConstants';
|
||||
|
||||
class OrderItem extends Component {
|
||||
render() {
|
||||
const {order, isViewAllOrdersChecked} = this.props;
|
||||
|
||||
return (
|
||||
<WiaasTableRow className={'order-central-row line-' + order.status}>
|
||||
<WiaasTableCol header="#">
|
||||
<i className="fa fa-list-alt package-photo" aria-hidden="true" />
|
||||
<div className="orderNumber">{order.orderNumber}</div>
|
||||
</WiaasTableCol>
|
||||
<WiaasTableCol header={dashboardTexts.tableHeaders.ORDER_DATE}>{order.orderDate}</WiaasTableCol>
|
||||
{
|
||||
isViewAllOrdersChecked &&
|
||||
<WiaasTableCol header={dashboardTexts.tableHeaders.PLACED_BY}>{order.placedBy}</WiaasTableCol>
|
||||
}
|
||||
<WiaasTableCol header={dashboardTexts.tableHeaders.REFERENCE}>{order.reference}</WiaasTableCol>
|
||||
<WiaasTableCol header={dashboardTexts.tableHeaders.ON_DELIVERY}>{order.fixedPrice.toLocaleString()} {order.currency}</WiaasTableCol>
|
||||
<WiaasTableCol header={dashboardTexts.tableHeaders.MONTHLY}>{order.recurringPrice.toLocaleString()} {order.currency}</WiaasTableCol>
|
||||
<WiaasTableCol header={dashboardTexts.tableHeaders.STATUS}>
|
||||
<div className={'status-icon ' + order.status}></div>{dashboardTexts.statuses[order.status]}
|
||||
</WiaasTableCol>
|
||||
<WiaasTableCol><Link to={'orders/'+ order.idOrder}><Button className="wiaas-button">{dashboardTexts.buttons.DETAILS}</Button></Link></WiaasTableCol>
|
||||
</WiaasTableRow>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default OrderItem;
|
||||
@@ -0,0 +1,59 @@
|
||||
import React, {Component} from 'react';
|
||||
import OrderItem from './OrderItem';
|
||||
import {WiaasTable, WiaasTableHeader, WiaasTableBody} from '../../../mainComponents/table/WiaasTable.jsx';
|
||||
import {dashboardTexts} from '../../../constants/dashboardConstants';
|
||||
|
||||
class OrdersList extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
isViewAllOrdersChecked: this.props.isViewAllOrdersChecked || false
|
||||
};
|
||||
this.getHeaderForOrders = this.getHeaderForOrders.bind(this);
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
this.setState({isViewAllOrdersChecked: nextProps.isViewAllOrdersChecked});
|
||||
}
|
||||
|
||||
getHeaderForOrders() {
|
||||
const headers = [
|
||||
dashboardTexts.tableHeaders.ORDER,
|
||||
dashboardTexts.tableHeaders.ORDER_DATE,
|
||||
dashboardTexts.tableHeaders.REFERENCE,
|
||||
dashboardTexts.tableHeaders.ON_DELIVERY,
|
||||
dashboardTexts.tableHeaders.MONTHLY,
|
||||
dashboardTexts.tableHeaders.STATUS,
|
||||
''
|
||||
];
|
||||
if(this.state.isViewAllOrdersChecked) {
|
||||
headers.splice(2, 0, dashboardTexts.tableHeaders.PLACED_BY);
|
||||
headers.join();
|
||||
}
|
||||
|
||||
return headers;
|
||||
}
|
||||
|
||||
render() {
|
||||
const {orders, isViewAllOrdersChecked} = this.props;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<WiaasTable>
|
||||
<WiaasTableHeader headers={this.getHeaderForOrders()}/>
|
||||
<WiaasTableBody>
|
||||
{
|
||||
orders &&
|
||||
orders.map((order, index) =>
|
||||
<OrderItem key={'order-' + order.orderNumber} order={order} isViewAllOrdersChecked={isViewAllOrdersChecked}/>
|
||||
)
|
||||
}
|
||||
</WiaasTableBody>
|
||||
</WiaasTable>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default OrdersList;
|
||||
17
client-wiaas/src/containers/footer/Footer.jsx
Normal file
17
client-wiaas/src/containers/footer/Footer.jsx
Normal file
@@ -0,0 +1,17 @@
|
||||
import React, {Component} from 'react';
|
||||
import TermsContainer from '../terms/TermsContainer.jsx';
|
||||
import './style/Footer.css';
|
||||
|
||||
class Footer extends Component {
|
||||
render() {
|
||||
return (
|
||||
<footer className="App-footer">
|
||||
<div className="footer-buttons">
|
||||
<TermsContainer />
|
||||
</div>
|
||||
</footer>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Footer;
|
||||
12
client-wiaas/src/containers/footer/style/Footer.scss
Normal file
12
client-wiaas/src/containers/footer/style/Footer.scss
Normal file
@@ -0,0 +1,12 @@
|
||||
@import '../../../styleConstants.scss';
|
||||
|
||||
footer {
|
||||
.footer-btn {
|
||||
cursor: pointer;
|
||||
color: $whiteColor;
|
||||
}
|
||||
}
|
||||
|
||||
.modal-dialog{
|
||||
max-width: 80%;
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import {Link, Redirect} from 'react-router-dom';
|
||||
import {
|
||||
Alert,
|
||||
Form,
|
||||
FormGroup,
|
||||
Label,
|
||||
Input,
|
||||
Button
|
||||
} from 'reactstrap';
|
||||
import {changePassword} from '../../actions/login/authActions';
|
||||
import {loginMessages, loginTexts} from '../../constants/authConstants';
|
||||
|
||||
class ChangePasswordContainer extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
credentials: {
|
||||
password: '',
|
||||
repassword: ''
|
||||
}
|
||||
};
|
||||
|
||||
this.handleChange = this.handleChange.bind(this);
|
||||
this.handleSubmit = this.handleSubmit.bind(this);
|
||||
}
|
||||
|
||||
handleChange(event) {
|
||||
const field = event.target.name;
|
||||
const credentials = this.state.credentials;
|
||||
credentials[field] = event.target.value;
|
||||
return this.setState({credentials: credentials});
|
||||
}
|
||||
|
||||
handleSubmit(event) {
|
||||
const token = this.props.match && this.props.match.params ? this.props.match.params.token : '';
|
||||
event.preventDefault();
|
||||
this.props.dispatch(changePassword(token, this.state.credentials.password, this.state.credentials.repassword));
|
||||
}
|
||||
|
||||
render() {
|
||||
const {isPasswordChanged} = this.props;
|
||||
|
||||
return (<div className="chnage-password">
|
||||
{
|
||||
isPasswordChanged && <Redirect push to="/"/>
|
||||
}
|
||||
<Form onSubmit={this.handleSubmit}>
|
||||
<FormGroup className="sign-in">{loginTexts.labels.CHANGE_PASSWORD}</FormGroup>
|
||||
|
||||
<FormGroup className="login-input-group">
|
||||
<Label className="login-input-text" for="password">{loginTexts.labels.NEW_PASSWORD}</Label>
|
||||
<Input className="base" type="password" name="password" id="password" placeholder={loginTexts.labels.NEW_PASSWORD} value={this.state.password} onChange={this.handleChange} autoFocus />
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup className="login-input-group">
|
||||
<Label className="login-input-text" for="repassword">{loginTexts.labels.CONFIRM_PASSWORD}</Label>
|
||||
<Input className="base" type="password" name="repassword" id="repassword" placeholder={loginTexts.labels.CONFIRM_PASSWORD} value={this.state.repassword} onChange={this.handleChange} />
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup className="login-form-group">
|
||||
<Button className="base-sign-in" type="submit" id="change-button">{loginTexts.buttons.CHANGE_PASSWORD}</Button>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup className="login-form-group" id="login-message">
|
||||
{loginMessages[this.props.errorMessage] && <Alert className='alert-form wiaas-alert' color={this.props.messageColor}>{loginMessages[this.props.errorMessage]}</Alert>}
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup className="login-input-group">
|
||||
<hr className="divider"/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup className="login-input-group">
|
||||
<Link to={'/'}>
|
||||
<Button className="forgot-password">{loginTexts.buttons.BACK_TO_SIGNIN}</Button>
|
||||
</Link>
|
||||
</FormGroup>
|
||||
</Form>
|
||||
</div>);
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
errorMessage: state.auth.errorMessage,
|
||||
messageColor: state.auth.messageColor,
|
||||
isPasswordChanged: state.auth.isPasswordChanged
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps)(ChangePasswordContainer);
|
||||
91
client-wiaas/src/containers/login/LogInContainer.jsx
Normal file
91
client-wiaas/src/containers/login/LogInContainer.jsx
Normal file
@@ -0,0 +1,91 @@
|
||||
import React, {Component} from 'react';
|
||||
import {Switch, Route} from 'react-router-dom';
|
||||
import Particles from 'react-particles-js';
|
||||
import {BrowserRouter} from 'react-router-dom';
|
||||
import logoDefault from '../../svg/logoDefault.svg';
|
||||
import {
|
||||
Row,
|
||||
Card,
|
||||
CardImg,
|
||||
CardText,
|
||||
CardBody,
|
||||
Container,
|
||||
Col,
|
||||
CardTitle
|
||||
} from 'reactstrap';
|
||||
import './login.css';
|
||||
import {APPLICATION_NAME} from '../../config';
|
||||
import LogInForm from './LogInForm.jsx';
|
||||
import ChangePasswordContainer from './ChangePasswordContainer.jsx';
|
||||
import {loginTexts} from '../../constants/authConstants';
|
||||
|
||||
const paramsForParticles = {
|
||||
particles: {
|
||||
number: {
|
||||
value: 110,
|
||||
density: {
|
||||
enable: true,
|
||||
value_area: 2500
|
||||
}
|
||||
},
|
||||
line_linked: {
|
||||
enable: true,
|
||||
distance: 300,
|
||||
color: "#ffffff",
|
||||
opacity: 1.5,
|
||||
width: 3
|
||||
},
|
||||
"shape": {
|
||||
"type": "circle",
|
||||
"stroke": {
|
||||
"width": 10,
|
||||
"height": 100,
|
||||
"color": "white"
|
||||
},
|
||||
polygon: {
|
||||
nb_sides: 6
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class LogInContainer extends Component {
|
||||
|
||||
render() {
|
||||
return (
|
||||
<BrowserRouter>
|
||||
<Container fluid={true} className="main-col">
|
||||
|
||||
<Col className="background-allPage" >
|
||||
<Col className="background-left"></Col>
|
||||
<Col className="background-right">
|
||||
<Particles className="particles background-right w3-display-topright" params={paramsForParticles}/>
|
||||
</Col>
|
||||
<Row className="form-login">
|
||||
<Col md={{ size: 4, offset: 2 }} xs="12" sm="12" className="login-intro">
|
||||
<Card className="border-card-color">
|
||||
<CardImg className="icon-logo-v2" src={logoDefault} alt="Wiaas logo"/>
|
||||
<CardBody className="introduction">
|
||||
<CardTitle className="welcome-to-WIAAS">
|
||||
<span >{loginTexts.labels.WELCOME_TO}</span>{' '}
|
||||
<span className="text-style-1">{APPLICATION_NAME}</span>
|
||||
</CardTitle>
|
||||
<CardText className="welcome-text"></CardText>
|
||||
</CardBody>
|
||||
</Card>
|
||||
<hr className="divider login-separator"/>
|
||||
</Col>
|
||||
<Col md="3" xs="12" sm="12" className="form-BG">
|
||||
<Switch>
|
||||
<Route exact path='/changePassword/:token' component={ChangePasswordContainer} />
|
||||
<Route path='/' component={LogInForm} />
|
||||
</Switch>
|
||||
</Col>
|
||||
</Row>
|
||||
</Col>
|
||||
</Container>
|
||||
</BrowserRouter>);
|
||||
}
|
||||
}
|
||||
|
||||
export default LogInContainer;
|
||||
128
client-wiaas/src/containers/login/LogInForm.jsx
Normal file
128
client-wiaas/src/containers/login/LogInForm.jsx
Normal file
@@ -0,0 +1,128 @@
|
||||
import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import {
|
||||
Alert,
|
||||
Form,
|
||||
FormGroup,
|
||||
Label,
|
||||
Input,
|
||||
Button
|
||||
} from 'reactstrap';
|
||||
import './login.css';
|
||||
import {validateCredentials, validateAccessToken, generatePassword} from '../../actions/login/authActions';
|
||||
import {setDialogContent, setDialogOpenFlag} from '../../actions/dialog/dialogActions';
|
||||
import {loginMessages, loginTexts} from '../../constants/authConstants';
|
||||
|
||||
class LogInForm extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
credentials: {
|
||||
username: '',
|
||||
password: ''
|
||||
},
|
||||
modal: false,
|
||||
email: ''
|
||||
};
|
||||
|
||||
this.handleChange = this.handleChange.bind(this);
|
||||
this.handleSubmit = this.handleSubmit.bind(this);
|
||||
this.toggle = this.toggle.bind(this);
|
||||
this.handlePwdGenerator = this.handlePwdGenerator.bind(this);
|
||||
}
|
||||
|
||||
toggle() {
|
||||
this.setState({
|
||||
modal: !this.state.modal
|
||||
});
|
||||
}
|
||||
|
||||
handleChange(event) {
|
||||
const field = event.target.name;
|
||||
const credentials = this.state.credentials;
|
||||
credentials[field] = event.target.value;
|
||||
return this.setState({credentials: credentials});
|
||||
}
|
||||
|
||||
handleSubmit(event) {
|
||||
this.props.dispatch(validateCredentials(this.state.credentials.username, this.state.credentials.password));
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
handlePwdGenerator(currentDialogState) {
|
||||
this.props.dispatch(generatePassword(currentDialogState.inputValue));
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
if (localStorage.accessToken) {
|
||||
this.props.dispatch(validateAccessToken(localStorage.accessToken));
|
||||
}
|
||||
}
|
||||
|
||||
setDialogParams(dialogContent) {
|
||||
this.props.dispatch(setDialogOpenFlag(true));
|
||||
this.props.dispatch(setDialogContent(dialogContent));
|
||||
}
|
||||
|
||||
render() {
|
||||
const dialogContent = {
|
||||
buttons: [
|
||||
{
|
||||
color:'success',
|
||||
action: this.handlePwdGenerator,
|
||||
name: 'Recover password',
|
||||
id: 'recover-password-confirmation'
|
||||
|
||||
}, {
|
||||
color:'secondary',
|
||||
name: 'Cancel',
|
||||
id: 'cancel-recover-password-item'
|
||||
}
|
||||
],
|
||||
header: 'Recover password',
|
||||
body: 'Please enter your email address for password generation',
|
||||
inputArray: [
|
||||
{
|
||||
class: 'base',
|
||||
type: 'email',
|
||||
placeholder: 'your@email.com'
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
return (
|
||||
<Form onSubmit={this.handleSubmit}>
|
||||
<FormGroup className="sign-in">{loginTexts.labels.SIGN_IN}</FormGroup>
|
||||
|
||||
<FormGroup className="login-input-group">
|
||||
<Label className="login-input-text" for="username">{loginTexts.labels.USERNAME}</Label>
|
||||
<Input className="base" type="text" name="username" id="username" placeholder={loginTexts.labels.USERNAME} value={this.state.username} onChange={this.handleChange} autoFocus />
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup className="login-input-group">
|
||||
<Label className="login-input-text" for="password">{loginTexts.labels.PASSWORD}</Label>
|
||||
<Input className="base" type="password" name="password" id="password" placeholder={loginTexts.labels.PASSWORD} value={this.state.password} onChange={this.handleChange}/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup className="login-form-group">
|
||||
<Button className="base-sign-in" type="submit" id="login-button" >{loginTexts.buttons.SIGN_IN}</Button>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup className="login-form-group" id="login-message">
|
||||
{loginMessages[this.props.errorMessage] && <Alert className='alert-form wiaas-alert' color={this.props.messageColor}>{loginMessages[this.props.errorMessage]}</Alert>}
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup className="login-input-group">
|
||||
<hr className="divider"/>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup className="login-input-group">
|
||||
<Button className="forgot-password" id="forgot-password-button" onClick={() => this.setDialogParams(dialogContent)}>
|
||||
{loginTexts.buttons.FORGOT_PASSWORD}
|
||||
</Button>
|
||||
</FormGroup>
|
||||
</Form>);
|
||||
}
|
||||
}
|
||||
const mapStateToProps = (state) => ({errorMessage: state.auth.errorMessage, messageColor: state.auth.messageColor});
|
||||
export default connect(mapStateToProps)(LogInForm);
|
||||
208
client-wiaas/src/containers/login/login.scss
Normal file
208
client-wiaas/src/containers/login/login.scss
Normal file
@@ -0,0 +1,208 @@
|
||||
@import "../../styleConstants.scss";
|
||||
|
||||
header {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
#form-sign {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.my-label {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.introduction {
|
||||
margin: auto;
|
||||
object-fit: contain;
|
||||
text-align: -webkit-center;
|
||||
}
|
||||
|
||||
.welcome-to-WIAAS {
|
||||
font-size: 2rem;
|
||||
color: $header-background;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.welcome-to-WIAAS .text-style-1 {
|
||||
font-weight: $font-weight;
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.welcome-text {
|
||||
opacity: 0.9;
|
||||
font-size: $font-size-big;
|
||||
text-align: left;
|
||||
color: $warmGreyColor;
|
||||
}
|
||||
|
||||
.back-to-login{
|
||||
color: $warmGreyColor;
|
||||
}
|
||||
|
||||
.login {
|
||||
height: 100%;
|
||||
background-color: $whiteColor;
|
||||
}
|
||||
|
||||
.background-allPage {
|
||||
height: 100%;
|
||||
background-image: linear-gradient(to bottom, $footer-background , $bottom-background);
|
||||
overflow: overlay;
|
||||
}
|
||||
|
||||
.background-left {
|
||||
width: 50%;
|
||||
height: 100%;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
background-color: $whiteColor;
|
||||
}
|
||||
|
||||
.background-right {
|
||||
position: fixed;
|
||||
width: 69.375%;
|
||||
opacity: 0.2;
|
||||
right: 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.main-col {
|
||||
height: 100%;
|
||||
padding-right: unset;
|
||||
}
|
||||
|
||||
.form-login {
|
||||
top: 32%;
|
||||
position: relative;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.login-intro {
|
||||
width: 58.5%;
|
||||
height: -webkit-stretch;
|
||||
background: $whiteColor;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.icon-logo-v2 {
|
||||
margin: auto;
|
||||
width: 53%;
|
||||
margin-top: 7%;
|
||||
}
|
||||
|
||||
.form-BG {
|
||||
background-color: $whiteColor;
|
||||
box-shadow: 0.25rem 0.125rem 0.25rem 0 $shadow-color;
|
||||
border-radius: 0 0.4375rem 0.4375rem 0;
|
||||
}
|
||||
|
||||
.sign-in {
|
||||
text-align: center;
|
||||
font-size: 1.5rem;
|
||||
color: $darkGreyColor;
|
||||
margin-top: 7%;
|
||||
}
|
||||
|
||||
.login-input-group {
|
||||
text-align: left;
|
||||
margin-right: 5%;
|
||||
margin-left: 5%;
|
||||
margin-bottom: 5%;
|
||||
}
|
||||
|
||||
.login-input-text {
|
||||
font-size: $font-size-small;
|
||||
font-weight: $font-weight;
|
||||
text-align: left;
|
||||
color: $warmGreyColor;
|
||||
}
|
||||
|
||||
.base {
|
||||
border-radius: 0.25rem;
|
||||
background-color: $whiteColor;
|
||||
border: solid 0.0625rem $border-grey;
|
||||
}
|
||||
|
||||
.base-sign-in {
|
||||
width: 100%;
|
||||
border-radius: 0.25rem;
|
||||
background-color: $greenColor;
|
||||
border-color: $greenColor;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.divider {
|
||||
width: 100%;
|
||||
height: 0.0625rem;
|
||||
background-color: $borderColor;
|
||||
}
|
||||
|
||||
.forgot-password {
|
||||
width: 100%;
|
||||
height: 2.25rem;
|
||||
border-radius: 0.25rem;
|
||||
border: solid 0.0625 $border-grey;
|
||||
margin-bottom: 7%;
|
||||
background-color: $whiteColor;
|
||||
color: $darkGreyColor;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.alert-form {
|
||||
margin:-1rem;
|
||||
}
|
||||
|
||||
.alert-danger {
|
||||
color: $redColor;
|
||||
}
|
||||
|
||||
.border-card-color {
|
||||
border-color: $whiteColor;
|
||||
}
|
||||
|
||||
.alert-form-group {
|
||||
height: 1rem;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.login-form-group {
|
||||
text-align: left;
|
||||
margin-right: 5%;
|
||||
margin-left: 5%;
|
||||
}
|
||||
|
||||
.login-separator {
|
||||
display: none;
|
||||
}
|
||||
@media all and (orientation: landscape) and (max-width: 766px){
|
||||
.form-login {
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
.form-login {
|
||||
top: 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.form-BG {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.icon-logo-v2 {
|
||||
width: 8rem;
|
||||
height: 5rem;
|
||||
}
|
||||
|
||||
.login-separator {
|
||||
display: block;
|
||||
width: 40%;
|
||||
}
|
||||
|
||||
.background-allPage {
|
||||
background-image: none;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import React, {Component} from 'react';
|
||||
import InstallationSchedulingForPackages from './components/installationScheduling/InstallationSchedulingForPackages.jsx';
|
||||
|
||||
class InstallationSchedulingContainer extends Component {
|
||||
render() {
|
||||
const {orderPackages, areComponentsDisabled, isInstallationSet, isInstallationInPackage, areAllShippingDatesConfirmed} = this.props.params;
|
||||
|
||||
return (
|
||||
<span>
|
||||
{orderPackages &&
|
||||
orderPackages.map(orderPackage =>
|
||||
<InstallationSchedulingForPackages key={orderPackage.idPackage}
|
||||
orderPackage={orderPackage}
|
||||
areComponentsDisabled={areComponentsDisabled}
|
||||
isInstallationSet={isInstallationSet}
|
||||
isInstallationInPackage={isInstallationInPackage}
|
||||
areAllShippingDatesConfirmed={areAllShippingDatesConfirmed}
|
||||
noOfPackages={orderPackages.length}/>)
|
||||
}
|
||||
</span>
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default InstallationSchedulingContainer;
|
||||
78
client-wiaas/src/containers/orders/OrdersContainer.jsx
Normal file
78
client-wiaas/src/containers/orders/OrdersContainer.jsx
Normal file
@@ -0,0 +1,78 @@
|
||||
import React, {Component} from 'react';
|
||||
import {Container, TabContent, TabPane, Nav, NavItem, NavLink, Row, Col} from 'reactstrap';
|
||||
import classnames from 'classnames';
|
||||
import './style/Orders.css';
|
||||
import OrdersDataContainer from './OrdersDataContainer.jsx';
|
||||
import ProcessContainer from './ProcessContainer.jsx';
|
||||
import {orderTexts} from '../../constants/ordersConstants';
|
||||
|
||||
class OrdersContainer extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.toggle = this.toggle.bind(this);
|
||||
this.state = {
|
||||
activeTab: '1'
|
||||
};
|
||||
}
|
||||
|
||||
toggle(tab) {
|
||||
if (this.state.activeTab !== tab) {
|
||||
this.setState({
|
||||
activeTab: tab
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const urlParams = this.props.match.params;
|
||||
|
||||
return (
|
||||
<Container fluid={true} id="orders-container">
|
||||
<Row>
|
||||
<Col lg="12" md="12" sm="12" xs="12">
|
||||
{
|
||||
urlParams.idOrder ?
|
||||
<ProcessContainer idOrder={urlParams.idOrder}/> :
|
||||
<div id="orders-list-container">
|
||||
<Nav tabs>
|
||||
<NavItem>
|
||||
<NavLink id="activeOrders" className={classnames({active: this.state.activeTab === '1'}) + ' orders-tab'}
|
||||
onClick={() => { this.toggle('1'); }}>
|
||||
{orderTexts.labels.ACTIVE_ORDERS}
|
||||
</NavLink>
|
||||
</NavItem>
|
||||
<NavItem>
|
||||
<NavLink id="historyOrders" className={classnames({ active: this.state.activeTab === '2' }) + ' orders-tab'}
|
||||
onClick={() => { this.toggle('2'); }}>
|
||||
{orderTexts.labels.ORDER_HISTORY}
|
||||
</NavLink>
|
||||
</NavItem>
|
||||
</Nav>
|
||||
|
||||
<TabContent activeTab={this.state.activeTab}>
|
||||
<TabPane tabId="1">
|
||||
<Row>
|
||||
<Col lg="12" md="12" sm="12" xs="12">
|
||||
<OrdersDataContainer type="active" />
|
||||
</Col>
|
||||
</Row>
|
||||
</TabPane>
|
||||
<TabPane tabId="2">
|
||||
<Row>
|
||||
<Col lg="12" md="12" sm="12" xs="12">
|
||||
<OrdersDataContainer type="history" />
|
||||
</Col>
|
||||
</Row>
|
||||
</TabPane>
|
||||
</TabContent>
|
||||
</div>
|
||||
}
|
||||
</Col>
|
||||
</Row>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default OrdersContainer;
|
||||
57
client-wiaas/src/containers/orders/OrdersDataContainer.jsx
Normal file
57
client-wiaas/src/containers/orders/OrdersDataContainer.jsx
Normal file
@@ -0,0 +1,57 @@
|
||||
import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import {Alert, Row, Col} from 'reactstrap';
|
||||
import WiaasBox from '../../mainComponents/box/WiaasBox.jsx';
|
||||
import {getActiveOrders, getHistoryOrders} from '../../actions/orders/ordersActions';
|
||||
import OrderList from './components/OrderList.jsx';
|
||||
import OrderListHeader from './components/OrderListHeader.jsx';
|
||||
import {orderTexts} from '../../constants/ordersConstants';
|
||||
|
||||
class OrdersDataContainer extends Component {
|
||||
componentDidMount() {
|
||||
this.props.dispatch(getActiveOrders());
|
||||
this.props.dispatch(getHistoryOrders());
|
||||
}
|
||||
|
||||
checkIfOrdersExistForUser(orders) {
|
||||
return orders.every((order) => {
|
||||
return 'isMyOrder' in order && !order.isMyOrder;
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
const {activeOrders, historyOrders, type, isLoading} = this.props;
|
||||
const orders = type ? type === 'active' ? activeOrders : historyOrders : {};
|
||||
const mainTitleOrder = type.charAt(0).toUpperCase() + type.slice(1);
|
||||
|
||||
return (
|
||||
<Row>
|
||||
<Col lg="12" xs="12">
|
||||
<WiaasBox id={type + "-orders-container"} mainTitle={mainTitleOrder + " Orders"} customHeader={OrderListHeader} customHeaderParams={type}>
|
||||
{
|
||||
isLoading &&
|
||||
<div className="loader">
|
||||
<i className="fa fa-spinner fa-spin fa-3x" aria-hidden="true"></i>
|
||||
</div>
|
||||
}
|
||||
{ (orders && !isLoading) &&
|
||||
<OrderList orders={orders} type={type}/>
|
||||
}
|
||||
{
|
||||
((orders && orders.length === 0 && !isLoading) || (orders && this.checkIfOrdersExistForUser(orders))) &&
|
||||
<Alert color="info">{orderTexts.labels.NO_RECORDS}</Alert>
|
||||
}
|
||||
</WiaasBox>
|
||||
</Col>
|
||||
</Row>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
activeOrders: state.ordersReducer.activeOrders,
|
||||
historyOrders: state.ordersReducer.historyOrders,
|
||||
isLoading: state.ordersReducer.isLoading
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps)(OrdersDataContainer);
|
||||
267
client-wiaas/src/containers/orders/ProcessContainer.jsx
Normal file
267
client-wiaas/src/containers/orders/ProcessContainer.jsx
Normal file
@@ -0,0 +1,267 @@
|
||||
import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import WiaasBox from '../../mainComponents/box/WiaasBox.jsx';
|
||||
import {fetchOrderInfo, getAllDataForInstallation} from '../../actions/orders/processActions';
|
||||
import OrderInfo from './components/OrderInfo.jsx';
|
||||
import OrderProcess from './components/process/OrderProcess.jsx';
|
||||
import ProcessPackage from './components/packages/ProcessPackage.jsx';
|
||||
import OrderComments from './components/OrderComments.jsx';
|
||||
import PackagesNav from './components/PackagesNav.jsx';
|
||||
import PriceHelper from '../../helpers/coMarket/PriceHelper';
|
||||
import ProcessNavContainer from './ProcessNavContainer.jsx';
|
||||
import OrderDocuments from './components/OrderDocuments.jsx';
|
||||
import {orderTexts} from '../../constants/ordersConstants';
|
||||
import './style/ProcessContainer.css';
|
||||
import './style/ProcessNavContainer.css';
|
||||
|
||||
const priceHelper = new PriceHelper();
|
||||
const usedForDirective = 'installationScheduling';
|
||||
const stepsNameForInstallation = {
|
||||
firstStepEnabled: 5,
|
||||
lastStepEnabled: 6
|
||||
};
|
||||
const fileType = 'installationProtocol';
|
||||
|
||||
class ProcessContainer extends Component {
|
||||
constructor(props){
|
||||
super(props);
|
||||
|
||||
this.onViewChange = this.onViewChange.bind(this);
|
||||
this.getActiveView = this.getActiveView.bind(this);
|
||||
this.onPackageFilter = this.onPackageFilter.bind(this);
|
||||
this.filterPackages = this.filterPackages.bind(this);
|
||||
this.state = {
|
||||
activeView : 'info',
|
||||
packageNameFilter: 'all',
|
||||
isSchedulingDisabled: {},
|
||||
isOnePackageAndInstallationNotExists: {},
|
||||
isInstallationInPackage: {},
|
||||
orderPackagePairs: [],
|
||||
tooltipOpen: false,
|
||||
isScheduleBtnClicked: false
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.props.dispatch(fetchOrderInfo(this.props.idOrder));
|
||||
this.props.dispatch(getAllDataForInstallation(this.props.idOrder, usedForDirective, stepsNameForInstallation, fileType));
|
||||
const orderPackagePairs = [];
|
||||
const isSchedulingDisabled = {};
|
||||
isSchedulingDisabled[this.props.idOrder] = true;
|
||||
const newState = Object.assign(isSchedulingDisabled, this.state.isSchedulingDisabled);
|
||||
|
||||
if(this.props.orderInfo) {
|
||||
this.props.orderInfo.packages.forEach(orderPackage => {
|
||||
orderPackagePairs.push(orderPackage.idOrder + '-' + orderPackage.idPackage);
|
||||
});
|
||||
}
|
||||
this.setState({
|
||||
orderPackagePairs,
|
||||
isSchedulingDisabled: newState
|
||||
});
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
const {installCompanies, isComponentDisabled, earliestInstallDate, areAllShippingDatesConfirmed} = nextProps;
|
||||
const allPackagesScheduleInstallDisabled = [];
|
||||
const areComponentsDisabled = {};
|
||||
const isInstallationSet = {};
|
||||
const isOnePackageAndInstallationNotExists = {};
|
||||
const isInstallationInPackage = {};
|
||||
|
||||
if(installCompanies && isComponentDisabled && earliestInstallDate) {
|
||||
if(nextProps.orderInfo) {
|
||||
nextProps.orderInfo.packages.forEach(orderPackage => {
|
||||
const idOrder = orderPackage && orderPackage.idOrder;
|
||||
const idOrderPackagePair = orderPackage ? idOrder + '-' + orderPackage.idPackage : '';
|
||||
orderPackage.idOrderPackagePair = idOrderPackagePair;
|
||||
areComponentsDisabled[idOrder] = this.checkIfComponentIsDisabled(orderPackage.idOrder, isComponentDisabled, earliestInstallDate);
|
||||
|
||||
const availableCompanies = {};
|
||||
const selectedCompanies = {};
|
||||
isInstallationSet[idOrderPackagePair] = false;
|
||||
|
||||
if(installCompanies) {
|
||||
availableCompanies[idOrderPackagePair] = idOrderPackagePair in installCompanies.available ? installCompanies.available[idOrderPackagePair] : [];
|
||||
selectedCompanies[idOrderPackagePair] = idOrderPackagePair in installCompanies.selected ? installCompanies.selected[idOrderPackagePair] : {};
|
||||
if (idOrderPackagePair in selectedCompanies && Object.keys(selectedCompanies[idOrderPackagePair]).length > 0) {
|
||||
isInstallationSet[idOrderPackagePair] = true;
|
||||
}
|
||||
|
||||
if(availableCompanies[idOrderPackagePair].length === 0 && Object.keys(selectedCompanies[idOrderPackagePair]).length === 0) {
|
||||
isOnePackageAndInstallationNotExists[orderPackage.idOrder] = nextProps.orderInfo.packages.length === 1 ? true : false;
|
||||
isInstallationInPackage[idOrderPackagePair] = false;
|
||||
} else {
|
||||
isInstallationInPackage[idOrderPackagePair] = true;
|
||||
}
|
||||
}
|
||||
|
||||
const isSchedulingDisabled = areComponentsDisabled[idOrder] || (isInstallationSet && !isInstallationSet[idOrderPackagePair]);
|
||||
allPackagesScheduleInstallDisabled.push(isSchedulingDisabled);
|
||||
});
|
||||
|
||||
const isSchedulingDisabled = Object.assign({}, this.state.isSchedulingDisabled);
|
||||
isSchedulingDisabled[nextProps.orderInfo.info.id] = allPackagesScheduleInstallDisabled.every(isDisabled => {return isDisabled === true;});
|
||||
this.setState({
|
||||
isSchedulingDisabled,
|
||||
areComponentsDisabled,
|
||||
isInstallationSet,
|
||||
isOnePackageAndInstallationNotExists,
|
||||
isInstallationInPackage,
|
||||
areAllShippingDatesConfirmed,
|
||||
packages: nextProps.orderInfo.packages
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
checkIfComponentIsDisabled(idOrder, isComponentDisabled, earliestInstallDate) {
|
||||
if(isComponentDisabled && usedForDirective in isComponentDisabled && idOrder in isComponentDisabled[usedForDirective]) {
|
||||
const isScheduleComponentDisabled = isComponentDisabled[usedForDirective][idOrder];
|
||||
if(earliestInstallDate) {
|
||||
return isScheduleComponentDisabled || (!(idOrder in earliestInstallDate) || earliestInstallDate[idOrder] === '-');
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
calculatetTotalPrice(packages) {
|
||||
let fixedPrice = priceHelper.sumPrices(packages.map(pkg => { return pkg.units * pkg.packageFixedPrice}));
|
||||
let recurrentPrice = priceHelper.sumPrices(packages.map(pkg => { return pkg.units * pkg.packageRecuringPrice}));
|
||||
let servicesPrice = priceHelper.sumPrices(packages.map(pkg => { return pkg.units * pkg.packageServicePrice}));
|
||||
|
||||
return {
|
||||
fixedPrice,
|
||||
recurrentPrice: priceHelper.sumPrices([recurrentPrice, servicesPrice]),
|
||||
periodUnit: packages[0].periodUnit,
|
||||
currency: packages[0].packageCurrency.currency
|
||||
}
|
||||
}
|
||||
|
||||
onViewChange(activeView){
|
||||
if(activeView === 'documents'){
|
||||
this.props.dispatch(fetchOrderInfo(this.props.idOrder));
|
||||
}
|
||||
this.setState({activeView});
|
||||
}
|
||||
|
||||
getActiveView() {
|
||||
return this.state.activeView;
|
||||
}
|
||||
|
||||
onPackageFilter(packageNameFilter) {
|
||||
this.setState({packageNameFilter});
|
||||
}
|
||||
|
||||
filterPackages(orderPackage){
|
||||
if(this.state.packageNameFilter === 'all') {
|
||||
return true;
|
||||
}else{
|
||||
return orderPackage.packageName === this.state.packageNameFilter;
|
||||
}
|
||||
}
|
||||
|
||||
getProcess(process){
|
||||
const processKeys = Object.keys(process) || [];
|
||||
return processKeys.length > 0 ? process[processKeys[0]] : {};
|
||||
}
|
||||
|
||||
getButtonClass() {
|
||||
if(this.props.orderInfo) {
|
||||
return this.state.isSchedulingDisabled[this.props.orderInfo.id] ? 'schedule-inactive' : 'schedule-active';
|
||||
}
|
||||
|
||||
return 'schedule-inactive';
|
||||
}
|
||||
|
||||
render() {
|
||||
const {orderInfo, isLoading} = this.props;
|
||||
|
||||
return (
|
||||
<div id="order-info">
|
||||
{
|
||||
isLoading &&
|
||||
<div className="loader">
|
||||
<i className="fa fa-spinner fa-spin fa-3x" aria-hidden="true"></i>
|
||||
</div>
|
||||
}
|
||||
{
|
||||
(orderInfo && orderInfo.info && !isLoading) &&
|
||||
<div>
|
||||
<WiaasBox
|
||||
customHeader={ProcessNavContainer}
|
||||
customHeaderParams={{
|
||||
orderInfo: orderInfo.info,
|
||||
packages: orderInfo.packages,
|
||||
onViewChange: this.onViewChange,
|
||||
getActiveView: this.getActiveView,
|
||||
installationData: this.state
|
||||
}}>
|
||||
<OrderInfo totalPrice={this.calculatetTotalPrice(orderInfo.packages)} orderDetails={orderInfo} installationData={this.state}/>
|
||||
</WiaasBox>
|
||||
{
|
||||
this.state.activeView !== 'info' &&
|
||||
<div className="components-link">
|
||||
<div className="link-line"></div>
|
||||
</div>
|
||||
}
|
||||
{
|
||||
this.state.activeView === 'info' &&
|
||||
<OrderProcess
|
||||
onViewChange={this.onViewChange}
|
||||
orderStatus={orderInfo.status}
|
||||
orderProcess={this.getProcess(orderInfo.process)}/>
|
||||
}
|
||||
{
|
||||
this.state.activeView === 'packages' &&
|
||||
<WiaasBox id="order-packages"
|
||||
customHeader={PackagesNav}
|
||||
customHeaderParams={{packages: orderInfo.packages, onPackageFilter: this.onPackageFilter, packageNameFilter: this.state.packageNameFilter}}
|
||||
>
|
||||
{
|
||||
orderInfo.packages.filter(this.filterPackages).map(orderPackage =>
|
||||
<ProcessPackage key={orderPackage.idPackage}
|
||||
onViewChange={this.onViewChange}
|
||||
idCommercialLead={orderInfo.info.idCommercialLead}
|
||||
orderPackage={orderPackage}/>
|
||||
)
|
||||
}
|
||||
</WiaasBox>
|
||||
}
|
||||
{
|
||||
this.state.activeView === 'comments' &&
|
||||
<OrderComments orderInfo={orderInfo.info} orderComments={orderInfo.orderComments} orderPackages={orderInfo.packages}/>
|
||||
}
|
||||
|
||||
{
|
||||
this.state.activeView === 'documents' &&
|
||||
<OrderDocuments idOrder={orderInfo.info.id} />
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
{
|
||||
(orderInfo && !orderInfo.info && !isLoading) &&
|
||||
<div className="no-rigths">
|
||||
{orderTexts.labels.NOT_AVAILABLE}!
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
isCompanyAdmin: state.auth.isCompanyAdmin,
|
||||
orderInfo: state.processReducer.orderInfo,
|
||||
confirmationDates: state.processReducer.confirmationDates,
|
||||
isLoading: state.processReducer.isLoading,
|
||||
isNextStepWanted: state.processReducer.isNextStepWanted,
|
||||
isComponentDisabled: state.processReducer.isComponentDisabled,
|
||||
earliestInstallDate: state.processReducer.earliestInstallDate,
|
||||
installCompanies: state.processReducer.installCompanies,
|
||||
areAllShippingDatesConfirmed: state.processReducer.areAllShippingDatesConfirmed
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps)(ProcessContainer);
|
||||
110
client-wiaas/src/containers/orders/ProcessNavContainer.jsx
Normal file
110
client-wiaas/src/containers/orders/ProcessNavContainer.jsx
Normal file
@@ -0,0 +1,110 @@
|
||||
import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import {Row, Col, Button, Tooltip} from 'reactstrap';
|
||||
import {orderTexts} from '../../constants/ordersConstants';
|
||||
import {setDialogContent, setDialogOpenFlag} from '../../actions/dialog/dialogActions';
|
||||
import InstallationSchedulingContainer from './InstallationSchedulingContainer.jsx';
|
||||
|
||||
class ProcessNavContainer extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
tooltipOpen: false,
|
||||
isScheduleBtnClicked: false
|
||||
};
|
||||
|
||||
this.toggle = this.toggle.bind(this);
|
||||
this.handleScheduleBtn = this.handleScheduleBtn.bind(this);
|
||||
this.setContentDialog = this.setContentDialog.bind(this);
|
||||
this.openDialogContent = this.openDialogContent.bind(this);
|
||||
}
|
||||
|
||||
getClass(buttonView) {
|
||||
const view = this.props.params.getActiveView();
|
||||
|
||||
return buttonView === view ? 'process-nav-div selected-nav' : 'process-nav-div';
|
||||
}
|
||||
|
||||
toggle() {
|
||||
this.setState({
|
||||
tooltipOpen: !this.state.tooltipOpen
|
||||
});
|
||||
}
|
||||
|
||||
handleScheduleBtn() {
|
||||
this.setState({isScheduleBtnClicked: !this.state.isScheduleBtnClicked});
|
||||
}
|
||||
|
||||
setContentDialog() {
|
||||
const {installationData} = this.props.params;
|
||||
|
||||
return {
|
||||
class: 'installation-scheduling',
|
||||
hasCloseIcon: true,
|
||||
header: orderTexts.labels.INSTALLATION_SCHEDULE_HEADER,
|
||||
TagName: InstallationSchedulingContainer,
|
||||
params: {
|
||||
orderPackages: installationData.packages,
|
||||
areComponentsDisabled: installationData.areComponentsDisabled,
|
||||
isInstallationSet: installationData.isInstallationSet,
|
||||
isInstallationInPackage: installationData.isInstallationInPackage,
|
||||
areAllShippingDatesConfirmed: installationData.areAllShippingDatesConfirmed,
|
||||
openDialogContent: this.openDialogContent
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
openDialogContent() {
|
||||
if(!this.props.params.installationData.isSchedulingDisabled[this.props.params.orderInfo.id]) {
|
||||
const dialogContent = this.setContentDialog();
|
||||
|
||||
this.props.dispatch(setDialogOpenFlag(true));
|
||||
this.props.dispatch(setDialogContent(dialogContent));
|
||||
}
|
||||
}
|
||||
|
||||
getButtonClass() {
|
||||
const {installationData, orderInfo} = this.props.params;
|
||||
|
||||
return installationData.isSchedulingDisabled[orderInfo.id] ? 'schedule-inactive' : 'schedule-active';
|
||||
}
|
||||
|
||||
render() {
|
||||
const {orderInfo, onViewChange, installationData} = this.props.params;
|
||||
|
||||
return (
|
||||
<Row id="process-nav" className="process-nav">
|
||||
<Col xl="2" lg="2" md="4" sm="12" xs="12" className="process-nav-buttons">
|
||||
<div className="wiaas-main-title">
|
||||
{orderTexts.labels.ORDER} {orderInfo.orderNumber} <div className={'status-layer ' + orderInfo.status}>{orderTexts.statuses[orderInfo.status]}</div>
|
||||
</div>
|
||||
</Col>
|
||||
<Col xl="2" lg="2" md="2" sm="12" xs="12" className="process-nav-buttons">
|
||||
<Button className={"schedule-installation-btn " + this.getButtonClass()}
|
||||
id="schedule-installation-button"
|
||||
onClick={this.openDialogContent}>
|
||||
{orderTexts.buttons.SCHEDULE_INSTALLATION}
|
||||
</Button>
|
||||
<Tooltip placement="bottom" isOpen={this.state.tooltipOpen} target="schedule-installation-button" toggle={this.toggle}>
|
||||
{
|
||||
installationData.isSchedulingDisabled[orderInfo.id]
|
||||
? installationData.isOnePackageAndInstallationNotExists[orderInfo.id]
|
||||
? orderTexts.labels.SCHEDULE_INSTALLATION_NOT_EXIST
|
||||
: orderTexts.labels.SCHEDULE_INSTALLATION_DISABLED
|
||||
: orderTexts.labels.SCHEDULE_INSTALLATION_ENABLED
|
||||
}
|
||||
</Tooltip>
|
||||
</Col>
|
||||
<Col xl="4" lg="6" md="6" sm="12" xs="12" className="process-menu">
|
||||
<div className={this.getClass('info')} onClick={()=>{onViewChange('info')}}>{orderTexts.labels.ORDER_INFO}</div>
|
||||
<div className={this.getClass('packages')} onClick={()=>{onViewChange('packages')}}>{orderTexts.labels.PACKAGES}</div>
|
||||
<div className={this.getClass('comments')} onClick={()=>{onViewChange('comments')}}>{orderTexts.labels.COMMENTS}</div>
|
||||
<div className={this.getClass('documents')} onClick={()=>{onViewChange('documents')}}>{orderTexts.labels.DOCUMENTS}</div>
|
||||
</Col>
|
||||
</Row>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default connect()(ProcessNavContainer);
|
||||
@@ -0,0 +1,79 @@
|
||||
import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import {Button} from 'reactstrap';
|
||||
import {Link} from 'react-router-dom';
|
||||
import {WiaasTableRow, WiaasTableCol} from '../../../mainComponents/table/WiaasTable.jsx';
|
||||
import {orderTexts} from '../../../constants/ordersConstants';
|
||||
import '../style/Orders.css';
|
||||
import OrderPackage from './OrderPackage.jsx';
|
||||
|
||||
class ActiveOrderItem extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
showPackages: false
|
||||
};
|
||||
|
||||
this.toggle = this.toggle.bind(this);
|
||||
}
|
||||
|
||||
toggle() {
|
||||
this.setState({
|
||||
showPackages: !this.state.showPackages
|
||||
});
|
||||
}
|
||||
|
||||
getIconClass(type) {
|
||||
return 'fa fa-angle-' + type + ' toggle-view-packages';
|
||||
}
|
||||
|
||||
render() {
|
||||
const {order, isViewAllOrdersChecked} = this.props;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<WiaasTableRow className={"order-central-row order-border-" + order.status}>
|
||||
<WiaasTableCol header="#">
|
||||
{!this.state.showPackages && <i className={this.getIconClass('down')} aria-hidden="true" onClick={this.toggle}></i>}
|
||||
{this.state.showPackages && <i className={this.getIconClass('up')} aria-hidden="true" onClick={this.toggle}></i>}
|
||||
<i className="fa fa-list-alt package-photo" aria-hidden="true" />
|
||||
<div className="order-number">{order.orderNumber}</div>
|
||||
</WiaasTableCol>
|
||||
<WiaasTableCol header={orderTexts.labels.REFERENCE}>{order.reference ? order.reference : '-'}</WiaasTableCol>
|
||||
{isViewAllOrdersChecked['active'] && <WiaasTableCol header={orderTexts.labels.PLACED_BY}>{order.customerName ? order.customerName : ''}</WiaasTableCol>}
|
||||
<WiaasTableCol header={orderTexts.labels.ORDER_DATE}>{order.orderDate ? order.orderDate : '-'}</WiaasTableCol>
|
||||
<WiaasTableCol header={orderTexts.labels.EST_DELIVERY}>{order.estimatedDeliveryDate ? order.estimatedDeliveryDate : '-'}</WiaasTableCol>
|
||||
<WiaasTableCol header="Catalogue">
|
||||
<div className="order-item-cl">
|
||||
<img className="cl-photo" src="static/img/man-icon.png" alt="Catalogue" />
|
||||
<div className="cl-details">
|
||||
<div className="cl-contact-name">{order.clContactName}</div>
|
||||
<div className="cl-name">{order.clName}</div>
|
||||
</div>
|
||||
</div>
|
||||
</WiaasTableCol>
|
||||
<WiaasTableCol header={orderTexts.labels.AMOUNT}>
|
||||
{order.orderCurrency && order.orderCurrency.currency
|
||||
? order.orderTotalPrice.toLocaleString() + ' ' + order.orderCurrency.currency
|
||||
: parseFloat(order.orderTotalPrice).toLocaleString()}
|
||||
</WiaasTableCol>
|
||||
<WiaasTableCol header={orderTexts.labels.STATUS}>
|
||||
<div className={'status-icon ' + order.status}></div>{order.status}
|
||||
</WiaasTableCol>
|
||||
<WiaasTableCol header="Buttons details">
|
||||
<Link to={'/orders/' + order.id} className="actions-link">
|
||||
<Button color="secondary" className="actions-button">{orderTexts.buttons.DELIVERY_DETAILS}</Button>
|
||||
</Link>
|
||||
|
||||
</WiaasTableCol>
|
||||
</WiaasTableRow>
|
||||
{ this.state.showPackages && <OrderPackage order={order} type="active"/> }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
isViewAllOrdersChecked: state.ordersReducer.isViewAllOrdersChecked
|
||||
});
|
||||
export default connect(mapStateToProps)(ActiveOrderItem);
|
||||
26
client-wiaas/src/containers/orders/components/AddComment.jsx
Normal file
26
client-wiaas/src/containers/orders/components/AddComment.jsx
Normal file
@@ -0,0 +1,26 @@
|
||||
import React, {Component} from 'react';
|
||||
import { Editor } from '@tinymce/tinymce-react';
|
||||
|
||||
class AddComment extends Component {
|
||||
handleEditorChange = (e) => {
|
||||
const comment = e.target.getContent();
|
||||
this.props.onEditorChange(comment);
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Editor
|
||||
init={{
|
||||
plugins: 'link textcolor lists colorpicker code',
|
||||
toolbar: 'undo redo | styleselect | bold italic underline forecolor fontsizeselect | link | alignleft aligncenter alignright | numlist bullist | outdent indent | code'
|
||||
}}
|
||||
onChange={this.handleEditorChange}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default AddComment;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user