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) } }