initial docker setup
This commit is contained in:
44
frontend/src/containers/cart/CartContainer.jsx
Normal file
44
frontend/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);
|
||||
229
frontend/src/containers/cart/CartCustomerDetailsContainer.jsx
Normal file
229
frontend/src/containers/cart/CartCustomerDetailsContainer.jsx
Normal file
@@ -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
frontend/src/containers/cart/CartItemsContainer.jsx
Normal file
83
frontend/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
frontend/src/containers/cart/CartReviewOrderContainer.jsx
Normal file
177
frontend/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
frontend/src/containers/cart/CartStepsContainer.jsx
Normal file
75
frontend/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);
|
||||
49
frontend/src/containers/cart/components/AddOrderProject.jsx
Normal file
49
frontend/src/containers/cart/components/AddOrderProject.jsx
Normal file
@@ -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
frontend/src/containers/cart/components/BidItem.jsx
Normal file
40
frontend/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
frontend/src/containers/cart/components/BidsList.jsx
Normal file
34
frontend/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
frontend/src/containers/cart/components/CartIcon.jsx
Normal file
23
frontend/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
frontend/src/containers/cart/components/CartItem.jsx
Normal file
272
frontend/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
frontend/src/containers/cart/components/PackageBids.jsx
Normal file
47
frontend/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
frontend/src/containers/cart/style/Cart.scss
Normal file
170
frontend/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
frontend/src/containers/cart/style/CartStepsContainer.scss
Normal file
165
frontend/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
frontend/src/containers/cart/style/OrderProjects.scss
Normal file
20
frontend/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
frontend/src/containers/cart/style/PacakgeBids.scss
Normal file
13
frontend/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%;
|
||||
}
|
||||
Reference in New Issue
Block a user