Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
E
ecommerce-maven
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Ascend
ecommerce-maven
Commits
3181467b
Commit
3181467b
authored
May 11, 2021
by
Shaphen Pangburn
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'AFP68-OrderPage' into 'master'
Afp68 order page See merge request
!13
parents
1f99e20f
132f13f0
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
575 additions
and
43 deletions
+575
-43
checkout_actions.js
ecom-web/src/actions/checkout_actions.js
+13
-0
PaymentMethod.js
ecom-web/src/components/checkout/PaymentMethod.js
+40
-3
ReviewOrder.js
ecom-web/src/components/checkout/ReviewOrder.js
+75
-4
ShippingAddress.js
ecom-web/src/components/checkout/ShippingAddress.js
+62
-3
SubmitOrder.js
ecom-web/src/components/checkout/SubmitOrder.js
+21
-4
checkout.css
ecom-web/src/components/checkout/checkout.css
+82
-0
checkout.js
ecom-web/src/components/checkout/checkout.js
+250
-0
checkout.jsx
ecom-web/src/components/checkout/checkout.jsx
+0
-28
order_reducer.js
ecom-web/src/reducers/order_reducer.js
+22
-0
root_reducer.js
ecom-web/src/reducers/root_reducer.js
+5
-1
order-api.js
ecom-web/src/util/order-api.js
+5
-0
No files found.
ecom-web/src/actions/checkout_actions.js
0 → 100644
View file @
3181467b
// import util api call for cart order
import
{
sendOrderPost
}
from
'./../util/order-api'
;
export
const
SEND_USER_ORDER
=
"SEND_USER_ORDER"
const
sendUserOrder
=
(
orderConfirmationResponse
)
=>
({
type
:
SEND_USER_ORDER
,
payload
:
orderConfirmationResponse
})
export
const
dispatchOrderInfo
=
(
orderInfo
)
=>
dispatch
=>
sendOrderPost
(
orderInfo
)
.
then
(
response
=>
dispatch
(
sendUserOrder
(
response
.
data
))
)
ecom-web/src/components/checkout/PaymentMethod.js
View file @
3181467b
// import React, {useState, useEffect} from 'react'
// import React, {useState, useEffect} from 'react'
export
default
function
PaymentMethod
()
{
export
default
function
PaymentMethod
(
props
)
{
return
(
return
(
<
div
>
<
div
className
=
"order-component"
id
=
"PaymentInput"
>
PAYMENT
METHOD
COMPONENT
<
div
className
=
"OrderDirectionsElement"
id
=
"PaymentLabel"
>
<
p
>
Step
2
-
Billing
<
/p
>
<
/div
>
<
div
className
=
"shippingInfoInput"
id
=
"cardNumberInput"
>
<
input
placeholder
=
{
props
.
cardNumber
}
type
=
"text"
onChange
=
{(
e
)
=>
props
.
captureCardNumber
(
e
.
target
.
value
)}
className
=
"input-text"
><
/input
>
<
/div
>
<
div
className
=
"shippingInfoInput"
id
=
"cardholderNameInput"
>
<
input
placeholder
=
{
props
.
cardHolderName
}
type
=
"text"
onChange
=
{(
e
)
=>
props
.
captureCardHolderName
(
e
.
target
.
value
)}
className
=
"input-text"
><
/input
>
<
/div
>
<
div
className
=
"shippingInfoInput"
id
=
"expirationDateInput"
>
<
input
placeholder
=
{
props
.
expirationDate
}
type
=
"text"
onChange
=
{(
e
)
=>
props
.
captureExpirationDate
(
e
.
target
.
value
)}
className
=
"input-text"
><
/input
>
<
/div
>
<
div
className
=
"shippingInfoInput"
id
=
"cvvCodeInput"
>
<
input
placeholder
=
{
props
.
cvv
}
type
=
"text"
onChange
=
{(
e
)
=>
props
.
captureCVV
(
e
.
target
.
value
)}
className
=
"input-text"
><
/input
>
<
/div
>
<
/div
>
<
/div
>
)
)
}
}
ecom-web/src/components/checkout/ReviewOrder.js
View file @
3181467b
// import React, {useState, useEffect} from 'react'
import
React
,
{
useState
,
useEffect
}
from
'react'
export
default
function
ReviewOrder
(
props
)
{
let
calcTotalBeforeTax
=
(
itemsTotal
,
shippingTotal
)
=>
{
return
parseFloat
(
itemsTotal
)
+
parseFloat
(
shippingTotal
)
}
let
calcTaxAmount
=
(
itemsTotal
,
shippingTotal
,
taxRate
)
=>
{
return
calcTotalBeforeTax
(
itemsTotal
,
shippingTotal
)
*
taxRate
}
let
calcGrandTotal
=
(
itemsTotal
,
shippingTotal
,
taxRate
)
=>
{
return
calcTotalBeforeTax
(
itemsTotal
,
shippingTotal
)
*
(
parseFloat
(
1.00
)
+
parseFloat
(
taxRate
))
}
export
default
function
ReviewOrder
()
{
return
(
return
(
<
div
>
<
div
className
=
"order-component"
id
=
"ReviewOrder"
>
REVIEW
ORDER
COMPONENT
<
div
className
=
"OrderDirectionsElement"
id
=
"OrderSummary"
>
<
p
>
Step
3
-
Order
Summary
<
/p
>
<
/div
>
<
div
id
=
"orderSummaryContainer"
>
<
div
className
=
"OrderSummaryElement"
id
=
"itemsPrice"
>
<
div
>
Items
({
props
.
numCartItems
}):
<
/div
>
<
div
>
$
{
parseFloat
(
props
.
itemsTotal
).
toFixed
(
2
)}
<
/div
>
<
/div
>
<
div
className
=
"OrderSummaryElement"
id
=
"shippingHandling"
>
<
div
id
=
"shippingHandlingLabel"
>
Shipping
and
Handling
:
<
/div
>
<
div
id
=
"shippingHandlingPrice"
>
$
{
parseFloat
(
props
.
shippingHandling
).
toFixed
(
2
)}
<
/div
>
<
/div
>
<
div
className
=
"OrderSummaryElement"
id
=
"beforeTax"
>
<
div
id
=
"beforeTaxLabel"
>
Total
Before
Tax
<
/div
>
<
div
id
=
"beforeTaxPrice"
>
$
{
calcTotalBeforeTax
(
props
.
itemsTotal
,
props
.
shippingHandling
).
toFixed
(
2
)}
<
/div
>
<
/div
>
<
div
className
=
"OrderSummaryElement"
id
=
"taxCalculated"
>
<
div
id
=
"taxCalculatedLabel"
>
Estimated
Tax
:
<
/div
>
<
div
id
=
"taxCalculatedPrice"
>
$
{
calcTaxAmount
(
props
.
itemsTotal
,
props
.
shippingHandling
,
props
.
taxRate
).
toFixed
(
2
)}
<
/div
>
<
/div
>
<
div
className
=
"OrderSummaryElement"
id
=
"orderTotal"
>
<
div
id
=
"orderTotalLabel"
>
Order
Total
:
<
/div
>
<
div
id
=
"orderTotalPrice"
>
$
{
calcGrandTotal
(
props
.
itemsTotal
,
props
.
shippingHandling
,
props
.
taxRate
).
toFixed
(
2
)}
<
/div
>
<
/div
>
<
/div
>
<
/div
>
<
/div
>
)
)
}
}
ecom-web/src/components/checkout/ShippingAddress.js
View file @
3181467b
// import React, {useState, useEffect} from 'react'
// import React, {useState, useEffect} from 'react'
export
default
function
ShippingAddress
()
{
export
default
function
ShippingAddress
(
props
)
{
return
(
return
(
<
div
>
<
div
className
=
"order-component"
id
=
"shippingInput"
>
SHIPPING
ADDRESS
COMPONENT
<
div
className
=
"OrderDirectionsElement"
id
=
"ShippingLabel"
>
<
p
>
Step
1
-
Shipping
<
/p
>
<
/div
>
<
div
className
=
"shippingInfoInput"
id
=
"firstNameInput"
>
<
input
placeholder
=
"First Name*"
type
=
"text"
onChange
=
{(
e
)
=>
props
.
captureFirstName
(
e
.
target
.
value
)}
className
=
"input-text"
><
/input
>
<
/div
>
<
div
className
=
"shippingInfoInput"
id
=
"lastNameInput"
>
<
input
placeholder
=
"Last Name*"
type
=
"text"
onChange
=
{(
e
)
=>
props
.
captureLastName
(
e
.
target
.
value
)}
className
=
"input-text"
><
/input
>
<
/div
>
<
div
className
=
"shippingInfoInput"
id
=
"addressInput"
>
<
input
placeholder
=
"Shipping Address*"
type
=
"text"
onChange
=
{(
e
)
=>
props
.
captureShippingAddress
(
e
.
target
.
value
)}
className
=
"input-text"
><
/input
>
<
/div
>
<
div
className
=
"shippingInfoInput"
id
=
"aptSuiteInput"
>
<
input
placeholder
=
"Apt. / Suite no"
type
=
"text"
onChange
=
{(
e
)
=>
props
.
captureAptSuiteNo
(
e
.
target
.
value
)}
className
=
"input-text"
><
/input
>
<
/div
>
<
div
className
=
"shippingInfoInput"
id
=
"cityInput"
>
<
input
placeholder
=
"City*"
type
=
"text"
onChange
=
{(
e
)
=>
props
.
captureCity
(
e
.
target
.
value
)}
className
=
"input-text"
><
/input
>
<
/div
>
<
div
className
=
"shippingInfoInput"
id
=
"stateInput"
>
<
input
placeholder
=
"State*"
type
=
"text"
onChange
=
{(
e
)
=>
props
.
captureState
(
e
.
target
.
value
)}
className
=
"input-text"
><
/input
>
<
/div
>
<
div
className
=
"shippingInfoInput"
id
=
"zipCodeInput"
>
<
input
placeholder
=
"Postal Code*"
type
=
"text"
onChange
=
{(
e
)
=>
props
.
captureZipCode
(
e
.
target
.
value
)}
className
=
"input-text"
><
/input
>
<
/div
>
<
/div
>
<
/div
>
)
)
}
}
ecom-web/src/components/checkout/SubmitOrder.js
View file @
3181467b
// import React, {useState, useEffect
} from 'react'
import
React
,
{
useState
,
useEffect
}
from
'react'
export
default
function
SubmitOrder
()
{
export
default
function
SubmitOrder
(
props
)
{
let
handleSubmitClick
=
(
e
)
=>
{
console
.
log
(
"Submit Button Clicked"
)
props
.
setSubmitButtonActive
(
1
)
}
return
(
return
(
<
div
>
<
div
className
=
"order-component"
id
=
"SubmitOrder"
>
SUBMIT
ORDER
COMPONENT
<
div
className
=
"OrderDirectionsElement"
id
=
"SubmitLabel"
>
<
p
>
Step
4
-
Checkout
<
/p
>
<
/div
>
<
div
id
=
"SubmitButtonContainer"
>
<
p
className
=
"errorMessage"
>
{(
props
.
errorWhileValidating
===
1
&&
props
.
allFieldsValidated
[
0
]
===
0
)?
'One or more fields is missing a value'
:
''
}
<
/p
>
<
button
id
=
"SubmitButtonInput"
onClick
=
{
handleSubmitClick
}
>
Submit
Order
<
/button
>
<
/div
>
<
/div
>
<
/div
>
)
)
}
}
ecom-web/src/components/checkout/checkout.css
0 → 100644
View file @
3181467b
*
{
font-family
:
Arial
,
sans-serif
;
}
#checkout-container
{
height
:
100vh
;
width
:
100%
;
display
:
flex
;
flex-direction
:
column
;
justify-content
:
flex-start
;
align-items
:
center
;
}
.OrderDirectionsElement
{
font-size
:
150%
;
font-weight
:
bold
;
}
.shippingInfoInput
{
margin-bottom
:
10px
;
}
.input-text
{
height
:
40px
;
width
:
100%
;
padding-left
:
20px
;
font-size
:
120%
;
}
.order-component
{
border-top
:
2px
solid
black
;
min-width
:
60%
;
margin-bottom
:
50px
;
}
#orderSummaryContainer
{
display
:
flex
;
flex-direction
:
column
;
width
:
100%
;
align-items
:
center
;
justify-content
:
center
;
margin-top
:
50px
;
}
.OrderSummaryElement
{
display
:
flex
;
flex-direction
:
row
;
width
:
40%
;
justify-content
:
space-between
;
margin-bottom
:
10px
;
font-size
:
150%
;
}
#orderTotal
{
border-top
:
2px
solid
black
;
padding-top
:
10px
;
font-weight
:
bolder
;
color
:
rgb
(
223
,
5
,
5
);
}
#SubmitButtonContainer
{
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
flex-direction
:
column
;
margin-bottom
:
100px
;
margin-top
:
75px
;
}
#SubmitButtonInput
{
width
:
75%
;
color
:
white
;
background-color
:
black
;
height
:
80px
;
font-size
:
200%
;
}
.errorMessage
{
color
:
red
;
font-weight
:
bold
;
font-size
:
120%
;
}
\ No newline at end of file
ecom-web/src/components/checkout/checkout.js
0 → 100644
View file @
3181467b
import
React
,
{
useState
,
useEffect
}
from
'react'
import
{
useSelector
,
useDispatch
}
from
'react-redux'
import
ShippingAddress
from
'./ShippingAddress.js'
import
PaymentMethod
from
'./PaymentMethod.js'
import
ReviewOrder
from
'./ReviewOrder.js'
import
SubmitOrder
from
'./SubmitOrder.js'
import
'./checkout.css'
import
{
dispatchOrderInfo
}
from
'./../../actions/checkout_actions'
export
default
function
Checkout
()
{
///////////////////////
// REDUX Global State
///////////////////////
// const {currentUser} = useSelector(state => state)
// const {cart} = useSelector(state => state)
///////////////////////
// Shipping Info State
///////////////////////
const
[
firstName
,
setFirstName
]
=
useState
([])
const
[
lastName
,
setLastName
]
=
useState
([])
const
[
shippingAddress
,
setShippingAddress
]
=
useState
([])
const
[
aptSuiteNo
,
setAptSuiteNo
]
=
useState
([])
const
[
city
,
setCity
]
=
useState
([])
const
[
state
,
setState
]
=
useState
([])
const
[
zipCode
,
setZipCode
]
=
useState
([])
///////////////////////
// Billing Info State
///////////////////////
const
[
cardNumber
,
setCardNumber
]
=
useState
([
"123456789"
])
const
[
cardHolderName
,
setCardHolderName
]
=
useState
([
"Jane Doe"
])
const
[
expirationDate
,
setExpirationDate
]
=
useState
([
"05/20206"
])
const
[
cvv
,
setCVV
]
=
useState
([
"123"
])
///////////////////////
// Order Review / Summary State
///////////////////////
const
[
numCartItems
,
setNumCartItems
]
=
useState
([
3
])
const
[
itemsTotal
,
setItemsTotal
]
=
useState
([
87.65
])
// arbitrary cart total
const
[
shippingHandling
,
setShippingHandling
]
=
useState
([
8.00
])
// arbitraty shipping and handling amount
const
[
taxRate
,
setTaxRate
]
=
useState
([
0.0725
])
// california tax rate
///////////////////////
// Submit Button State
///////////////////////
const
[
submitButtonActive
,
setSubmitButtonActive
]
=
useState
([
0
])
const
[
allFieldsValidated
,
setAllFieldsValidated
]
=
useState
([
0
])
const
[
errorWhileValidating
,
setErrorWhileValidating
]
=
useState
([
0
])
///////////////////////
// Submit Action State
///////////////////////
const
dispatch
=
useDispatch
()
// This effect listens for the submit button to be clicked
// It then checks each of the required fields to make sure they are non null
useEffect
(
()
=>
{
// when submit button clicked after being inactive
if
(
submitButtonActive
===
1
)
{
// fields to make sure are non-empty
let
fieldsToCheck
=
[
firstName
,
lastName
,
shippingAddress
,
city
,
state
,
zipCode
,
// cardNumber,
// cardHolderName,
// expirationDate,
// cvv
]
// initially validated, gets flipped if required field is empty
let
validated
=
1
for
(
let
i
in
fieldsToCheck
)
{
if
(
fieldsToCheck
[
i
].
length
===
0
)
{
console
.
log
(
"a required Field Value was empty"
)
validated
=
0
break
}
}
// if validated, propogate to component state that all fields were validated
if
(
validated
===
1
)
{
setAllFieldsValidated
(
1
)
}
// if invalid, propogate to component state
else
{
console
.
log
(
"Failed to validate"
)
setErrorWhileValidating
(
1
)
setSubmitButtonActive
(
0
)
}
}
// when submit button gets reset from active to inactive
else
if
(
submitButtonActive
===
0
)
{
;
}
},
[
submitButtonActive
])
// This effect looks for the allFieldsValidated signal and fires off the order submission when complete
useEffect
(
()
=>
{
handleSubmit
()
console
.
log
(
"Successful submission request"
)
},
[
allFieldsValidated
])
let
handleSubmit
=
()
=>
{
console
.
log
(
"Submitting Order!"
)
// let order = {}
// order["firstName"] = firstName
// order["lastName"] = lastName
// order["shippingAddress"] = shippingAddress
// order["aptSuitNo"] = aptSuiteNo
// order["city"] = city
// order["state"] = state
// order["zipCode"] = zipCode
// order["cardNumber"] = cardNumber
// order["cardHolderName"] = cardHolderName
// order["expirationDate"] = expirationDate
// order["cvv"] = cvv
// console.log(order)
let
chrisSpec
=
{
"user"
:
{
"userId"
:
"e-com-test-id"
,
"email"
:
"test@test.test"
,
"firstName"
:
"ecom"
,
"lastName"
:
"test"
},
"address"
:
{
"state"
:
"IL"
,
"city"
:
"chicago"
,
"zip"
:
"90210"
,
"street"
:
"Grand"
},
"cart"
:
{
"id"
:
"something"
,
"userId"
:
"e-com-test-id"
,
"cartItems"
:[
{
"quantity"
:
2
,
"productRef"
:
{
"id"
:
"something"
,
"sku"
:
"AFP-1"
,
"upc"
:
"00002"
}
}
]
}
}
dispatch
(
dispatchOrderInfo
(
chrisSpec
))
}
// This watches for changes on any shipping input fields and prints the current states on any change
useEffect
(
()
=>
{
console
.
log
(
"======================================"
)
console
.
log
(
"First Name: "
+
firstName
)
console
.
log
(
"Last Name: "
+
lastName
)
console
.
log
(
"Shipping Address: "
+
shippingAddress
)
console
.
log
(
"Apt Suite No: "
+
aptSuiteNo
)
console
.
log
(
"City: "
+
city
)
console
.
log
(
"State: "
+
state
)
console
.
log
(
"Zip: "
+
zipCode
)
},
[
firstName
,
lastName
,
shippingAddress
,
aptSuiteNo
,
city
,
state
,
zipCode
])
// This watches for changes on any billing input fields and prints the current states on any change
useEffect
(
()
=>
{
console
.
log
(
"======================================"
)
console
.
log
(
"Card Number: "
+
cardNumber
)
console
.
log
(
"Card Holder Name: "
+
cardHolderName
)
console
.
log
(
"Expiration Date: "
+
expirationDate
)
console
.
log
(
"CVV: "
+
cvv
)
},
[
cardNumber
,
cardHolderName
,
expirationDate
,
cvv
])
return
(
<
div
id
=
"checkout-container"
>
{
/* Collects User's shipping info */
}
<
ShippingAddress
captureFirstName
=
{
setFirstName
}
captureLastName
=
{
setLastName
}
captureShippingAddress
=
{
setShippingAddress
}
captureAptSuiteNo
=
{
setAptSuiteNo
}
captureCity
=
{
setCity
}
captureState
=
{
setState
}
captureZipCode
=
{
setZipCode
}
/
>
{
/* Collects User's payment info */
}
<
PaymentMethod
cardNumber
=
{
cardNumber
}
cardHolderName
=
{
cardHolderName
}
expirationDate
=
{
expirationDate
}
cvv
=
{
cvv
}
captureCardNumber
=
{
setCardNumber
}
captureCardHolderName
=
{
setCardHolderName
}
captureExpirationDate
=
{
setExpirationDate
}
captureCVV
=
{
setCVV
}
/
>
{
/* Displays info about order. Calculates price with tax / shipping applied */
}
<
ReviewOrder
numCartItems
=
{
numCartItems
}
itemsTotal
=
{
itemsTotal
}
shippingHandling
=
{
shippingHandling
}
taxRate
=
{
taxRate
}
/
>
{
/* Request to submit happens here, initiates input validation and sends if success */
}
<
SubmitOrder
submitButtonActive
=
{
submitButtonActive
}
setSubmitButtonActive
=
{
setSubmitButtonActive
}
errorWhileValidating
=
{
errorWhileValidating
}
allFieldsValidated
=
{
allFieldsValidated
}
/
>
<
/div
>
)
}
ecom-web/src/components/checkout/checkout.jsx
deleted
100644 → 0
View file @
1f99e20f
// import React, {useState, useEffect} from 'react'
// import ShippingAddress from './ShippingAddress.js'
// import PaymentMethod from './PaymentMethod.js'
// import ReviewOrder from './ReviewOrder.js'
// import SubmitOrder from './SubmitOrder.js'
export
default
function
checkout
()
{
return
(
<
div
>
</
div
>
)
}
/*
1. Shipping Address
2. Payment Method
3. Review Order
4. Submit Order
*/
\ No newline at end of file
ecom-web/src/reducers/order_reducer.js
0 → 100644
View file @
3181467b
import
{
SEND_USER_ORDER
}
from
'./../actions/checkout_actions'
const
initialState
=
{
orderResponse
:
{},
}
const
orderReducer
=
(
prevState
=
initialState
,
action
)
=>
{
Object
.
freeze
(
prevState
);
const
nextState
=
{...
prevState
};
switch
(
action
.
type
)
{
case
SEND_USER_ORDER
:
nextState
.
orderResponse
=
action
.
payload
return
nextState
default
:
return
nextState
}
}
export
default
orderReducer
\ No newline at end of file
ecom-web/src/reducers/root_reducer.js
View file @
3181467b
import
{
combineReducers
}
from
'redux'
;
import
{
combineReducers
}
from
'redux'
;
import
productsReducer
from
'./products_reducer'
;
import
productsReducer
from
'./products_reducer'
;
import
orderReducer
from
'./order_reducer'
import
userReducer
from
'./user_reducer'
import
userReducer
from
'./user_reducer'
import
cartReducer
from
'./cart_reducer'
;
import
cartReducer
from
'./cart_reducer'
;
const
rootReducer
=
combineReducers
({
const
rootReducer
=
combineReducers
({
market
:
productsReducer
,
market
:
productsReducer
,
user
:
userReducer
,
user
:
userReducer
,
cart
:
cartReducer
cart
:
cartReducer
,
orderStatus
:
orderReducer
});
});
export
default
rootReducer
;
export
default
rootReducer
;
\ No newline at end of file
ecom-web/src/util/order-api.js
0 → 100644
View file @
3181467b
import
axios
from
'axios'
export
const
sendOrderPost
=
(
order
)
=>
{
return
axios
.
post
(
"http://localhost:8080/api/orders"
,
order
)
}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment