package main
import (
"errors"
"fmt"
"html/template"
"net/http"
"os"
"strconv"
)
var (
templates = template.Must(template.ParseFiles("templates/index.html", "templates/pizza.html", "templates/ordered.html"))
)
type Pizza struct {
Name string `json:"name"`
Price int `json:"price"`
Quantity int `json:"quantity"`
}
/**
* Handler function for "/"
*/
func indexHandler(w http.ResponseWriter, r *http.Request) {
templates.ExecuteTemplate(w, "index.html", nil)
}
/**
* Handler function for "/print", only accepts POST requests
*
* Tells the API to print the text specified in its Form
*/
func printHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
return
}
text := r.PostFormValue("text")
json_command := PrintCommand{Command: "print", Text: text}
_, err := sendJSONToServer(nil, json_command)
if err != nil {
fmt.Fprintf(w, "Error while connecting to the printer server")
return
}
http.Redirect(w, r, "/", http.StatusSeeOther)
}
/**
* Handler function for "/pizza", only accepts POST requests
*
* Tells the API to print the pizza order specified in its Form, then receive
* back the correct price and return a formatted HTML page
*/
func pizzaHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
return
}
pizzas := make([]Pizza, 0)
r.ParseForm()
for key, _ := range r.Form {
// only put in the pizzas that have a quantity bigger than 0
if key != "submit" && r.Form[key][0] != "0" {
quantity, _ := strconv.ParseInt(r.Form[key][0], 10, 0)
pizzas = append(pizzas, Pizza{key, 0, int(quantity)})
}
}
json_command := PizzaCommand{Command: "pizza", Pizzas: pizzas}
socket, err := sendJSONToServer(nil, json_command)
if err != nil {
fmt.Fprintf(w, "Error while connecting to the printer server")
return
}
price := ReceivePrice{}
_, err = receiveJSONFromServer(socket, &price)
if err != nil {
fmt.Fprintf(w, "Error while connecting to the printer server")
return
}
// pass the order data to the HTML
order := struct {
Pizzas []Pizza
TotalPrice int
}{
pizzas,
price.TotalPrice,
}
templates.ExecuteTemplate(w, "ordered.html", order)
}
/**
* Handler function for "/order_pizzas"
*
* Asks the API for the list of all pizzas then returns a formatted HTML page
*/
func orderPizzasHandler(w http.ResponseWriter, r *http.Request) {
json_command := GetPizzasCommand{Command: "get-pizzas"}
socket, err := sendJSONToServer(nil, json_command)
if err != nil {
fmt.Fprintf(w, "Error while connecting to the printer server")
return
}
pizzas := ReceivePizzas{}
_, err = receiveJSONFromServer(socket, &pizzas)
if err != nil {
fmt.Fprintf(w, "Error while connecting to the printer server")
return
}
templates.ExecuteTemplate(w, "pizza.html", pizzas.Pizzas)
}
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", indexHandler)
mux.HandleFunc("/print", printHandler)
mux.HandleFunc("/pizza", pizzaHandler)
mux.HandleFunc("/order_pizzas", orderPizzasHandler)
mux.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))
err := http.ListenAndServe(":8080", mux)
if errors.Is(err, http.ErrServerClosed) {
fmt.Println("Server closed")
} else if err != nil {
fmt.Printf("Error starting server: %s\n", err)
os.Exit(1)
}
}