use htmx to add line items

eliminates a db round trip
This commit is contained in:
Ruidy 2024-02-09 12:05:15 +01:00
parent 8968198045
commit 9d3b0fec6d
No known key found for this signature in database
GPG key ID: E00F51288CB857CC
7 changed files with 174 additions and 82 deletions

View file

@ -1,8 +1,11 @@
package server
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"os"
"strconv"
"time"
@ -47,9 +50,9 @@ func (s Server) handleCreateBooking() echo.HandlerFunc {
return err
}
ts, err := parseTime(c.FormValue("from"))
ts, _ := parseTime(c.FormValue("from"))
nb.From = ts
ts, err = parseTime(c.FormValue("to"))
ts, _ = parseTime(c.FormValue("to"))
nb.To = ts
b := &booking.Booking{
@ -111,7 +114,7 @@ func (s Server) handleCreateItem() echo.HandlerFunc {
PaymentMethod: ni.PaymentMethod,
}
_ = s.db.Create(i)
return c.Redirect(http.StatusSeeOther, fmt.Sprintf("%s/%d", constants.RouteBooking, bid))
return s.renderTempl(c, http.StatusCreated, views.LineItem(i))
}
}

View file

@ -11,6 +11,7 @@ templ BaseLayout() {
<link rel="icon" href="/static/img/favicon.svg"/>
<link rel="stylesheet" href="/static/css/pico.min.css"/>
<link rel="stylesheet" href="/static/css/style.css"/>
<script src="https://unpkg.com/htmx.org@1.9.10"></script>
</head>
<body>
<nav class="container-fluid">

View file

@ -32,21 +32,30 @@ func BaseLayout() templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</title><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><meta name=\"description\" content=\"AI assistant to help you improve your management\"><link rel=\"icon\" href=\"/static/img/favicon.svg\"><link rel=\"stylesheet\" href=\"/static/css/pico.min.css\"><link rel=\"stylesheet\" href=\"/static/css/style.css\"></head><body><nav class=\"container-fluid\"><ul><li><a href=\"/\"><b>")
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</title><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><meta name=\"description\" content=\"AI assistant to help you improve your management\"><link rel=\"icon\" href=\"/static/img/favicon.svg\"><link rel=\"stylesheet\" href=\"/static/css/pico.min.css\"><link rel=\"stylesheet\" href=\"/static/css/style.css\"><script src=\"https://unpkg.com/htmx.org@1.9.10\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Var3 := `🏨 RentEase `
templ_7745c5c3_Var3 := ``
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var3)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</script></head><body><nav class=\"container-fluid\"><ul><li><a href=\"/\"><b>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Var4 := `🏨 RentEase `
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var4)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</b></a></li></ul><ul><li><a href=\"/bookings\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Var4 := `Bookings`
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var4)
templ_7745c5c3_Var5 := `Bookings`
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var5)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@ -54,8 +63,8 @@ func BaseLayout() templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Var5 := `New Booking`
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var5)
templ_7745c5c3_Var6 := `New Booking`
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var6)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@ -71,8 +80,8 @@ func BaseLayout() templ.Component {
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Var6 := `🏨 RentEase &copy 2024`
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var6)
templ_7745c5c3_Var7 := `🏨 RentEase &copy 2024`
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var7)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}

View file

