added store

This commit is contained in:
bronku 2025-02-07 08:40:04 +01:00
parent ea6546ec17
commit 0570e47be9
6 changed files with 208 additions and 151 deletions

View file

@ -1,30 +1,6 @@
# iroon - [ ] filtering by date, location
## todo: - [ ] saving to db
- [x] extract order creation form into it's own element - [ ] auth
- [x] option to add additional cakes - [ ] adding cakes
- [x] saving orders on server - [ ] save order/cake should return an error
- [ ] displaying orders - [ ] change store to zero value representing new object
- [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

93
handler.go Normal file
View file

@ -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 <a href='/'>back</a>"))
}
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)
}
}

127
main.go
View file

@ -1,144 +1,29 @@
package main package main
import ( import (
"fmt"
"html/template" "html/template"
"log" "log"
"net/http" "net/http"
"strconv"
"strings"
"time" "time"
_ "github.com/mattn/go-sqlite3" _ "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 <a href='/'>back</a>"))
}
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() { func main() {
var h handler var h handler
templates, err := template.ParseFiles("index.html", "order.html") templates, err := template.ParseFiles("index.html", "order.html")
if err != nil { if err != nil {
log.Fatal("can't parse templates: ", err) log.Fatal("can't parse templates: ", err)
} }
h.tmpl = templates h.tmpl = templates
h.s = NewStore()
orders := make([]order, 0) h.s.saveCake(cake{"Sernik", -1, 120, 0})
orders = append(orders, order{0, "Albert", "Camus", "123456789", "Kartuzy", time.Now().AddDate(0, 0, 7), 0, nil}) h.s.saveCake(cake{"Malinowa chmurka", -1, 120, 0})
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
cakes := make([]cake, 0) h.s.saveOrder(order{-1, "Albert", "Camus", "123456789", "Kartuzy", time.Now().AddDate(0, 0, 7), 0, nil})
cakes = append(cakes, cake{"Sernik", 0, 120, 0}) h.s.saveOrder(order{-1, "George", "Orwell", "", "Kartuzy", time.Now().AddDate(0, 1, 0), 0, nil})
cakes = append(cakes, cake{"Malinowa chmurka", 1, 120, 0}) h.s.saveOrder(order{-1, "Karl", "Marx", "0700", "Somonino", time.Now(), 0, nil})
h.cakes = cakes
http.HandleFunc("GET /order/", logger(h.form)) http.HandleFunc("GET /order/", logger(h.form))
http.HandleFunc("GET /", logger(h.index)) http.HandleFunc("GET /", logger(h.index))

17
middleware.go Normal file
View file

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

21
model.go Normal file
View file

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

65
store.go Normal file
View file

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