From 0570e47be96669f562de9a164452d0b526e76c8d Mon Sep 17 00:00:00 2001 From: bronku Date: Fri, 7 Feb 2025 08:40:04 +0100 Subject: [PATCH] added store --- README.md | 36 +++----------- handler.go | 93 ++++++++++++++++++++++++++++++++++++ main.go | 127 +++----------------------------------------------- middleware.go | 17 +++++++ model.go | 21 +++++++++ store.go | 65 ++++++++++++++++++++++++++ 6 files changed, 208 insertions(+), 151 deletions(-) create mode 100644 handler.go create mode 100644 middleware.go create mode 100644 model.go create mode 100644 store.go diff --git a/README.md b/README.md index b8ba9df..42b511f 100644 --- a/README.md +++ b/README.md @@ -1,30 +1,6 @@ -# iroon -## todo: -- [x] extract order creation form into it's own element -- [x] option to add additional cakes -- [x] saving orders on server -- [ ] displaying orders -- [x] move id to cake struct -- [x] refresh the list on submission -- [ ] persistent storage -- [x] rudimentary css -## ux design -### adding an order: -1. user selects the _add order_ button - 1. the button should open an order creation menu -2. user enters the customer details - 1. incorrect details are highlighted - 2. user can't submit an incorrect order -3. user selects the cakes to add from the list - 1. the list should be scrollable, with a search box if needed - 2. added cakes should appear next to other order details - 3. the user can change the count, or remove the cake entirely -4. user submits the order - 1. after submission the user should get a confirmation, and an order id along with the link to said order page - 2. the form should disappear after submission - 3. there should be a button to go back to creating a new form -### adding a new cake: -1. user selects the _new cake_ button -2. enters the new details -3. user selects submit - \ No newline at end of file +- [ ] filtering by date, location +- [ ] saving to db +- [ ] auth +- [ ] adding cakes +- [ ] save order/cake should return an error +- [ ] change store to zero value representing new object \ No newline at end of file diff --git a/handler.go b/handler.go new file mode 100644 index 0000000..2e9790e --- /dev/null +++ b/handler.go @@ -0,0 +1,93 @@ +package main + +import ( + "fmt" + "html/template" + "net/http" + "strconv" + "strings" + "time" +) + +type handler struct { + tmpl *template.Template + s *store +} + +func (h *handler) form(w http.ResponseWriter, r *http.Request) { + url := strings.Split(r.URL.String(), "/") + o := order{ + ID: -1, + Date: time.Now(), + } + id, err := strconv.Atoi(url[2]) + if err == nil { + newOrder, err := h.s.getOrder(id) + if err == nil { + o = newOrder + } + } + type formData struct { + Order order + Catalogue []cake + } + data := formData{o, h.s.getCakes()} + fmt.Println(data) + + w.Header().Set("content-type", "text/html") + err = h.tmpl.ExecuteTemplate(w, "order.html", data) + if err != nil { + fmt.Println("error executing the template: ", err) + } +} + +func (h *handler) addOrder(w http.ResponseWriter, r *http.Request) { + err := r.ParseForm() + if err != nil { + fmt.Println("can't parse the form") + w.WriteHeader(http.StatusBadRequest) + return + } + fmt.Println("received form: ", r.Form) + + var n order + n.ID, err = strconv.Atoi(r.FormValue("id")) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + fmt.Println("can't parse order id: ", err) + return + } + n.Name = r.FormValue("name") + n.Surname = r.FormValue("surname") + n.Phone = r.FormValue("phone") + n.Location = r.FormValue("location") + n.Date, err = time.Parse("2006-01-02", r.FormValue("date")) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + fmt.Println("can't parse order date: ", err) + return + } + n.Paid, err = strconv.Atoi(r.FormValue("paid")) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + fmt.Println("can't parse order paid: ", err) + return + } + n.Cakes = make([]cake, 0) + + h.s.saveOrder(n) + + fmt.Println("parsed order: ", n) + + w.Header().Set("content-type", "text/html") + w.WriteHeader(http.StatusAccepted) + w.Write([]byte("accepted back")) +} + +func (h *handler) index(w http.ResponseWriter, r *http.Request) { + w.Header().Set("content-type", "text/html") + err := h.tmpl.ExecuteTemplate(w, "index.html", h.s.getOrders()) + if err != nil { + fmt.Println("error executing the template: ", err) + } +} diff --git a/main.go b/main.go index f2e205a..2d30540 100644 --- a/main.go +++ b/main.go @@ -1,144 +1,29 @@ package main import ( - "fmt" "html/template" "log" "net/http" - "strconv" - "strings" "time" _ "github.com/mattn/go-sqlite3" ) -type cake struct { - Name string - ID int - Price int - Amount int -} - -type order struct { - ID int - Name string - Surname string - Phone string - Location string - Date time.Time - Paid int // increments of 0.01 - Cakes []cake -} - -type handler struct { - tmpl *template.Template - cakes []cake - orders []order -} - -func (h *handler) form(w http.ResponseWriter, r *http.Request) { - url := strings.Split(r.URL.String(), "/") - o := order{ - ID: -1, - Date: time.Now(), - } - id, err := strconv.Atoi(url[2]) - if err == nil { - o = h.orders[id] - } - type formData struct { - Order order - Catalogue []cake - } - data := formData{o, h.cakes} - - w.Header().Set("content-type", "text/html") - err = h.tmpl.ExecuteTemplate(w, "order.html", data) - if err != nil { - fmt.Println("error executing the template: ", err) - } -} - -func (h *handler) addOrder(w http.ResponseWriter, r *http.Request) { - err := r.ParseForm() - if err != nil { - fmt.Println("can't parse the form") - w.WriteHeader(http.StatusBadRequest) - return - } - fmt.Println("received form: ", r.Form) - - var n order - n.ID, err = strconv.Atoi(r.FormValue("id")) - if err != nil { - w.WriteHeader(http.StatusBadRequest) - fmt.Println("can't parse order id: ", err) - return - } - n.Name = r.FormValue("name") - n.Surname = r.FormValue("surname") - n.Phone = r.FormValue("phone") - n.Location = r.FormValue("location") - n.Date, err = time.Parse("2006-01-02", r.FormValue("date")) - if err != nil { - w.WriteHeader(http.StatusBadRequest) - fmt.Println("can't parse order date: ", err) - return - } - n.Paid, err = strconv.Atoi(r.FormValue("paid")) - if err != nil { - w.WriteHeader(http.StatusBadRequest) - fmt.Println("can't parse order paid: ", err) - return - } - n.Cakes = make([]cake, 0) - - h.orders = append(h.orders, n) - - fmt.Println("parsed order: ", n) - - w.Header().Set("content-type", "text/html") - w.WriteHeader(http.StatusAccepted) - w.Write([]byte("accepted back")) -} - -func (h *handler) index(w http.ResponseWriter, r *http.Request) { - w.Header().Set("content-type", "text/html") - err := h.tmpl.ExecuteTemplate(w, "index.html", h.orders) - if err != nil { - fmt.Println("error executing the template: ", err) - } -} - -func logger(in http.HandlerFunc) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - start := time.Now() - log := fmt.Sprint(r.Method, " ", r.URL.String()) - in(w, r) - log += fmt.Sprint(" ", time.Since(start)) - fmt.Println(log) - } -} - func main() { var h handler templates, err := template.ParseFiles("index.html", "order.html") if err != nil { log.Fatal("can't parse templates: ", err) } - h.tmpl = templates + h.s = NewStore() - orders := make([]order, 0) - orders = append(orders, order{0, "Albert", "Camus", "123456789", "Kartuzy", time.Now().AddDate(0, 0, 7), 0, nil}) - orders = append(orders, order{1, "George", "Orwell", "", "Kartuzy", time.Now().AddDate(0, 1, 0), 0, nil}) - orders = append(orders, order{2, "Karl", "Marx", "0700", "Somonino", time.Now(), 0, nil}) - h.orders = orders + h.s.saveCake(cake{"Sernik", -1, 120, 0}) + h.s.saveCake(cake{"Malinowa chmurka", -1, 120, 0}) - cakes := make([]cake, 0) - cakes = append(cakes, cake{"Sernik", 0, 120, 0}) - cakes = append(cakes, cake{"Malinowa chmurka", 1, 120, 0}) - h.cakes = cakes + h.s.saveOrder(order{-1, "Albert", "Camus", "123456789", "Kartuzy", time.Now().AddDate(0, 0, 7), 0, nil}) + h.s.saveOrder(order{-1, "George", "Orwell", "", "Kartuzy", time.Now().AddDate(0, 1, 0), 0, nil}) + h.s.saveOrder(order{-1, "Karl", "Marx", "0700", "Somonino", time.Now(), 0, nil}) http.HandleFunc("GET /order/", logger(h.form)) http.HandleFunc("GET /", logger(h.index)) diff --git a/middleware.go b/middleware.go new file mode 100644 index 0000000..0fcd6cf --- /dev/null +++ b/middleware.go @@ -0,0 +1,17 @@ +package main + +import ( + "fmt" + "net/http" + "time" +) + +func logger(in http.HandlerFunc) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + start := time.Now() + log := fmt.Sprint(r.Method, " ", r.URL.String()) + in(w, r) + log += fmt.Sprint(" ", time.Since(start)) + fmt.Println(log) + } +} diff --git a/model.go b/model.go new file mode 100644 index 0000000..58cc687 --- /dev/null +++ b/model.go @@ -0,0 +1,21 @@ +package main + +import "time" + +type cake struct { + Name string + ID int + Price int + Amount int +} + +type order struct { + ID int + Name string + Surname string + Phone string + Location string + Date time.Time + Paid int // increments of 0.01 + Cakes []cake +} diff --git a/store.go b/store.go new file mode 100644 index 0000000..7499083 --- /dev/null +++ b/store.go @@ -0,0 +1,65 @@ +package main + +import ( + "errors" +) + +type store struct { + cakes []cake + orders []order +} + +func NewStore() *store { + var out store + out.cakes = make([]cake, 0) + out.orders = make([]order, 0) + return &out +} + +func (s *store) getCakes() []cake { + return s.cakes +} + +func (s *store) saveCake(newCake cake) int { + if newCake.ID == -1 { + newCake.ID = len(s.cakes) + s.cakes = append(s.cakes, newCake) + return newCake.ID + } + for i := range s.cakes { + if s.cakes[i].ID == newCake.ID { + s.cakes[i] = newCake + break + } + } + return newCake.ID +} + +func (s *store) getOrder(id int) (order, error) { + for _, e := range s.orders { + if e.ID == id { + return e, nil + } + } + return order{}, errors.New("order not found") +} + +func (s *store) getOrders() []order { + return s.orders +} + +func (s *store) saveOrder(newOrder order) int { + if newOrder.ID == -1 { + newOrder.ID = len(s.orders) + s.orders = append(s.orders, newOrder) + return newOrder.ID + } + + for i := range s.orders { + if s.orders[i].ID == newOrder.ID { + s.orders[i] = newOrder + break + } + } + return newOrder.ID +}