2023-08-08 00:29:14 +00:00
|
|
|
/*
|
|
|
|
* SPDX-FileCopyrightText: 2023 jordi fita mas <jfita@peritasoft.com>
|
|
|
|
* SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
*/
|
|
|
|
|
|
|
|
package template
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
|
|
|
"net/http"
|
|
|
|
"sort"
|
|
|
|
|
|
|
|
"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/locale"
|
|
|
|
)
|
|
|
|
|
|
|
|
type PublicPage struct {
|
|
|
|
LocalizedAlternates []*LocalizedAlternate
|
|
|
|
Menu *siteMenu
|
Add the contact page, containing a map with the company location
I was not sure whether to use PostGIS to store the GPS location of the
company, as i am sure i will only use that point just to show the map.
However, just in case, it is not a big deal.
There is no way to change that from the administration pages for now,
because of time constraints, and it is very unlikely that they will
change the campgrounds’ location in the near future.
The location is in a separate table because i did not want to have to
change every test file, to be honest, but this also makes the map
“optional” without the need for NULL values.
I added the contact address to every public page because the new design
adds it to the footer, so i will be needing it everywhere, just like the
menu.
2023-10-06 19:21:00 +00:00
|
|
|
CompanyAddress *address
|
2023-08-08 00:29:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func NewPublicPage() *PublicPage {
|
Add the contact page, containing a map with the company location
I was not sure whether to use PostGIS to store the GPS location of the
company, as i am sure i will only use that point just to show the map.
However, just in case, it is not a big deal.
There is no way to change that from the administration pages for now,
because of time constraints, and it is very unlikely that they will
change the campgrounds’ location in the near future.
The location is in a separate table because i did not want to have to
change every test file, to be honest, but this also makes the map
“optional” without the need for NULL values.
I added the contact address to every public page because the new design
adds it to the footer, so i will be needing it everywhere, just like the
menu.
2023-10-06 19:21:00 +00:00
|
|
|
return &PublicPage{
|
|
|
|
CompanyAddress: &address{},
|
|
|
|
}
|
2023-08-08 00:29:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (p *PublicPage) Setup(r *http.Request, user *auth.User, company *auth.Company, conn *database.Conn) {
|
|
|
|
schema := httplib.Protocol(r)
|
|
|
|
authority := httplib.Host(r)
|
|
|
|
_, path := httplib.ShiftPath(r.RequestURI)
|
|
|
|
for _, l := range company.Locales {
|
|
|
|
p.LocalizedAlternates = append(p.LocalizedAlternates, &LocalizedAlternate{
|
|
|
|
Lang: l.Language.String(),
|
|
|
|
Endonym: l.Endonym,
|
|
|
|
HRef: fmt.Sprintf("%s://%s/%s%s", schema, authority, l.Language, path),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
sort.Slice(p.LocalizedAlternates, func(i, j int) bool { return p.LocalizedAlternates[i].Lang < p.LocalizedAlternates[j].Lang })
|
|
|
|
|
|
|
|
p.Menu = &siteMenu{
|
2023-09-12 18:20:23 +00:00
|
|
|
CampsiteTypes: mustCollectMenuItems(r.Context(), conn, user.Locale, `
|
|
|
|
select coalesce(i18n.name, campsite_type.name) as l10n_name
|
|
|
|
, '/campsites/types/' || slug
|
|
|
|
from campsite_type
|
|
|
|
left join campsite_type_i18n as i18n on campsite_type.campsite_type_id = i18n.campsite_type_id and i18n.lang_tag = $1
|
|
|
|
where company_id = $2
|
|
|
|
and active
|
|
|
|
`, user.Locale.Language, company.ID),
|
2023-08-08 00:29:14 +00:00
|
|
|
}
|
Add the contact page, containing a map with the company location
I was not sure whether to use PostGIS to store the GPS location of the
company, as i am sure i will only use that point just to show the map.
However, just in case, it is not a big deal.
There is no way to change that from the administration pages for now,
because of time constraints, and it is very unlikely that they will
change the campgrounds’ location in the near future.
The location is in a separate table because i did not want to have to
change every test file, to be honest, but this also makes the map
“optional” without the need for NULL values.
I added the contact address to every public page because the new design
adds it to the footer, so i will be needing it everywhere, just like the
menu.
2023-10-06 19:21:00 +00:00
|
|
|
|
|
|
|
if err := p.CompanyAddress.FillFromDatabase(r.Context(), conn, company); err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
2023-08-08 00:29:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type LocalizedAlternate struct {
|
|
|
|
Lang string
|
|
|
|
HRef string
|
|
|
|
Endonym string
|
|
|
|
}
|
|
|
|
|
|
|
|
type siteMenu struct {
|
|
|
|
CampsiteTypes []*menuItem
|
|
|
|
}
|
|
|
|
|
|
|
|
type menuItem struct {
|
|
|
|
Label string
|
|
|
|
HRef string
|
|
|
|
}
|
|
|
|
|
|
|
|
func mustCollectMenuItems(ctx context.Context, conn *database.Conn, loc *locale.Locale, sql string, args ...interface{}) []*menuItem {
|
|
|
|
rows, err := conn.Query(ctx, sql, args...)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
defer rows.Close()
|
|
|
|
|
|
|
|
localePath := "/" + loc.Language.String()
|
|
|
|
var items []*menuItem
|
|
|
|
for rows.Next() {
|
|
|
|
item := &menuItem{}
|
|
|
|
err = rows.Scan(&item.Label, &item.HRef)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
item.HRef = localePath + item.HRef
|
|
|
|
items = append(items, item)
|
|
|
|
}
|
|
|
|
if rows.Err() != nil {
|
|
|
|
panic(rows.Err())
|
|
|
|
}
|
|
|
|
|
|
|
|
return items
|
|
|
|
}
|
Add the contact page, containing a map with the company location
I was not sure whether to use PostGIS to store the GPS location of the
company, as i am sure i will only use that point just to show the map.
However, just in case, it is not a big deal.
There is no way to change that from the administration pages for now,
because of time constraints, and it is very unlikely that they will
change the campgrounds’ location in the near future.
The location is in a separate table because i did not want to have to
change every test file, to be honest, but this also makes the map
“optional” without the need for NULL values.
I added the contact address to every public page because the new design
adds it to the footer, so i will be needing it everywhere, just like the
menu.
2023-10-06 19:21:00 +00:00
|
|
|
|
|
|
|
type address struct {
|
|
|
|
TradeName string
|
|
|
|
Address string
|
|
|
|
PostalCode string
|
|
|
|
Province string
|
|
|
|
City string
|
|
|
|
Phone string
|
|
|
|
Email string
|
|
|
|
}
|
|
|
|
|
|
|
|
func (addr *address) FillFromDatabase(ctx context.Context, conn *database.Conn, company *auth.Company) error {
|
|
|
|
row := conn.QueryRow(ctx, `
|
|
|
|
select trade_name
|
|
|
|
, address
|
|
|
|
, postal_code
|
|
|
|
, province
|
|
|
|
, city
|
|
|
|
, phone::text
|
|
|
|
, email::text
|
|
|
|
from company
|
|
|
|
where company_id = $1
|
|
|
|
`, company.ID)
|
|
|
|
return row.Scan(
|
|
|
|
&addr.TradeName,
|
|
|
|
&addr.Address,
|
|
|
|
&addr.PostalCode,
|
|
|
|
&addr.Province,
|
|
|
|
&addr.City,
|
|
|
|
&addr.Phone,
|
|
|
|
&addr.Email,
|
|
|
|
)
|
|
|
|
}
|