/* * SPDX-FileCopyrightText: 2023 jordi fita mas * SPDX-License-Identifier: AGPL-3.0-only */ package booking import ( "context" "golang.org/x/text/language" "net/http" "strings" "time" "dev.tandem.ws/tandem/camper/pkg/auth" "dev.tandem.ws/tandem/camper/pkg/database" httplib "dev.tandem.ws/tandem/camper/pkg/http" "dev.tandem.ws/tandem/camper/pkg/template" ) type AdminHandler struct { } func NewAdminHandler() *AdminHandler { return &AdminHandler{} } func (h *AdminHandler) Handler(user *auth.User, company *auth.Company, conn *database.Conn) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { var head string head, r.URL.Path = httplib.ShiftPath(r.URL.Path) switch head { case "": switch r.Method { case http.MethodGet: serveBookingIndex(w, r, user, company, conn) default: httplib.MethodNotAllowed(w, r, http.MethodGet) } default: http.NotFound(w, r) } }) } func serveBookingIndex(w http.ResponseWriter, r *http.Request, user *auth.User, company *auth.Company, conn *database.Conn) { bookings, err := collectBookingEntries(r.Context(), conn, user.Locale.Language) if err != nil { panic(err) } page := bookingIndex(bookings) page.MustRender(w, r, user, company) } func collectBookingEntries(ctx context.Context, conn *database.Conn, lang language.Tag) ([]*bookingEntry, error) { rows, err := conn.Query(ctx, ` select left(slug::text, 10) , '/admin/booking/' || slug , lower(stay) , upper(stay) , holder_name , booking.booking_status , coalesce(i18n.name, status.name) from booking join booking_status as status using (booking_status) left join booking_status_i18n as i18n on status.booking_status = i18n.booking_status and i18n.lang_tag = $1 order by stay desc `, lang) if err != nil { return nil, err } defer rows.Close() var entries []*bookingEntry for rows.Next() { entry := &bookingEntry{} if err = rows.Scan(&entry.Reference, &entry.URL, &entry.ArrivalDate, &entry.DepartureDate, &entry.HolderName, &entry.Status, &entry.StatusLabel); err != nil { return nil, err } entries = append(entries, entry) } return entries, nil } type bookingEntry struct { Reference string URL string ArrivalDate time.Time DepartureDate time.Time HolderName string Status string StatusLabel string } type bookingIndex []*bookingEntry func (page bookingIndex) MustRender(w http.ResponseWriter, r *http.Request, user *auth.User, company *auth.Company) { switch r.URL.Query().Get("format") { case "ods": columns := []string{ "Reference", "Arrival Date", "Departure Date", "Holder Name", "Status", } ods, err := writeTableOds(page, columns, user.Locale, func(sb *strings.Builder, entry *bookingEntry) error { if err := writeCellString(sb, entry.Reference); err != nil { return err } writeCellDate(sb, entry.ArrivalDate) writeCellDate(sb, entry.DepartureDate) if err := writeCellString(sb, entry.HolderName); err != nil { return err } if err := writeCellString(sb, entry.StatusLabel); err != nil { return err } return nil }) if err != nil { panic(err) } mustWriteOdsResponse(w, ods, user.Locale.Pgettext("bookings.ods", "filename")) default: template.MustRenderAdmin(w, r, user, company, "booking/index.gohtml", page) } }