Replace contact page with location
Customer does not want a contact page, but a page where they can write the direction on how to reach the campground, with a Google map embed instead of using Leaflet, because Google Maps shows the reviews right in the map. That means i had to replace the GPS locations with XML fields for the customer to write. In all four languages. This time i tried a translation approach inspired by PrestaShop: instead of opening a new page for each language, i have all languages in the same page and use AlpineJS to show just a single language. It is far easier to write the translations, even though you do not have the source text visible, specially in this section that there is no place for me to put the language links.
This commit is contained in:
parent
84423166e1
commit
ff6e9497b5
|
@ -18,10 +18,6 @@ values (52, 'localhost:8080')
|
|||
, (52, 'camper.tandem.ws')
|
||||
;
|
||||
|
||||
insert into company_geography (company_id, geog)
|
||||
values (52, 'SRID=4326;POINT(2.598825853208973 42.24256146290889)')
|
||||
;
|
||||
|
||||
insert into company_user (company_id, user_id, role)
|
||||
values (52, 42, 'employee')
|
||||
, (52, 43, 'admin')
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
-- Deploy camper:extension_postgis to pg
|
||||
-- requires: schema_public
|
||||
|
||||
begin;
|
||||
|
||||
create extension if not exists postgis;
|
||||
|
||||
commit;
|
|
@ -1,33 +1,33 @@
|
|||
-- Deploy camper:company_geography to pg
|
||||
-- requires: roles
|
||||
-- Deploy camper:location to pg
|
||||
-- requires: schema_camper
|
||||
-- requires: roles
|
||||
-- requires: company
|
||||
-- requires: user_profile
|
||||
-- requires: extension_postgis
|
||||
|
||||
begin;
|
||||
|
||||
set search_path to camper, public;
|
||||
|
||||
create table company_geography (
|
||||
create table location (
|
||||
company_id integer primary key references company,
|
||||
geog geography not null
|
||||
directions xml not null,
|
||||
map_embed xml not null,
|
||||
opening_dates xml not null
|
||||
);
|
||||
|
||||
grant select on table company_geography to guest;
|
||||
grant select on table company_geography to employee;
|
||||
grant select, insert, update, delete on table company_geography to admin;
|
||||
grant select on table location to guest;
|
||||
grant select on table location to employee;
|
||||
grant select, insert, update, delete on table location to admin;
|
||||
|
||||
alter table company_geography enable row level security;
|
||||
alter table location enable row level security;
|
||||
|
||||
create policy guest_ok
|
||||
on company_geography
|
||||
on location
|
||||
for select
|
||||
using (true)
|
||||
;
|
||||
|
||||
create policy insert_to_company
|
||||
on company_geography
|
||||
on location
|
||||
for insert
|
||||
with check (
|
||||
company_id in (select company_id from user_profile)
|
||||
|
@ -35,7 +35,7 @@ with check (
|
|||
;
|
||||
|
||||
create policy update_company
|
||||
on company_geography
|
||||
on location
|
||||
for update
|
||||
using (
|
||||
company_id in (select company_id from user_profile)
|
||||
|
@ -43,7 +43,7 @@ using (
|
|||
;
|
||||
|
||||
create policy delete_from_company
|
||||
on company_geography
|
||||
on location
|
||||
for delete
|
||||
using (
|
||||
company_id in (select company_id from user_profile)
|
|
@ -0,0 +1,23 @@
|
|||
-- Deploy camper:location_i18n to pg
|
||||
-- requires: roles
|
||||
-- requires: schema_camper
|
||||
-- requires: location
|
||||
-- requires: language
|
||||
|
||||
begin;
|
||||
|
||||
set search_path to camper, public;
|
||||
|
||||
create table location_i18n (
|
||||
company_id integer not null references location,
|
||||
lang_tag text not null references language,
|
||||
directions xml not null,
|
||||
opening_dates xml not null,
|
||||
primary key (company_id, lang_tag)
|
||||
);
|
||||
|
||||
grant select on table location_i18n to guest;
|
||||
grant select on table location_i18n to employee;
|
||||
grant select, insert, update, delete on table location_i18n to admin;
|
||||
|
||||
commit;
|
|
@ -0,0 +1,26 @@
|
|||
-- Deploy camper:setup_location to pg
|
||||
-- requires: roles
|
||||
-- requires: schema_camper
|
||||
-- requires: location
|
||||
|
||||
begin;
|
||||
|
||||
set search_path to camper, public;
|
||||
|
||||
create or replace function setup_location(company integer, directions text, map_embed text, opening_dates text) returns void as
|
||||
$$
|
||||
insert into location (company_id, directions, map_embed, opening_dates)
|
||||
values (company, xmlparse(content directions), xmlparse(content map_embed), xmlparse(content opening_dates))
|
||||
on conflict (company_id) do update
|
||||
set directions = excluded.directions
|
||||
, map_embed = excluded.map_embed
|
||||
, opening_dates = excluded.opening_dates
|
||||
;
|
||||
$$
|
||||
language sql
|
||||
;
|
||||
|
||||
revoke execute on function setup_location(integer, text, text, text) from public;
|
||||
grant execute on function setup_location(integer, text, text, text) to admin;
|
||||
|
||||
commit;
|
|
@ -0,0 +1,25 @@
|
|||
-- Deploy camper:translate_location to pg
|
||||
-- requires: roles
|
||||
-- requires: schema_camper
|
||||
-- requires: location_i18n
|
||||
|
||||
begin;
|
||||
|
||||
set search_path to camper, public;
|
||||
|
||||
create or replace function translate_location(company_id integer, lang_tag text, directions text, opening_dates text) returns void as
|
||||
$$
|
||||
insert into location_i18n (company_id, lang_tag, directions, opening_dates)
|
||||
values (company_id, lang_tag, xmlparse(content coalesce(directions, '')), xmlparse(content coalesce(opening_dates, '')))
|
||||
on conflict (company_id, lang_tag) do update
|
||||
set directions = excluded.directions
|
||||
, opening_dates = excluded.opening_dates
|
||||
;
|
||||
$$
|
||||
language sql
|
||||
;
|
||||
|
||||
revoke execute on function translate_location(integer, text, text, text) from public;
|
||||
grant execute on function translate_location(integer, text, text, text) to admin;
|
||||
|
||||
commit;
|
|
@ -6,6 +6,7 @@
|
|||
package app
|
||||
|
||||
import (
|
||||
"dev.tandem.ws/tandem/camper/pkg/location"
|
||||
"net/http"
|
||||
|
||||
"dev.tandem.ws/tandem/camper/pkg/auth"
|
||||
|
@ -26,6 +27,7 @@ type adminHandler struct {
|
|||
campsite *campsite.AdminHandler
|
||||
company *company.AdminHandler
|
||||
home *home.AdminHandler
|
||||
location *location.AdminHandler
|
||||
media *media.AdminHandler
|
||||
payment *booking.AdminHandler
|
||||
season *season.AdminHandler
|
||||
|
@ -37,6 +39,7 @@ func newAdminHandler(locales locale.Locales, mediaDir string) *adminHandler {
|
|||
campsite: campsite.NewAdminHandler(locales),
|
||||
company: company.NewAdminHandler(),
|
||||
home: home.NewAdminHandler(locales),
|
||||
location: location.NewAdminHandler(),
|
||||
media: media.NewAdminHandler(mediaDir),
|
||||
payment: booking.NewAdminHandler(),
|
||||
season: season.NewAdminHandler(locales),
|
||||
|
@ -66,6 +69,8 @@ func (h *adminHandler) Handle(user *auth.User, company *auth.Company, conn *data
|
|||
h.company.Handler(user, company, conn).ServeHTTP(w, r)
|
||||
case "home":
|
||||
h.home.Handler(user, company, conn).ServeHTTP(w, r)
|
||||
case "location":
|
||||
h.location.Handler(user, company, conn).ServeHTTP(w, r)
|
||||
case "media":
|
||||
h.media.Handler(user, company, conn).ServeHTTP(w, r)
|
||||
case "payment":
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
"dev.tandem.ws/tandem/camper/pkg/database"
|
||||
"dev.tandem.ws/tandem/camper/pkg/home"
|
||||
httplib "dev.tandem.ws/tandem/camper/pkg/http"
|
||||
"dev.tandem.ws/tandem/camper/pkg/location"
|
||||
"dev.tandem.ws/tandem/camper/pkg/services"
|
||||
"dev.tandem.ws/tandem/camper/pkg/template"
|
||||
)
|
||||
|
@ -22,6 +23,7 @@ type publicHandler struct {
|
|||
home *home.PublicHandler
|
||||
booking *booking.PublicHandler
|
||||
campsite *campsite.PublicHandler
|
||||
location *location.PublicHandler
|
||||
services *services.PublicHandler
|
||||
}
|
||||
|
||||
|
@ -30,6 +32,7 @@ func newPublicHandler() *publicHandler {
|
|||
home: home.NewPublicHandler(),
|
||||
booking: booking.NewPublicHandler(),
|
||||
campsite: campsite.NewPublicHandler(),
|
||||
location: location.NewPublicHandler(),
|
||||
services: services.NewPublicHandler(),
|
||||
}
|
||||
}
|
||||
|
@ -47,8 +50,8 @@ func (h *publicHandler) Handler(user *auth.User, company *auth.Company, conn *da
|
|||
campgroundHandler(user, company, conn).ServeHTTP(w, r)
|
||||
case "campsites":
|
||||
h.campsite.Handler(user, company, conn).ServeHTTP(w, r)
|
||||
case "contact":
|
||||
contactHandler(user, company, conn).ServeHTTP(w, r)
|
||||
case "location":
|
||||
h.location.Handler(user, company, conn).ServeHTTP(w, r)
|
||||
case "services":
|
||||
h.services.Handler(user, company, conn).ServeHTTP(w, r)
|
||||
case "surroundings":
|
||||
|
@ -98,53 +101,3 @@ func campgroundHandler(user *auth.User, company *auth.Company, conn *database.Co
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
func contactHandler(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:
|
||||
page := newContactPage()
|
||||
page.MustRender(w, r, user, company, conn)
|
||||
default:
|
||||
httplib.MethodNotAllowed(w, r, http.MethodGet)
|
||||
}
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
type contactPage struct {
|
||||
*template.PublicPage
|
||||
CompanyGeography *geographyPoint
|
||||
}
|
||||
|
||||
func newContactPage() *contactPage {
|
||||
page := &contactPage{
|
||||
PublicPage: template.NewPublicPage(),
|
||||
}
|
||||
return page
|
||||
}
|
||||
|
||||
func (p *contactPage) MustRender(w http.ResponseWriter, r *http.Request, user *auth.User, company *auth.Company, conn *database.Conn) {
|
||||
p.Setup(r, user, company, conn)
|
||||
row := conn.QueryRow(r.Context(), `select st_x(geog::geometry)::text, st_y(geog::geometry)::text from company_geography where company_id = $1`, company.ID)
|
||||
geography := &geographyPoint{}
|
||||
if err := row.Scan(&geography.Lng, &geography.Lat); err != nil {
|
||||
if !database.ErrorIsNotFound(err) {
|
||||
panic(err)
|
||||
}
|
||||
} else {
|
||||
p.CompanyGeography = geography
|
||||
}
|
||||
template.MustRenderPublic(w, r, user, company, "contact.gohtml", p)
|
||||
}
|
||||
|
||||
type geographyPoint struct {
|
||||
Lat string
|
||||
Lng string
|
||||
}
|
||||
|
|
|
@ -7,19 +7,22 @@ package auth
|
|||
|
||||
import (
|
||||
"context"
|
||||
"golang.org/x/text/language"
|
||||
|
||||
"dev.tandem.ws/tandem/camper/pkg/database"
|
||||
"dev.tandem.ws/tandem/camper/pkg/locale"
|
||||
)
|
||||
|
||||
type Company struct {
|
||||
ID int
|
||||
Locales locale.Locales
|
||||
ID int
|
||||
DefaultLanguage language.Tag
|
||||
Locales locale.Locales
|
||||
}
|
||||
|
||||
func CompanyByHost(ctx context.Context, conn *database.Conn, host string, allLocales locale.Locales) (*Company, error) {
|
||||
company := &Company{
|
||||
Locales: allLocales,
|
||||
Locales: allLocales,
|
||||
DefaultLanguage: language.Catalan,
|
||||
}
|
||||
if err := conn.QueryRow(ctx, `
|
||||
select company_id
|
||||
|
|
|
@ -92,3 +92,13 @@ func (c *Conn) OrderSeasons(ctx context.Context, slugs []string) error {
|
|||
_, err := c.Exec(ctx, "select order_seasons($1)", slugs)
|
||||
return err
|
||||
}
|
||||
|
||||
func (tx *Tx) SetupLocation(ctx context.Context, companyID int, directions string, mapEmbed string, openingHours string) error {
|
||||
_, err := tx.Exec(ctx, "select setup_location($1, $2, $3, $4)", companyID, directions, mapEmbed, openingHours)
|
||||
return err
|
||||
}
|
||||
|
||||
func (tx *Tx) TranslateLocation(ctx context.Context, companyID int, langTag language.Tag, directions string, openingHours string) error {
|
||||
_, err := tx.Exec(ctx, "select translate_location($1, $2, $3, $4)", companyID, langTag, directions, openingHours)
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ package form
|
|||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"dev.tandem.ws/tandem/camper/pkg/locale"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
@ -50,3 +51,21 @@ type L10nInput struct {
|
|||
Input
|
||||
Source string
|
||||
}
|
||||
|
||||
type I18nInput map[string]*Input
|
||||
|
||||
func NewI18nInput(locales locale.Locales, name string) I18nInput {
|
||||
input := make(I18nInput)
|
||||
for lang := range locales {
|
||||
input[lang.String()] = &Input{
|
||||
Name: name + "." + lang.String(),
|
||||
}
|
||||
}
|
||||
return input
|
||||
}
|
||||
|
||||
func (input I18nInput) FillValue(r *http.Request) {
|
||||
for _, inner := range input {
|
||||
inner.FillValue(r)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,156 @@
|
|||
package location
|
||||
|
||||
import (
|
||||
"context"
|
||||
"golang.org/x/text/language"
|
||||
"net/http"
|
||||
|
||||
"github.com/jackc/pgx/v4"
|
||||
|
||||
"dev.tandem.ws/tandem/camper/pkg/auth"
|
||||
"dev.tandem.ws/tandem/camper/pkg/database"
|
||||
"dev.tandem.ws/tandem/camper/pkg/form"
|
||||
httplib "dev.tandem.ws/tandem/camper/pkg/http"
|
||||
"dev.tandem.ws/tandem/camper/pkg/locale"
|
||||
"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:
|
||||
f := newLocationForm(company.Locales)
|
||||
if err := f.FillFromDatabase(r.Context(), company, conn); err != nil {
|
||||
if !database.ErrorIsNotFound(err) {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
f.MustRender(w, r, user, company)
|
||||
case http.MethodPut:
|
||||
updateLocationSettings(w, r, user, company, conn)
|
||||
default:
|
||||
httplib.MethodNotAllowed(w, r, http.MethodGet)
|
||||
}
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func updateLocationSettings(w http.ResponseWriter, r *http.Request, user *auth.User, company *auth.Company, conn *database.Conn) {
|
||||
f := newLocationForm(company.Locales)
|
||||
if ok, err := form.Handle(f, w, r, user); err != nil {
|
||||
return
|
||||
} else if !ok {
|
||||
f.MustRender(w, r, user, company)
|
||||
return
|
||||
}
|
||||
tx := conn.MustBegin(r.Context())
|
||||
defer tx.Rollback(r.Context())
|
||||
var defaultLang = company.DefaultLanguage.String()
|
||||
if err := tx.SetupLocation(r.Context(), company.ID, f.Directions[defaultLang].Val, f.MapEmbed.Val, f.OpeningDates[defaultLang].Val); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for lang := range company.Locales {
|
||||
if lang == company.DefaultLanguage {
|
||||
continue
|
||||
}
|
||||
if err := tx.TranslateLocation(r.Context(), company.ID, lang, f.Directions[lang.String()].Val, f.OpeningDates[lang.String()].Val); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
tx.MustCommit(r.Context())
|
||||
httplib.Redirect(w, r, "/admin/location", http.StatusSeeOther)
|
||||
}
|
||||
|
||||
type locationForm struct {
|
||||
Directions form.I18nInput
|
||||
MapEmbed *form.Input
|
||||
OpeningDates form.I18nInput
|
||||
}
|
||||
|
||||
func newLocationForm(locales locale.Locales) *locationForm {
|
||||
return &locationForm{
|
||||
Directions: form.NewI18nInput(locales, "directions"),
|
||||
MapEmbed: &form.Input{
|
||||
Name: "map_embed",
|
||||
},
|
||||
OpeningDates: form.NewI18nInput(locales, "opening_dates"),
|
||||
}
|
||||
}
|
||||
|
||||
func (f *locationForm) FillFromDatabase(ctx context.Context, company *auth.Company, conn *database.Conn) error {
|
||||
var directions database.RecordArray
|
||||
var openingDates database.RecordArray
|
||||
err := conn.QueryRow(ctx, `
|
||||
select location.directions::text
|
||||
, location.map_embed::text
|
||||
, location.opening_dates::text
|
||||
, array_agg((lang_tag, i18n.directions::text))
|
||||
, array_agg((lang_tag, i18n.opening_dates::text))
|
||||
from location
|
||||
left join location_i18n as i18n using (company_id)
|
||||
where company_id = $1
|
||||
group by location.directions::text
|
||||
, location.map_embed::text
|
||||
, location.opening_dates::text
|
||||
`, pgx.QueryResultFormats{pgx.BinaryFormatCode}, company.ID).Scan(
|
||||
&f.Directions[company.DefaultLanguage.String()].Val,
|
||||
&f.MapEmbed.Val,
|
||||
&f.OpeningDates[company.DefaultLanguage.String()].Val,
|
||||
&directions,
|
||||
&openingDates,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := fillI18nInput(f.Directions, directions); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := fillI18nInput(f.OpeningDates, openingDates); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func fillI18nInput(input form.I18nInput, array database.RecordArray) error {
|
||||
for _, el := range array.Elements {
|
||||
tag, err := language.Parse(el.Fields[0].Get().(string))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
input[tag.String()].Val = el.Fields[1].Get().(string)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *locationForm) MustRender(w http.ResponseWriter, r *http.Request, user *auth.User, company *auth.Company) {
|
||||
template.MustRenderAdmin(w, r, user, company, "location.gohtml", f)
|
||||
}
|
||||
|
||||
func (f *locationForm) Parse(r *http.Request) error {
|
||||
if err := r.ParseForm(); err != nil {
|
||||
return err
|
||||
}
|
||||
f.Directions.FillValue(r)
|
||||
f.MapEmbed.FillValue(r)
|
||||
f.OpeningDates.FillValue(r)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *locationForm) Valid(l *locale.Locale) bool {
|
||||
v := form.NewValidator(l)
|
||||
return v.AllOK
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
package location
|
||||
|
||||
import (
|
||||
"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"
|
||||
gotemplate "html/template"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
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) {
|
||||
var head string
|
||||
head, r.URL.Path = httplib.ShiftPath(r.URL.Path)
|
||||
|
||||
switch head {
|
||||
case "":
|
||||
switch r.Method {
|
||||
case http.MethodGet:
|
||||
page := newLocationPage()
|
||||
page.MustRender(w, r, user, company, conn)
|
||||
default:
|
||||
httplib.MethodNotAllowed(w, r, http.MethodGet)
|
||||
}
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
type locationPage struct {
|
||||
*template.PublicPage
|
||||
Directions gotemplate.HTML
|
||||
MapEmbed gotemplate.HTML
|
||||
}
|
||||
|
||||
func newLocationPage() *locationPage {
|
||||
page := &locationPage{
|
||||
PublicPage: template.NewPublicPage(),
|
||||
}
|
||||
return page
|
||||
}
|
||||
|
||||
func (p *locationPage) MustRender(w http.ResponseWriter, r *http.Request, user *auth.User, company *auth.Company, conn *database.Conn) {
|
||||
p.Setup(r, user, company, conn)
|
||||
row := conn.QueryRow(r.Context(), `
|
||||
select coalesce(i18n.directions, location.directions)::text
|
||||
, map_embed::text
|
||||
from location
|
||||
left join location_i18n as i18n on location.company_id = i18n.company_id and i18n.lang_tag = $1
|
||||
where location.company_id = $2
|
||||
`, user.Locale.Language, company.ID)
|
||||
if err := row.Scan(&p.Directions, &p.MapEmbed); err != nil {
|
||||
if !database.ErrorIsNotFound(err) {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
template.MustRenderPublic(w, r, user, company, "location.gohtml", p)
|
||||
}
|
|
@ -8,6 +8,7 @@ package template
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
gotemplate "html/template"
|
||||
"net/http"
|
||||
"sort"
|
||||
|
||||
|
@ -21,6 +22,7 @@ type PublicPage struct {
|
|||
LocalizedAlternates []*LocalizedAlternate
|
||||
Menu *siteMenu
|
||||
CompanyAddress *address
|
||||
OpeningDates gotemplate.HTML
|
||||
}
|
||||
|
||||
func NewPublicPage() *PublicPage {
|
||||
|
@ -54,6 +56,15 @@ func (p *PublicPage) Setup(r *http.Request, user *auth.User, company *auth.Compa
|
|||
`, user.Locale.Language, company.ID),
|
||||
}
|
||||
|
||||
if err := conn.QueryRow(r.Context(), `
|
||||
select coalesce(i18n.opening_dates, location.opening_dates)
|
||||
from location
|
||||
left join location_i18n as i18n on location.company_id = i18n.company_id and i18n.lang_tag = $1
|
||||
where location.company_id = $2
|
||||
`, user.Locale.Language, company.ID).Scan(&p.OpeningDates); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if err := p.CompanyAddress.FillFromDatabase(r.Context(), conn, user, company); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@ -113,19 +124,19 @@ type address struct {
|
|||
|
||||
func (addr *address) FillFromDatabase(ctx context.Context, conn *database.Conn, user *auth.User, company *auth.Company) error {
|
||||
row := conn.QueryRow(ctx, `
|
||||
select trade_name
|
||||
, address
|
||||
, postal_code
|
||||
, province
|
||||
, city
|
||||
, coalesce(country_i18n.name, country.name) as country_name
|
||||
, phone::text
|
||||
, email::text
|
||||
, rtc_number
|
||||
from company
|
||||
join country using (country_code)
|
||||
left join country_i18n on country.country_code = country_i18n.country_code and country_i18n.lang_tag = $2
|
||||
where company_id = $1
|
||||
select trade_name
|
||||
, address
|
||||
, postal_code
|
||||
, province
|
||||
, city
|
||||
, coalesce(country_i18n.name, country.name) as country_name
|
||||
, phone::text
|
||||
, email::text
|
||||
, rtc_number
|
||||
from company
|
||||
join country using (country_code)
|
||||
left join country_i18n on country.country_code = country_i18n.country_code and country_i18n.lang_tag = $2
|
||||
where company_id = $1
|
||||
`, company.ID, user.Locale.Language)
|
||||
return row.Scan(
|
||||
&addr.TradeName,
|
||||
|
|
120
po/ca.po
120
po/ca.po
|
@ -8,7 +8,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: camper\n"
|
||||
"Report-Msgid-Bugs-To: jordi@tandem.blog\n"
|
||||
"POT-Creation-Date: 2023-12-21 17:32+0100\n"
|
||||
"POT-Creation-Date: 2023-12-21 21:08+0100\n"
|
||||
"PO-Revision-Date: 2023-07-22 23:45+0200\n"
|
||||
"Last-Translator: jordi fita mas <jordi@tandem.blog>\n"
|
||||
"Language-Team: Catalan <ca@dodds.net>\n"
|
||||
|
@ -43,7 +43,7 @@ msgstr "Ha fallat el pagament"
|
|||
|
||||
#: web/templates/public/services.gohtml:6
|
||||
#: web/templates/public/services.gohtml:15
|
||||
#: web/templates/public/layout.gohtml:52 web/templates/public/layout.gohtml:79
|
||||
#: web/templates/public/layout.gohtml:51 web/templates/public/layout.gohtml:79
|
||||
#: web/templates/admin/services/index.gohtml:66
|
||||
msgctxt "title"
|
||||
msgid "Services"
|
||||
|
@ -53,6 +53,14 @@ msgstr "Serveis"
|
|||
msgid "The campsite offers many different services."
|
||||
msgstr "El càmping disposa de diversos serveis."
|
||||
|
||||
#: web/templates/public/location.gohtml:6
|
||||
#: web/templates/public/location.gohtml:12
|
||||
#: web/templates/public/layout.gohtml:53 web/templates/public/layout.gohtml:81
|
||||
#: web/templates/admin/layout.gohtml:60
|
||||
msgctxt "title"
|
||||
msgid "Location"
|
||||
msgstr "Com arribar"
|
||||
|
||||
#: web/templates/public/home.gohtml:6 web/templates/public/layout.gohtml:37
|
||||
#: web/templates/public/layout.gohtml:77
|
||||
msgctxt "title"
|
||||
|
@ -79,7 +87,7 @@ msgstr "Vine a gaudir!"
|
|||
#: web/templates/public/home.gohtml:35
|
||||
#: web/templates/public/surroundings.gohtml:6
|
||||
#: web/templates/public/surroundings.gohtml:10
|
||||
#: web/templates/public/layout.gohtml:53 web/templates/public/layout.gohtml:80
|
||||
#: web/templates/public/layout.gohtml:52 web/templates/public/layout.gohtml:80
|
||||
msgctxt "title"
|
||||
msgid "Surroundings"
|
||||
msgstr "L’entorn"
|
||||
|
@ -268,14 +276,8 @@ msgctxt "title"
|
|||
msgid "Campground"
|
||||
msgstr "El càmping"
|
||||
|
||||
#: web/templates/public/contact.gohtml:6 web/templates/public/contact.gohtml:18
|
||||
#: web/templates/public/layout.gohtml:54 web/templates/public/layout.gohtml:81
|
||||
msgctxt "title"
|
||||
msgid "Contact"
|
||||
msgstr "Contacte"
|
||||
|
||||
#: web/templates/public/booking.gohtml:6 web/templates/public/booking.gohtml:11
|
||||
#: web/templates/public/layout.gohtml:51
|
||||
#: web/templates/public/layout.gohtml:54
|
||||
msgctxt "title"
|
||||
msgid "Booking"
|
||||
msgstr "Reserva"
|
||||
|
@ -364,18 +366,18 @@ msgid "I have read and I accept the reservation conditions"
|
|||
msgstr "He llegit i accepto les condicions de reserves"
|
||||
|
||||
#: web/templates/public/layout.gohtml:11 web/templates/public/layout.gohtml:32
|
||||
#: web/templates/public/layout.gohtml:110
|
||||
#: web/templates/public/layout.gohtml:109
|
||||
msgid "Campsite Montagut"
|
||||
msgstr "Càmping Montagut"
|
||||
|
||||
#: web/templates/public/layout.gohtml:23 web/templates/admin/layout.gohtml:19
|
||||
#: web/templates/public/layout.gohtml:23 web/templates/admin/layout.gohtml:20
|
||||
msgid "Skip to main content"
|
||||
msgstr "Salta al contingut principal"
|
||||
|
||||
#: web/templates/public/layout.gohtml:42 web/templates/public/layout.gohtml:88
|
||||
#: web/templates/admin/campsite/index.gohtml:6
|
||||
#: web/templates/admin/campsite/index.gohtml:12
|
||||
#: web/templates/admin/layout.gohtml:44 web/templates/admin/layout.gohtml:75
|
||||
#: web/templates/admin/layout.gohtml:45 web/templates/admin/layout.gohtml:79
|
||||
msgctxt "title"
|
||||
msgid "Campsites"
|
||||
msgstr "Allotjaments"
|
||||
|
@ -385,7 +387,12 @@ msgctxt "title"
|
|||
msgid "Sections"
|
||||
msgstr "Apartats"
|
||||
|
||||
#: web/templates/public/layout.gohtml:107
|
||||
#: web/templates/public/layout.gohtml:99
|
||||
msgctxt "title"
|
||||
msgid "Opening"
|
||||
msgstr "Obertura"
|
||||
|
||||
#: web/templates/public/layout.gohtml:106
|
||||
msgid "<abbr title=\"Catalonia Tourism Registry\">RTC</abbr> <abbr title=\"Number\">#</abbr>%s"
|
||||
msgstr "<abbr title=\"Número\">Núm.</abbr> <abbr title=\"Registre de Turisme de Catalunya\">RTC</abbr> %s"
|
||||
|
||||
|
@ -482,6 +489,33 @@ msgctxt "action"
|
|||
msgid "Translate"
|
||||
msgstr "Tradueix"
|
||||
|
||||
#: web/templates/admin/location.gohtml:6 web/templates/admin/location.gohtml:12
|
||||
msgctxt "title"
|
||||
msgid "Location Settings"
|
||||
msgstr "Paràmetres de com arribar"
|
||||
|
||||
#: web/templates/admin/location.gohtml:17
|
||||
msgctxt "input"
|
||||
msgid "Directions"
|
||||
msgstr "Instruccions"
|
||||
|
||||
#: web/templates/admin/location.gohtml:35
|
||||
msgctxt "input"
|
||||
msgid "Opening Dates"
|
||||
msgstr "Data d’obertura"
|
||||
|
||||
#: web/templates/admin/location.gohtml:53
|
||||
msgctxt "input"
|
||||
msgid "Map Embed"
|
||||
msgstr "Incrustació del mapa"
|
||||
|
||||
#: web/templates/admin/location.gohtml:60 web/templates/admin/payment.gohtml:62
|
||||
#: web/templates/admin/profile.gohtml:75
|
||||
#: web/templates/admin/taxDetails.gohtml:152
|
||||
msgctxt "action"
|
||||
msgid "Save changes"
|
||||
msgstr "Desa els canvis"
|
||||
|
||||
#: web/templates/admin/campsite/feature/form.gohtml:8
|
||||
#: web/templates/admin/campsite/feature/form.gohtml:25
|
||||
msgctxt "title"
|
||||
|
@ -802,7 +836,7 @@ msgstr "Descripció"
|
|||
|
||||
#: web/templates/admin/campsite/type/index.gohtml:6
|
||||
#: web/templates/admin/campsite/type/index.gohtml:12
|
||||
#: web/templates/admin/layout.gohtml:41
|
||||
#: web/templates/admin/layout.gohtml:42
|
||||
msgctxt "title"
|
||||
msgid "Campsite Types"
|
||||
msgstr "Tipus d’allotjaments"
|
||||
|
@ -877,7 +911,7 @@ msgstr "Color"
|
|||
|
||||
#: web/templates/admin/season/index.gohtml:6
|
||||
#: web/templates/admin/season/index.gohtml:12
|
||||
#: web/templates/admin/layout.gohtml:47
|
||||
#: web/templates/admin/layout.gohtml:48
|
||||
msgctxt "title"
|
||||
msgid "Seasons"
|
||||
msgstr "Temporades"
|
||||
|
@ -909,7 +943,7 @@ msgid "Cancel"
|
|||
msgstr "Canceŀla"
|
||||
|
||||
#: web/templates/admin/payment.gohtml:6 web/templates/admin/payment.gohtml:12
|
||||
#: web/templates/admin/layout.gohtml:38
|
||||
#: web/templates/admin/layout.gohtml:39
|
||||
msgctxt "title"
|
||||
msgid "Payment Settings"
|
||||
msgstr "Paràmetres de pagament"
|
||||
|
@ -944,14 +978,8 @@ msgctxt "title"
|
|||
msgid "Integration"
|
||||
msgstr "Integració"
|
||||
|
||||
#: web/templates/admin/payment.gohtml:62 web/templates/admin/profile.gohtml:75
|
||||
#: web/templates/admin/taxDetails.gohtml:152
|
||||
msgctxt "action"
|
||||
msgid "Save changes"
|
||||
msgstr "Desa els canvis"
|
||||
|
||||
#: web/templates/admin/dashboard.gohtml:6
|
||||
#: web/templates/admin/dashboard.gohtml:10 web/templates/admin/layout.gohtml:72
|
||||
#: web/templates/admin/dashboard.gohtml:10 web/templates/admin/layout.gohtml:76
|
||||
msgctxt "title"
|
||||
msgid "Dashboard"
|
||||
msgstr "Tauler"
|
||||
|
@ -984,7 +1012,7 @@ msgid "New Service"
|
|||
msgstr "Nou servei"
|
||||
|
||||
#: web/templates/admin/services/index.gohtml:6
|
||||
#: web/templates/admin/layout.gohtml:56
|
||||
#: web/templates/admin/layout.gohtml:57
|
||||
msgctxt "title"
|
||||
msgid "Services Page"
|
||||
msgstr "Pàgina de serveis"
|
||||
|
@ -1020,7 +1048,7 @@ msgid "Translate Service to %s"
|
|||
msgstr "Traducció del servei a %s"
|
||||
|
||||
#: web/templates/admin/profile.gohtml:6 web/templates/admin/profile.gohtml:12
|
||||
#: web/templates/admin/layout.gohtml:31
|
||||
#: web/templates/admin/layout.gohtml:32
|
||||
msgctxt "title"
|
||||
msgid "Profile"
|
||||
msgstr "Perfil"
|
||||
|
@ -1112,29 +1140,29 @@ msgctxt "input"
|
|||
msgid "Legal Disclaimer"
|
||||
msgstr "Nota legal"
|
||||
|
||||
#: web/templates/admin/layout.gohtml:27
|
||||
#: web/templates/admin/layout.gohtml:28
|
||||
msgctxt "title"
|
||||
msgid "User Menu"
|
||||
msgstr "Menú d’usuari"
|
||||
|
||||
#: web/templates/admin/layout.gohtml:35
|
||||
#: web/templates/admin/layout.gohtml:36
|
||||
msgctxt "title"
|
||||
msgid "Company Settings"
|
||||
msgstr "Paràmetres de l’empresa"
|
||||
|
||||
#: web/templates/admin/layout.gohtml:50
|
||||
#: web/templates/admin/layout.gohtml:51
|
||||
#: web/templates/admin/media/index.gohtml:6
|
||||
#: web/templates/admin/media/index.gohtml:11
|
||||
msgctxt "title"
|
||||
msgid "Media"
|
||||
msgstr "Mèdia"
|
||||
|
||||
#: web/templates/admin/layout.gohtml:53 web/templates/admin/home/index.gohtml:6
|
||||
#: web/templates/admin/layout.gohtml:54 web/templates/admin/home/index.gohtml:6
|
||||
msgctxt "title"
|
||||
msgid "Home Page"
|
||||
msgstr "Pàgina d’inici"
|
||||
|
||||
#: web/templates/admin/layout.gohtml:61
|
||||
#: web/templates/admin/layout.gohtml:65
|
||||
msgctxt "action"
|
||||
msgid "Logout"
|
||||
msgstr "Surt"
|
||||
|
@ -1265,7 +1293,7 @@ msgstr "L’idioma escollit no és vàlid."
|
|||
msgid "File must be a valid PNG or JPEG image."
|
||||
msgstr "El fitxer has de ser una imatge PNG o JPEG vàlida."
|
||||
|
||||
#: pkg/app/admin.go:56
|
||||
#: pkg/app/admin.go:59
|
||||
msgid "Access forbidden"
|
||||
msgstr "Accés prohibit"
|
||||
|
||||
|
@ -1534,55 +1562,55 @@ msgstr "No podeu deixar el fitxer del mèdia en blanc."
|
|||
msgid "Filename can not be empty."
|
||||
msgstr "No podeu deixar el nom del fitxer en blanc."
|
||||
|
||||
#: pkg/booking/admin.go:74
|
||||
#: pkg/booking/admin.go:76
|
||||
msgctxt "redsys environment"
|
||||
msgid "Test"
|
||||
msgstr "Proves"
|
||||
|
||||
#: pkg/booking/admin.go:78
|
||||
#: pkg/booking/admin.go:80
|
||||
msgctxt "redsys environment"
|
||||
msgid "Live"
|
||||
msgstr "Real"
|
||||
|
||||
#: pkg/booking/admin.go:87
|
||||
#: pkg/booking/admin.go:89
|
||||
msgctxt "redsys integration"
|
||||
msgid "InSite"
|
||||
msgstr "InSite"
|
||||
|
||||
#: pkg/booking/admin.go:91
|
||||
#: pkg/booking/admin.go:93
|
||||
msgctxt "redsys integration"
|
||||
msgid "Redirect"
|
||||
msgstr "Redirecció"
|
||||
|
||||
#: pkg/booking/admin.go:135
|
||||
#: pkg/booking/admin.go:137
|
||||
msgid "Merchant code can not be empty."
|
||||
msgstr "No podeu deixar el codi del comerç en blanc."
|
||||
|
||||
#: pkg/booking/admin.go:136
|
||||
#: pkg/booking/admin.go:138
|
||||
msgid "Merchant code must be exactly nine digits long."
|
||||
msgstr "El codi del comerç ha de ser de nou dígits."
|
||||
|
||||
#: pkg/booking/admin.go:137
|
||||
#: pkg/booking/admin.go:139
|
||||
msgid "Merchant code must be a number."
|
||||
msgstr "El codi del comerç."
|
||||
|
||||
#: pkg/booking/admin.go:141
|
||||
#: pkg/booking/admin.go:143
|
||||
msgid "Terminal number can not be empty."
|
||||
msgstr "No podeu deixar el número del terminal en blanc."
|
||||
|
||||
#: pkg/booking/admin.go:142
|
||||
#: pkg/booking/admin.go:144
|
||||
msgid "Terminal number must be a number between 1 and 999."
|
||||
msgstr "El número del terminal ha de ser entre 1 i 999"
|
||||
|
||||
#: pkg/booking/admin.go:150
|
||||
#: pkg/booking/admin.go:152
|
||||
msgid "Selected environment is not valid."
|
||||
msgstr "L’entorn escollit no és vàlid."
|
||||
|
||||
#: pkg/booking/admin.go:151
|
||||
#: pkg/booking/admin.go:153
|
||||
msgid "Selected integration is not valid."
|
||||
msgstr "La integració escollida no és vàlida."
|
||||
|
||||
#: pkg/booking/admin.go:154
|
||||
#: pkg/booking/admin.go:156
|
||||
msgid "The merchant key is not valid."
|
||||
msgstr "Aquesta clau del comerç no és vàlid."
|
||||
|
||||
|
@ -1638,6 +1666,10 @@ msgstr "El valor de %s ha de ser com a mínim %d."
|
|||
msgid "%s must be at most %d."
|
||||
msgstr "El valor de %s ha de ser com a màxim %d."
|
||||
|
||||
#~ msgctxt "title"
|
||||
#~ msgid "Contact"
|
||||
#~ msgstr "Contacte"
|
||||
|
||||
#~ msgctxt "title"
|
||||
#~ msgid "Party Details"
|
||||
#~ msgstr "Dades dels visitants"
|
||||
|
|
120
po/es.po
120
po/es.po
|
@ -8,7 +8,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: camper\n"
|
||||
"Report-Msgid-Bugs-To: jordi@tandem.blog\n"
|
||||
"POT-Creation-Date: 2023-12-21 17:32+0100\n"
|
||||
"POT-Creation-Date: 2023-12-21 21:08+0100\n"
|
||||
"PO-Revision-Date: 2023-07-22 23:46+0200\n"
|
||||
"Last-Translator: jordi fita mas <jordi@tandem.blog>\n"
|
||||
"Language-Team: Spanish <es@tp.org.es>\n"
|
||||
|
@ -43,7 +43,7 @@ msgstr "Pago fallido"
|
|||
|
||||
#: web/templates/public/services.gohtml:6
|
||||
#: web/templates/public/services.gohtml:15
|
||||
#: web/templates/public/layout.gohtml:52 web/templates/public/layout.gohtml:79
|
||||
#: web/templates/public/layout.gohtml:51 web/templates/public/layout.gohtml:79
|
||||
#: web/templates/admin/services/index.gohtml:66
|
||||
msgctxt "title"
|
||||
msgid "Services"
|
||||
|
@ -53,6 +53,14 @@ msgstr "Servicios"
|
|||
msgid "The campsite offers many different services."
|
||||
msgstr "El camping dispone de varios servicios."
|
||||
|
||||
#: web/templates/public/location.gohtml:6
|
||||
#: web/templates/public/location.gohtml:12
|
||||
#: web/templates/public/layout.gohtml:53 web/templates/public/layout.gohtml:81
|
||||
#: web/templates/admin/layout.gohtml:60
|
||||
msgctxt "title"
|
||||
msgid "Location"
|
||||
msgstr "Cómo llegar"
|
||||
|
||||
#: web/templates/public/home.gohtml:6 web/templates/public/layout.gohtml:37
|
||||
#: web/templates/public/layout.gohtml:77
|
||||
msgctxt "title"
|
||||
|
@ -79,7 +87,7 @@ msgstr "¡Ven a disfrutar!"
|
|||
#: web/templates/public/home.gohtml:35
|
||||
#: web/templates/public/surroundings.gohtml:6
|
||||
#: web/templates/public/surroundings.gohtml:10
|
||||
#: web/templates/public/layout.gohtml:53 web/templates/public/layout.gohtml:80
|
||||
#: web/templates/public/layout.gohtml:52 web/templates/public/layout.gohtml:80
|
||||
msgctxt "title"
|
||||
msgid "Surroundings"
|
||||
msgstr "El entorno"
|
||||
|
@ -268,14 +276,8 @@ msgctxt "title"
|
|||
msgid "Campground"
|
||||
msgstr "El camping"
|
||||
|
||||
#: web/templates/public/contact.gohtml:6 web/templates/public/contact.gohtml:18
|
||||
#: web/templates/public/layout.gohtml:54 web/templates/public/layout.gohtml:81
|
||||
msgctxt "title"
|
||||
msgid "Contact"
|
||||
msgstr "Contacto"
|
||||
|
||||
#: web/templates/public/booking.gohtml:6 web/templates/public/booking.gohtml:11
|
||||
#: web/templates/public/layout.gohtml:51
|
||||
#: web/templates/public/layout.gohtml:54
|
||||
msgctxt "title"
|
||||
msgid "Booking"
|
||||
msgstr "Reserva"
|
||||
|
@ -364,18 +366,18 @@ msgid "I have read and I accept the reservation conditions"
|
|||
msgstr "He leído y acepto las condiciones de reserva"
|
||||
|
||||
#: web/templates/public/layout.gohtml:11 web/templates/public/layout.gohtml:32
|
||||
#: web/templates/public/layout.gohtml:110
|
||||
#: web/templates/public/layout.gohtml:109
|
||||
msgid "Campsite Montagut"
|
||||
msgstr "Camping Montagut"
|
||||
|
||||
#: web/templates/public/layout.gohtml:23 web/templates/admin/layout.gohtml:19
|
||||
#: web/templates/public/layout.gohtml:23 web/templates/admin/layout.gohtml:20
|
||||
msgid "Skip to main content"
|
||||
msgstr "Saltar al contenido principal"
|
||||
|
||||
#: web/templates/public/layout.gohtml:42 web/templates/public/layout.gohtml:88
|
||||
#: web/templates/admin/campsite/index.gohtml:6
|
||||
#: web/templates/admin/campsite/index.gohtml:12
|
||||
#: web/templates/admin/layout.gohtml:44 web/templates/admin/layout.gohtml:75
|
||||
#: web/templates/admin/layout.gohtml:45 web/templates/admin/layout.gohtml:79
|
||||
msgctxt "title"
|
||||
msgid "Campsites"
|
||||
msgstr "Alojamientos"
|
||||
|
@ -385,7 +387,12 @@ msgctxt "title"
|
|||
msgid "Sections"
|
||||
msgstr "Apartados"
|
||||
|
||||
#: web/templates/public/layout.gohtml:107
|
||||
#: web/templates/public/layout.gohtml:99
|
||||
msgctxt "title"
|
||||
msgid "Opening"
|
||||
msgstr "Apertura"
|
||||
|
||||
#: web/templates/public/layout.gohtml:106
|
||||
msgid "<abbr title=\"Catalonia Tourism Registry\">RTC</abbr> <abbr title=\"Number\">#</abbr>%s"
|
||||
msgstr "<abbr title=\"Número\">Nº</abbr> <abbr title=\"Registro de Turismo de Cataluña\">RTC</abbr> %s"
|
||||
|
||||
|
@ -482,6 +489,33 @@ msgctxt "action"
|
|||
msgid "Translate"
|
||||
msgstr "Traducir"
|
||||
|
||||
#: web/templates/admin/location.gohtml:6 web/templates/admin/location.gohtml:12
|
||||
msgctxt "title"
|
||||
msgid "Location Settings"
|
||||
msgstr "Parámetros de cómo llegar"
|
||||
|
||||
#: web/templates/admin/location.gohtml:17
|
||||
msgctxt "input"
|
||||
msgid "Directions"
|
||||
msgstr "Instrucciones"
|
||||
|
||||
#: web/templates/admin/location.gohtml:35
|
||||
msgctxt "input"
|
||||
msgid "Opening Dates"
|
||||
msgstr "Fechas de apertura"
|
||||
|
||||
#: web/templates/admin/location.gohtml:53
|
||||
msgctxt "input"
|
||||
msgid "Map Embed"
|
||||
msgstr "Incrustación del mapa"
|
||||
|
||||
#: web/templates/admin/location.gohtml:60 web/templates/admin/payment.gohtml:62
|
||||
#: web/templates/admin/profile.gohtml:75
|
||||
#: web/templates/admin/taxDetails.gohtml:152
|
||||
msgctxt "action"
|
||||
msgid "Save changes"
|
||||
msgstr "Guardar los cambios"
|
||||
|
||||
#: web/templates/admin/campsite/feature/form.gohtml:8
|
||||
#: web/templates/admin/campsite/feature/form.gohtml:25
|
||||
msgctxt "title"
|
||||
|
@ -802,7 +836,7 @@ msgstr "Descripción"
|
|||
|
||||
#: web/templates/admin/campsite/type/index.gohtml:6
|
||||
#: web/templates/admin/campsite/type/index.gohtml:12
|
||||
#: web/templates/admin/layout.gohtml:41
|
||||
#: web/templates/admin/layout.gohtml:42
|
||||
msgctxt "title"
|
||||
msgid "Campsite Types"
|
||||
msgstr "Tipos de alojamientos"
|
||||
|
@ -877,7 +911,7 @@ msgstr "Color"
|
|||
|
||||
#: web/templates/admin/season/index.gohtml:6
|
||||
#: web/templates/admin/season/index.gohtml:12
|
||||
#: web/templates/admin/layout.gohtml:47
|
||||
#: web/templates/admin/layout.gohtml:48
|
||||
msgctxt "title"
|
||||
msgid "Seasons"
|
||||
msgstr "Temporadas"
|
||||
|
@ -909,7 +943,7 @@ msgid "Cancel"
|
|||
msgstr "Cancelar"
|
||||
|
||||
#: web/templates/admin/payment.gohtml:6 web/templates/admin/payment.gohtml:12
|
||||
#: web/templates/admin/layout.gohtml:38
|
||||
#: web/templates/admin/layout.gohtml:39
|
||||
msgctxt "title"
|
||||
msgid "Payment Settings"
|
||||
msgstr "Parámetros de pago"
|
||||
|
@ -944,14 +978,8 @@ msgctxt "title"
|
|||
msgid "Integration"
|
||||
msgstr "Integración"
|
||||
|
||||
#: web/templates/admin/payment.gohtml:62 web/templates/admin/profile.gohtml:75
|
||||
#: web/templates/admin/taxDetails.gohtml:152
|
||||
msgctxt "action"
|
||||
msgid "Save changes"
|
||||
msgstr "Guardar los cambios"
|
||||
|
||||
#: web/templates/admin/dashboard.gohtml:6
|
||||
#: web/templates/admin/dashboard.gohtml:10 web/templates/admin/layout.gohtml:72
|
||||
#: web/templates/admin/dashboard.gohtml:10 web/templates/admin/layout.gohtml:76
|
||||
msgctxt "title"
|
||||
msgid "Dashboard"
|
||||
msgstr "Panel"
|
||||
|
@ -984,7 +1012,7 @@ msgid "New Service"
|
|||
msgstr "Nuevo servicio"
|
||||
|
||||
#: web/templates/admin/services/index.gohtml:6
|
||||
#: web/templates/admin/layout.gohtml:56
|
||||
#: web/templates/admin/layout.gohtml:57
|
||||
msgctxt "title"
|
||||
msgid "Services Page"
|
||||
msgstr "Página de servicios"
|
||||
|
@ -1020,7 +1048,7 @@ msgid "Translate Service to %s"
|
|||
msgstr "Traducción del servicio a %s"
|
||||
|
||||
#: web/templates/admin/profile.gohtml:6 web/templates/admin/profile.gohtml:12
|
||||
#: web/templates/admin/layout.gohtml:31
|
||||
#: web/templates/admin/layout.gohtml:32
|
||||
msgctxt "title"
|
||||
msgid "Profile"
|
||||
msgstr "Perfil"
|
||||
|
@ -1112,29 +1140,29 @@ msgctxt "input"
|
|||
msgid "Legal Disclaimer"
|
||||
msgstr "Nota legal"
|
||||
|
||||
#: web/templates/admin/layout.gohtml:27
|
||||
#: web/templates/admin/layout.gohtml:28
|
||||
msgctxt "title"
|
||||
msgid "User Menu"
|
||||
msgstr "Menú de usuario"
|
||||
|
||||
#: web/templates/admin/layout.gohtml:35
|
||||
#: web/templates/admin/layout.gohtml:36
|
||||
msgctxt "title"
|
||||
msgid "Company Settings"
|
||||
msgstr "Parámetros de la empresa"
|
||||
|
||||
#: web/templates/admin/layout.gohtml:50
|
||||
#: web/templates/admin/layout.gohtml:51
|
||||
#: web/templates/admin/media/index.gohtml:6
|
||||
#: web/templates/admin/media/index.gohtml:11
|
||||
msgctxt "title"
|
||||
msgid "Media"
|
||||
msgstr "Medios"
|
||||
|
||||
#: web/templates/admin/layout.gohtml:53 web/templates/admin/home/index.gohtml:6
|
||||
#: web/templates/admin/layout.gohtml:54 web/templates/admin/home/index.gohtml:6
|
||||
msgctxt "title"
|
||||
msgid "Home Page"
|
||||
msgstr "Página de inicio"
|
||||
|
||||
#: web/templates/admin/layout.gohtml:61
|
||||
#: web/templates/admin/layout.gohtml:65
|
||||
msgctxt "action"
|
||||
msgid "Logout"
|
||||
msgstr "Salir"
|
||||
|
@ -1265,7 +1293,7 @@ msgstr "El idioma escogido no es válido."
|
|||
msgid "File must be a valid PNG or JPEG image."
|
||||
msgstr "El archivo tiene que ser una imagen PNG o JPEG válida."
|
||||
|
||||
#: pkg/app/admin.go:56
|
||||
#: pkg/app/admin.go:59
|
||||
msgid "Access forbidden"
|
||||
msgstr "Acceso prohibido"
|
||||
|
||||
|
@ -1534,55 +1562,55 @@ msgstr "No podéis dejar el archivo del medio en blanco."
|
|||
msgid "Filename can not be empty."
|
||||
msgstr "No podéis dejar el nombre del archivo en blanco."
|
||||
|
||||
#: pkg/booking/admin.go:74
|
||||
#: pkg/booking/admin.go:76
|
||||
msgctxt "redsys environment"
|
||||
msgid "Test"
|
||||
msgstr "Pruebas"
|
||||
|
||||
#: pkg/booking/admin.go:78
|
||||
#: pkg/booking/admin.go:80
|
||||
msgctxt "redsys environment"
|
||||
msgid "Live"
|
||||
msgstr "Real"
|
||||
|
||||
#: pkg/booking/admin.go:87
|
||||
#: pkg/booking/admin.go:89
|
||||
msgctxt "redsys integration"
|
||||
msgid "InSite"
|
||||
msgstr "InSite"
|
||||
|
||||
#: pkg/booking/admin.go:91
|
||||
#: pkg/booking/admin.go:93
|
||||
msgctxt "redsys integration"
|
||||
msgid "Redirect"
|
||||
msgstr "Redirección"
|
||||
|
||||
#: pkg/booking/admin.go:135
|
||||
#: pkg/booking/admin.go:137
|
||||
msgid "Merchant code can not be empty."
|
||||
msgstr "No podéis dejar el código del comercio en blanco."
|
||||
|
||||
#: pkg/booking/admin.go:136
|
||||
#: pkg/booking/admin.go:138
|
||||
msgid "Merchant code must be exactly nine digits long."
|
||||
msgstr "El código del comercio tiene que ser de nueve dígitos."
|
||||
|
||||
#: pkg/booking/admin.go:137
|
||||
#: pkg/booking/admin.go:139
|
||||
msgid "Merchant code must be a number."
|
||||
msgstr "El código del comercio tiene que ser un número."
|
||||
|
||||
#: pkg/booking/admin.go:141
|
||||
#: pkg/booking/admin.go:143
|
||||
msgid "Terminal number can not be empty."
|
||||
msgstr "No podéis dejar el número de terminal en blanco."
|
||||
|
||||
#: pkg/booking/admin.go:142
|
||||
#: pkg/booking/admin.go:144
|
||||
msgid "Terminal number must be a number between 1 and 999."
|
||||
msgstr "El número de terminal tiene que ser entre 1 y 999."
|
||||
|
||||
#: pkg/booking/admin.go:150
|
||||
#: pkg/booking/admin.go:152
|
||||
msgid "Selected environment is not valid."
|
||||
msgstr "El entorno escogido no es válido."
|
||||
|
||||
#: pkg/booking/admin.go:151
|
||||
#: pkg/booking/admin.go:153
|
||||
msgid "Selected integration is not valid."
|
||||
msgstr "La integración escogida no es válida."
|
||||
|
||||
#: pkg/booking/admin.go:154
|
||||
#: pkg/booking/admin.go:156
|
||||
msgid "The merchant key is not valid."
|
||||
msgstr "Esta clave del comercio no es válida."
|
||||
|
||||
|
@ -1638,6 +1666,10 @@ msgstr "%s tiene que ser como mínimo %d."
|
|||
msgid "%s must be at most %d."
|
||||
msgstr "%s tiene que ser como máximo %d"
|
||||
|
||||
#~ msgctxt "title"
|
||||
#~ msgid "Contact"
|
||||
#~ msgstr "Contacto"
|
||||
|
||||
#~ msgctxt "title"
|
||||
#~ msgid "Party Details"
|
||||
#~ msgstr "Datos de los visitantes"
|
||||
|
|
120
po/fr.po
120
po/fr.po
|
@ -8,7 +8,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: camper\n"
|
||||
"Report-Msgid-Bugs-To: jordi@tandem.blog\n"
|
||||
"POT-Creation-Date: 2023-12-21 17:32+0100\n"
|
||||
"POT-Creation-Date: 2023-12-21 21:08+0100\n"
|
||||
"PO-Revision-Date: 2023-12-20 10:13+0100\n"
|
||||
"Last-Translator: Oriol Carbonell <info@oriolcarbonell.cat>\n"
|
||||
"Language-Team: French <traduc@traduc.org>\n"
|
||||
|
@ -44,7 +44,7 @@ msgstr "Le paiement a échoué"
|
|||
|
||||
#: web/templates/public/services.gohtml:6
|
||||
#: web/templates/public/services.gohtml:15
|
||||
#: web/templates/public/layout.gohtml:52 web/templates/public/layout.gohtml:79
|
||||
#: web/templates/public/layout.gohtml:51 web/templates/public/layout.gohtml:79
|
||||
#: web/templates/admin/services/index.gohtml:66
|
||||
msgctxt "title"
|
||||
msgid "Services"
|
||||
|
@ -54,6 +54,14 @@ msgstr "Services"
|
|||
msgid "The campsite offers many different services."
|
||||
msgstr "Le camping propose de nombreux services différents."
|
||||
|
||||
#: web/templates/public/location.gohtml:6
|
||||
#: web/templates/public/location.gohtml:12
|
||||
#: web/templates/public/layout.gohtml:53 web/templates/public/layout.gohtml:81
|
||||
#: web/templates/admin/layout.gohtml:60
|
||||
msgctxt "title"
|
||||
msgid "Location"
|
||||
msgstr "Comment nous rejoindre"
|
||||
|
||||
#: web/templates/public/home.gohtml:6 web/templates/public/layout.gohtml:37
|
||||
#: web/templates/public/layout.gohtml:77
|
||||
msgctxt "title"
|
||||
|
@ -80,7 +88,7 @@ msgstr "Venez et profitez-en !"
|
|||
#: web/templates/public/home.gohtml:35
|
||||
#: web/templates/public/surroundings.gohtml:6
|
||||
#: web/templates/public/surroundings.gohtml:10
|
||||
#: web/templates/public/layout.gohtml:53 web/templates/public/layout.gohtml:80
|
||||
#: web/templates/public/layout.gohtml:52 web/templates/public/layout.gohtml:80
|
||||
msgctxt "title"
|
||||
msgid "Surroundings"
|
||||
msgstr "Entourage"
|
||||
|
@ -269,14 +277,8 @@ msgctxt "title"
|
|||
msgid "Campground"
|
||||
msgstr "Camping"
|
||||
|
||||
#: web/templates/public/contact.gohtml:6 web/templates/public/contact.gohtml:18
|
||||
#: web/templates/public/layout.gohtml:54 web/templates/public/layout.gohtml:81
|
||||
msgctxt "title"
|
||||
msgid "Contact"
|
||||
msgstr "Contact"
|
||||
|
||||
#: web/templates/public/booking.gohtml:6 web/templates/public/booking.gohtml:11
|
||||
#: web/templates/public/layout.gohtml:51
|
||||
#: web/templates/public/layout.gohtml:54
|
||||
msgctxt "title"
|
||||
msgid "Booking"
|
||||
msgstr "Reservation"
|
||||
|
@ -365,18 +367,18 @@ msgid "I have read and I accept the reservation conditions"
|
|||
msgstr "J’ai lu et j’accepte les conditions de réservation"
|
||||
|
||||
#: web/templates/public/layout.gohtml:11 web/templates/public/layout.gohtml:32
|
||||
#: web/templates/public/layout.gohtml:110
|
||||
#: web/templates/public/layout.gohtml:109
|
||||
msgid "Campsite Montagut"
|
||||
msgstr "Camping Montagut"
|
||||
|
||||
#: web/templates/public/layout.gohtml:23 web/templates/admin/layout.gohtml:19
|
||||
#: web/templates/public/layout.gohtml:23 web/templates/admin/layout.gohtml:20
|
||||
msgid "Skip to main content"
|
||||
msgstr "Passer au contenu principal"
|
||||
|
||||
#: web/templates/public/layout.gohtml:42 web/templates/public/layout.gohtml:88
|
||||
#: web/templates/admin/campsite/index.gohtml:6
|
||||
#: web/templates/admin/campsite/index.gohtml:12
|
||||
#: web/templates/admin/layout.gohtml:44 web/templates/admin/layout.gohtml:75
|
||||
#: web/templates/admin/layout.gohtml:45 web/templates/admin/layout.gohtml:79
|
||||
msgctxt "title"
|
||||
msgid "Campsites"
|
||||
msgstr "Locatifs"
|
||||
|
@ -386,7 +388,12 @@ msgctxt "title"
|
|||
msgid "Sections"
|
||||
msgstr "Sections"
|
||||
|
||||
#: web/templates/public/layout.gohtml:107
|
||||
#: web/templates/public/layout.gohtml:99
|
||||
msgctxt "title"
|
||||
msgid "Opening"
|
||||
msgstr "Ouverture"
|
||||
|
||||
#: web/templates/public/layout.gohtml:106
|
||||
msgid "<abbr title=\"Catalonia Tourism Registry\">RTC</abbr> <abbr title=\"Number\">#</abbr>%s"
|
||||
msgstr "<abbr title=\"Registre du tourisme de Catalogne\"># RTC</abbr> %s"
|
||||
|
||||
|
@ -483,6 +490,33 @@ msgctxt "action"
|
|||
msgid "Translate"
|
||||
msgstr "Traduire"
|
||||
|
||||
#: web/templates/admin/location.gohtml:6 web/templates/admin/location.gohtml:12
|
||||
msgctxt "title"
|
||||
msgid "Location Settings"
|
||||
msgstr "Paramètres de comment nous rejoindre"
|
||||
|
||||
#: web/templates/admin/location.gohtml:17
|
||||
msgctxt "input"
|
||||
msgid "Directions"
|
||||
msgstr "Directions"
|
||||
|
||||
#: web/templates/admin/location.gohtml:35
|
||||
msgctxt "input"
|
||||
msgid "Opening Dates"
|
||||
msgstr "Dates d’ouverture"
|
||||
|
||||
#: web/templates/admin/location.gohtml:53
|
||||
msgctxt "input"
|
||||
msgid "Map Embed"
|
||||
msgstr "Carte intégrée"
|
||||
|
||||
#: web/templates/admin/location.gohtml:60 web/templates/admin/payment.gohtml:62
|
||||
#: web/templates/admin/profile.gohtml:75
|
||||
#: web/templates/admin/taxDetails.gohtml:152
|
||||
msgctxt "action"
|
||||
msgid "Save changes"
|
||||
msgstr "Enregistrer les changements"
|
||||
|
||||
#: web/templates/admin/campsite/feature/form.gohtml:8
|
||||
#: web/templates/admin/campsite/feature/form.gohtml:25
|
||||
msgctxt "title"
|
||||
|
@ -803,7 +837,7 @@ msgstr "Description"
|
|||
|
||||
#: web/templates/admin/campsite/type/index.gohtml:6
|
||||
#: web/templates/admin/campsite/type/index.gohtml:12
|
||||
#: web/templates/admin/layout.gohtml:41
|
||||
#: web/templates/admin/layout.gohtml:42
|
||||
msgctxt "title"
|
||||
msgid "Campsite Types"
|
||||
msgstr "Types d’emplacements de camping"
|
||||
|
@ -878,7 +912,7 @@ msgstr "Couleur"
|
|||
|
||||
#: web/templates/admin/season/index.gohtml:6
|
||||
#: web/templates/admin/season/index.gohtml:12
|
||||
#: web/templates/admin/layout.gohtml:47
|
||||
#: web/templates/admin/layout.gohtml:48
|
||||
msgctxt "title"
|
||||
msgid "Seasons"
|
||||
msgstr "Saisons"
|
||||
|
@ -910,7 +944,7 @@ msgid "Cancel"
|
|||
msgstr "Annuler"
|
||||
|
||||
#: web/templates/admin/payment.gohtml:6 web/templates/admin/payment.gohtml:12
|
||||
#: web/templates/admin/layout.gohtml:38
|
||||
#: web/templates/admin/layout.gohtml:39
|
||||
msgctxt "title"
|
||||
msgid "Payment Settings"
|
||||
msgstr "Paramètres de paiement"
|
||||
|
@ -945,14 +979,8 @@ msgctxt "title"
|
|||
msgid "Integration"
|
||||
msgstr "Intégration"
|
||||
|
||||
#: web/templates/admin/payment.gohtml:62 web/templates/admin/profile.gohtml:75
|
||||
#: web/templates/admin/taxDetails.gohtml:152
|
||||
msgctxt "action"
|
||||
msgid "Save changes"
|
||||
msgstr "Enregistrer les changements"
|
||||
|
||||
#: web/templates/admin/dashboard.gohtml:6
|
||||
#: web/templates/admin/dashboard.gohtml:10 web/templates/admin/layout.gohtml:72
|
||||
#: web/templates/admin/dashboard.gohtml:10 web/templates/admin/layout.gohtml:76
|
||||
msgctxt "title"
|
||||
msgid "Dashboard"
|
||||
msgstr "Tableau de bord"
|
||||
|
@ -985,7 +1013,7 @@ msgid "New Service"
|
|||
msgstr "Nouveau service"
|
||||
|
||||
#: web/templates/admin/services/index.gohtml:6
|
||||
#: web/templates/admin/layout.gohtml:56
|
||||
#: web/templates/admin/layout.gohtml:57
|
||||
msgctxt "title"
|
||||
msgid "Services Page"
|
||||
msgstr "La page des services"
|
||||
|
@ -1021,7 +1049,7 @@ msgid "Translate Service to %s"
|
|||
msgstr "Traduire le service en %s"
|
||||
|
||||
#: web/templates/admin/profile.gohtml:6 web/templates/admin/profile.gohtml:12
|
||||
#: web/templates/admin/layout.gohtml:31
|
||||
#: web/templates/admin/layout.gohtml:32
|
||||
msgctxt "title"
|
||||
msgid "Profile"
|
||||
msgstr "Profil"
|
||||
|
@ -1113,29 +1141,29 @@ msgctxt "input"
|
|||
msgid "Legal Disclaimer"
|
||||
msgstr "Avertissement juridique"
|
||||
|
||||
#: web/templates/admin/layout.gohtml:27
|
||||
#: web/templates/admin/layout.gohtml:28
|
||||
msgctxt "title"
|
||||
msgid "User Menu"
|
||||
msgstr "Menu utilisateur"
|
||||
|
||||
#: web/templates/admin/layout.gohtml:35
|
||||
#: web/templates/admin/layout.gohtml:36
|
||||
msgctxt "title"
|
||||
msgid "Company Settings"
|
||||
msgstr "Paramètres de l'entreprise"
|
||||
|
||||
#: web/templates/admin/layout.gohtml:50
|
||||
#: web/templates/admin/layout.gohtml:51
|
||||
#: web/templates/admin/media/index.gohtml:6
|
||||
#: web/templates/admin/media/index.gohtml:11
|
||||
msgctxt "title"
|
||||
msgid "Media"
|
||||
msgstr "Média"
|
||||
|
||||
#: web/templates/admin/layout.gohtml:53 web/templates/admin/home/index.gohtml:6
|
||||
#: web/templates/admin/layout.gohtml:54 web/templates/admin/home/index.gohtml:6
|
||||
msgctxt "title"
|
||||
msgid "Home Page"
|
||||
msgstr "Page d'accueil"
|
||||
|
||||
#: web/templates/admin/layout.gohtml:61
|
||||
#: web/templates/admin/layout.gohtml:65
|
||||
msgctxt "action"
|
||||
msgid "Logout"
|
||||
msgstr "Déconnexion"
|
||||
|
@ -1266,7 +1294,7 @@ msgstr "La langue sélectionnée n’est pas valide."
|
|||
msgid "File must be a valid PNG or JPEG image."
|
||||
msgstr "Le fichier doit être une image PNG ou JPEG valide."
|
||||
|
||||
#: pkg/app/admin.go:56
|
||||
#: pkg/app/admin.go:59
|
||||
msgid "Access forbidden"
|
||||
msgstr "Accès interdit"
|
||||
|
||||
|
@ -1535,55 +1563,55 @@ msgstr "Le fichier téléchargé ne peut pas être vide."
|
|||
msgid "Filename can not be empty."
|
||||
msgstr "Le nom de fichier ne peut pas être vide."
|
||||
|
||||
#: pkg/booking/admin.go:74
|
||||
#: pkg/booking/admin.go:76
|
||||
msgctxt "redsys environment"
|
||||
msgid "Test"
|
||||
msgstr "Test"
|
||||
|
||||
#: pkg/booking/admin.go:78
|
||||
#: pkg/booking/admin.go:80
|
||||
msgctxt "redsys environment"
|
||||
msgid "Live"
|
||||
msgstr "Live"
|
||||
|
||||
#: pkg/booking/admin.go:87
|
||||
#: pkg/booking/admin.go:89
|
||||
msgctxt "redsys integration"
|
||||
msgid "InSite"
|
||||
msgstr "Insite"
|
||||
|
||||
#: pkg/booking/admin.go:91
|
||||
#: pkg/booking/admin.go:93
|
||||
msgctxt "redsys integration"
|
||||
msgid "Redirect"
|
||||
msgstr "Redirection"
|
||||
|
||||
#: pkg/booking/admin.go:135
|
||||
#: pkg/booking/admin.go:137
|
||||
msgid "Merchant code can not be empty."
|
||||
msgstr "Le code marchand ne peut pas être vide."
|
||||
|
||||
#: pkg/booking/admin.go:136
|
||||
#: pkg/booking/admin.go:138
|
||||
msgid "Merchant code must be exactly nine digits long."
|
||||
msgstr "Le code marchand doit comporter exactement neuf chiffres."
|
||||
|
||||
#: pkg/booking/admin.go:137
|
||||
#: pkg/booking/admin.go:139
|
||||
msgid "Merchant code must be a number."
|
||||
msgstr "Le code du commerçant doit être un chiffre."
|
||||
|
||||
#: pkg/booking/admin.go:141
|
||||
#: pkg/booking/admin.go:143
|
||||
msgid "Terminal number can not be empty."
|
||||
msgstr "Le numéro de terminal ne peut pas être vide."
|
||||
|
||||
#: pkg/booking/admin.go:142
|
||||
#: pkg/booking/admin.go:144
|
||||
msgid "Terminal number must be a number between 1 and 999."
|
||||
msgstr "Le numéro de terminal doit être compris entre 1 et 999."
|
||||
|
||||
#: pkg/booking/admin.go:150
|
||||
#: pkg/booking/admin.go:152
|
||||
msgid "Selected environment is not valid."
|
||||
msgstr "L’environnement sélectionné n’est pas valide."
|
||||
|
||||
#: pkg/booking/admin.go:151
|
||||
#: pkg/booking/admin.go:153
|
||||
msgid "Selected integration is not valid."
|
||||
msgstr "L’intégration sélectionnée n’est pas valide."
|
||||
|
||||
#: pkg/booking/admin.go:154
|
||||
#: pkg/booking/admin.go:156
|
||||
msgid "The merchant key is not valid."
|
||||
msgstr "La clé marchand n’est pas valide."
|
||||
|
||||
|
@ -1638,3 +1666,7 @@ msgstr "%s doit être %d ou plus."
|
|||
#, c-format
|
||||
msgid "%s must be at most %d."
|
||||
msgstr "%s doit être tout au plus %d."
|
||||
|
||||
#~ msgctxt "title"
|
||||
#~ msgid "Contact"
|
||||
#~ msgstr "Contact"
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
-- Revert camper:company_geography from pg
|
||||
|
||||
begin;
|
||||
|
||||
drop table if exists camper.company_geography;
|
||||
|
||||
commit;
|
|
@ -1,7 +0,0 @@
|
|||
-- Revert camper:extension_postgis from pg
|
||||
|
||||
begin;
|
||||
|
||||
drop extension if exists postgis;
|
||||
|
||||
commit;
|
|
@ -0,0 +1,7 @@
|
|||
-- Revert camper:location from pg
|
||||
|
||||
begin;
|
||||
|
||||
drop table if exists camper.location;
|
||||
|
||||
commit;
|
|
@ -0,0 +1,7 @@
|
|||
-- Revert camper:location_i18n from pg
|
||||
|
||||
begin;
|
||||
|
||||
drop table if exists camper.location_i18n;
|
||||
|
||||
commit;
|
|
@ -0,0 +1,7 @@
|
|||
-- Revert camper:setup_location from pg
|
||||
|
||||
begin;
|
||||
|
||||
drop function if exists camper.setup_location(integer, text, text, text);
|
||||
|
||||
commit;
|
|
@ -0,0 +1,7 @@
|
|||
-- Revert camper:translate_location from pg
|
||||
|
||||
begin;
|
||||
|
||||
drop function if exists camper.translate_location(integer, text, text, text);
|
||||
|
||||
commit;
|
|
@ -97,8 +97,6 @@ campsite_type_option_cost [roles schema_camper campsite_type season campsite_typ
|
|||
set_campsite_type_option_cost [roles schema_camper campsite_type_option_cost parse_price] 2023-10-05T17:41:58Z jordi fita mas <jordi@tandem.blog> # Add function to set cost of campsite type option
|
||||
add_campsite_type_option [roles schema_camper campsite_type_option campsite_type] 2023-10-06T09:40:03Z jordi fita mas <jordi@tandem.blog> # Add function to create new campsite type options
|
||||
edit_campsite_type_option [roles schema_camper campsite_type_option] 2023-10-06T09:51:02Z jordi fita mas <jordi@tandem.blog> # Add function to edit campsite type options
|
||||
extension_postgis [schema_public] 2023-10-06T17:18:52Z jordi fita mas <jordi@tandem.blog> # Add PostGIS extension
|
||||
company_geography [roles schema_camper company user_profile extension_postgis] 2023-10-06T17:53:34Z jordi fita mas <jordi@tandem.blog> # Add the relation for the GPS coordinates of companies
|
||||
campsite_type_carousel [roles schema_camper campsite_type media user_profile] 2023-10-09T17:18:38Z jordi fita mas <jordi@tandem.blog> # Add the carousel for campsite types
|
||||
campsite_type_carousel_i18n [roles schema_camper campsite_type_carousel language] 2023-10-09T17:45:09Z jordi fita mas <jordi@tandem.blog> # Add relation for campsite type carousel translations
|
||||
add_campsite_type_carousel_slide [roles schema_camper campsite_type_carousel campsite_type] 2023-10-09T17:59:49Z jordi fita mas <jordi@tandem.blog> # Add function to create slides for the campsite type carousel
|
||||
|
@ -126,3 +124,7 @@ order_campsite_type_carousel [schema_camper roles campsite_type campsite_type_ca
|
|||
order_home_carousel [schema_camper roles home_carousel] 2023-12-20T18:30:12Z jordi fita mas <jordi@tandem.blog> # Add function to order home carousel
|
||||
order_services_carousel [schema_camper roles services_carousel] 2023-12-20T18:39:18Z jordi fita mas <jordi@tandem.blog> # Add function to order services carousel
|
||||
order_campsite_type_features [schema_camper roles campsite_type_feature] 2023-12-21T16:13:14Z jordi fita mas <jordi@tandem.blog> # Add function to order campsite type features
|
||||
location [schema_camper roles company] 2023-12-21T17:01:28Z jordi fita mas <jordi@tandem.blog> # Add table to keep location information
|
||||
location_i18n [roles schema_camper location language] 2023-12-21T17:32:50Z jordi fita mas <jordi@tandem.blog> # Add relation for location internationalization
|
||||
translate_location [roles schema_camper location_i18n] 2023-12-21T17:37:47Z jordi fita mas <jordi@tandem.blog> # Add function to translate location
|
||||
setup_location [roles schema_camper location] 2023-12-21T19:26:53Z jordi fita mas <jordi@tandem.blog> # Add function to setup location settings
|
||||
|
|
|
@ -1,168 +0,0 @@
|
|||
-- Test company_geography
|
||||
set client_min_messages to warning;
|
||||
create extension if not exists pgtap;
|
||||
reset client_min_messages;
|
||||
|
||||
begin;
|
||||
|
||||
select plan(30);
|
||||
|
||||
set search_path to camper, public;
|
||||
|
||||
select has_table('company_geography');
|
||||
select has_pk('company_geography');
|
||||
select table_privs_are('company_geography', 'guest', array['SELECT']);
|
||||
select table_privs_are('company_geography', 'employee', array['SELECT']);
|
||||
select table_privs_are('company_geography', 'admin', array['SELECT', 'INSERT', 'UPDATE', 'DELETE']);
|
||||
select table_privs_are('company_geography', 'authenticator', array[]::text[]);
|
||||
|
||||
select has_column('company_geography', 'company_id');
|
||||
select col_is_pk('company_geography', 'company_id');
|
||||
select col_is_fk('company_geography', 'company_id');
|
||||
select fk_ok('company_geography', 'company_id', 'company', 'company_id');
|
||||
select col_type_is('company_geography', 'company_id', 'integer');
|
||||
select col_not_null('company_geography', 'company_id');
|
||||
select col_hasnt_default('company_geography', 'company_id');
|
||||
|
||||
select has_column('company_geography', 'geog');
|
||||
select col_type_is('company_geography', 'geog', 'geography');
|
||||
select col_not_null('company_geography', 'geog');
|
||||
select col_hasnt_default('company_geography', 'geog');
|
||||
|
||||
|
||||
set client_min_messages to warning;
|
||||
truncate company_geography cascade;
|
||||
truncate company_host cascade;
|
||||
truncate company_user cascade;
|
||||
truncate company cascade;
|
||||
truncate auth."user" cascade;
|
||||
reset client_min_messages;
|
||||
|
||||
insert into auth."user" (user_id, email, name, password, cookie, cookie_expires_at)
|
||||
values (1, 'demo@tandem.blog', 'Demo', 'test', '44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e', current_timestamp + interval '1 month')
|
||||
, (5, 'admin@tandem.blog', 'Demo', 'test', '12af4c88b528c2ad4222e3740496ecbc58e76e26f087657524', current_timestamp + interval '1 month')
|
||||
;
|
||||
|
||||
insert into company (company_id, business_name, vatin, trade_name, phone, email, web, address, city, province, postal_code, rtc_number, country_code, currency_code, default_lang_tag)
|
||||
values (2, 'Company 2', 'XX123', '', '555-555-555', 'a@a', '', '', '', '', '', '', 'ES', 'EUR', 'ca')
|
||||
, (4, 'Company 4', 'XX234', '', '666-666-666', 'b@b', '', '', '', '', '', '', 'FR', 'USD', 'ca')
|
||||
, (8, 'Company 8', 'XX345', '', '777-777-777', 'c@c', '', '', '', '', '', '', 'DE', 'USD', 'en')
|
||||
;
|
||||
|
||||
insert into company_user (company_id, user_id, role)
|
||||
values (2, 1, 'admin')
|
||||
, (4, 5, 'admin')
|
||||
;
|
||||
|
||||
insert into company_host (company_id, host)
|
||||
values (2, 'co2')
|
||||
, (4, 'co4')
|
||||
;
|
||||
|
||||
insert into company_geography (company_id, geog)
|
||||
values (2, 'SRID=4326;POINT(-118.4079 33.9434)')
|
||||
, (4, 'SRID=4326;POINT(2.5559 49.0083)')
|
||||
;
|
||||
|
||||
prepare geog_data as
|
||||
select company_id, st_x(geog::geometry), st_y(geog::geometry)
|
||||
from company_geography
|
||||
;
|
||||
|
||||
set role guest;
|
||||
select bag_eq(
|
||||
'geog_data',
|
||||
$$ values (2, -118.4079, 33.9434)
|
||||
, (4, 2.5559, 49.0083)
|
||||
$$,
|
||||
'Everyone should be able to list all geography across all companies'
|
||||
);
|
||||
reset role;
|
||||
|
||||
select set_cookie('44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e/demo@tandem.blog', 'co2');
|
||||
|
||||
select lives_ok(
|
||||
$$ delete from company_geography where company_id = 2 $$,
|
||||
'Admin from company 2 should be able to delete geography from that company.'
|
||||
);
|
||||
|
||||
select bag_eq(
|
||||
'geog_data',
|
||||
$$ values (4, 2.5559, 49.0083)
|
||||
$$,
|
||||
'The row should have been deleted.'
|
||||
);
|
||||
|
||||
select lives_ok(
|
||||
$$ insert into company_geography(company_id, geog) values (2, 'SRID=4326;POINT(-22.6056 63.9850)') $$,
|
||||
'Admin from company 2 should be able to insert a new geography to that company.'
|
||||
);
|
||||
|
||||
select bag_eq(
|
||||
'geog_data',
|
||||
$$ values (2, -22.6056, 63.9850)
|
||||
, (4, 2.5559, 49.0083)
|
||||
$$,
|
||||
'The new row should have been added'
|
||||
);
|
||||
|
||||
select lives_ok(
|
||||
$$ update company_geography set geog = 'SRID=4326;POINT(139.7330 35.5670)' where company_id = 2 $$,
|
||||
'Admin from company 2 should be able to update geography of that company.'
|
||||
);
|
||||
|
||||
select bag_eq(
|
||||
'geog_data',
|
||||
$$ values (2, 139.7330, 35.5670)
|
||||
, (4, 2.5559, 49.0083)
|
||||
$$,
|
||||
'The row should have been updated.'
|
||||
);
|
||||
|
||||
|
||||
select throws_ok(
|
||||
$$ insert into company_geography (company_id, geog) values (8, 'SRID=4326;POINT(2.5559 49.0083)') $$,
|
||||
'42501', 'new row violates row-level security policy for table "company_geography"',
|
||||
'Admin from company 2 should NOT be able to insert new geography to another company 8.'
|
||||
);
|
||||
|
||||
select lives_ok(
|
||||
$$ update company_geography set geog = 'SRID=4326;POINT(139.7330 35.5670)' where company_id = 4 $$,
|
||||
'Admin from company 2 should not be able to update geography of company 4, but no error if company_id is not changed.'
|
||||
);
|
||||
|
||||
select bag_eq(
|
||||
'geog_data',
|
||||
$$ values (2, 139.7330, 35.5670)
|
||||
, (4, 2.5559, 49.0083)
|
||||
$$,
|
||||
'No row should have been changed.'
|
||||
);
|
||||
|
||||
select throws_ok(
|
||||
$$ update company_geography set company_id = 4 where company_id = 2 $$,
|
||||
'42501', 'new row violates row-level security policy for table "company_geography"',
|
||||
'Admin from company 2 should NOT be able to move geography to company 4'
|
||||
);
|
||||
|
||||
select lives_ok(
|
||||
$$ delete from company_geography where company_id = 4 $$,
|
||||
'Admin from company 2 should NOT be able to delete geography from company 4, but not error is thrown'
|
||||
);
|
||||
|
||||
select bag_eq(
|
||||
'geog_data',
|
||||
$$ values (2, 139.7330, 35.5670)
|
||||
, (4, 2.5559, 49.0083)
|
||||
$$,
|
||||
'No row should have been changed'
|
||||
);
|
||||
|
||||
reset role;
|
||||
|
||||
|
||||
select *
|
||||
from finish();
|
||||
|
||||
rollback;
|
||||
|
|
@ -14,7 +14,6 @@ select extensions_are(array [
|
|||
, 'pg_libphonenumber'
|
||||
, 'pgtap'
|
||||
, 'plpgsql'
|
||||
, 'postgis'
|
||||
, 'uri'
|
||||
, 'vat'
|
||||
]);
|
||||
|
|
|
@ -0,0 +1,178 @@
|
|||
-- Test location
|
||||
set client_min_messages to warning;
|
||||
create extension if not exists pgtap;
|
||||
reset client_min_messages;
|
||||
|
||||
begin;
|
||||
|
||||
select plan(38);
|
||||
|
||||
set search_path to camper, public;
|
||||
|
||||
select has_table('location');
|
||||
select has_pk('location');
|
||||
select table_privs_are('location', 'guest', array ['SELECT']);
|
||||
select table_privs_are('location', 'employee', array ['SELECT']);
|
||||
select table_privs_are('location', 'admin', array ['SELECT', 'INSERT', 'UPDATE', 'DELETE']);
|
||||
select table_privs_are('location', 'authenticator', array []::text[]);
|
||||
|
||||
select has_column('location', 'company_id');
|
||||
select col_is_pk('location', 'company_id');
|
||||
select col_is_fk('location', 'company_id');
|
||||
select fk_ok('location', 'company_id', 'company', 'company_id');
|
||||
select col_type_is('location', 'company_id', 'integer');
|
||||
select col_not_null('location', 'company_id');
|
||||
select col_hasnt_default('location', 'company_id');
|
||||
|
||||
select has_column('location', 'directions');
|
||||
select col_type_is('location', 'directions', 'xml');
|
||||
select col_not_null('location', 'directions');
|
||||
select col_hasnt_default('location', 'directions');
|
||||
|
||||
select has_column('location', 'map_embed');
|
||||
select col_type_is('location', 'map_embed', 'xml');
|
||||
select col_not_null('location', 'map_embed');
|
||||
select col_hasnt_default('location', 'map_embed');
|
||||
|
||||
select has_column('location', 'opening_dates');
|
||||
select col_type_is('location', 'opening_dates', 'xml');
|
||||
select col_not_null('location', 'opening_dates');
|
||||
select col_hasnt_default('location', 'opening_dates');
|
||||
|
||||
|
||||
set client_min_messages to warning;
|
||||
truncate location cascade;
|
||||
truncate company_host cascade;
|
||||
truncate company_user cascade;
|
||||
truncate company cascade;
|
||||
truncate auth."user" cascade;
|
||||
reset client_min_messages;
|
||||
|
||||
insert into auth."user" (user_id, email, name, password, cookie, cookie_expires_at)
|
||||
values (1, 'demo@tandem.blog', 'Demo', 'test', '44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e', current_timestamp + interval '1 month')
|
||||
, (5, 'admin@tandem.blog', 'Demo', 'test', '12af4c88b528c2ad4222e3740496ecbc58e76e26f087657524', current_timestamp + interval '1 month')
|
||||
;
|
||||
|
||||
insert into company (company_id, business_name, vatin, trade_name, phone, email, web, address, city, province, postal_code, rtc_number, country_code, currency_code, default_lang_tag)
|
||||
values (2, 'Company 2', 'XX123', '', '555-555-555', 'a@a', '', '', '', '', '', '', 'ES', 'EUR', 'ca')
|
||||
, (4, 'Company 4', 'XX234', '', '666-666-666', 'b@b', '', '', '', '', '', '', 'FR', 'USD', 'ca')
|
||||
, (8, 'Company 8', 'XX345', '', '777-777-777', 'c@c', '', '', '', '', '', '', 'DE', 'USD', 'en')
|
||||
;
|
||||
|
||||
insert into company_user (company_id, user_id, role)
|
||||
values (2, 1, 'admin')
|
||||
, (4, 5, 'admin')
|
||||
;
|
||||
|
||||
insert into company_host (company_id, host)
|
||||
values (2, 'co2')
|
||||
, (4, 'co4')
|
||||
;
|
||||
|
||||
insert into location (company_id, directions, map_embed, opening_dates)
|
||||
values (2, '<p>up</p>', '<map/>', '<p>today</p>')
|
||||
, (4, '<p>down</p>', '<mapp/>', '<p>yesterday</p>')
|
||||
;
|
||||
|
||||
prepare location_data as
|
||||
select company_id, directions::text, map_embed::text, opening_dates::text
|
||||
from location
|
||||
;
|
||||
|
||||
set role guest;
|
||||
select bag_eq(
|
||||
'location_data',
|
||||
$$ values (2, '<p>up</p>', '<map/>', '<p>today</p>')
|
||||
, (4, '<p>down</p>', '<mapp/>', '<p>yesterday</p>')
|
||||
$$,
|
||||
'Everyone should be able to list all location across all companies'
|
||||
);
|
||||
reset role;
|
||||
|
||||
select set_cookie('44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e/demo@tandem.blog', 'co2');
|
||||
|
||||
select lives_ok(
|
||||
$$ delete from location where company_id = 2 $$,
|
||||
'Admin from company 2 should be able to delete location from that company.'
|
||||
);
|
||||
|
||||
select bag_eq(
|
||||
'location_data',
|
||||
$$ values (4, '<p>down</p>', '<mapp/>', '<p>yesterday</p>')
|
||||
$$,
|
||||
'The row should have been deleted.'
|
||||
);
|
||||
|
||||
select lives_ok(
|
||||
$$ insert into location(company_id, directions, map_embed, opening_dates) values (2, '<p>left</p>', '<leafletf/>', '<p>tomorrow</p>') $$,
|
||||
'Admin from company 2 should be able to insert a new location to that company.'
|
||||
);
|
||||
|
||||
select bag_eq(
|
||||
'location_data',
|
||||
$$ values (2, '<p>left</p>', '<leafletf/>', '<p>tomorrow</p>')
|
||||
, (4, '<p>down</p>', '<mapp/>', '<p>yesterday</p>')
|
||||
$$,
|
||||
'The new row should have been added'
|
||||
);
|
||||
|
||||
select lives_ok(
|
||||
$$ update location set directions = '<p>up</p>', map_embed = '<map/>', opening_dates = '<p>today</p>' where company_id = 2 $$,
|
||||
'Admin from company 2 should be able to update location of that company.'
|
||||
);
|
||||
|
||||
select bag_eq(
|
||||
'location_data',
|
||||
$$ values (2, '<p>up</p>', '<map/>', '<p>today</p>')
|
||||
, (4, '<p>down</p>', '<mapp/>', '<p>yesterday</p>')
|
||||
$$,
|
||||
'The row should have been updated.'
|
||||
);
|
||||
|
||||
|
||||
select throws_ok(
|
||||
$$ insert into location (company_id, directions, map_embed, opening_dates) values (8, '<p/>', '<div/>', '<p/>') $$,
|
||||
'42501', 'new row violates row-level security policy for table "location"',
|
||||
'Admin from company 2 should NOT be able to insert new location to another company.'
|
||||
);
|
||||
|
||||
select lives_ok(
|
||||
$$ update location set opening_dates = '<p>never</p>' where company_id = 4 $$,
|
||||
'Admin from company 2 should not be able to update location of company 4, but no error if company_id is not changed.'
|
||||
);
|
||||
|
||||
select bag_eq(
|
||||
'location_data',
|
||||
$$ values (2, '<p>up</p>', '<map/>', '<p>today</p>')
|
||||
, (4, '<p>down</p>', '<mapp/>', '<p>yesterday</p>')
|
||||
$$,
|
||||
'No row should have been changed.'
|
||||
);
|
||||
|
||||
select throws_ok(
|
||||
$$ update location set company_id = 4 where company_id = 2 $$,
|
||||
'42501', 'new row violates row-level security policy for table "location"',
|
||||
'Admin from company 2 should NOT be able to move location to company 4'
|
||||
);
|
||||
|
||||
select lives_ok(
|
||||
$$ delete from location where company_id = 4 $$,
|
||||
'Admin from company 2 should NOT be able to delete location from company 4, but not error is thrown'
|
||||
);
|
||||
|
||||
select bag_eq(
|
||||
'location_data',
|
||||
$$ values (2, '<p>up</p>', '<map/>', '<p>today</p>')
|
||||
, (4, '<p>down</p>', '<mapp/>', '<p>yesterday</p>')
|
||||
$$,
|
||||
'No row should have been changed'
|
||||
);
|
||||
|
||||
reset role;
|
||||
|
||||
|
||||
select *
|
||||
from finish();
|
||||
|
||||
rollback;
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
-- Test location_i18n
|
||||
set client_min_messages to warning;
|
||||
create extension if not exists pgtap;
|
||||
reset client_min_messages;
|
||||
|
||||
begin;
|
||||
|
||||
select plan(27);
|
||||
|
||||
set search_path to camper, public;
|
||||
|
||||
select has_table('location_i18n');
|
||||
select has_pk('location_i18n');
|
||||
select col_is_pk('location_i18n', array['company_id', 'lang_tag']);
|
||||
select table_privs_are('location_i18n', 'guest', array['SELECT']);
|
||||
select table_privs_are('location_i18n', 'employee', array['SELECT']);
|
||||
select table_privs_are('location_i18n', 'admin', array['SELECT', 'INSERT', 'UPDATE', 'DELETE']);
|
||||
select table_privs_are('location_i18n', 'authenticator', array[]::text[]);
|
||||
|
||||
select has_column('location_i18n', 'company_id');
|
||||
select col_is_fk('location_i18n', 'company_id');
|
||||
select fk_ok('location_i18n', 'company_id', 'location', 'company_id');
|
||||
select col_type_is('location_i18n', 'company_id', 'integer');
|
||||
select col_not_null('location_i18n', 'company_id');
|
||||
select col_hasnt_default('location_i18n', 'company_id');
|
||||
|
||||
select has_column('location_i18n', 'lang_tag');
|
||||
select col_is_fk('location_i18n', 'lang_tag');
|
||||
select fk_ok('location_i18n', 'lang_tag', 'language', 'lang_tag');
|
||||
select col_type_is('location_i18n', 'lang_tag', 'text');
|
||||
select col_not_null('location_i18n', 'lang_tag');
|
||||
select col_hasnt_default('location_i18n', 'lang_tag');
|
||||
|
||||
select has_column('location_i18n', 'directions');
|
||||
select col_type_is('location_i18n', 'directions', 'xml');
|
||||
select col_not_null('location_i18n', 'directions');
|
||||
select col_hasnt_default('location_i18n', 'directions');
|
||||
|
||||
select has_column('location_i18n', 'opening_dates');
|
||||
select col_type_is('location_i18n', 'opening_dates', 'xml');
|
||||
select col_not_null('location_i18n', 'opening_dates');
|
||||
select col_hasnt_default('location_i18n', 'opening_dates');
|
||||
|
||||
|
||||
select *
|
||||
from finish();
|
||||
|
||||
rollback;
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
-- Test setup_location
|
||||
set client_min_messages to warning;
|
||||
create extension if not exists pgtap;
|
||||
reset client_min_messages;
|
||||
|
||||
begin;
|
||||
|
||||
select plan(15);
|
||||
|
||||
set search_path to camper, public;
|
||||
|
||||
select has_function('camper', 'setup_location', array['integer', 'text', 'text', 'text']);
|
||||
select function_lang_is('camper', 'setup_location', array['integer', 'text', 'text', 'text'], 'sql');
|
||||
select function_returns('camper', 'setup_location', array['integer', 'text', 'text', 'text'], 'void');
|
||||
select isnt_definer('camper', 'setup_location', array['integer', 'text', 'text', 'text']);
|
||||
select volatility_is('camper', 'setup_location', array['integer', 'text', 'text', 'text'], 'volatile');
|
||||
select function_privs_are('camper', 'setup_location', array ['integer', 'text', 'text', 'text'], 'guest', array[]::text[]);
|
||||
select function_privs_are('camper', 'setup_location', array ['integer', 'text', 'text', 'text'], 'employee', array[]::text[]);
|
||||
select function_privs_are('camper', 'setup_location', array ['integer', 'text', 'text', 'text'], 'admin', array['EXECUTE']);
|
||||
select function_privs_are('camper', 'setup_location', array ['integer', 'text', 'text', 'text'], 'authenticator', array[]::text[]);
|
||||
|
||||
set client_min_messages to warning;
|
||||
truncate location cascade;
|
||||
truncate company cascade;
|
||||
reset client_min_messages;
|
||||
|
||||
insert into company (company_id, business_name, vatin, trade_name, phone, email, web, address, city, province, postal_code, rtc_number, country_code, currency_code, default_lang_tag)
|
||||
values (1, 'Company 2', 'XX123', '', '555-555-555', 'a@a', '', '', '', '', '', '', 'ES', 'EUR', 'ca')
|
||||
, (2, 'Company 4', 'XX234', '', '666-666-666', 'b@b', '', '', '', '', '', '', 'FR', 'USD', 'ca')
|
||||
;
|
||||
|
||||
prepare location_data as
|
||||
select company_id, directions::text, map_embed::text, opening_dates::text
|
||||
from location
|
||||
;
|
||||
|
||||
select lives_ok(
|
||||
$$ select setup_location(1, '<p>Up</p>', '<map/>', '<p>Today</p>') $$,
|
||||
'Should be able to setup location parameters for the first company'
|
||||
);
|
||||
|
||||
select lives_ok(
|
||||
$$ select setup_location(2, '<p>Left</p>', '<leaflet/>', '<p>Tomorrow</p>') $$,
|
||||
'Should be able to setup location parameters for the second company'
|
||||
);
|
||||
|
||||
select bag_eq(
|
||||
'location_data',
|
||||
$$ values (1, '<p>Up</p>', '<map/>', '<p>Today</p>'),
|
||||
(2, '<p>Left</p>', '<leaflet/>', '<p>Tomorrow</p>')
|
||||
$$,
|
||||
'Should have inserted all location parameters'
|
||||
);
|
||||
|
||||
select lives_ok(
|
||||
$$ select setup_location(1, '<p>Down</p>', '<google/>', '<p>Never</p>') $$,
|
||||
'Should be able to update location parameters for the first company'
|
||||
);
|
||||
|
||||
select lives_ok(
|
||||
$$ select setup_location(2, '<p>Right</p>', '<map/>', '<p>Yesterday</p>') $$,
|
||||
'Should be able to update location parameters for the second company'
|
||||
);
|
||||
|
||||
select bag_eq(
|
||||
'location_data',
|
||||
$$ values (1, '<p>Down</p>', '<google/>', '<p>Never</p>'),
|
||||
(2, '<p>Right</p>', '<map/>', '<p>Yesterday</p>')
|
||||
$$,
|
||||
'Should have updated all location parameters'
|
||||
);
|
||||
|
||||
select *
|
||||
from finish();
|
||||
|
||||
rollback;
|
|
@ -0,0 +1,72 @@
|
|||
-- Test translate_location
|
||||
set client_min_messages to warning;
|
||||
create extension if not exists pgtap;
|
||||
reset client_min_messages;
|
||||
|
||||
begin;
|
||||
|
||||
select plan(13);
|
||||
|
||||
set search_path to camper, public;
|
||||
|
||||
select has_function('camper', 'translate_location', array['integer', 'text', 'text', 'text']);
|
||||
select function_lang_is('camper', 'translate_location', array['integer', 'text', 'text', 'text'], 'sql');
|
||||
select function_returns('camper', 'translate_location', array['integer', 'text', 'text', 'text'], 'void');
|
||||
select isnt_definer('camper', 'translate_location', array['integer', 'text', 'text', 'text']);
|
||||
select volatility_is('camper', 'translate_location', array['integer', 'text', 'text', 'text'], 'volatile');
|
||||
select function_privs_are('camper', 'translate_location', array['integer', 'text', 'text', 'text'], 'guest', array[]::text[]);
|
||||
select function_privs_are('camper', 'translate_location', array['integer', 'text', 'text', 'text'], 'employee', array[]::text[]);
|
||||
select function_privs_are('camper', 'translate_location', array['integer', 'text', 'text', 'text'], 'admin', array['EXECUTE']);
|
||||
select function_privs_are('camper', 'translate_location', array['integer', 'text', 'text', 'text'], 'authenticator', array[]::text[]);
|
||||
|
||||
|
||||
set client_min_messages to warning;
|
||||
truncate location_i18n cascade;
|
||||
truncate location cascade;
|
||||
truncate company cascade;
|
||||
reset client_min_messages;
|
||||
|
||||
insert into company (company_id, business_name, vatin, trade_name, phone, email, web, address, city, province, postal_code, rtc_number, country_code, currency_code, default_lang_tag)
|
||||
values (2, 'Company 2', 'XX123', '', '555-555-555', 'a@a', '', '', '', '', '', '', 'ES', 'EUR', 'ca')
|
||||
, (4, 'Company 4', 'XX234', '', '666-666-666', 'b@b', '', '', '', '', '', '', 'FR', 'USD', 'ca')
|
||||
;
|
||||
|
||||
insert into location (company_id, directions, map_embed, opening_dates)
|
||||
values (2, '<p>Up</p>', '<map/>', '<p>Tomorrow</p>')
|
||||
, (4, '<p>Left</p>', '<map/>', '<p>Today</p>')
|
||||
;
|
||||
|
||||
insert into location_i18n (company_id, lang_tag, directions, opening_dates)
|
||||
values (2, 'ca', '<p>Uh?</p>', '<p>Uh?</p>')
|
||||
, (4, 'ca', '<p>Uh?</p>', '<p>Uh?</p>')
|
||||
;
|
||||
|
||||
select lives_ok(
|
||||
$$ select translate_location(2, 'es', '<p>Arriba</p>', '<p>Mañana</p>') $$,
|
||||
'Should be able to translate the location of the first company to a new language'
|
||||
);
|
||||
|
||||
select lives_ok(
|
||||
$$ select translate_location(2, 'ca', '<p>Dalt</p>', '<p>Demà</p>') $$,
|
||||
'Should be able to overwrite a location’s translation'
|
||||
);
|
||||
|
||||
select lives_ok(
|
||||
$$ select translate_location(4, 'ca', null, null) $$,
|
||||
'Should be able to “translate” a location to empty strings'
|
||||
);
|
||||
|
||||
|
||||
select bag_eq(
|
||||
$$ select company_id, lang_tag, directions::text, opening_dates::text from location_i18n $$,
|
||||
$$ values (2, 'ca', '<p>Dalt</p>', '<p>Demà</p>')
|
||||
, (2, 'es', '<p>Arriba</p>', '<p>Mañana</p>')
|
||||
, (4, 'ca', '', '')
|
||||
$$,
|
||||
'Should have translated all locations'
|
||||
);
|
||||
|
||||
select *
|
||||
from finish();
|
||||
|
||||
rollback;
|
|
@ -1,16 +0,0 @@
|
|||
-- Verify camper:company_geography on pg
|
||||
|
||||
begin;
|
||||
|
||||
select company_id
|
||||
, geog
|
||||
from camper.company_geography
|
||||
where false;
|
||||
|
||||
select 1 / count(*) from pg_class where oid = 'camper.company_geography'::regclass and relrowsecurity;
|
||||
select 1 / count(*) from pg_policy where polname = 'guest_ok' and polrelid = 'camper.company_geography'::regclass;
|
||||
select 1 / count(*) from pg_policy where polname = 'insert_to_company' and polrelid = 'camper.company_geography'::regclass;
|
||||
select 1 / count(*) from pg_policy where polname = 'update_company' and polrelid = 'camper.company_geography'::regclass;
|
||||
select 1 / count(*) from pg_policy where polname = 'delete_from_company' and polrelid = 'camper.company_geography'::regclass;
|
||||
|
||||
rollback;
|
|
@ -1,10 +0,0 @@
|
|||
-- Verify camper:extension_postgis on pg
|
||||
|
||||
begin;
|
||||
|
||||
select 1 / count(*)
|
||||
from pg_extension
|
||||
where extname = 'postgis'
|
||||
;
|
||||
|
||||
rollback;
|
|
@ -0,0 +1,18 @@
|
|||
-- Verify camper:location on pg
|
||||
|
||||
begin;
|
||||
|
||||
select company_id
|
||||
, directions
|
||||
, map_embed
|
||||
, opening_dates
|
||||
from camper.location
|
||||
where false;
|
||||
|
||||
select 1 / count(*) from pg_class where oid = 'camper.location'::regclass and relrowsecurity;
|
||||
select 1 / count(*) from pg_policy where polname = 'guest_ok' and polrelid = 'camper.location'::regclass;
|
||||
select 1 / count(*) from pg_policy where polname = 'insert_to_company' and polrelid = 'camper.location'::regclass;
|
||||
select 1 / count(*) from pg_policy where polname = 'update_company' and polrelid = 'camper.location'::regclass;
|
||||
select 1 / count(*) from pg_policy where polname = 'delete_from_company' and polrelid = 'camper.location'::regclass;
|
||||
|
||||
rollback;
|
|
@ -0,0 +1,12 @@
|
|||
-- Verify camper:location_i18n on pg
|
||||
|
||||
begin;
|
||||
|
||||
select company_id
|
||||
, lang_tag
|
||||
, directions
|
||||
, opening_dates
|
||||
from camper.location_i18n
|
||||
where false;
|
||||
|
||||
rollback;
|
|
@ -0,0 +1,7 @@
|
|||
-- Verify camper:setup_location on pg
|
||||
|
||||
begin;
|
||||
|
||||
select has_function_privilege('camper.setup_location(integer, text, text, text)', 'execute');
|
||||
|
||||
rollback;
|
|
@ -0,0 +1,7 @@
|
|||
-- Verify camper:translate_location on pg
|
||||
|
||||
begin;
|
||||
|
||||
select has_function_privilege('camper.translate_location(integer, text, text, text)', 'execute');
|
||||
|
||||
rollback;
|
File diff suppressed because one or more lines are too long
|
@ -365,7 +365,7 @@ label, legend {
|
|||
font-style: italic;
|
||||
}
|
||||
|
||||
fieldset + label, label + label {
|
||||
fieldset + label, fieldset + fieldset, label + label:not([x-show]) {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
|
@ -644,9 +644,33 @@ textarea {
|
|||
|
||||
|
||||
#arbres {
|
||||
mix-blend-mode: multiply;
|
||||
mix-blend-mode: multiply;
|
||||
}
|
||||
|
||||
#zones {
|
||||
mix-blend-mode: multiply;
|
||||
}
|
||||
#zones {
|
||||
mix-blend-mode: multiply;
|
||||
}
|
||||
|
||||
/* i18n input */
|
||||
[x-cloak] {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.lang-selector {
|
||||
display: flex;
|
||||
gap: .25em;
|
||||
}
|
||||
|
||||
.lang-selector button {
|
||||
min-width: auto;
|
||||
padding: .15em;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.lang-selector button[aria-pressed="true"] {
|
||||
background-color: var(--camper--color--hay);
|
||||
}
|
||||
|
||||
label[x-show] span, label[x-show] br {
|
||||
display: none;
|
||||
}
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 1.2 KiB |
Binary file not shown.
Before Width: | Height: | Size: 696 B |
Binary file not shown.
Before Width: | Height: | Size: 2.4 KiB |
Binary file not shown.
Before Width: | Height: | Size: 1.4 KiB |
Binary file not shown.
Before Width: | Height: | Size: 618 B |
|
@ -1,661 +0,0 @@
|
|||
/* required styles */
|
||||
|
||||
.leaflet-pane,
|
||||
.leaflet-tile,
|
||||
.leaflet-marker-icon,
|
||||
.leaflet-marker-shadow,
|
||||
.leaflet-tile-container,
|
||||
.leaflet-pane > svg,
|
||||
.leaflet-pane > canvas,
|
||||
.leaflet-zoom-box,
|
||||
.leaflet-image-layer,
|
||||
.leaflet-layer {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
.leaflet-container {
|
||||
overflow: hidden;
|
||||
}
|
||||
.leaflet-tile,
|
||||
.leaflet-marker-icon,
|
||||
.leaflet-marker-shadow {
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
user-select: none;
|
||||
-webkit-user-drag: none;
|
||||
}
|
||||
/* Prevents IE11 from highlighting tiles in blue */
|
||||
.leaflet-tile::selection {
|
||||
background: transparent;
|
||||
}
|
||||
/* Safari renders non-retina tile on retina better with this, but Chrome is worse */
|
||||
.leaflet-safari .leaflet-tile {
|
||||
image-rendering: -webkit-optimize-contrast;
|
||||
}
|
||||
/* hack that prevents hw layers "stretching" when loading new tiles */
|
||||
.leaflet-safari .leaflet-tile-container {
|
||||
width: 1600px;
|
||||
height: 1600px;
|
||||
-webkit-transform-origin: 0 0;
|
||||
}
|
||||
.leaflet-marker-icon,
|
||||
.leaflet-marker-shadow {
|
||||
display: block;
|
||||
}
|
||||
/* .leaflet-container svg: reset svg max-width decleration shipped in Joomla! (joomla.org) 3.x */
|
||||
/* .leaflet-container img: map is broken in FF if you have max-width: 100% on tiles */
|
||||
.leaflet-container .leaflet-overlay-pane svg {
|
||||
max-width: none !important;
|
||||
max-height: none !important;
|
||||
}
|
||||
.leaflet-container .leaflet-marker-pane img,
|
||||
.leaflet-container .leaflet-shadow-pane img,
|
||||
.leaflet-container .leaflet-tile-pane img,
|
||||
.leaflet-container img.leaflet-image-layer,
|
||||
.leaflet-container .leaflet-tile {
|
||||
max-width: none !important;
|
||||
max-height: none !important;
|
||||
width: auto;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.leaflet-container img.leaflet-tile {
|
||||
/* See: https://bugs.chromium.org/p/chromium/issues/detail?id=600120 */
|
||||
mix-blend-mode: plus-lighter;
|
||||
}
|
||||
|
||||
.leaflet-container.leaflet-touch-zoom {
|
||||
-ms-touch-action: pan-x pan-y;
|
||||
touch-action: pan-x pan-y;
|
||||
}
|
||||
.leaflet-container.leaflet-touch-drag {
|
||||
-ms-touch-action: pinch-zoom;
|
||||
/* Fallback for FF which doesn't support pinch-zoom */
|
||||
touch-action: none;
|
||||
touch-action: pinch-zoom;
|
||||
}
|
||||
.leaflet-container.leaflet-touch-drag.leaflet-touch-zoom {
|
||||
-ms-touch-action: none;
|
||||
touch-action: none;
|
||||
}
|
||||
.leaflet-container {
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
.leaflet-container a {
|
||||
-webkit-tap-highlight-color: rgba(51, 181, 229, 0.4);
|
||||
}
|
||||
.leaflet-tile {
|
||||
filter: inherit;
|
||||
visibility: hidden;
|
||||
}
|
||||
.leaflet-tile-loaded {
|
||||
visibility: inherit;
|
||||
}
|
||||
.leaflet-zoom-box {
|
||||
width: 0;
|
||||
height: 0;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
z-index: 800;
|
||||
}
|
||||
/* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */
|
||||
.leaflet-overlay-pane svg {
|
||||
-moz-user-select: none;
|
||||
}
|
||||
|
||||
.leaflet-pane { z-index: 400; }
|
||||
|
||||
.leaflet-tile-pane { z-index: 200; }
|
||||
.leaflet-overlay-pane { z-index: 400; }
|
||||
.leaflet-shadow-pane { z-index: 500; }
|
||||
.leaflet-marker-pane { z-index: 600; }
|
||||
.leaflet-tooltip-pane { z-index: 650; }
|
||||
.leaflet-popup-pane { z-index: 700; }
|
||||
|
||||
.leaflet-map-pane canvas { z-index: 100; }
|
||||
.leaflet-map-pane svg { z-index: 200; }
|
||||
|
||||
.leaflet-vml-shape {
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
}
|
||||
.lvml {
|
||||
behavior: url(#default#VML);
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
|
||||
/* control positioning */
|
||||
|
||||
.leaflet-control {
|
||||
position: relative;
|
||||
z-index: 800;
|
||||
pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
|
||||
pointer-events: auto;
|
||||
}
|
||||
.leaflet-top,
|
||||
.leaflet-bottom {
|
||||
position: absolute;
|
||||
z-index: 1000;
|
||||
pointer-events: none;
|
||||
}
|
||||
.leaflet-top {
|
||||
top: 0;
|
||||
}
|
||||
.leaflet-right {
|
||||
right: 0;
|
||||
}
|
||||
.leaflet-bottom {
|
||||
bottom: 0;
|
||||
}
|
||||
.leaflet-left {
|
||||
left: 0;
|
||||
}
|
||||
.leaflet-control {
|
||||
float: left;
|
||||
clear: both;
|
||||
}
|
||||
.leaflet-right .leaflet-control {
|
||||
float: right;
|
||||
}
|
||||
.leaflet-top .leaflet-control {
|
||||
margin-top: 10px;
|
||||
}
|
||||
.leaflet-bottom .leaflet-control {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.leaflet-left .leaflet-control {
|
||||
margin-left: 10px;
|
||||
}
|
||||
.leaflet-right .leaflet-control {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
|
||||
/* zoom and fade animations */
|
||||
|
||||
.leaflet-fade-anim .leaflet-popup {
|
||||
opacity: 0;
|
||||
-webkit-transition: opacity 0.2s linear;
|
||||
-moz-transition: opacity 0.2s linear;
|
||||
transition: opacity 0.2s linear;
|
||||
}
|
||||
.leaflet-fade-anim .leaflet-map-pane .leaflet-popup {
|
||||
opacity: 1;
|
||||
}
|
||||
.leaflet-zoom-animated {
|
||||
-webkit-transform-origin: 0 0;
|
||||
-ms-transform-origin: 0 0;
|
||||
transform-origin: 0 0;
|
||||
}
|
||||
svg.leaflet-zoom-animated {
|
||||
will-change: transform;
|
||||
}
|
||||
|
||||
.leaflet-zoom-anim .leaflet-zoom-animated {
|
||||
-webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1);
|
||||
-moz-transition: -moz-transform 0.25s cubic-bezier(0,0,0.25,1);
|
||||
transition: transform 0.25s cubic-bezier(0,0,0.25,1);
|
||||
}
|
||||
.leaflet-zoom-anim .leaflet-tile,
|
||||
.leaflet-pan-anim .leaflet-tile {
|
||||
-webkit-transition: none;
|
||||
-moz-transition: none;
|
||||
transition: none;
|
||||
}
|
||||
|
||||
.leaflet-zoom-anim .leaflet-zoom-hide {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
|
||||
/* cursors */
|
||||
|
||||
.leaflet-interactive {
|
||||
cursor: pointer;
|
||||
}
|
||||
.leaflet-grab {
|
||||
cursor: -webkit-grab;
|
||||
cursor: -moz-grab;
|
||||
cursor: grab;
|
||||
}
|
||||
.leaflet-crosshair,
|
||||
.leaflet-crosshair .leaflet-interactive {
|
||||
cursor: crosshair;
|
||||
}
|
||||
.leaflet-popup-pane,
|
||||
.leaflet-control {
|
||||
cursor: auto;
|
||||
}
|
||||
.leaflet-dragging .leaflet-grab,
|
||||
.leaflet-dragging .leaflet-grab .leaflet-interactive,
|
||||
.leaflet-dragging .leaflet-marker-draggable {
|
||||
cursor: move;
|
||||
cursor: -webkit-grabbing;
|
||||
cursor: -moz-grabbing;
|
||||
cursor: grabbing;
|
||||
}
|
||||
|
||||
/* marker & overlays interactivity */
|
||||
.leaflet-marker-icon,
|
||||
.leaflet-marker-shadow,
|
||||
.leaflet-image-layer,
|
||||
.leaflet-pane > svg path,
|
||||
.leaflet-tile-container {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.leaflet-marker-icon.leaflet-interactive,
|
||||
.leaflet-image-layer.leaflet-interactive,
|
||||
.leaflet-pane > svg path.leaflet-interactive,
|
||||
svg.leaflet-image-layer.leaflet-interactive path {
|
||||
pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
/* visual tweaks */
|
||||
|
||||
.leaflet-container {
|
||||
background: #ddd;
|
||||
outline-offset: 1px;
|
||||
}
|
||||
.leaflet-container a {
|
||||
color: #0078A8;
|
||||
}
|
||||
.leaflet-zoom-box {
|
||||
border: 2px dotted #38f;
|
||||
background: rgba(255,255,255,0.5);
|
||||
}
|
||||
|
||||
|
||||
/* general typography */
|
||||
.leaflet-container {
|
||||
font-family: "Helvetica Neue", Arial, Helvetica, sans-serif;
|
||||
font-size: 12px;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
|
||||
/* general toolbar styles */
|
||||
|
||||
.leaflet-bar {
|
||||
box-shadow: 0 1px 5px rgba(0,0,0,0.65);
|
||||
border-radius: 4px;
|
||||
}
|
||||
.leaflet-bar a {
|
||||
background-color: #fff;
|
||||
border-bottom: 1px solid #ccc;
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
line-height: 26px;
|
||||
display: block;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
color: black;
|
||||
}
|
||||
.leaflet-bar a,
|
||||
.leaflet-control-layers-toggle {
|
||||
background-position: 50% 50%;
|
||||
background-repeat: no-repeat;
|
||||
display: block;
|
||||
}
|
||||
.leaflet-bar a:hover,
|
||||
.leaflet-bar a:focus {
|
||||
background-color: #f4f4f4;
|
||||
}
|
||||
.leaflet-bar a:first-child {
|
||||
border-top-left-radius: 4px;
|
||||
border-top-right-radius: 4px;
|
||||
}
|
||||
.leaflet-bar a:last-child {
|
||||
border-bottom-left-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
border-bottom: none;
|
||||
}
|
||||
.leaflet-bar a.leaflet-disabled {
|
||||
cursor: default;
|
||||
background-color: #f4f4f4;
|
||||
color: #bbb;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-bar a {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
}
|
||||
.leaflet-touch .leaflet-bar a:first-child {
|
||||
border-top-left-radius: 2px;
|
||||
border-top-right-radius: 2px;
|
||||
}
|
||||
.leaflet-touch .leaflet-bar a:last-child {
|
||||
border-bottom-left-radius: 2px;
|
||||
border-bottom-right-radius: 2px;
|
||||
}
|
||||
|
||||
/* zoom control */
|
||||
|
||||
.leaflet-control-zoom-in,
|
||||
.leaflet-control-zoom-out {
|
||||
font: bold 18px 'Lucida Console', Monaco, monospace;
|
||||
text-indent: 1px;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-control-zoom-in, .leaflet-touch .leaflet-control-zoom-out {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
|
||||
/* layers control */
|
||||
|
||||
.leaflet-control-layers {
|
||||
box-shadow: 0 1px 5px rgba(0,0,0,0.4);
|
||||
background: #fff;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.leaflet-control-layers-toggle {
|
||||
background-image: url(images/layers.png);
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
}
|
||||
.leaflet-retina .leaflet-control-layers-toggle {
|
||||
background-image: url(images/layers-2x.png);
|
||||
background-size: 26px 26px;
|
||||
}
|
||||
.leaflet-touch .leaflet-control-layers-toggle {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
}
|
||||
.leaflet-control-layers .leaflet-control-layers-list,
|
||||
.leaflet-control-layers-expanded .leaflet-control-layers-toggle {
|
||||
display: none;
|
||||
}
|
||||
.leaflet-control-layers-expanded .leaflet-control-layers-list {
|
||||
display: block;
|
||||
position: relative;
|
||||
}
|
||||
.leaflet-control-layers-expanded {
|
||||
padding: 6px 10px 6px 6px;
|
||||
color: #333;
|
||||
background: #fff;
|
||||
}
|
||||
.leaflet-control-layers-scrollbar {
|
||||
overflow-y: scroll;
|
||||
overflow-x: hidden;
|
||||
padding-right: 5px;
|
||||
}
|
||||
.leaflet-control-layers-selector {
|
||||
margin-top: 2px;
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
.leaflet-control-layers label {
|
||||
display: block;
|
||||
font-size: 13px;
|
||||
font-size: 1.08333em;
|
||||
}
|
||||
.leaflet-control-layers-separator {
|
||||
height: 0;
|
||||
border-top: 1px solid #ddd;
|
||||
margin: 5px -10px 5px -6px;
|
||||
}
|
||||
|
||||
/* Default icon URLs */
|
||||
.leaflet-default-icon-path { /* used only in path-guessing heuristic, see L.Icon.Default */
|
||||
background-image: url(images/marker-icon.png);
|
||||
}
|
||||
|
||||
|
||||
/* attribution and scale controls */
|
||||
|
||||
.leaflet-container .leaflet-control-attribution {
|
||||
background: #fff;
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
margin: 0;
|
||||
}
|
||||
.leaflet-control-attribution,
|
||||
.leaflet-control-scale-line {
|
||||
padding: 0 5px;
|
||||
color: #333;
|
||||
line-height: 1.4;
|
||||
}
|
||||
.leaflet-control-attribution a {
|
||||
text-decoration: none;
|
||||
}
|
||||
.leaflet-control-attribution a:hover,
|
||||
.leaflet-control-attribution a:focus {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.leaflet-attribution-flag {
|
||||
display: inline !important;
|
||||
vertical-align: baseline !important;
|
||||
width: 1em;
|
||||
height: 0.6669em;
|
||||
}
|
||||
.leaflet-left .leaflet-control-scale {
|
||||
margin-left: 5px;
|
||||
}
|
||||
.leaflet-bottom .leaflet-control-scale {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.leaflet-control-scale-line {
|
||||
border: 2px solid #777;
|
||||
border-top: none;
|
||||
line-height: 1.1;
|
||||
padding: 2px 5px 1px;
|
||||
white-space: nowrap;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
text-shadow: 1px 1px #fff;
|
||||
}
|
||||
.leaflet-control-scale-line:not(:first-child) {
|
||||
border-top: 2px solid #777;
|
||||
border-bottom: none;
|
||||
margin-top: -2px;
|
||||
}
|
||||
.leaflet-control-scale-line:not(:first-child):not(:last-child) {
|
||||
border-bottom: 2px solid #777;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-control-attribution,
|
||||
.leaflet-touch .leaflet-control-layers,
|
||||
.leaflet-touch .leaflet-bar {
|
||||
box-shadow: none;
|
||||
}
|
||||
.leaflet-touch .leaflet-control-layers,
|
||||
.leaflet-touch .leaflet-bar {
|
||||
border: 2px solid rgba(0,0,0,0.2);
|
||||
background-clip: padding-box;
|
||||
}
|
||||
|
||||
|
||||
/* popup */
|
||||
|
||||
.leaflet-popup {
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.leaflet-popup-content-wrapper {
|
||||
padding: 1px;
|
||||
text-align: left;
|
||||
border-radius: 12px;
|
||||
}
|
||||
.leaflet-popup-content {
|
||||
margin: 13px 24px 13px 20px;
|
||||
line-height: 1.3;
|
||||
font-size: 13px;
|
||||
font-size: 1.08333em;
|
||||
min-height: 1px;
|
||||
}
|
||||
.leaflet-popup-content p {
|
||||
margin: 17px 0;
|
||||
margin: 1.3em 0;
|
||||
}
|
||||
.leaflet-popup-tip-container {
|
||||
width: 40px;
|
||||
height: 20px;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
margin-top: -1px;
|
||||
margin-left: -20px;
|
||||
overflow: hidden;
|
||||
pointer-events: none;
|
||||
}
|
||||
.leaflet-popup-tip {
|
||||
width: 17px;
|
||||
height: 17px;
|
||||
padding: 1px;
|
||||
|
||||
margin: -10px auto 0;
|
||||
pointer-events: auto;
|
||||
|
||||
-webkit-transform: rotate(45deg);
|
||||
-moz-transform: rotate(45deg);
|
||||
-ms-transform: rotate(45deg);
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
.leaflet-popup-content-wrapper,
|
||||
.leaflet-popup-tip {
|
||||
background: white;
|
||||
color: #333;
|
||||
box-shadow: 0 3px 14px rgba(0,0,0,0.4);
|
||||
}
|
||||
.leaflet-container a.leaflet-popup-close-button {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
border: none;
|
||||
text-align: center;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
font: 16px/24px Tahoma, Verdana, sans-serif;
|
||||
color: #757575;
|
||||
text-decoration: none;
|
||||
background: transparent;
|
||||
}
|
||||
.leaflet-container a.leaflet-popup-close-button:hover,
|
||||
.leaflet-container a.leaflet-popup-close-button:focus {
|
||||
color: #585858;
|
||||
}
|
||||
.leaflet-popup-scrolled {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.leaflet-oldie .leaflet-popup-content-wrapper {
|
||||
-ms-zoom: 1;
|
||||
}
|
||||
.leaflet-oldie .leaflet-popup-tip {
|
||||
width: 24px;
|
||||
margin: 0 auto;
|
||||
|
||||
-ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)";
|
||||
filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678);
|
||||
}
|
||||
|
||||
.leaflet-oldie .leaflet-control-zoom,
|
||||
.leaflet-oldie .leaflet-control-layers,
|
||||
.leaflet-oldie .leaflet-popup-content-wrapper,
|
||||
.leaflet-oldie .leaflet-popup-tip {
|
||||
border: 1px solid #999;
|
||||
}
|
||||
|
||||
|
||||
/* div icon */
|
||||
|
||||
.leaflet-div-icon {
|
||||
background: #fff;
|
||||
border: 1px solid #666;
|
||||
}
|
||||
|
||||
|
||||
/* Tooltip */
|
||||
/* Base styles for the element that has a tooltip */
|
||||
.leaflet-tooltip {
|
||||
position: absolute;
|
||||
padding: 6px;
|
||||
background-color: #fff;
|
||||
border: 1px solid #fff;
|
||||
border-radius: 3px;
|
||||
color: #222;
|
||||
white-space: nowrap;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
pointer-events: none;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.4);
|
||||
}
|
||||
.leaflet-tooltip.leaflet-interactive {
|
||||
cursor: pointer;
|
||||
pointer-events: auto;
|
||||
}
|
||||
.leaflet-tooltip-top:before,
|
||||
.leaflet-tooltip-bottom:before,
|
||||
.leaflet-tooltip-left:before,
|
||||
.leaflet-tooltip-right:before {
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
border: 6px solid transparent;
|
||||
background: transparent;
|
||||
content: "";
|
||||
}
|
||||
|
||||
/* Directions */
|
||||
|
||||
.leaflet-tooltip-bottom {
|
||||
margin-top: 6px;
|
||||
}
|
||||
.leaflet-tooltip-top {
|
||||
margin-top: -6px;
|
||||
}
|
||||
.leaflet-tooltip-bottom:before,
|
||||
.leaflet-tooltip-top:before {
|
||||
left: 50%;
|
||||
margin-left: -6px;
|
||||
}
|
||||
.leaflet-tooltip-top:before {
|
||||
bottom: 0;
|
||||
margin-bottom: -12px;
|
||||
border-top-color: #fff;
|
||||
}
|
||||
.leaflet-tooltip-bottom:before {
|
||||
top: 0;
|
||||
margin-top: -12px;
|
||||
margin-left: -6px;
|
||||
border-bottom-color: #fff;
|
||||
}
|
||||
.leaflet-tooltip-left {
|
||||
margin-left: -6px;
|
||||
}
|
||||
.leaflet-tooltip-right {
|
||||
margin-left: 6px;
|
||||
}
|
||||
.leaflet-tooltip-left:before,
|
||||
.leaflet-tooltip-right:before {
|
||||
top: 50%;
|
||||
margin-top: -6px;
|
||||
}
|
||||
.leaflet-tooltip-left:before {
|
||||
right: 0;
|
||||
margin-right: -12px;
|
||||
border-left-color: #fff;
|
||||
}
|
||||
.leaflet-tooltip-right:before {
|
||||
left: 0;
|
||||
margin-left: -12px;
|
||||
border-right-color: #fff;
|
||||
}
|
||||
|
||||
/* Printing */
|
||||
|
||||
@media print {
|
||||
/* Prevent printers from removing background-images of controls. */
|
||||
.leaflet-control {
|
||||
-webkit-print-color-adjust: exact;
|
||||
print-color-adjust: exact;
|
||||
}
|
||||
}
|
File diff suppressed because one or more lines are too long
|
@ -1152,7 +1152,7 @@ body > footer {
|
|||
gap: 1rem;
|
||||
}
|
||||
|
||||
body > footer div, .campsite_type_features, .campsite_type_detail {
|
||||
body > footer > div, .campsite_type_features, .campsite_type_detail {
|
||||
padding: 5rem 0;
|
||||
border-top: 3px solid black;
|
||||
}
|
||||
|
@ -1168,7 +1168,7 @@ body > footer section:nth-child(3) {
|
|||
padding-bottom: 2.5rem;
|
||||
}
|
||||
|
||||
body > footer div {
|
||||
body > footer > div {
|
||||
display: flex;
|
||||
gap: 3rem;
|
||||
justify-content: space-between;
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
<link rel="stylesheet" media="screen" href="/static/camper.css">
|
||||
<link rel="stylesheet" media="screen" href="/static/icons.css">
|
||||
<script src="/static/sortable@1.15.1.min.js"></script>
|
||||
<script src="/static/alpinejs@3.13.3.min.js"></script>
|
||||
<script src="/static/htmx@1.9.3.min.js"></script>
|
||||
<script type="module" src="/static/camper.js"></script>
|
||||
{{ block "head" . }}{{ end }}
|
||||
|
@ -55,6 +56,9 @@
|
|||
<li>
|
||||
<a href="/admin/services">{{( pgettext "Services Page" "title" )}}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/admin/location">{{( pgettext "Location" "title" )}}</a>
|
||||
</li>
|
||||
{{- end }}
|
||||
<li class="icon_logout">
|
||||
<button data-hx-delete="/me/session" data-hx-headers='{ {{ CSRFHeader }} }'
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
<!--
|
||||
SPDX-FileCopyrightText: 2023 jordi fita mas <jordi@tandem.blog>
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
{{ define "title" -}}
|
||||
{{( pgettext "Location Settings" "title" )}}
|
||||
{{- end }}
|
||||
|
||||
{{ define "content" -}}
|
||||
{{- /*gotype: dev.tandem.ws/tandem/camper/pkg/location.locationForm*/ -}}
|
||||
<form data-hx-put="/admin/location">
|
||||
<h2>{{( pgettext "Location Settings" "title" )}}</h2>
|
||||
{{ CSRFInput }}
|
||||
<fieldset x-data="{ lang: 'ca' }">
|
||||
{{ with .Directions -}}
|
||||
<fieldset>
|
||||
<legend>{{( pgettext "Directions" "input" )}}</legend>
|
||||
<div class="lang-selector" role="toolbar">
|
||||
{{ range $lang, $input := . -}}
|
||||
<button :aria-pressed="lang === '{{ $lang }}'"
|
||||
@click.prevent="lang = '{{ $lang }}'">{{ $lang }}</button>
|
||||
{{- end }}
|
||||
</div>
|
||||
{{ range $lang, $input := . -}}
|
||||
<label x-cloak x-show="lang === '{{ $lang }}'"><span>{{ $lang }}</span><br>
|
||||
<textarea class="html"
|
||||
name="{{ $input.Name }}" {{ template "error-attrs" . }}>{{ $input.Val }}</textarea><br>
|
||||
</label>
|
||||
{{- end }}
|
||||
{{ template "error-message" . }}
|
||||
</fieldset>
|
||||
{{- end }}
|
||||
{{ with .OpeningDates -}}
|
||||
<fieldset>
|
||||
<legend>{{( pgettext "Opening Dates" "input" )}}</legend>
|
||||
<div class="lang-selector" role="toolbar">
|
||||
{{ range $lang, $input := . -}}
|
||||
<button :aria-pressed="lang === '{{ $lang }}'"
|
||||
@click.prevent="lang = '{{ $lang }}'">{{ $lang }}</button>
|
||||
{{- end }}
|
||||
</div>
|
||||
{{ range $lang, $input := . -}}
|
||||
<label x-cloak x-show="lang === '{{ $lang }}'"><span>{{ $lang }}</span><br>
|
||||
<textarea class="html"
|
||||
name="{{ $input.Name }}" {{ template "error-attrs" . }}>{{ $input.Val }}</textarea><br>
|
||||
</label>
|
||||
{{- end }}
|
||||
{{ template "error-message" . }}
|
||||
</fieldset>
|
||||
{{- end }}
|
||||
{{ with .MapEmbed -}}
|
||||
<label>
|
||||
{{( pgettext "Map Embed" "input")}}<br>
|
||||
<textarea name="{{ .Name }}" {{ template "error-attrs" . }}>{{ .Val }}</textarea><br>
|
||||
{{ template "error-message" . }}
|
||||
</label>
|
||||
{{- end }}
|
||||
</fieldset>
|
||||
<footer>
|
||||
<button type="submit">{{( pgettext "Save changes" "action" )}}</button>
|
||||
</footer>
|
||||
</form>
|
||||
{{- end }}
|
|
@ -1,62 +0,0 @@
|
|||
<!--
|
||||
SPDX-FileCopyrightText: 2023 jordi fita mas <jordi@tandem.blog>
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
{{ define "title" -}}
|
||||
{{( pgettext "Contact" "title" )}}
|
||||
{{- end }}
|
||||
|
||||
{{ define "head" -}}
|
||||
<link rel="stylesheet" href="/static/leaflet@1.9.4/leaflet.css">
|
||||
{{- end }}
|
||||
|
||||
{{ define "content" -}}
|
||||
{{- /*gotype: dev.tandem.ws/tandem/camper/pkg/app.contactPage*/ -}}
|
||||
|
||||
<div class="contact-page">
|
||||
<div class="contact-details">
|
||||
<h2>{{( pgettext "Contact" "title" )}}</h2>
|
||||
|
||||
{{ template "companyAddress" .PublicPage.CompanyAddress }}
|
||||
<p>GPS: 42º 14’ 43,86’’ / 2º 35’ 58,26’’</p>
|
||||
</div>
|
||||
|
||||
<div id="map"></div>
|
||||
</div>
|
||||
|
||||
{{ if .CompanyGeography -}}
|
||||
<script src="/static/leaflet@1.9.4/leaflet.js"></script>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
var container = document.getElementById("map");
|
||||
container.style.height = '600px';
|
||||
var map = L.map(container).setView(['{{ .CompanyGeography.Lat }}', '{{ .CompanyGeography.Lng }}'], '9');
|
||||
|
||||
L
|
||||
.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png', {
|
||||
attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>, © <a href="https://carto.com/attributions">CARTO</a>'
|
||||
})
|
||||
.addTo(map)
|
||||
;
|
||||
|
||||
map.scrollWheelZoom.disable();
|
||||
|
||||
var content =
|
||||
{{- with .PublicPage.CompanyAddress -}}
|
||||
'{{ .Address }}<br>{{ .City }} - {{ .PostalCode }}<br>{{ .Province }}'
|
||||
{{- end -}}
|
||||
;
|
||||
L
|
||||
.marker(['{{ .CompanyGeography.Lat }}', '{{ .CompanyGeography.Lng }}'])
|
||||
.addTo(map)
|
||||
.bindPopup(content)
|
||||
;
|
||||
|
||||
var observer = ResizeObserver && new ResizeObserver(function () {
|
||||
map.invalidateSize(true);
|
||||
});
|
||||
observer && observer.observe(container);
|
||||
});
|
||||
</script>
|
||||
{{- end }}
|
||||
{{- end }}
|
|
@ -50,7 +50,7 @@
|
|||
{{- end }}
|
||||
<li><a href="/{{ currentLocale }}/services">{{( pgettext "Services" "title" )}}</a></li>
|
||||
<li><a href="/{{ currentLocale }}/surroundings">{{( pgettext "Surroundings" "title" )}}</a></li>
|
||||
<li><a href="/{{ currentLocale }}/contact">{{( pgettext "Contact" "title" )}}</a></li>
|
||||
<li><a href="/{{ currentLocale }}/location">{{( pgettext "Location" "title" )}}</a></li>
|
||||
<li class="boto-reserva"><a href="/{{ currentLocale }}/booking">{{( pgettext "Booking" "title" )}}</a></li>
|
||||
{{ if .LocalizedAlternates -}}
|
||||
<li class="has-submenu">{{ range .LocalizedAlternates -}}
|
||||
|
@ -78,7 +78,7 @@
|
|||
<li><a href="/{{ currentLocale }}/campground">{{( pgettext "Campground" "title" )}}</a></li>
|
||||
<li><a href="/{{ currentLocale }}/services">{{( pgettext "Services" "title" )}}</a></li>
|
||||
<li><a href="/{{ currentLocale }}/surroundings">{{( pgettext "Surroundings" "title" )}}</a></li>
|
||||
<li><a href="/{{ currentLocale }}/contact">{{( pgettext "Contact" "title" )}}</a></li>
|
||||
<li><a href="/{{ currentLocale }}/location">{{( pgettext "Location" "title" )}}</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
|
@ -96,9 +96,8 @@
|
|||
{{- end }}
|
||||
|
||||
<section>
|
||||
<h2>Obertura 2023</h2>
|
||||
<p><strong>Camping i Safari tents:</strong><br>de 08/04 a 09/10</p>
|
||||
<p><strong>Cabanes i Bungalows:</strong><br>de 08/04 a 11/12</p>
|
||||
<h2>{{ (pgettext "Opening" "title" )}}</h2>
|
||||
{{ .OpeningDates }}
|
||||
</section>
|
||||
|
||||
<section>
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
<!--
|
||||
SPDX-FileCopyrightText: 2023 jordi fita mas <jordi@tandem.blog>
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
{{ define "title" -}}
|
||||
{{( pgettext "Location" "title" )}}
|
||||
{{- end }}
|
||||
|
||||
{{ define "content" -}}
|
||||
{{- /*gotype: dev.tandem.ws/tandem/camper/pkg/location.locationPage*/ -}}
|
||||
|
||||
<h2>{{( pgettext "Location" "title" )}}</h2>
|
||||
<div class="contact-page">
|
||||
<div class="contact-details">
|
||||
|
||||
{{ .Directions }}
|
||||
</div>
|
||||
|
||||
{{ .MapEmbed }}
|
||||
</div>
|
||||
{{- end }}
|
Loading…
Reference in New Issue