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
0ec403fd
Commit
0ec403fd
authored
May 13, 2021
by
Kyle Muldoon
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'AFP-46/order-confirmation-page' into 'Dev'
Afp 46/order confirmation page See merge request
!25
parents
91cbb5a3
60e81925
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
222 additions
and
42 deletions
+222
-42
ProductsController.java
.../com/nisum/ecomservice/controller/ProductsController.java
+9
-4
checkout_actions.js
ecom-web/src/actions/checkout_actions.js
+1
-1
SubmitOrder.js
ecom-web/src/components/checkout/SubmitOrder.js
+8
-2
checkout.js
ecom-web/src/components/checkout/checkout.js
+6
-1
order-confirmation.css
.../src/components/order-confirmation/order-confirmation.css
+17
-0
order-confirmation.jsx
.../src/components/order-confirmation/order-confirmation.jsx
+38
-0
Order.jsx
ecom-web/src/components/order-history/Order.jsx
+23
-17
OrderItem.jsx
ecom-web/src/components/order-history/OrderItem.jsx
+23
-6
order-history.css
ecom-web/src/components/order-history/order-history.css
+77
-4
order-history.jsx
ecom-web/src/components/order-history/order-history.jsx
+3
-3
root.js
ecom-web/src/components/root.js
+2
-0
shopping-cart.js
ecom-web/src/components/shopping-cart/shopping-cart.js
+11
-4
product_api_util.js
ecom-web/src/util/product_api_util.js
+4
-0
No files found.
ecom-service/src/main/java/com/nisum/ecomservice/controller/ProductsController.java
View file @
0ec403fd
...
@@ -6,11 +6,9 @@ import com.nisum.ecomservice.service.ProductService;
...
@@ -6,11 +6,9 @@ import com.nisum.ecomservice.service.ProductService;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.http.HttpStatus
;
import
org.springframework.http.HttpStatus
;
import
org.springframework.http.ResponseEntity
;
import
org.springframework.http.ResponseEntity
;
import
org.springframework.web.bind.annotation.CrossOrigin
;
import
org.springframework.web.bind.annotation.*
;
import
org.springframework.web.bind.annotation.GetMapping
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
reactor.core.publisher.Flux
;
import
reactor.core.publisher.Flux
;
import
reactor.core.publisher.Mono
;
@RestController
@RestController
@RequestMapping
(
"/api"
)
@RequestMapping
(
"/api"
)
...
@@ -38,4 +36,11 @@ public class ProductsController {
...
@@ -38,4 +36,11 @@ public class ProductsController {
return
ResponseEntity
.
ok
(
productService
.
getAllPromotions
());
return
ResponseEntity
.
ok
(
productService
.
getAllPromotions
());
}
}
@GetMapping
(
"/products/{sku}"
)
public
ResponseEntity
<
Mono
<
Product
>>
getProductBySku
(
@PathVariable
String
sku
)
{
return
ResponseEntity
.
ok
(
productService
.
getProductBySku
(
sku
));
}
}
}
ecom-web/src/actions/checkout_actions.js
View file @
0ec403fd
...
@@ -4,7 +4,7 @@ import { sendOrderPost } from './../util/order-api';
...
@@ -4,7 +4,7 @@ import { sendOrderPost } from './../util/order-api';
export
const
SEND_USER_ORDER
=
"SEND_USER_ORDER"
export
const
SEND_USER_ORDER
=
"SEND_USER_ORDER"
const
sendUserOrder
=
(
orderConfirmationResponse
)
=>
({
export
const
sendUserOrder
=
(
orderConfirmationResponse
)
=>
({
type
:
SEND_USER_ORDER
,
type
:
SEND_USER_ORDER
,
payload
:
orderConfirmationResponse
payload
:
orderConfirmationResponse
})
})
...
...
ecom-web/src/components/checkout/SubmitOrder.js
View file @
0ec403fd
import
React
,
{
useState
,
useEffect
}
from
'react'
import
React
,
{
useState
,
useEffect
}
from
'react'
import
{
useSelector
}
from
'react-redux'
;
export
default
function
SubmitOrder
(
props
)
{
export
default
function
SubmitOrder
(
props
)
{
const
{
currentUser
}
=
useSelector
(
state
=>
state
);
let
handleSubmitClick
=
()
=>
{
let
handleSubmitClick
=
()
=>
{
console
.
log
(
"Submit Button Clicked"
)
console
.
log
(
"Submit Button Clicked"
)
...
@@ -16,9 +19,12 @@ export default function SubmitOrder(props) {
...
@@ -16,9 +19,12 @@ export default function SubmitOrder(props) {
<
p
>
Step
4
-
Checkout
<
/p
>
<
p
>
Step
4
-
Checkout
<
/p
>
<
/div
>
<
/div
>
<
div
id
=
"SubmitButtonContainer"
>
<
div
id
=
"SubmitButtonContainer"
>
<
p
className
=
"errorMessage"
>
{(
props
.
errorWhileValidating
===
1
&&
props
.
allFieldsValidated
===
0
)?
'One or more fields is missing a value'
:
''
}
<
/p
>
<
p
className
=
"errorMessage"
>
{(
props
.
errorWhileValidating
===
1
&&
props
.
allFieldsValidated
===
0
)?
'One or more fields is missing a value'
:
''
}
<
/p
>
<
button
id
=
"SubmitButtonInput"
onClick
=
{()
=>
{
handleSubmitClick
()}}
>
Submit
Order
<
/button
>
<
button
id
=
"SubmitButtonInput"
onClick
=
{()
=>
{
handleSubmitClick
()}}
>
Submit
Order
<
/button
>
<
/div
>
<
/div
>
<
/div
>
<
/div
>
...
...
ecom-web/src/components/checkout/checkout.js
View file @
0ec403fd
...
@@ -7,7 +7,8 @@ import ReviewOrder from './ReviewOrder.js'
...
@@ -7,7 +7,8 @@ import ReviewOrder from './ReviewOrder.js'
import
SubmitOrder
from
'./SubmitOrder.js'
import
SubmitOrder
from
'./SubmitOrder.js'
import
'./checkout.css'
import
'./checkout.css'
import
{
dispatchOrderInfo
}
from
'./../../actions/checkout_actions'
import
{
dispatchOrderInfo
}
from
'./../../actions/checkout_actions'
import
{
Redirect
}
from
'react-router'
import
{
updateUserCart
}
from
'./../../actions/cart_actions'
import
{
updateUserCart
}
from
'./../../actions/cart_actions'
import
{
calcTotalPrice
,
calcNumItems
,
storeCartItemsInProcessing
}
from
'./../../actions/cart_processing_actions'
import
{
calcTotalPrice
,
calcNumItems
,
storeCartItemsInProcessing
}
from
'./../../actions/cart_processing_actions'
...
@@ -143,6 +144,10 @@ export default function Checkout() {
...
@@ -143,6 +144,10 @@ export default function Checkout() {
}
}
//redirect to order confirmation page once reponse is recieved
const
{
orderResponse
}
=
useSelector
(
state
=>
state
.
orderStatus
);
if
(
orderResponse
.
id
)
return
<
Redirect
to
=
"/order-confirmation"
/>
return
(
return
(
<
div
id
=
"checkout-container"
>
<
div
id
=
"checkout-container"
>
...
...
ecom-web/src/components/order-confirmation/order-confirmation.css
0 → 100644
View file @
0ec403fd
main
{
margin
:
0
auto
;
max-width
:
1080px
;
}
#order-confirmation-header
{
font-size
:
40px
;
text-align
:
center
;
padding
:
10px
;
}
#return-to-martket
{
margin-top
:
50px
;
display
:
flex
;
justify-content
:
center
;
width
:
100%
;
}
\ No newline at end of file
ecom-web/src/components/order-confirmation/order-confirmation.jsx
0 → 100644
View file @
0ec403fd
import
React
,
{
useEffect
}
from
'react'
;
import
{
useDispatch
,
useSelector
}
from
'react-redux'
;
import
{
Redirect
}
from
'react-router'
;
import
{
NavLink
}
from
'react-router-dom'
;
import
{
sendUserOrder
}
from
'../../actions/checkout_actions'
import
Order
from
'../order-history/Order'
;
import
'./order-confirmation.css'
const
OrderConfirmation
=
()
=>
{
const
dispatch
=
useDispatch
();
const
{
orderResponse
}
=
useSelector
(
state
=>
state
.
orderStatus
);
useEffect
(()
=>
{
return
()
=>
dispatch
(
sendUserOrder
({}));
},[])
const
orderPlaced
=
new
Date
(
orderResponse
.
orderCreatedAt
);
if
(
!
orderResponse
.
id
)
return
(<
Redirect
to=
"/product-market"
/>)
//once we have flow from place order page, this can be uncommented
return
(
<
main
>
<
h1
id=
"order-confirmation-header"
>
Thanks for your order!
</
h1
>
<
Order
order=
{
orderResponse
}
alt=
{
0
}
/>
<
div
id=
"return-to-market"
>
<
NavLink
to=
"/product-market"
>
Return To Market
</
NavLink
>
</
div
>
</
main
>
);
}
export
default
OrderConfirmation
;
\ No newline at end of file
ecom-web/src/components/order-history/Order.jsx
View file @
0ec403fd
...
@@ -5,28 +5,15 @@ import OrderItem from './OrderItem';
...
@@ -5,28 +5,15 @@ import OrderItem from './OrderItem';
const
Order
=
(
props
)
=>
{
const
Order
=
(
props
)
=>
{
const
{
order
}
=
props
;
const
{
order
,
alt
}
=
props
;
const
{
orderItems
,
customerAddress
}
=
order
;
const
{
orderItems
,
customerAddress
}
=
order
;
const
orderTotalPrice
=
totalPrice
(
orderItems
);
const
orderTotalPrice
=
totalPrice
(
orderItems
);
const
orderPlaced
=
new
Date
(
order
.
orderCreatedAt
);
const
orderPlaced
=
new
Date
(
order
.
orderCreatedAt
);
return
(
return
(
<
div
className=
"order"
>
<
div
className=
{
`order order-${alt%2}`
}
>
<
p
><
span
className=
"order-field"
>
Order ID:
</
span
>
{
order
.
id
}
</
p
>
<
p
className=
"order-number"
>
Order #:
{
order
.
id
}
</
p
>
<
p
><
span
className=
"order-field"
>
Order Status:
</
span
>
{
order
.
orderStatus
}
</
p
>
<
p
><
span
className=
"order-field"
>
Order Placed:
</
span
>
{
orderPlaced
.
getUTCMonth
()
}
/
{
orderPlaced
.
getUTCDay
()
}
/
{
orderPlaced
.
getUTCFullYear
()
}
</
p
>
<
p
>
<
span
className=
"order-field"
>
Delivery Address:
</
span
>
{
`
${customerAddress.street},
${customerAddress.city},
${customerAddress.state} ${customerAddress.zip}
`
}
</
p
>
<
p
><
span
className=
"order-field"
>
Items Ordered:
</
span
></
p
>
<
div
className=
"products-ordered"
>
<
div
className=
"products-ordered"
>
{
orderItems
.
map
((
orderItem
,
ind
)
=>
{
{
orderItems
.
map
((
orderItem
,
ind
)
=>
{
return
(
return
(
...
@@ -34,8 +21,27 @@ const Order = (props) => {
...
@@ -34,8 +21,27 @@ const Order = (props) => {
)
)
})
}
})
}
</
div
>
</
div
>
<
div
className=
"total-price"
>
<
p
><
span
className=
"order-field"
>
Total Price:
</
span
>
$
{
orderTotalPrice
}
</
p
>
<
p
><
span
className=
"order-field"
>
Total Price:
</
span
>
$
{
orderTotalPrice
}
</
p
>
</
div
>
<
div
className=
"order-details"
>
<
div
className=
"order-description"
>
<
p
className=
"order-status-header"
>
Status
</
p
>
<
p
><
span
className=
"order-field"
>
Order Placed:
</
span
>
{
orderPlaced
.
getUTCMonth
()
}
/
{
orderPlaced
.
getUTCDay
()
}
/
{
orderPlaced
.
getUTCFullYear
()
}
</
p
>
<
p
><
span
className=
"order-field"
>
Order Status:
</
span
>
{
order
.
orderStatus
}
</
p
>
</
div
>
<
div
className=
"shipping-details"
>
<
p
className=
"shipping-details-header"
>
Shipping Address
</
p
>
<
span
>
{
customerAddress
.
street
}
,
</
span
>
<
p
>
{
`${customerAddress.city},
${customerAddress.state} ${customerAddress.zip}
`
}
</
p
>
</
div
>
</
div
>
</
div
>
</
div
>
)
)
}
}
...
...
ecom-web/src/components/order-history/OrderItem.jsx
View file @
0ec403fd
import
React
from
'react'
;
import
React
,
{
useEffect
,
useState
}
from
'react'
;
import
{
fetchProductBySku
}
from
'../../util/product_api_util'
;
const
OrderItem
=
(
props
)
=>
{
const
OrderItem
=
(
props
)
=>
{
const
{
orderItem
}
=
props
;
const
{
orderItem
}
=
props
;
const
{
itemName
,
itemPrice
,
itemQuantity
}
=
orderItem
;
const
{
itemName
,
itemPrice
,
itemQuantity
,
itemSku
}
=
orderItem
;
const
subTotal
=
itemQuantity
*
itemPrice
;
const
subTotal
=
itemQuantity
*
itemPrice
;
const
[
fullItemDetails
,
setFullItemDetails
]
=
useState
({});
useEffect
(
async
()
=>
{
const
item
=
await
fetchProductBySku
(
itemSku
);
setFullItemDetails
(
item
.
data
);
},
[]);
return
(
return
(
<
div
className=
"order-item"
>
<
div
className=
"order-item"
>
<
p
>
Item:
{
itemName
}
</
p
>
<
div
className=
"pic-container"
>
<
p
>
Quantity:
{
itemQuantity
}
</
p
>
<
img
className=
"order-item-pic"
src=
{
fullItemDetails
.
productImageUrl
}
/>
<
p
>
Price Per Unit: $
{
itemPrice
.
toFixed
(
2
)
}
</
p
>
</
div
>
<
p
>
Subtotal: $
{
subTotal
.
toFixed
(
2
)
}
</
p
>
<
div
className=
"item-details-container"
>
<
p
className=
"order-item-name"
>
{
itemName
}
</
p
>
<
p
className=
"order-item-quantity"
>
QTY:
{
itemQuantity
}
</
p
>
</
div
>
<
div
className=
"item-price-container"
>
<
p
>
Price Per Unit: $
{
itemPrice
.
toFixed
(
2
)
}
</
p
>
<
p
className=
"order-subtotal"
>
Subtotal: $
{
subTotal
.
toFixed
(
2
)
}
</
p
>
</
div
>
</
div
>
</
div
>
)
)
}
}
...
...
ecom-web/src/components/order-history/order-history.css
View file @
0ec403fd
...
@@ -6,8 +6,8 @@ main {
...
@@ -6,8 +6,8 @@ main {
.order
{
.order
{
display
:
flex
;
display
:
flex
;
flex-direction
:
column
;
flex-direction
:
column
;
border
:
1px
solid
black
;
padding
:
20px
;
padding
:
20px
;
margin-bottom
:
10px
;
}
}
.products-ordered
{
.products-ordered
{
...
@@ -16,12 +16,16 @@ main {
...
@@ -16,12 +16,16 @@ main {
}
}
.order-item
{
.order-item
{
border
:
1px
solid
gray
;
display
:
grid
;
padding
:
5px
;
grid-template-columns
:
1
fr
4
fr
1
fr
;
grid-template-rows
:
auto
;
border-bottom
:
1px
solid
lightgray
;
width
:
100%
;
}
}
.order-
field
{
.order-
number
{
font-weight
:
600
;
font-weight
:
600
;
border-bottom
:
1px
solid
black
;
}
}
#order-history-header
{
#order-history-header
{
...
@@ -29,3 +33,72 @@ main {
...
@@ -29,3 +33,72 @@ main {
text-align
:
center
;
text-align
:
center
;
padding
:
10px
;
padding
:
10px
;
}
}
.order-item-pic
{
width
:
200px
;
height
:
200px
;
padding
:
25px
;
}
.item-details-container
{
display
:
flex
;
flex-direction
:
column
;
justify-content
:
center
;
align-items
:
center
;
}
.order-item-name
{
font-size
:
24px
;
}
.order-item-quantity
{
color
:
gray
;
}
.item-price-container
{
display
:
flex
;
flex-direction
:
column
;
align-items
:
center
;
justify-content
:
center
;
}
.order-subtotal
{
font-weight
:
600
;
}
.order-details
{
display
:
grid
;
grid-template-columns
:
1
fr
1
fr
;
grid-template-rows
:
auto
;
}
.total-price
{
display
:
flex
;
justify-content
:
flex-end
;
border-bottom
:
1px
solid
lightgray
;
padding
:
20px
;
font-weight
:
600
;
font-size
:
20px
;
}
.order-status-header
,
.shipping-details-header
{
font-weight
:
600
;
border-bottom
:
1px
solid
black
;
width
:
fit-content
;
margin-bottom
:
10px
;
font-size
:
16px
;
margin-top
:
10px
;
}
.shipping-details
,
.order-description
{
display
:
flex
;
flex-direction
:
column
;
justify-content
:
center
;
align-items
:
center
;
}
.order-1
{
background-color
:
#f0f0f0
;
}
\ No newline at end of file
ecom-web/src/components/order-history/order-history.jsx
View file @
0ec403fd
...
@@ -25,12 +25,12 @@ const OrderHistory = () => {
...
@@ -25,12 +25,12 @@ const OrderHistory = () => {
return
(
return
(
<
main
>
<
main
>
<
h1
id=
"order-history-header"
>
Order History
</
h1
>
<
h1
id=
"order-history-header"
>
Order History
</
h1
>
{
user
===
null
?
(
{
user
===
null
||
user
.
currentUser
===
null
?
(
<
div
>
Please login to place orders!
</
div
>
<
div
>
Please login to place orders!
</
div
>
)
:
null
}
)
:
null
}
<
div
id=
"orders"
>
<
div
id=
"orders"
>
{
orderHistory
.
map
(
order
=>
{
{
orderHistory
.
map
(
(
order
,
ind
)
=>
{
return
<
Order
order=
{
order
}
/>;
return
<
Order
order=
{
order
}
key=
{
ind
}
alt=
{
ind
}
/>;
})
}
})
}
</
div
>
</
div
>
</
main
>
</
main
>
...
...
ecom-web/src/components/root.js
View file @
0ec403fd
...
@@ -7,6 +7,7 @@ import ShoppingCartContainer from './shopping-cart/shopping-cart-container';
...
@@ -7,6 +7,7 @@ import ShoppingCartContainer from './shopping-cart/shopping-cart-container';
import
CheckoutContianer
from
'./checkout/checkout-container'
;
import
CheckoutContianer
from
'./checkout/checkout-container'
;
import
Header
from
'./Header/header-container'
import
Header
from
'./Header/header-container'
import
OrderHistory
from
'./order-history/order-history'
;
import
OrderHistory
from
'./order-history/order-history'
;
import
OrderConfirmation
from
'./order-confirmation/order-confirmation'
;
const
Root
=
({
store
})
=>
(
const
Root
=
({
store
})
=>
(
<
Provider
store
=
{
store
}
>
<
Provider
store
=
{
store
}
>
...
@@ -24,6 +25,7 @@ const Root = ({ store }) => (
...
@@ -24,6 +25,7 @@ const Root = ({ store }) => (
<
Route
path
=
"/cart"
component
=
{
ShoppingCartContainer
}
/
>
<
Route
path
=
"/cart"
component
=
{
ShoppingCartContainer
}
/
>
<
Route
path
=
"/checkout"
component
=
{
CheckoutContianer
}
/
>
<
Route
path
=
"/checkout"
component
=
{
CheckoutContianer
}
/
>
<
Route
path
=
"/orders"
component
=
{
OrderHistory
}
/
>
<
Route
path
=
"/orders"
component
=
{
OrderHistory
}
/
>
<
Route
path
=
"/order-confirmation"
component
=
{
OrderConfirmation
}
/
>
<
/Switch
>
<
/Switch
>
<
/BrowserRouter
>
<
/BrowserRouter
>
<
/Provider
>
<
/Provider
>
...
...
ecom-web/src/components/shopping-cart/shopping-cart.js
View file @
0ec403fd
...
@@ -90,7 +90,7 @@ export default function ShoppingCart() {
...
@@ -90,7 +90,7 @@ export default function ShoppingCart() {
},
[
cartItems
])
},
[
cartItems
])
if
(
!
userSession
)
return
<
Redirect
to
=
"/product-market"
/>
//
if (!userSession) return <Redirect to="/product-market" />
return
(
return
(
<
div
id
=
"shoppingCartContainer"
>
<
div
id
=
"shoppingCartContainer"
>
...
@@ -110,9 +110,16 @@ export default function ShoppingCart() {
...
@@ -110,9 +110,16 @@ export default function ShoppingCart() {
})}
})}
<
/div
>
<
/div
>
<
Link
id
=
"checkoutButtonContainer"
to
=
"/checkout"
>
{
<
button
id
=
"checkoutButton"
>
Proceed
To
Checkout
<
/button
>
cartItems
.
length
>
0
?
(
<
/Link
>
<
Link
id
=
"checkoutButtonContainer"
to
=
"/checkout"
>
<
button
id
=
"checkoutButton"
>
Proceed
To
Checkout
<
/button
>
<
/Link
>
)
:
(
<
div
>
Add
more
items
to
your
cart
!<
/div
>
)
}
<
/div
>
<
/div
>
...
...
ecom-web/src/util/product_api_util.js
View file @
0ec403fd
...
@@ -11,4 +11,8 @@ export const fetchPromotions = () => {
...
@@ -11,4 +11,8 @@ export const fetchPromotions = () => {
export
const
fetchProductsAndPromotions
=
()
=>
{
export
const
fetchProductsAndPromotions
=
()
=>
{
return
axios
.
get
(
`
${
Config
.
baseApiUrl
}
/api/products-and-promos`
)
return
axios
.
get
(
`
${
Config
.
baseApiUrl
}
/api/products-and-promos`
)
}
export
const
fetchProductBySku
=
(
sku
)
=>
{
return
axios
.
get
(
`
${
Config
.
baseApiUrl
}
/api/products/
${
sku
}
`
)
}
}
\ 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