frontend: checkout form

Signed-off-by: Ahmet Alp Balkan <ahmetb@google.com>
This commit is contained in:
Ahmet Alp Balkan 2018-06-27 15:43:24 -07:00
parent 10748d6b0a
commit 2ec570c507
5 changed files with 111 additions and 36 deletions

View File

@ -233,6 +233,28 @@ func (fe *frontendServer) viewCartHandler(w http.ResponseWriter, r *http.Request
}
}
func (fe *frontendServer) prepareCheckoutHandler(w http.ResponseWriter, r *http.Request) {
streetAddress1 := r.FormValue("street_address_1")
streetAddress2 := r.FormValue("street_address_2")
city := r.FormValue("city")
country := r.FormValue("country")
zipCode, _ := strconv.ParseInt(r.FormValue("country"), 10, 32)
log.Printf("[prepareCheckout] session_id=%+v", sessionID(r))
_, _ = pb.NewCheckoutServiceClient(fe.checkoutSvcConn).CreateOrder(r.Context(),
&pb.CreateOrderRequest{
UserId: sessionID(r),
UserCurrency: currentCurrency(r),
Address: &pb.Address{
StreetAddress_1: streetAddress1,
StreetAddress_2: streetAddress2,
City: city,
ZipCode: int32(zipCode),
Country: country,
},
})
}
func (fe *frontendServer) logoutHandler(w http.ResponseWriter, r *http.Request) {
log.Printf("[home] session_id=%+v", sessionID(r))
for _, c := range r.Cookies() {

View File

@ -40,6 +40,9 @@ type frontendServer struct {
recommendationSvcAddr string
recommendationSvcConn *grpc.ClientConn
checkoutSvcAddr string
checkoutSvcConn *grpc.ClientConn
}
func main() {
@ -55,6 +58,7 @@ func main() {
mustMapEnv(&svc.currencySvcAddr, "CURRENCY_SERVICE_ADDR")
mustMapEnv(&svc.cartSvcAddr, "CART_SERVICE_ADDR")
mustMapEnv(&svc.recommendationSvcAddr, "RECOMMENDATION_SERVICE_ADDR")
mustMapEnv(&svc.checkoutSvcAddr, "CHECKOUT_SERVICE_ADDR")
var err error
svc.currencySvcConn, err = grpc.DialContext(ctx, svc.currencySvcAddr, grpc.WithInsecure())
@ -82,6 +86,7 @@ func main() {
r.HandleFunc("/cart/empty", ensureSessionID(svc.emptyCartHandler)).Methods(http.MethodPost)
r.HandleFunc("/setCurrency", ensureSessionID(svc.setCurrencyHandler)).Methods(http.MethodPost)
r.HandleFunc("/logout", svc.logoutHandler).Methods(http.MethodGet)
r.HandleFunc("/checkout", ensureSessionID(svc.prepareCheckoutHandler)).Methods(http.MethodGet, http.MethodHead)
r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.Dir("./static/"))))
log.Printf("starting server on :" + srvPort)
log.Fatal(http.ListenAndServe("localhost:"+srvPort, r))

View File

@ -0,0 +1,13 @@
#!/bin/bash
set -ex
kubectl port-forward $(kubectl get pods -l app=currencyservice -o=name) 7000:31337 &
kubectl port-forward $(kubectl get pods -l app=recommendationservice -o=name) 8081:8080 &
kubectl port-forward $(kubectl get pods -l app=cartservice -o=name) 7070:7070 &
kubectl port-forward $(kubectl get pods -l app=productcatalogservice -o=name) 3550:3550 &
kubectl port-forward $(kubectl get pods -l app=checkoutservice -o=name) 5050:5050 &
set +x
trap "exit" INT TERM ERR
trap "kill 0" EXIT
wait

View File

@ -5,45 +5,80 @@
<div class="py-5">
<div class="container bg-light py-3 px-lg-5 py-lg-5">
{{ if eq (len $.items) 0 }}
<h3>Your shopping cart is empty!</h3>
<p>Items you add to your shopping cart will appear here.</p>
<a class="btn btn-primary" href="/" role="button">Browse Products &rarr; </a>
<h3>Your shopping cart is empty!</h3>
<p>Items you add to your shopping cart will appear here.</p>
<a class="btn btn-primary" href="/" role="button">Browse Products &rarr; </a>
{{ else }}
<h3>{{ len $.items }} item {{- if gt (len $.items) 0}}s{{end}}
in your Shopping Cart</h3>
{{ end }}
{{ range $.items }}
<div class="row pt-2 mb-2">
<div class="col text-right">
<a href="/product/{{.Item.Id}}"><img class="img-fluid" style="width: auto; max-height: 60px;"
src="{{.Item.Picture}}" /></a>
</div>
<div class="col align-middle">
<strong>{{.Item.Name}}</strong><br/>
<small class="text-muted">SKU: #{{.Item.Id}}</small>
</div>
<div class="col text-left">
Qty: {{.Quantity}}<br/>
<strong>
{{ renderMoney .Price}}
</strong>
</div>
</div>
{{ end }}
{{ if $.items }}
<div class="row mt-5">
<div class="col-8 offset-2">
<div class="d-flex justify-content-between align-items-center">
<form method="POST" action="/cart/empty">
<button class="btn btn-secondary" type="submit">Empty Cart</button>
</form>
<a class="btn btn-primary" href="/checkout" role="button">Proceed to Checkout &rarr;</a>
<h3>{{ len $.items }} item {{- if gt (len $.items) 1}}s{{end}}
in your Shopping Cart</h3>
{{ range $.items }}
<div class="row pt-2 mb-2">
<div class="col text-right">
<a href="/product/{{.Item.Id}}"><img class="img-fluid" style="width: auto; max-height: 60px;"
src="{{.Item.Picture}}" /></a>
</div>
<div class="col align-middle">
<strong>{{.Item.Name}}</strong><br/>
<small class="text-muted">SKU: #{{.Item.Id}}</small>
</div>
<div class="col text-left">
Qty: {{.Quantity}}<br/>
<strong>
{{ renderMoney .Price}}
</strong>
</div>
</div>
</div>
{{ end }}
{{ end }} <!-- range $.items-->
<hr/>
<div class="row py-3 my-2">
<div class="col-12 col-lg-8 offset-lg-2">
<h3>Prepare to checkout</h3>
<form class="needs-validation">
<div class="form-row">
<div class="col-md-5 mb-3">
<label for="street_address_1">Street Address</label>
<input type="text" class="form-control" id="street_address_1"
value="1600 Amphitheatre Parkway" required>
</div>
<div class="col-md-5 mb-3">
<label for="street_address_2">Street Address (cont.)</label>
<input type="text" class="form-control" id="street_address_2" placeholder="...your address here">
</div>
<div class="col-md-2 mb-3">
<label for="zip_code">Zip Code</label>
<input type="text" class="form-control" id="zip_code" value="94043" required>
</div>
</div>
<div class="form-row">
<div class="col-md-6 mb-3">
<label for="city">City</label>
<input type="text" class="form-control" id="city" placeholder="City" value="Mountain View" required>
</div>
<div class="col-md-3 mb-3">
<label for="state">State</label>
<input type="text" class="form-control" id="state" placeholder="State" value="CA" required>
</div>
<div class="col-md-3 mb-3">
<label for="country">Country</label>
<input type="text" class="form-control" id="country" placeholder="Country Name"
value="United States" required>
</div>
</div>
<div class="form-row">
<div class="col-12 d-flex justify-content-between align-items-center">
<form method="POST" action="/cart/empty">
<button class="btn btn-secondary" type="submit">Empty Cart</button>
</form>
<a class="btn btn-primary" href="/checkout" role="button">Proceed to Checkout &rarr;</a>
</div>
</div>
</form>
</div>
</div>
{{ end }} <!-- end if $.items -->
{{ if $.recommendations}}
<hr/>

View File

@ -1,6 +1,6 @@
{{ define "recommendations" }}
<h5 class="text-muted">Products you might like</h5>
<div class="row mt-2">
<div class="row my-2 py-3">
{{range . }}
<div class="col-3">
<div class="card mb-3 box-shadow">