@ -79,10 +79,10 @@ templ BookingById(booking *booking.Booking, items, platforms, paymentMethods []s
<th scope="col">Payment Status</th>
</tr>
</thead>
<tbody>
for i, item := range booking.Items {
<tbody id="line-items">
for _, item := range booking.Items {
<tr>
<th scope="row">{ strconv.Itoa(i+1) }</th>
<th scope="row"></th>
<td>{ item.Item }</td>
<td>{ strconv.Itoa(item.Quantity) }</td>
<td>{ item.Price }</td>
@ -93,14 +93,10 @@ templ BookingById(booking *booking.Booking, items, platforms, paymentMethods []s
</tbody>
</table>
</figure>
<button class="secondary" onclick="new_line_modal.showModal()">Add line </button>
<dialog id="new_line_modal">
<form method="post" action={ templ.SafeURL(fmt.Sprintf("/bookings/%d/items", booking.Id)) }>
<details>
<summary role="button" class="secondary">Add line </summary>
<form hx-post={ fmt.Sprintf("/bookings/%d/items", booking.Id) } hx-target="#line-items" hx-swap="afterend">
<article>
<header>
<a onclick="new_line_modal.close()" aria-label="Close" class="close"></a>
New line item
</header>
<label for="new-line-item">
Item
<select name="item" id="new-line-item">
@ -128,6 +124,6 @@ templ BookingById(booking *booking.Booking, items, platforms, paymentMethods []s
<button type="submit">Add</button>
</article>
</form>
</dialog>
</details>
}
}

View file

@ -312,25 +312,25 @@ func BookingById(booking *booking.Booking, items, platforms, paymentMethods []st
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</th></tr></thead> <tbody>")
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</th></tr></thead> <tbody id=\"line-items\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
for i, item := range booking.Items {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<tr><th scope=\"row\">")
for _, item := range booking.Items {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<tr><th scope=\"row\"></th><td>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var25 string = strconv.Itoa(i + 1)
var templ_7745c5c3_Var25 string = item.Item
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var25))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</th><td>")
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</td><td>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var26 string = item.Item
var templ_7745c5c3_Var26 string = strconv.Itoa(item.Quantity)
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var26))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
@ -339,7 +339,7 @@ func BookingById(booking *booking.Booking, items, platforms, paymentMethods []st
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var27 string = strconv.Itoa(item.Quantity)
var templ_7745c5c3_Var27 string = item.Price
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var27))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
@ -348,7 +348,7 @@ func BookingById(booking *booking.Booking, items, platforms, paymentMethods []st
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var28 string = item.Price
var templ_7745c5c3_Var28 string = item.PaymentMethod
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var28))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
@ -357,61 +357,42 @@ func BookingById(booking *booking.Booking, items, platforms, paymentMethods []st
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var29 string = item.PaymentMethod
var templ_7745c5c3_Var29 string = item.PaymentStatus
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var29))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</td><td>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var30 string = item.PaymentStatus
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var30))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</td></tr>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</tbody></table></figure><button class=\"secondary\" onclick=\"new_line_modal.showModal()\">")
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</tbody></table></figure><details><summary role=\"button\" class=\"secondary\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Var31 := `Add line `
templ_7745c5c3_Var30 := `Add line `
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var30)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</summary><form hx-post=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(fmt.Sprintf("/bookings/%d/items", booking.Id)))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\" hx-target=\"#line-items\" hx-swap=\"afterend\"><article><label for=\"new-line-item\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Var31 := `Item`
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var31)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</button> <dialog id=\"new_line_modal\"><form method=\"post\" action=\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var32 templ.SafeURL = templ.SafeURL(fmt.Sprintf("/bookings/%d/items", booking.Id))
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var32)))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"><article><header><a onclick=\"new_line_modal.close()\" aria-label=\"Close\" class=\"close\"></a> ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Var33 := `New line item`
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var33)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</header><label for=\"new-line-item\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Var34 := `Item`
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var34)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" <select name=\"item\" id=\"new-line-item\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
@ -429,8 +410,8 @@ func BookingById(booking *booking.Booking, items, platforms, paymentMethods []st
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var35 string = item
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var35))
var templ_7745c5c3_Var32 string = item
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var32))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@ -443,8 +424,8 @@ func BookingById(booking *booking.Booking, items, platforms, paymentMethods []st
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Var36 := `Quantity`
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var36)
templ_7745c5c3_Var33 := `Quantity`
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var33)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@ -452,8 +433,8 @@ func BookingById(booking *booking.Booking, items, platforms, paymentMethods []st
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Var37 := `Price`
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var37)
templ_7745c5c3_Var34 := `Price`
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var34)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@ -461,8 +442,8 @@ func BookingById(booking *booking.Booking, items, platforms, paymentMethods []st
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Var38 := `Payment Method`
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var38)
templ_7745c5c3_Var35 := `Payment Method`
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var35)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@ -483,8 +464,8 @@ func BookingById(booking *booking.Booking, items, platforms, paymentMethods []st
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var39 string = paymentMethod
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var39))
var templ_7745c5c3_Var36 string = paymentMethod
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var36))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
@ -497,12 +478,12 @@ func BookingById(booking *booking.Booking, items, platforms, paymentMethods []st
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Var40 := `Add`
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var40)
templ_7745c5c3_Var37 := `Add`
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ_7745c5c3_Var37)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</button></article></form></dialog>")
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</button></article></form></details>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}

View file

@ -0,0 +1,17 @@
package views
import (
"strconv"
"github.com/rjNemo/rentease/internal/domains/booking"
)
templ LineItem(item *booking.Item) {
<tr>
<th scope="row"></th>
<td>{ item.Item }</td>
<td>{ strconv.Itoa(item.Quantity) }</td>
<td>{ item.Price }</td>
<td>{ item.PaymentMethod }</td>
<td>{ item.PaymentStatus }</td>
</tr>
}

View file

@ -0,0 +1,85 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: 0.2.476
package views
//lint:file-ignore SA4006 This context is only used if a nested component is present.
import "github.com/a-h/templ"
import "context"
import "io"
import "bytes"
import (
"github.com/rjNemo/rentease/internal/domains/booking"
"strconv"
)
func LineItem(item *booking.Item) templ.Component {
return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) {
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer)
if !templ_7745c5c3_IsBuffer {
templ_7745c5c3_Buffer = templ.GetBuffer()
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
}
ctx = templ.InitializeContext(ctx)
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
if templ_7745c5c3_Var1 == nil {
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<tr><th scope=\"row\"></th><td>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var2 string = item.Item
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</td><td>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var3 string = strconv.Itoa(item.Quantity)
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</td><td>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var4 string = item.Price
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</td><td>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var5 string = item.PaymentMethod
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</td><td>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var6 string = item.PaymentStatus
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("</td></tr>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if !templ_7745c5c3_IsBuffer {
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W)
}
return templ_7745c5c3_Err
})
}