I use Sortable, exactly like HTMx’s sorting example does[0]. Had to export the slug or ID of some entries to be able to add it in the hidden input. For forms that use ID instead of slug, had to use an input name other than “id” because otherwise the swap would fail due to bug #1496[1]. It is apparently fixed in a recent version of HTMx, but i did not want to update for fear of behaviour changes. [0]: https://htmx.org/examples/sortable/ [1]: https://github.com/bigskysoftware/htmx/issues/1496
96 lines
2.5 KiB
Go
96 lines
2.5 KiB
Go
/*
|
|
* SPDX-FileCopyrightText: 2023 jordi fita mas <jfita@peritasoft.com>
|
|
* SPDX-License-Identifier: AGPL-3.0-only
|
|
*/
|
|
|
|
package home
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
|
|
"dev.tandem.ws/tandem/camper/pkg/auth"
|
|
"dev.tandem.ws/tandem/camper/pkg/carousel"
|
|
"dev.tandem.ws/tandem/camper/pkg/database"
|
|
httplib "dev.tandem.ws/tandem/camper/pkg/http"
|
|
"dev.tandem.ws/tandem/camper/pkg/locale"
|
|
"dev.tandem.ws/tandem/camper/pkg/template"
|
|
)
|
|
|
|
type PublicHandler struct {
|
|
}
|
|
|
|
func NewPublicHandler() *PublicHandler {
|
|
return &PublicHandler{}
|
|
}
|
|
|
|
func (h *PublicHandler) Handler(user *auth.User, company *auth.Company, conn *database.Conn) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
switch r.Method {
|
|
case http.MethodGet:
|
|
home := newHomePage()
|
|
home.MustRender(w, r, user, company, conn)
|
|
default:
|
|
httplib.MethodNotAllowed(w, r, http.MethodGet)
|
|
}
|
|
})
|
|
}
|
|
|
|
type homePage struct {
|
|
*template.PublicPage
|
|
CampsiteTypes []*campsiteType
|
|
Carousel []*carousel.Slide
|
|
}
|
|
|
|
func newHomePage() *homePage {
|
|
return &homePage{PublicPage: template.NewPublicPage()}
|
|
}
|
|
|
|
func (p *homePage) MustRender(w http.ResponseWriter, r *http.Request, user *auth.User, company *auth.Company, conn *database.Conn) {
|
|
p.Setup(r, user, company, conn)
|
|
p.CampsiteTypes = mustCollectCampsiteTypes(r.Context(), company, conn, user.Locale)
|
|
p.Carousel = carousel.MustCollectSlides(r.Context(), company, conn, user.Locale, carouselName)
|
|
template.MustRenderPublic(w, r, user, company, "home.gohtml", p)
|
|
}
|
|
|
|
type campsiteType struct {
|
|
Label string
|
|
HRef string
|
|
Media string
|
|
}
|
|
|
|
func mustCollectCampsiteTypes(ctx context.Context, company *auth.Company, conn *database.Conn, loc *locale.Locale) []*campsiteType {
|
|
rows, err := conn.Query(ctx, `
|
|
select coalesce(i18n.name, campsite_type.name) as l10_name
|
|
, '/campsites/types/' || slug
|
|
, media.path
|
|
from campsite_type
|
|
left join campsite_type_i18n as i18n on campsite_type.campsite_type_id = i18n.campsite_type_id and lang_tag = $1
|
|
join media using (media_id)
|
|
where campsite_type.company_id = $2
|
|
and campsite_type.active
|
|
order by position, l10_name
|
|
`, loc.Language, company.ID)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
defer rows.Close()
|
|
|
|
localePath := "/" + loc.Language.String()
|
|
var items []*campsiteType
|
|
for rows.Next() {
|
|
item := &campsiteType{}
|
|
err = rows.Scan(&item.Label, &item.HRef, &item.Media)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
item.HRef = localePath + item.HRef
|
|
items = append(items, item)
|
|
}
|
|
if rows.Err() != nil {
|
|
panic(rows.Err())
|
|
}
|
|
|
|
return items
|
|
}
|