Add management of legal texts
This commit is contained in:
parent
ee86b34e93
commit
03c20fec88
|
@ -0,0 +1,56 @@
|
|||
-- Deploy camper:legal_text to pg
|
||||
-- requires: roles
|
||||
-- requires: schema_camper
|
||||
-- requires: company
|
||||
-- requires: user_profile
|
||||
|
||||
begin;
|
||||
|
||||
set search_path to camper, public;
|
||||
|
||||
create table legal_text (
|
||||
company_id integer not null references company,
|
||||
slug text constraint valid_slug check(slug ~ '^[a-z0-9]+(-[a-z0-9])*$'),
|
||||
name text not null constraint name_not_empty check(length(trim(name)) > 0),
|
||||
content xml not null,
|
||||
primary key (company_id, slug)
|
||||
);
|
||||
|
||||
grant select on table legal_text to guest;
|
||||
grant select on table legal_text to employee;
|
||||
grant select, insert, update, delete on table legal_text to admin;
|
||||
|
||||
|
||||
alter table legal_text enable row level security;
|
||||
|
||||
create policy guest_ok
|
||||
on legal_text
|
||||
for select
|
||||
using (true)
|
||||
;
|
||||
|
||||
create policy insert_to_company
|
||||
on legal_text
|
||||
for insert
|
||||
with check (
|
||||
company_id in (select company_id from user_profile)
|
||||
)
|
||||
;
|
||||
|
||||
create policy update_company
|
||||
on legal_text
|
||||
for update
|
||||
using (
|
||||
company_id in (select company_id from user_profile)
|
||||
)
|
||||
;
|
||||
|
||||
create policy delete_from_company
|
||||
on legal_text
|
||||
for delete
|
||||
using (
|
||||
company_id in (select company_id from user_profile)
|
||||
)
|
||||
;
|
||||
|
||||
commit;
|
|
@ -0,0 +1,25 @@
|
|||
-- Deploy camper:legal_text_i18n to pg
|
||||
-- requires: roles
|
||||
-- requires: schema_camper
|
||||
-- requires: legal_text
|
||||
-- requires: language
|
||||
|
||||
begin;
|
||||
|
||||
set search_path to camper, public;
|
||||
|
||||
create table legal_text_i18n (
|
||||
company_id integer not null,
|
||||
slug text not null,
|
||||
lang_tag text not null references language,
|
||||
name text not null,
|
||||
content xml not null,
|
||||
foreign key (company_id, slug) references legal_text,
|
||||
primary key (company_id, slug, lang_tag)
|
||||
);
|
||||
|
||||
grant select on table legal_text_i18n to guest;
|
||||
grant select on table legal_text_i18n to employee;
|
||||
grant select, insert, update, delete on table legal_text_i18n to admin;
|
||||
|
||||
commit;
|
|
@ -0,0 +1,25 @@
|
|||
-- Deploy camper:translate_legal_text to pg
|
||||
-- requires: roles
|
||||
-- requires: schema_camper
|
||||
-- requires: legal_text_i18n
|
||||
|
||||
begin;
|
||||
|
||||
set search_path to camper, public;
|
||||
|
||||
create or replace function translate_legal_text(company_id integer, slug text, lang_tag text, name text, content text) returns void as
|
||||
$$
|
||||
insert into legal_text_i18n (company_id, slug, lang_tag, name, content)
|
||||
values (company_id, slug, lang_tag, coalesce(name, ''), xmlparse(content coalesce(content, '')))
|
||||
on conflict (company_id, slug, lang_tag) do update
|
||||
set name = excluded.name
|
||||
, content = excluded.content
|
||||
;
|
||||
$$
|
||||
language sql
|
||||
;
|
||||
|
||||
revoke execute on function translate_legal_text(integer, text, text, text, text) from public;
|
||||
grant execute on function translate_legal_text(integer, text, text, text, text) to admin;
|
||||
|
||||
commit;
|
|
@ -6,7 +6,6 @@
|
|||
package app
|
||||
|
||||
import (
|
||||
"dev.tandem.ws/tandem/camper/pkg/location"
|
||||
"net/http"
|
||||
|
||||
"dev.tandem.ws/tandem/camper/pkg/auth"
|
||||
|
@ -16,7 +15,9 @@ 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/legal"
|
||||
"dev.tandem.ws/tandem/camper/pkg/locale"
|
||||
"dev.tandem.ws/tandem/camper/pkg/location"
|
||||
"dev.tandem.ws/tandem/camper/pkg/media"
|
||||
"dev.tandem.ws/tandem/camper/pkg/season"
|
||||
"dev.tandem.ws/tandem/camper/pkg/services"
|
||||
|
@ -27,6 +28,7 @@ type adminHandler struct {
|
|||
campsite *campsite.AdminHandler
|
||||
company *company.AdminHandler
|
||||
home *home.AdminHandler
|
||||
legal *legal.AdminHandler
|
||||
location *location.AdminHandler
|
||||
media *media.AdminHandler
|
||||
payment *booking.AdminHandler
|
||||
|
@ -39,6 +41,7 @@ func newAdminHandler(locales locale.Locales, mediaDir string) *adminHandler {
|
|||
campsite: campsite.NewAdminHandler(locales),
|
||||
company: company.NewAdminHandler(),
|
||||
home: home.NewAdminHandler(locales),
|
||||
legal: legal.NewAdminHandler(),
|
||||
location: location.NewAdminHandler(),
|
||||
media: media.NewAdminHandler(mediaDir),
|
||||
payment: booking.NewAdminHandler(),
|
||||
|
@ -69,6 +72,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 "legal":
|
||||
h.legal.Handler(user, company, conn).ServeHTTP(w, r)
|
||||
case "location":
|
||||
h.location.Handler(user, company, conn).ServeHTTP(w, r)
|
||||
case "media":
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
package app
|
||||
|
||||
import (
|
||||
"dev.tandem.ws/tandem/camper/pkg/legal"
|
||||
"net/http"
|
||||
|
||||
"dev.tandem.ws/tandem/camper/pkg/auth"
|
||||
|
@ -23,6 +24,7 @@ type publicHandler struct {
|
|||
home *home.PublicHandler
|
||||
booking *booking.PublicHandler
|
||||
campsite *campsite.PublicHandler
|
||||
legal *legal.PublicHandler
|
||||
location *location.PublicHandler
|
||||
services *services.PublicHandler
|
||||
}
|
||||
|
@ -32,6 +34,7 @@ func newPublicHandler() *publicHandler {
|
|||
home: home.NewPublicHandler(),
|
||||
booking: booking.NewPublicHandler(),
|
||||
campsite: campsite.NewPublicHandler(),
|
||||
legal: legal.NewPublicHandler(),
|
||||
location: location.NewPublicHandler(),
|
||||
services: services.NewPublicHandler(),
|
||||
}
|
||||
|
@ -50,6 +53,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 "legal":
|
||||
h.legal.Handler(user, company, conn).ServeHTTP(w, r)
|
||||
case "location":
|
||||
h.location.Handler(user, company, conn).ServeHTTP(w, r)
|
||||
case "services":
|
||||
|
|
|
@ -102,3 +102,8 @@ func (tx *Tx) TranslateLocation(ctx context.Context, companyID int, langTag lang
|
|||
_, err := tx.Exec(ctx, "select translate_location($1, $2, $3, $4)", companyID, langTag, directions, openingHours)
|
||||
return err
|
||||
}
|
||||
|
||||
func (tx *Tx) TranslateLegalText(ctx context.Context, companyID int, slug string, langTag language.Tag, name string, content string) error {
|
||||
_, err := tx.Exec(ctx, "select translate_legal_text($1, $2, $3, $4, $5)", companyID, slug, langTag, name, content)
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -7,10 +7,14 @@ package form
|
|||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"dev.tandem.ws/tandem/camper/pkg/locale"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/text/language"
|
||||
|
||||
"dev.tandem.ws/tandem/camper/pkg/database"
|
||||
"dev.tandem.ws/tandem/camper/pkg/locale"
|
||||
)
|
||||
|
||||
type Input struct {
|
||||
|
@ -69,3 +73,14 @@ func (input I18nInput) FillValue(r *http.Request) {
|
|||
inner.FillValue(r)
|
||||
}
|
||||
}
|
||||
|
||||
func (input I18nInput) FillArray(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
|
||||
}
|
||||
|
|
|
@ -0,0 +1,263 @@
|
|||
package legal
|
||||
|
||||
import (
|
||||
"context"
|
||||
"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:
|
||||
serveLegalIndex(w, r, user, company, conn)
|
||||
case http.MethodPost:
|
||||
addLegal(w, r, user, company, conn)
|
||||
default:
|
||||
httplib.MethodNotAllowed(w, r, http.MethodGet, http.MethodPost)
|
||||
}
|
||||
case "new":
|
||||
switch r.Method {
|
||||
case http.MethodGet:
|
||||
f := newLegalForm(company)
|
||||
f.MustRender(w, r, user, company)
|
||||
default:
|
||||
httplib.MethodNotAllowed(w, r, http.MethodGet)
|
||||
}
|
||||
default:
|
||||
f := newLegalForm(company)
|
||||
if err := f.FillFromDatabase(r.Context(), conn, head); err != nil {
|
||||
if database.ErrorIsNotFound(err) {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
panic(err)
|
||||
}
|
||||
h.legalHandler(user, company, conn, f).ServeHTTP(w, r)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func (h *AdminHandler) legalHandler(user *auth.User, company *auth.Company, conn *database.Conn, f *legalForm) 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.MustRender(w, r, user, company)
|
||||
case http.MethodPut:
|
||||
editLegal(w, r, user, company, conn, f)
|
||||
default:
|
||||
httplib.MethodNotAllowed(w, r, http.MethodGet, http.MethodPut)
|
||||
}
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func serveLegalIndex(w http.ResponseWriter, r *http.Request, user *auth.User, company *auth.Company, conn *database.Conn) {
|
||||
legals, err := collectLegalEntries(r.Context(), conn, company)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
page := &legalIndex{
|
||||
Texts: legals,
|
||||
}
|
||||
page.MustRender(w, r, user, company)
|
||||
}
|
||||
|
||||
func collectLegalEntries(ctx context.Context, conn *database.Conn, company *auth.Company) ([]*legalEntry, error) {
|
||||
rows, err := conn.Query(ctx, `
|
||||
select '/admin/legal/' || slug
|
||||
, name
|
||||
from legal_text
|
||||
where company_id = $1
|
||||
order by name
|
||||
`, company.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var legals []*legalEntry
|
||||
for rows.Next() {
|
||||
legal := &legalEntry{}
|
||||
if err = rows.Scan(&legal.URL, &legal.Name); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
legals = append(legals, legal)
|
||||
}
|
||||
|
||||
return legals, nil
|
||||
}
|
||||
|
||||
type legalEntry struct {
|
||||
URL string
|
||||
Name string
|
||||
}
|
||||
|
||||
type legalIndex struct {
|
||||
Texts []*legalEntry
|
||||
}
|
||||
|
||||
func (page *legalIndex) MustRender(w http.ResponseWriter, r *http.Request, user *auth.User, company *auth.Company) {
|
||||
template.MustRenderAdmin(w, r, user, company, "legal/index.gohtml", page)
|
||||
}
|
||||
|
||||
func addLegal(w http.ResponseWriter, r *http.Request, user *auth.User, company *auth.Company, conn *database.Conn) {
|
||||
f := newLegalForm(company)
|
||||
processLegalForm(w, r, user, company, conn, f, func(ctx context.Context, tx *database.Tx) error {
|
||||
_, err := tx.Exec(ctx, `
|
||||
insert into legal_text (company_id, slug, name, content)
|
||||
values ($1, $2, $3, xmlparse(content $4))
|
||||
`, company.ID, f.Slug.Val, f.Name[company.DefaultLanguage.String()].Val, f.Content[company.DefaultLanguage.String()])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for lang := range company.Locales {
|
||||
if err := tx.TranslateLegalText(ctx, company.ID, f.Slug.Val, lang, f.Name[lang.String()].Val, f.Content[lang.String()].Val); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func editLegal(w http.ResponseWriter, r *http.Request, user *auth.User, company *auth.Company, conn *database.Conn, f *legalForm) {
|
||||
processLegalForm(w, r, user, company, conn, f, func(ctx context.Context, tx *database.Tx) error {
|
||||
_, err := tx.Exec(ctx, `
|
||||
update legal_text
|
||||
set name = $3
|
||||
, content = xmlparse(content $4)
|
||||
where company_id = $1
|
||||
and slug = $2
|
||||
`, company.ID, f.Slug.Val, f.Name[company.DefaultLanguage.String()].Val, f.Content[company.DefaultLanguage.String()])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for lang := range company.Locales {
|
||||
if err := tx.TranslateLegalText(ctx, company.ID, f.Slug.Val, lang, f.Name[lang.String()].Val, f.Content[lang.String()].Val); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func processLegalForm(w http.ResponseWriter, r *http.Request, user *auth.User, company *auth.Company, conn *database.Conn, f *legalForm, act func(ctx context.Context, tx *database.Tx) error) {
|
||||
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())
|
||||
if err := act(r.Context(), tx); err == nil {
|
||||
if err := tx.Commit(r.Context()); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
} else {
|
||||
if err := tx.Rollback(r.Context()); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
panic(err)
|
||||
}
|
||||
httplib.Redirect(w, r, "/admin/legal/"+f.Slug.Val, http.StatusSeeOther)
|
||||
}
|
||||
|
||||
type legalForm struct {
|
||||
company *auth.Company
|
||||
URL string
|
||||
Slug *form.Input
|
||||
Name form.I18nInput
|
||||
Content form.I18nInput
|
||||
}
|
||||
|
||||
func newLegalForm(company *auth.Company) *legalForm {
|
||||
f := &legalForm{
|
||||
company: company,
|
||||
Slug: &form.Input{
|
||||
Name: "slug",
|
||||
},
|
||||
Name: form.NewI18nInput(company.Locales, "name"),
|
||||
Content: form.NewI18nInput(company.Locales, "content"),
|
||||
}
|
||||
return f
|
||||
}
|
||||
|
||||
func (f *legalForm) FillFromDatabase(ctx context.Context, conn *database.Conn, slug string) error {
|
||||
var name database.RecordArray
|
||||
var content database.RecordArray
|
||||
row := conn.QueryRow(ctx, `
|
||||
select '/admin/legal/' || text.slug
|
||||
, text.slug
|
||||
, text.name
|
||||
, text.content::text
|
||||
, array_agg((lang_tag, i18n.name))
|
||||
, array_agg((lang_tag, i18n.content::text))
|
||||
from legal_text as text
|
||||
left join legal_text_i18n as i18n using (company_id, slug)
|
||||
where text.company_id = $1
|
||||
and text.slug = $2
|
||||
group by text.slug
|
||||
, text.name
|
||||
, text.content::text
|
||||
`, pgx.QueryResultFormats{pgx.BinaryFormatCode}, f.company.ID, slug)
|
||||
if err := row.Scan(&f.URL, &f.Slug.Val, &f.Name[f.company.DefaultLanguage.String()].Val, &f.Content[f.company.DefaultLanguage.String()].Val, &name, &content); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := f.Name.FillArray(name); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := f.Content.FillArray(content); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *legalForm) Parse(r *http.Request) error {
|
||||
if err := r.ParseForm(); err != nil {
|
||||
return err
|
||||
}
|
||||
f.Slug.FillValue(r)
|
||||
f.Name.FillValue(r)
|
||||
f.Content.FillValue(r)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *legalForm) Valid(l *locale.Locale) bool {
|
||||
v := form.NewValidator(l)
|
||||
if v.CheckRequired(f.Name[f.company.DefaultLanguage.String()], l.GettextNoop("Name can not be empty.")) {
|
||||
v.CheckMinLength(f.Name[f.company.DefaultLanguage.String()], 1, l.GettextNoop("Name must have at least one letter."))
|
||||
}
|
||||
return v.AllOK
|
||||
}
|
||||
|
||||
func (f *legalForm) MustRender(w http.ResponseWriter, r *http.Request, user *auth.User, company *auth.Company) {
|
||||
template.MustRenderAdmin(w, r, user, company, "legal/form.gohtml", f)
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
package legal
|
||||
|
||||
import (
|
||||
"context"
|
||||
"dev.tandem.ws/tandem/camper/pkg/locale"
|
||||
gotemplate "html/template"
|
||||
"net/http"
|
||||
|
||||
"dev.tandem.ws/tandem/camper/pkg/auth"
|
||||
"dev.tandem.ws/tandem/camper/pkg/database"
|
||||
httplib "dev.tandem.ws/tandem/camper/pkg/http"
|
||||
"dev.tandem.ws/tandem/camper/pkg/template"
|
||||
)
|
||||
|
||||
type 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 slug string
|
||||
slug, r.URL.Path = httplib.ShiftPath(r.URL.Path)
|
||||
|
||||
var head string
|
||||
head, r.URL.Path = httplib.ShiftPath(r.URL.Path)
|
||||
|
||||
switch head {
|
||||
case "":
|
||||
switch r.Method {
|
||||
case http.MethodGet:
|
||||
page, err := newLegalPage(r.Context(), company, conn, user.Locale, slug)
|
||||
if database.ErrorIsNotFound(err) {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
} else if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
page.MustRender(w, r, user, company, conn)
|
||||
default:
|
||||
httplib.MethodNotAllowed(w, r, http.MethodGet)
|
||||
}
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
type legalPage struct {
|
||||
*template.PublicPage
|
||||
Name string
|
||||
Content gotemplate.HTML
|
||||
}
|
||||
|
||||
func newLegalPage(ctx context.Context, company *auth.Company, conn *database.Conn, loc *locale.Locale, slug string) (*legalPage, error) {
|
||||
page := &legalPage{
|
||||
PublicPage: template.NewPublicPage(),
|
||||
}
|
||||
row := conn.QueryRow(ctx, `
|
||||
select coalesce(i18n.name, text.name) as l10n_name
|
||||
, coalesce(i18n.content, text.content)::text as l10n_description
|
||||
from legal_text as text
|
||||
left join legal_text_i18n as i18n on text.company_id = i18n.company_id and text.slug = i18n.slug and i18n.lang_tag = $1
|
||||
where text.company_id = $2
|
||||
and text.slug = $3
|
||||
`, loc.Language, company.ID, slug)
|
||||
if err := row.Scan(&page.Name, &page.Content); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return page, nil
|
||||
}
|
||||
|
||||
func (p *legalPage) MustRender(w http.ResponseWriter, r *http.Request, user *auth.User, company *auth.Company, conn *database.Conn) {
|
||||
p.Setup(r, user, company, conn)
|
||||
template.MustRenderPublic(w, r, user, company, "legal.gohtml", p)
|
||||
}
|
|
@ -2,7 +2,6 @@ package location
|
|||
|
||||
import (
|
||||
"context"
|
||||
"golang.org/x/text/language"
|
||||
"net/http"
|
||||
|
||||
"github.com/jackc/pgx/v4"
|
||||
|
@ -116,26 +115,15 @@ func (f *locationForm) FillFromDatabase(ctx context.Context, company *auth.Compa
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := fillI18nInput(f.Directions, directions); err != nil {
|
||||
if err := f.Directions.FillArray(directions); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := fillI18nInput(f.OpeningDates, openingDates); err != nil {
|
||||
if err := f.OpeningDates.FillArray(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)
|
||||
}
|
||||
|
|
218
po/ca.po
218
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 21:08+0100\n"
|
||||
"POT-Creation-Date: 2023-12-22 02:19+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:51 web/templates/public/layout.gohtml:79
|
||||
#: web/templates/public/layout.gohtml:66 web/templates/public/layout.gohtml:94
|
||||
#: web/templates/admin/services/index.gohtml:66
|
||||
msgctxt "title"
|
||||
msgid "Services"
|
||||
|
@ -55,14 +55,14 @@ 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/public/layout.gohtml:68 web/templates/public/layout.gohtml:96
|
||||
#: 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
|
||||
#: web/templates/public/home.gohtml:6 web/templates/public/layout.gohtml:52
|
||||
#: web/templates/public/layout.gohtml:92
|
||||
msgctxt "title"
|
||||
msgid "Home"
|
||||
msgstr "Inici"
|
||||
|
@ -87,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:52 web/templates/public/layout.gohtml:80
|
||||
#: web/templates/public/layout.gohtml:67 web/templates/public/layout.gohtml:95
|
||||
msgctxt "title"
|
||||
msgid "Surroundings"
|
||||
msgstr "L’entorn"
|
||||
|
@ -271,13 +271,13 @@ msgstr "Hi ha diversos punts on poder anar amb caiac, des de trams del riu Ter c
|
|||
|
||||
#: web/templates/public/campground.gohtml:6
|
||||
#: web/templates/public/campground.gohtml:11
|
||||
#: web/templates/public/layout.gohtml:38 web/templates/public/layout.gohtml:78
|
||||
#: web/templates/public/layout.gohtml:53 web/templates/public/layout.gohtml:93
|
||||
msgctxt "title"
|
||||
msgid "Campground"
|
||||
msgstr "El càmping"
|
||||
|
||||
#: web/templates/public/booking.gohtml:6 web/templates/public/booking.gohtml:11
|
||||
#: web/templates/public/layout.gohtml:54
|
||||
#: web/templates/public/layout.gohtml:69
|
||||
msgctxt "title"
|
||||
msgid "Booking"
|
||||
msgstr "Reserva"
|
||||
|
@ -365,8 +365,8 @@ msgctxt "input"
|
|||
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:109
|
||||
#: web/templates/public/layout.gohtml:11 web/templates/public/layout.gohtml:47
|
||||
#: web/templates/public/layout.gohtml:130
|
||||
msgid "Campsite Montagut"
|
||||
msgstr "Càmping Montagut"
|
||||
|
||||
|
@ -374,28 +374,118 @@ msgstr "Càmping Montagut"
|
|||
msgid "Skip to main content"
|
||||
msgstr "Salta al contingut principal"
|
||||
|
||||
#: web/templates/public/layout.gohtml:42 web/templates/public/layout.gohtml:88
|
||||
#: web/templates/public/layout.gohtml:57 web/templates/public/layout.gohtml:103
|
||||
#: web/templates/admin/campsite/index.gohtml:6
|
||||
#: web/templates/admin/campsite/index.gohtml:12
|
||||
#: web/templates/admin/layout.gohtml:45 web/templates/admin/layout.gohtml:79
|
||||
#: web/templates/admin/layout.gohtml:45 web/templates/admin/layout.gohtml:82
|
||||
msgctxt "title"
|
||||
msgid "Campsites"
|
||||
msgstr "Allotjaments"
|
||||
|
||||
#: web/templates/public/layout.gohtml:75
|
||||
#: web/templates/public/layout.gohtml:90
|
||||
msgctxt "title"
|
||||
msgid "Sections"
|
||||
msgstr "Apartats"
|
||||
|
||||
#: web/templates/public/layout.gohtml:99
|
||||
#: web/templates/public/layout.gohtml:114
|
||||
msgctxt "title"
|
||||
msgid "Opening"
|
||||
msgstr "Obertura"
|
||||
|
||||
#: web/templates/public/layout.gohtml:106
|
||||
#: web/templates/public/layout.gohtml:121
|
||||
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"
|
||||
|
||||
#: web/templates/admin/legal/form.gohtml:8
|
||||
#: web/templates/admin/legal/form.gohtml:25
|
||||
msgctxt "title"
|
||||
msgid "Edit Legal Text"
|
||||
msgstr "Edició del text legal"
|
||||
|
||||
#: web/templates/admin/legal/form.gohtml:10
|
||||
#: web/templates/admin/legal/form.gohtml:27
|
||||
msgctxt "title"
|
||||
msgid "New Legal Text"
|
||||
msgstr "Nou text legal"
|
||||
|
||||
#: web/templates/admin/legal/form.gohtml:37
|
||||
msgctxt "input"
|
||||
msgid "Slug"
|
||||
msgstr "Àlies"
|
||||
|
||||
#: web/templates/admin/legal/form.gohtml:46
|
||||
#: web/templates/admin/campsite/feature/form.gohtml:52
|
||||
#: web/templates/admin/campsite/feature/l10n.gohtml:20
|
||||
#: web/templates/admin/campsite/option/form.gohtml:34
|
||||
#: web/templates/admin/campsite/option/l10n.gohtml:20
|
||||
#: web/templates/admin/campsite/type/form.gohtml:46
|
||||
#: web/templates/admin/campsite/type/l10n.gohtml:20
|
||||
#: web/templates/admin/season/form.gohtml:46
|
||||
#: web/templates/admin/season/l10n.gohtml:20
|
||||
#: web/templates/admin/services/form.gohtml:52
|
||||
#: web/templates/admin/services/l10n.gohtml:20
|
||||
#: web/templates/admin/profile.gohtml:26
|
||||
msgctxt "input"
|
||||
msgid "Name"
|
||||
msgstr "Nom"
|
||||
|
||||
#: web/templates/admin/legal/form.gohtml:64
|
||||
msgctxt "input"
|
||||
msgid "Content"
|
||||
msgstr "Contingut"
|
||||
|
||||
#: web/templates/admin/legal/form.gohtml:84
|
||||
#: web/templates/admin/carousel/form.gohtml:47
|
||||
#: web/templates/admin/campsite/feature/form.gohtml:62
|
||||
#: web/templates/admin/campsite/carousel/form.gohtml:47
|
||||
#: web/templates/admin/campsite/form.gohtml:70
|
||||
#: web/templates/admin/campsite/option/form.gohtml:78
|
||||
#: web/templates/admin/campsite/type/form.gohtml:129
|
||||
#: web/templates/admin/season/form.gohtml:64
|
||||
#: web/templates/admin/services/form.gohtml:69
|
||||
#: web/templates/admin/media/form.gohtml:35
|
||||
msgctxt "action"
|
||||
msgid "Update"
|
||||
msgstr "Actualitza"
|
||||
|
||||
#: web/templates/admin/legal/form.gohtml:86
|
||||
#: web/templates/admin/carousel/form.gohtml:49
|
||||
#: web/templates/admin/campsite/feature/form.gohtml:64
|
||||
#: web/templates/admin/campsite/carousel/form.gohtml:49
|
||||
#: web/templates/admin/campsite/form.gohtml:72
|
||||
#: web/templates/admin/campsite/option/form.gohtml:80
|
||||
#: web/templates/admin/campsite/type/form.gohtml:131
|
||||
#: web/templates/admin/season/form.gohtml:66
|
||||
#: web/templates/admin/services/form.gohtml:71
|
||||
msgctxt "action"
|
||||
msgid "Add"
|
||||
msgstr "Afegeix"
|
||||
|
||||
#: web/templates/admin/legal/index.gohtml:6
|
||||
#: web/templates/admin/legal/index.gohtml:12
|
||||
#: web/templates/admin/layout.gohtml:63
|
||||
msgctxt "title"
|
||||
msgid "Legal Texts"
|
||||
msgstr "Texts legals"
|
||||
|
||||
#: web/templates/admin/legal/index.gohtml:11
|
||||
msgctxt "action"
|
||||
msgid "Add Legal Text"
|
||||
msgstr "Afegeix text legal"
|
||||
|
||||
#: web/templates/admin/legal/index.gohtml:17
|
||||
#: web/templates/admin/campsite/feature/index.gohtml:26
|
||||
#: web/templates/admin/campsite/option/index.gohtml:25
|
||||
#: web/templates/admin/campsite/type/index.gohtml:25
|
||||
#: web/templates/admin/season/index.gohtml:26
|
||||
msgctxt "header"
|
||||
msgid "Name"
|
||||
msgstr "Nom"
|
||||
|
||||
#: web/templates/admin/legal/index.gohtml:29
|
||||
msgid "No legal texts added yet."
|
||||
msgstr "No s’ha afegit cap text legal encara."
|
||||
|
||||
#: web/templates/admin/carousel/form.gohtml:8
|
||||
#: web/templates/admin/carousel/form.gohtml:25
|
||||
msgctxt "title"
|
||||
|
@ -416,31 +506,6 @@ msgctxt "input"
|
|||
msgid "Caption"
|
||||
msgstr "Llegenda"
|
||||
|
||||
#: web/templates/admin/carousel/form.gohtml:47
|
||||
#: web/templates/admin/campsite/feature/form.gohtml:62
|
||||
#: web/templates/admin/campsite/carousel/form.gohtml:47
|
||||
#: web/templates/admin/campsite/form.gohtml:70
|
||||
#: web/templates/admin/campsite/option/form.gohtml:78
|
||||
#: web/templates/admin/campsite/type/form.gohtml:129
|
||||
#: web/templates/admin/season/form.gohtml:64
|
||||
#: web/templates/admin/services/form.gohtml:69
|
||||
#: web/templates/admin/media/form.gohtml:35
|
||||
msgctxt "action"
|
||||
msgid "Update"
|
||||
msgstr "Actualitza"
|
||||
|
||||
#: web/templates/admin/carousel/form.gohtml:49
|
||||
#: web/templates/admin/campsite/feature/form.gohtml:64
|
||||
#: web/templates/admin/campsite/carousel/form.gohtml:49
|
||||
#: web/templates/admin/campsite/form.gohtml:72
|
||||
#: web/templates/admin/campsite/option/form.gohtml:80
|
||||
#: web/templates/admin/campsite/type/form.gohtml:131
|
||||
#: web/templates/admin/season/form.gohtml:66
|
||||
#: web/templates/admin/services/form.gohtml:71
|
||||
msgctxt "action"
|
||||
msgid "Add"
|
||||
msgstr "Afegeix"
|
||||
|
||||
#: web/templates/admin/carousel/l10n.gohtml:7
|
||||
#: web/templates/admin/carousel/l10n.gohtml:14
|
||||
msgctxt "title"
|
||||
|
@ -534,21 +599,6 @@ msgctxt "input"
|
|||
msgid "Icon"
|
||||
msgstr "Icona"
|
||||
|
||||
#: web/templates/admin/campsite/feature/form.gohtml:52
|
||||
#: web/templates/admin/campsite/feature/l10n.gohtml:20
|
||||
#: web/templates/admin/campsite/option/form.gohtml:34
|
||||
#: web/templates/admin/campsite/option/l10n.gohtml:20
|
||||
#: web/templates/admin/campsite/type/form.gohtml:46
|
||||
#: web/templates/admin/campsite/type/l10n.gohtml:20
|
||||
#: web/templates/admin/season/form.gohtml:46
|
||||
#: web/templates/admin/season/l10n.gohtml:20
|
||||
#: web/templates/admin/services/form.gohtml:52
|
||||
#: web/templates/admin/services/l10n.gohtml:20
|
||||
#: web/templates/admin/profile.gohtml:26
|
||||
msgctxt "input"
|
||||
msgid "Name"
|
||||
msgstr "Nom"
|
||||
|
||||
#: web/templates/admin/campsite/feature/index.gohtml:6
|
||||
#: web/templates/admin/campsite/feature/index.gohtml:12
|
||||
msgctxt "title"
|
||||
|
@ -560,14 +610,6 @@ msgctxt "action"
|
|||
msgid "Add Feature"
|
||||
msgstr "Afegeix característica"
|
||||
|
||||
#: web/templates/admin/campsite/feature/index.gohtml:26
|
||||
#: web/templates/admin/campsite/option/index.gohtml:25
|
||||
#: web/templates/admin/campsite/type/index.gohtml:25
|
||||
#: web/templates/admin/season/index.gohtml:26
|
||||
msgctxt "header"
|
||||
msgid "Name"
|
||||
msgstr "Nom"
|
||||
|
||||
#: web/templates/admin/campsite/feature/index.gohtml:27
|
||||
#: web/templates/admin/campsite/carousel/index.gohtml:27
|
||||
#: web/templates/admin/campsite/option/index.gohtml:26
|
||||
|
@ -979,7 +1021,7 @@ msgid "Integration"
|
|||
msgstr "Integració"
|
||||
|
||||
#: web/templates/admin/dashboard.gohtml:6
|
||||
#: web/templates/admin/dashboard.gohtml:10 web/templates/admin/layout.gohtml:76
|
||||
#: web/templates/admin/dashboard.gohtml:10 web/templates/admin/layout.gohtml:79
|
||||
msgctxt "title"
|
||||
msgid "Dashboard"
|
||||
msgstr "Tauler"
|
||||
|
@ -1162,7 +1204,7 @@ msgctxt "title"
|
|||
msgid "Home Page"
|
||||
msgstr "Pàgina d’inici"
|
||||
|
||||
#: web/templates/admin/layout.gohtml:65
|
||||
#: web/templates/admin/layout.gohtml:68
|
||||
msgctxt "action"
|
||||
msgid "Logout"
|
||||
msgstr "Surt"
|
||||
|
@ -1232,6 +1274,19 @@ msgctxt "title"
|
|||
msgid "Upload Media"
|
||||
msgstr "Pujada de mèdia"
|
||||
|
||||
#: pkg/legal/admin.go:255 pkg/app/user.go:249 pkg/campsite/types/l10n.go:87
|
||||
#: pkg/campsite/types/l10n.go:144 pkg/campsite/types/l10n.go:268
|
||||
#: pkg/campsite/types/option.go:350 pkg/campsite/types/feature.go:253
|
||||
#: pkg/campsite/types/admin.go:447 pkg/season/l10n.go:69
|
||||
#: pkg/season/admin.go:405 pkg/services/l10n.go:73 pkg/services/admin.go:266
|
||||
msgid "Name can not be empty."
|
||||
msgstr "No podeu deixar el nom en blanc."
|
||||
|
||||
#: pkg/legal/admin.go:256 pkg/campsite/types/option.go:351
|
||||
#: pkg/campsite/types/feature.go:254 pkg/campsite/types/admin.go:448
|
||||
msgid "Name must have at least one letter."
|
||||
msgstr "El nom ha de tenir com a mínim una lletra."
|
||||
|
||||
#: pkg/carousel/admin.go:285 pkg/campsite/types/carousel.go:242
|
||||
msgctxt "input"
|
||||
msgid "Slide image"
|
||||
|
@ -1273,14 +1328,6 @@ msgctxt "language option"
|
|||
msgid "Automatic"
|
||||
msgstr "Automàtic"
|
||||
|
||||
#: pkg/app/user.go:249 pkg/campsite/types/l10n.go:87
|
||||
#: pkg/campsite/types/l10n.go:144 pkg/campsite/types/l10n.go:268
|
||||
#: pkg/campsite/types/option.go:350 pkg/campsite/types/feature.go:253
|
||||
#: pkg/campsite/types/admin.go:447 pkg/season/l10n.go:69
|
||||
#: pkg/season/admin.go:404 pkg/services/l10n.go:73 pkg/services/admin.go:266
|
||||
msgid "Name can not be empty."
|
||||
msgstr "No podeu deixar el nom en blanc."
|
||||
|
||||
#: pkg/app/user.go:250
|
||||
msgid "Confirmation does not match password."
|
||||
msgstr "La confirmació no es correspon amb la contrasenya."
|
||||
|
@ -1293,15 +1340,10 @@ 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:59
|
||||
#: pkg/app/admin.go:62
|
||||
msgid "Access forbidden"
|
||||
msgstr "Accés prohibit"
|
||||
|
||||
#: pkg/campsite/types/option.go:351 pkg/campsite/types/feature.go:254
|
||||
#: pkg/campsite/types/admin.go:448
|
||||
msgid "Name must have at least one letter."
|
||||
msgstr "El nom ha de tenir com a mínim una lletra."
|
||||
|
||||
#: pkg/campsite/types/option.go:354
|
||||
msgid "Minimum can not be empty."
|
||||
msgstr "No podeu deixar el mínim en blanc."
|
||||
|
@ -1457,32 +1499,32 @@ msgctxt "month"
|
|||
msgid "December"
|
||||
msgstr "desembre"
|
||||
|
||||
#: pkg/season/admin.go:405
|
||||
#: pkg/season/admin.go:406
|
||||
msgid "Color can not be empty."
|
||||
msgstr "No podeu deixar el color en blanc."
|
||||
|
||||
#: pkg/season/admin.go:406
|
||||
#: pkg/season/admin.go:407
|
||||
msgid "This color is not valid. It must be like #123abc."
|
||||
msgstr "Aquest color no és vàlid. Hauria de ser similar a #123abc."
|
||||
|
||||
#: pkg/season/admin.go:506
|
||||
#: pkg/season/admin.go:507
|
||||
msgctxt "action"
|
||||
msgid "Unset"
|
||||
msgstr "Desassigna"
|
||||
|
||||
#: pkg/season/admin.go:537
|
||||
#: pkg/season/admin.go:538
|
||||
msgid "Start date can not be empty."
|
||||
msgstr "No podeu deixar la data d’inici en blanc."
|
||||
|
||||
#: pkg/season/admin.go:538
|
||||
#: pkg/season/admin.go:539
|
||||
msgid "Start date must be a valid date."
|
||||
msgstr "La data d’inici ha de ser una data vàlida."
|
||||
|
||||
#: pkg/season/admin.go:540
|
||||
#: pkg/season/admin.go:541
|
||||
msgid "End date can not be empty."
|
||||
msgstr "No podeu deixar la data de fi en blanc."
|
||||
|
||||
#: pkg/season/admin.go:541
|
||||
#: pkg/season/admin.go:542
|
||||
msgid "End date must be a valid date."
|
||||
msgstr "La data de fi ha de ser una data vàlida."
|
||||
|
||||
|
@ -1666,10 +1708,6 @@ 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"
|
||||
|
|
218
po/es.po
218
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 21:08+0100\n"
|
||||
"POT-Creation-Date: 2023-12-22 02:19+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:51 web/templates/public/layout.gohtml:79
|
||||
#: web/templates/public/layout.gohtml:66 web/templates/public/layout.gohtml:94
|
||||
#: web/templates/admin/services/index.gohtml:66
|
||||
msgctxt "title"
|
||||
msgid "Services"
|
||||
|
@ -55,14 +55,14 @@ 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/public/layout.gohtml:68 web/templates/public/layout.gohtml:96
|
||||
#: 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
|
||||
#: web/templates/public/home.gohtml:6 web/templates/public/layout.gohtml:52
|
||||
#: web/templates/public/layout.gohtml:92
|
||||
msgctxt "title"
|
||||
msgid "Home"
|
||||
msgstr "Inicio"
|
||||
|
@ -87,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:52 web/templates/public/layout.gohtml:80
|
||||
#: web/templates/public/layout.gohtml:67 web/templates/public/layout.gohtml:95
|
||||
msgctxt "title"
|
||||
msgid "Surroundings"
|
||||
msgstr "El entorno"
|
||||
|
@ -271,13 +271,13 @@ msgstr "Hay diversos puntos dónde podéis ir en kayak, desde tramos del río Te
|
|||
|
||||
#: web/templates/public/campground.gohtml:6
|
||||
#: web/templates/public/campground.gohtml:11
|
||||
#: web/templates/public/layout.gohtml:38 web/templates/public/layout.gohtml:78
|
||||
#: web/templates/public/layout.gohtml:53 web/templates/public/layout.gohtml:93
|
||||
msgctxt "title"
|
||||
msgid "Campground"
|
||||
msgstr "El camping"
|
||||
|
||||
#: web/templates/public/booking.gohtml:6 web/templates/public/booking.gohtml:11
|
||||
#: web/templates/public/layout.gohtml:54
|
||||
#: web/templates/public/layout.gohtml:69
|
||||
msgctxt "title"
|
||||
msgid "Booking"
|
||||
msgstr "Reserva"
|
||||
|
@ -365,8 +365,8 @@ msgctxt "input"
|
|||
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:109
|
||||
#: web/templates/public/layout.gohtml:11 web/templates/public/layout.gohtml:47
|
||||
#: web/templates/public/layout.gohtml:130
|
||||
msgid "Campsite Montagut"
|
||||
msgstr "Camping Montagut"
|
||||
|
||||
|
@ -374,28 +374,118 @@ msgstr "Camping Montagut"
|
|||
msgid "Skip to main content"
|
||||
msgstr "Saltar al contenido principal"
|
||||
|
||||
#: web/templates/public/layout.gohtml:42 web/templates/public/layout.gohtml:88
|
||||
#: web/templates/public/layout.gohtml:57 web/templates/public/layout.gohtml:103
|
||||
#: web/templates/admin/campsite/index.gohtml:6
|
||||
#: web/templates/admin/campsite/index.gohtml:12
|
||||
#: web/templates/admin/layout.gohtml:45 web/templates/admin/layout.gohtml:79
|
||||
#: web/templates/admin/layout.gohtml:45 web/templates/admin/layout.gohtml:82
|
||||
msgctxt "title"
|
||||
msgid "Campsites"
|
||||
msgstr "Alojamientos"
|
||||
|
||||
#: web/templates/public/layout.gohtml:75
|
||||
#: web/templates/public/layout.gohtml:90
|
||||
msgctxt "title"
|
||||
msgid "Sections"
|
||||
msgstr "Apartados"
|
||||
|
||||
#: web/templates/public/layout.gohtml:99
|
||||
#: web/templates/public/layout.gohtml:114
|
||||
msgctxt "title"
|
||||
msgid "Opening"
|
||||
msgstr "Apertura"
|
||||
|
||||
#: web/templates/public/layout.gohtml:106
|
||||
#: web/templates/public/layout.gohtml:121
|
||||
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"
|
||||
|
||||
#: web/templates/admin/legal/form.gohtml:8
|
||||
#: web/templates/admin/legal/form.gohtml:25
|
||||
msgctxt "title"
|
||||
msgid "Edit Legal Text"
|
||||
msgstr "Edición del texto legal"
|
||||
|
||||
#: web/templates/admin/legal/form.gohtml:10
|
||||
#: web/templates/admin/legal/form.gohtml:27
|
||||
msgctxt "title"
|
||||
msgid "New Legal Text"
|
||||
msgstr "Nuevo texto legal"
|
||||
|
||||
#: web/templates/admin/legal/form.gohtml:37
|
||||
msgctxt "input"
|
||||
msgid "Slug"
|
||||
msgstr "Álias"
|
||||
|
||||
#: web/templates/admin/legal/form.gohtml:46
|
||||
#: web/templates/admin/campsite/feature/form.gohtml:52
|
||||
#: web/templates/admin/campsite/feature/l10n.gohtml:20
|
||||
#: web/templates/admin/campsite/option/form.gohtml:34
|
||||
#: web/templates/admin/campsite/option/l10n.gohtml:20
|
||||
#: web/templates/admin/campsite/type/form.gohtml:46
|
||||
#: web/templates/admin/campsite/type/l10n.gohtml:20
|
||||
#: web/templates/admin/season/form.gohtml:46
|
||||
#: web/templates/admin/season/l10n.gohtml:20
|
||||
#: web/templates/admin/services/form.gohtml:52
|
||||
#: web/templates/admin/services/l10n.gohtml:20
|
||||
#: web/templates/admin/profile.gohtml:26
|
||||
msgctxt "input"
|
||||
msgid "Name"
|
||||
msgstr "Nombre"
|
||||
|
||||
#: web/templates/admin/legal/form.gohtml:64
|
||||
msgctxt "input"
|
||||
msgid "Content"
|
||||
msgstr "Contenido"
|
||||
|
||||
#: web/templates/admin/legal/form.gohtml:84
|
||||
#: web/templates/admin/carousel/form.gohtml:47
|
||||
#: web/templates/admin/campsite/feature/form.gohtml:62
|
||||
#: web/templates/admin/campsite/carousel/form.gohtml:47
|
||||
#: web/templates/admin/campsite/form.gohtml:70
|
||||
#: web/templates/admin/campsite/option/form.gohtml:78
|
||||
#: web/templates/admin/campsite/type/form.gohtml:129
|
||||
#: web/templates/admin/season/form.gohtml:64
|
||||
#: web/templates/admin/services/form.gohtml:69
|
||||
#: web/templates/admin/media/form.gohtml:35
|
||||
msgctxt "action"
|
||||
msgid "Update"
|
||||
msgstr "Actualizar"
|
||||
|
||||
#: web/templates/admin/legal/form.gohtml:86
|
||||
#: web/templates/admin/carousel/form.gohtml:49
|
||||
#: web/templates/admin/campsite/feature/form.gohtml:64
|
||||
#: web/templates/admin/campsite/carousel/form.gohtml:49
|
||||
#: web/templates/admin/campsite/form.gohtml:72
|
||||
#: web/templates/admin/campsite/option/form.gohtml:80
|
||||
#: web/templates/admin/campsite/type/form.gohtml:131
|
||||
#: web/templates/admin/season/form.gohtml:66
|
||||
#: web/templates/admin/services/form.gohtml:71
|
||||
msgctxt "action"
|
||||
msgid "Add"
|
||||
msgstr "Añadir"
|
||||
|
||||
#: web/templates/admin/legal/index.gohtml:6
|
||||
#: web/templates/admin/legal/index.gohtml:12
|
||||
#: web/templates/admin/layout.gohtml:63
|
||||
msgctxt "title"
|
||||
msgid "Legal Texts"
|
||||
msgstr "Textos legales"
|
||||
|
||||
#: web/templates/admin/legal/index.gohtml:11
|
||||
msgctxt "action"
|
||||
msgid "Add Legal Text"
|
||||
msgstr "Añadir texto legal"
|
||||
|
||||
#: web/templates/admin/legal/index.gohtml:17
|
||||
#: web/templates/admin/campsite/feature/index.gohtml:26
|
||||
#: web/templates/admin/campsite/option/index.gohtml:25
|
||||
#: web/templates/admin/campsite/type/index.gohtml:25
|
||||
#: web/templates/admin/season/index.gohtml:26
|
||||
msgctxt "header"
|
||||
msgid "Name"
|
||||
msgstr "Nombre"
|
||||
|
||||
#: web/templates/admin/legal/index.gohtml:29
|
||||
msgid "No legal texts added yet."
|
||||
msgstr "No se ha añadido ningún texto legal todavía."
|
||||
|
||||
#: web/templates/admin/carousel/form.gohtml:8
|
||||
#: web/templates/admin/carousel/form.gohtml:25
|
||||
msgctxt "title"
|
||||
|
@ -416,31 +506,6 @@ msgctxt "input"
|
|||
msgid "Caption"
|
||||
msgstr "Leyenda"
|
||||
|
||||
#: web/templates/admin/carousel/form.gohtml:47
|
||||
#: web/templates/admin/campsite/feature/form.gohtml:62
|
||||
#: web/templates/admin/campsite/carousel/form.gohtml:47
|
||||
#: web/templates/admin/campsite/form.gohtml:70
|
||||
#: web/templates/admin/campsite/option/form.gohtml:78
|
||||
#: web/templates/admin/campsite/type/form.gohtml:129
|
||||
#: web/templates/admin/season/form.gohtml:64
|
||||
#: web/templates/admin/services/form.gohtml:69
|
||||
#: web/templates/admin/media/form.gohtml:35
|
||||
msgctxt "action"
|
||||
msgid "Update"
|
||||
msgstr "Actualizar"
|
||||
|
||||
#: web/templates/admin/carousel/form.gohtml:49
|
||||
#: web/templates/admin/campsite/feature/form.gohtml:64
|
||||
#: web/templates/admin/campsite/carousel/form.gohtml:49
|
||||
#: web/templates/admin/campsite/form.gohtml:72
|
||||
#: web/templates/admin/campsite/option/form.gohtml:80
|
||||
#: web/templates/admin/campsite/type/form.gohtml:131
|
||||
#: web/templates/admin/season/form.gohtml:66
|
||||
#: web/templates/admin/services/form.gohtml:71
|
||||
msgctxt "action"
|
||||
msgid "Add"
|
||||
msgstr "Añadir"
|
||||
|
||||
#: web/templates/admin/carousel/l10n.gohtml:7
|
||||
#: web/templates/admin/carousel/l10n.gohtml:14
|
||||
msgctxt "title"
|
||||
|
@ -534,21 +599,6 @@ msgctxt "input"
|
|||
msgid "Icon"
|
||||
msgstr "Icono"
|
||||
|
||||
#: web/templates/admin/campsite/feature/form.gohtml:52
|
||||
#: web/templates/admin/campsite/feature/l10n.gohtml:20
|
||||
#: web/templates/admin/campsite/option/form.gohtml:34
|
||||
#: web/templates/admin/campsite/option/l10n.gohtml:20
|
||||
#: web/templates/admin/campsite/type/form.gohtml:46
|
||||
#: web/templates/admin/campsite/type/l10n.gohtml:20
|
||||
#: web/templates/admin/season/form.gohtml:46
|
||||
#: web/templates/admin/season/l10n.gohtml:20
|
||||
#: web/templates/admin/services/form.gohtml:52
|
||||
#: web/templates/admin/services/l10n.gohtml:20
|
||||
#: web/templates/admin/profile.gohtml:26
|
||||
msgctxt "input"
|
||||
msgid "Name"
|
||||
msgstr "Nombre"
|
||||
|
||||
#: web/templates/admin/campsite/feature/index.gohtml:6
|
||||
#: web/templates/admin/campsite/feature/index.gohtml:12
|
||||
msgctxt "title"
|
||||
|
@ -560,14 +610,6 @@ msgctxt "action"
|
|||
msgid "Add Feature"
|
||||
msgstr "Añadir características"
|
||||
|
||||
#: web/templates/admin/campsite/feature/index.gohtml:26
|
||||
#: web/templates/admin/campsite/option/index.gohtml:25
|
||||
#: web/templates/admin/campsite/type/index.gohtml:25
|
||||
#: web/templates/admin/season/index.gohtml:26
|
||||
msgctxt "header"
|
||||
msgid "Name"
|
||||
msgstr "Nombre"
|
||||
|
||||
#: web/templates/admin/campsite/feature/index.gohtml:27
|
||||
#: web/templates/admin/campsite/carousel/index.gohtml:27
|
||||
#: web/templates/admin/campsite/option/index.gohtml:26
|
||||
|
@ -979,7 +1021,7 @@ msgid "Integration"
|
|||
msgstr "Integración"
|
||||
|
||||
#: web/templates/admin/dashboard.gohtml:6
|
||||
#: web/templates/admin/dashboard.gohtml:10 web/templates/admin/layout.gohtml:76
|
||||
#: web/templates/admin/dashboard.gohtml:10 web/templates/admin/layout.gohtml:79
|
||||
msgctxt "title"
|
||||
msgid "Dashboard"
|
||||
msgstr "Panel"
|
||||
|
@ -1162,7 +1204,7 @@ msgctxt "title"
|
|||
msgid "Home Page"
|
||||
msgstr "Página de inicio"
|
||||
|
||||
#: web/templates/admin/layout.gohtml:65
|
||||
#: web/templates/admin/layout.gohtml:68
|
||||
msgctxt "action"
|
||||
msgid "Logout"
|
||||
msgstr "Salir"
|
||||
|
@ -1232,6 +1274,19 @@ msgctxt "title"
|
|||
msgid "Upload Media"
|
||||
msgstr "Subida de medio"
|
||||
|
||||
#: pkg/legal/admin.go:255 pkg/app/user.go:249 pkg/campsite/types/l10n.go:87
|
||||
#: pkg/campsite/types/l10n.go:144 pkg/campsite/types/l10n.go:268
|
||||
#: pkg/campsite/types/option.go:350 pkg/campsite/types/feature.go:253
|
||||
#: pkg/campsite/types/admin.go:447 pkg/season/l10n.go:69
|
||||
#: pkg/season/admin.go:405 pkg/services/l10n.go:73 pkg/services/admin.go:266
|
||||
msgid "Name can not be empty."
|
||||
msgstr "No podéis dejar el nombre en blanco."
|
||||
|
||||
#: pkg/legal/admin.go:256 pkg/campsite/types/option.go:351
|
||||
#: pkg/campsite/types/feature.go:254 pkg/campsite/types/admin.go:448
|
||||
msgid "Name must have at least one letter."
|
||||
msgstr "El nombre tiene que tener como mínimo una letra."
|
||||
|
||||
#: pkg/carousel/admin.go:285 pkg/campsite/types/carousel.go:242
|
||||
msgctxt "input"
|
||||
msgid "Slide image"
|
||||
|
@ -1273,14 +1328,6 @@ msgctxt "language option"
|
|||
msgid "Automatic"
|
||||
msgstr "Automático"
|
||||
|
||||
#: pkg/app/user.go:249 pkg/campsite/types/l10n.go:87
|
||||
#: pkg/campsite/types/l10n.go:144 pkg/campsite/types/l10n.go:268
|
||||
#: pkg/campsite/types/option.go:350 pkg/campsite/types/feature.go:253
|
||||
#: pkg/campsite/types/admin.go:447 pkg/season/l10n.go:69
|
||||
#: pkg/season/admin.go:404 pkg/services/l10n.go:73 pkg/services/admin.go:266
|
||||
msgid "Name can not be empty."
|
||||
msgstr "No podéis dejar el nombre en blanco."
|
||||
|
||||
#: pkg/app/user.go:250
|
||||
msgid "Confirmation does not match password."
|
||||
msgstr "La confirmación no se corresponde con la contraseña."
|
||||
|
@ -1293,15 +1340,10 @@ 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:59
|
||||
#: pkg/app/admin.go:62
|
||||
msgid "Access forbidden"
|
||||
msgstr "Acceso prohibido"
|
||||
|
||||
#: pkg/campsite/types/option.go:351 pkg/campsite/types/feature.go:254
|
||||
#: pkg/campsite/types/admin.go:448
|
||||
msgid "Name must have at least one letter."
|
||||
msgstr "El nombre tiene que tener como mínimo una letra."
|
||||
|
||||
#: pkg/campsite/types/option.go:354
|
||||
msgid "Minimum can not be empty."
|
||||
msgstr "No podéis dejar el mínimo en blanco."
|
||||
|
@ -1457,32 +1499,32 @@ msgctxt "month"
|
|||
msgid "December"
|
||||
msgstr "diciembre"
|
||||
|
||||
#: pkg/season/admin.go:405
|
||||
#: pkg/season/admin.go:406
|
||||
msgid "Color can not be empty."
|
||||
msgstr "No podéis dejar el color en blanco."
|
||||
|
||||
#: pkg/season/admin.go:406
|
||||
#: pkg/season/admin.go:407
|
||||
msgid "This color is not valid. It must be like #123abc."
|
||||
msgstr "Este color no es válido. Tiene que ser parecido a #123abc."
|
||||
|
||||
#: pkg/season/admin.go:506
|
||||
#: pkg/season/admin.go:507
|
||||
msgctxt "action"
|
||||
msgid "Unset"
|
||||
msgstr "Desasignar"
|
||||
|
||||
#: pkg/season/admin.go:537
|
||||
#: pkg/season/admin.go:538
|
||||
msgid "Start date can not be empty."
|
||||
msgstr "No podéis dejar la fecha de inicio en blanco."
|
||||
|
||||
#: pkg/season/admin.go:538
|
||||
#: pkg/season/admin.go:539
|
||||
msgid "Start date must be a valid date."
|
||||
msgstr "La fecha de inicio tiene que ser una fecha válida."
|
||||
|
||||
#: pkg/season/admin.go:540
|
||||
#: pkg/season/admin.go:541
|
||||
msgid "End date can not be empty."
|
||||
msgstr "No podéis dejar la fecha final en blanco."
|
||||
|
||||
#: pkg/season/admin.go:541
|
||||
#: pkg/season/admin.go:542
|
||||
msgid "End date must be a valid date."
|
||||
msgstr "La fecha final tiene que ser una fecha válida."
|
||||
|
||||
|
@ -1666,10 +1708,6 @@ 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"
|
||||
|
|
220
po/fr.po
220
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 21:08+0100\n"
|
||||
"POT-Creation-Date: 2023-12-22 02:19+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:51 web/templates/public/layout.gohtml:79
|
||||
#: web/templates/public/layout.gohtml:66 web/templates/public/layout.gohtml:94
|
||||
#: web/templates/admin/services/index.gohtml:66
|
||||
msgctxt "title"
|
||||
msgid "Services"
|
||||
|
@ -56,14 +56,14 @@ 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/public/layout.gohtml:68 web/templates/public/layout.gohtml:96
|
||||
#: 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
|
||||
#: web/templates/public/home.gohtml:6 web/templates/public/layout.gohtml:52
|
||||
#: web/templates/public/layout.gohtml:92
|
||||
msgctxt "title"
|
||||
msgid "Home"
|
||||
msgstr "Accueil"
|
||||
|
@ -88,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:52 web/templates/public/layout.gohtml:80
|
||||
#: web/templates/public/layout.gohtml:67 web/templates/public/layout.gohtml:95
|
||||
msgctxt "title"
|
||||
msgid "Surroundings"
|
||||
msgstr "Entourage"
|
||||
|
@ -272,13 +272,13 @@ msgstr "Il y a plusieurs points où vous pouvez aller en kayak, à partir de sec
|
|||
|
||||
#: web/templates/public/campground.gohtml:6
|
||||
#: web/templates/public/campground.gohtml:11
|
||||
#: web/templates/public/layout.gohtml:38 web/templates/public/layout.gohtml:78
|
||||
#: web/templates/public/layout.gohtml:53 web/templates/public/layout.gohtml:93
|
||||
msgctxt "title"
|
||||
msgid "Campground"
|
||||
msgstr "Camping"
|
||||
|
||||
#: web/templates/public/booking.gohtml:6 web/templates/public/booking.gohtml:11
|
||||
#: web/templates/public/layout.gohtml:54
|
||||
#: web/templates/public/layout.gohtml:69
|
||||
msgctxt "title"
|
||||
msgid "Booking"
|
||||
msgstr "Reservation"
|
||||
|
@ -366,8 +366,8 @@ msgctxt "input"
|
|||
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:109
|
||||
#: web/templates/public/layout.gohtml:11 web/templates/public/layout.gohtml:47
|
||||
#: web/templates/public/layout.gohtml:130
|
||||
msgid "Campsite Montagut"
|
||||
msgstr "Camping Montagut"
|
||||
|
||||
|
@ -375,28 +375,120 @@ msgstr "Camping Montagut"
|
|||
msgid "Skip to main content"
|
||||
msgstr "Passer au contenu principal"
|
||||
|
||||
#: web/templates/public/layout.gohtml:42 web/templates/public/layout.gohtml:88
|
||||
#: web/templates/public/layout.gohtml:57 web/templates/public/layout.gohtml:103
|
||||
#: web/templates/admin/campsite/index.gohtml:6
|
||||
#: web/templates/admin/campsite/index.gohtml:12
|
||||
#: web/templates/admin/layout.gohtml:45 web/templates/admin/layout.gohtml:79
|
||||
#: web/templates/admin/layout.gohtml:45 web/templates/admin/layout.gohtml:82
|
||||
msgctxt "title"
|
||||
msgid "Campsites"
|
||||
msgstr "Locatifs"
|
||||
|
||||
#: web/templates/public/layout.gohtml:75
|
||||
#: web/templates/public/layout.gohtml:90
|
||||
msgctxt "title"
|
||||
msgid "Sections"
|
||||
msgstr "Sections"
|
||||
|
||||
#: web/templates/public/layout.gohtml:99
|
||||
#: web/templates/public/layout.gohtml:114
|
||||
msgctxt "title"
|
||||
msgid "Opening"
|
||||
msgstr "Ouverture"
|
||||
|
||||
#: web/templates/public/layout.gohtml:106
|
||||
#: web/templates/public/layout.gohtml:121
|
||||
msgid "<abbr title=\"Catalonia Tourism Registry\">RTC</abbr> <abbr title=\"Number\">#</abbr>%s"
|
||||
msgstr "<abbr title=\"Registre du tourisme de Catalogne\"># RTC</abbr> %s"
|
||||
|
||||
#: web/templates/admin/legal/form.gohtml:8
|
||||
#: web/templates/admin/legal/form.gohtml:25
|
||||
msgctxt "title"
|
||||
msgid "Edit Legal Text"
|
||||
msgstr ""
|
||||
|
||||
#: web/templates/admin/legal/form.gohtml:10
|
||||
#: web/templates/admin/legal/form.gohtml:27
|
||||
msgctxt "title"
|
||||
msgid "New Legal Text"
|
||||
msgstr ""
|
||||
|
||||
#: web/templates/admin/legal/form.gohtml:37
|
||||
msgctxt "input"
|
||||
msgid "Slug"
|
||||
msgstr ""
|
||||
|
||||
#: web/templates/admin/legal/form.gohtml:46
|
||||
#: web/templates/admin/campsite/feature/form.gohtml:52
|
||||
#: web/templates/admin/campsite/feature/l10n.gohtml:20
|
||||
#: web/templates/admin/campsite/option/form.gohtml:34
|
||||
#: web/templates/admin/campsite/option/l10n.gohtml:20
|
||||
#: web/templates/admin/campsite/type/form.gohtml:46
|
||||
#: web/templates/admin/campsite/type/l10n.gohtml:20
|
||||
#: web/templates/admin/season/form.gohtml:46
|
||||
#: web/templates/admin/season/l10n.gohtml:20
|
||||
#: web/templates/admin/services/form.gohtml:52
|
||||
#: web/templates/admin/services/l10n.gohtml:20
|
||||
#: web/templates/admin/profile.gohtml:26
|
||||
msgctxt "input"
|
||||
msgid "Name"
|
||||
msgstr "Nom"
|
||||
|
||||
#: web/templates/admin/legal/form.gohtml:64
|
||||
#, fuzzy
|
||||
msgctxt "input"
|
||||
msgid "Content"
|
||||
msgstr "Contact"
|
||||
|
||||
#: web/templates/admin/legal/form.gohtml:84
|
||||
#: web/templates/admin/carousel/form.gohtml:47
|
||||
#: web/templates/admin/campsite/feature/form.gohtml:62
|
||||
#: web/templates/admin/campsite/carousel/form.gohtml:47
|
||||
#: web/templates/admin/campsite/form.gohtml:70
|
||||
#: web/templates/admin/campsite/option/form.gohtml:78
|
||||
#: web/templates/admin/campsite/type/form.gohtml:129
|
||||
#: web/templates/admin/season/form.gohtml:64
|
||||
#: web/templates/admin/services/form.gohtml:69
|
||||
#: web/templates/admin/media/form.gohtml:35
|
||||
msgctxt "action"
|
||||
msgid "Update"
|
||||
msgstr "Mettre à jour"
|
||||
|
||||
#: web/templates/admin/legal/form.gohtml:86
|
||||
#: web/templates/admin/carousel/form.gohtml:49
|
||||
#: web/templates/admin/campsite/feature/form.gohtml:64
|
||||
#: web/templates/admin/campsite/carousel/form.gohtml:49
|
||||
#: web/templates/admin/campsite/form.gohtml:72
|
||||
#: web/templates/admin/campsite/option/form.gohtml:80
|
||||
#: web/templates/admin/campsite/type/form.gohtml:131
|
||||
#: web/templates/admin/season/form.gohtml:66
|
||||
#: web/templates/admin/services/form.gohtml:71
|
||||
msgctxt "action"
|
||||
msgid "Add"
|
||||
msgstr "Ajouter"
|
||||
|
||||
#: web/templates/admin/legal/index.gohtml:6
|
||||
#: web/templates/admin/legal/index.gohtml:12
|
||||
#: web/templates/admin/layout.gohtml:63
|
||||
msgctxt "title"
|
||||
msgid "Legal Texts"
|
||||
msgstr ""
|
||||
|
||||
#: web/templates/admin/legal/index.gohtml:11
|
||||
msgctxt "action"
|
||||
msgid "Add Legal Text"
|
||||
msgstr ""
|
||||
|
||||
#: web/templates/admin/legal/index.gohtml:17
|
||||
#: web/templates/admin/campsite/feature/index.gohtml:26
|
||||
#: web/templates/admin/campsite/option/index.gohtml:25
|
||||
#: web/templates/admin/campsite/type/index.gohtml:25
|
||||
#: web/templates/admin/season/index.gohtml:26
|
||||
msgctxt "header"
|
||||
msgid "Name"
|
||||
msgstr "Nom"
|
||||
|
||||
#: web/templates/admin/legal/index.gohtml:29
|
||||
#, fuzzy
|
||||
msgid "No legal texts added yet."
|
||||
msgstr "Aucune diapositive n’a encore été ajoutée."
|
||||
|
||||
#: web/templates/admin/carousel/form.gohtml:8
|
||||
#: web/templates/admin/carousel/form.gohtml:25
|
||||
msgctxt "title"
|
||||
|
@ -417,31 +509,6 @@ msgctxt "input"
|
|||
msgid "Caption"
|
||||
msgstr "Légende"
|
||||
|
||||
#: web/templates/admin/carousel/form.gohtml:47
|
||||
#: web/templates/admin/campsite/feature/form.gohtml:62
|
||||
#: web/templates/admin/campsite/carousel/form.gohtml:47
|
||||
#: web/templates/admin/campsite/form.gohtml:70
|
||||
#: web/templates/admin/campsite/option/form.gohtml:78
|
||||
#: web/templates/admin/campsite/type/form.gohtml:129
|
||||
#: web/templates/admin/season/form.gohtml:64
|
||||
#: web/templates/admin/services/form.gohtml:69
|
||||
#: web/templates/admin/media/form.gohtml:35
|
||||
msgctxt "action"
|
||||
msgid "Update"
|
||||
msgstr "Mettre à jour"
|
||||
|
||||
#: web/templates/admin/carousel/form.gohtml:49
|
||||
#: web/templates/admin/campsite/feature/form.gohtml:64
|
||||
#: web/templates/admin/campsite/carousel/form.gohtml:49
|
||||
#: web/templates/admin/campsite/form.gohtml:72
|
||||
#: web/templates/admin/campsite/option/form.gohtml:80
|
||||
#: web/templates/admin/campsite/type/form.gohtml:131
|
||||
#: web/templates/admin/season/form.gohtml:66
|
||||
#: web/templates/admin/services/form.gohtml:71
|
||||
msgctxt "action"
|
||||
msgid "Add"
|
||||
msgstr "Ajouter"
|
||||
|
||||
#: web/templates/admin/carousel/l10n.gohtml:7
|
||||
#: web/templates/admin/carousel/l10n.gohtml:14
|
||||
msgctxt "title"
|
||||
|
@ -535,21 +602,6 @@ msgctxt "input"
|
|||
msgid "Icon"
|
||||
msgstr "Icône"
|
||||
|
||||
#: web/templates/admin/campsite/feature/form.gohtml:52
|
||||
#: web/templates/admin/campsite/feature/l10n.gohtml:20
|
||||
#: web/templates/admin/campsite/option/form.gohtml:34
|
||||
#: web/templates/admin/campsite/option/l10n.gohtml:20
|
||||
#: web/templates/admin/campsite/type/form.gohtml:46
|
||||
#: web/templates/admin/campsite/type/l10n.gohtml:20
|
||||
#: web/templates/admin/season/form.gohtml:46
|
||||
#: web/templates/admin/season/l10n.gohtml:20
|
||||
#: web/templates/admin/services/form.gohtml:52
|
||||
#: web/templates/admin/services/l10n.gohtml:20
|
||||
#: web/templates/admin/profile.gohtml:26
|
||||
msgctxt "input"
|
||||
msgid "Name"
|
||||
msgstr "Nom"
|
||||
|
||||
#: web/templates/admin/campsite/feature/index.gohtml:6
|
||||
#: web/templates/admin/campsite/feature/index.gohtml:12
|
||||
msgctxt "title"
|
||||
|
@ -561,14 +613,6 @@ msgctxt "action"
|
|||
msgid "Add Feature"
|
||||
msgstr "Ajouter une fonctionnalité"
|
||||
|
||||
#: web/templates/admin/campsite/feature/index.gohtml:26
|
||||
#: web/templates/admin/campsite/option/index.gohtml:25
|
||||
#: web/templates/admin/campsite/type/index.gohtml:25
|
||||
#: web/templates/admin/season/index.gohtml:26
|
||||
msgctxt "header"
|
||||
msgid "Name"
|
||||
msgstr "Nom"
|
||||
|
||||
#: web/templates/admin/campsite/feature/index.gohtml:27
|
||||
#: web/templates/admin/campsite/carousel/index.gohtml:27
|
||||
#: web/templates/admin/campsite/option/index.gohtml:26
|
||||
|
@ -980,7 +1024,7 @@ msgid "Integration"
|
|||
msgstr "Intégration"
|
||||
|
||||
#: web/templates/admin/dashboard.gohtml:6
|
||||
#: web/templates/admin/dashboard.gohtml:10 web/templates/admin/layout.gohtml:76
|
||||
#: web/templates/admin/dashboard.gohtml:10 web/templates/admin/layout.gohtml:79
|
||||
msgctxt "title"
|
||||
msgid "Dashboard"
|
||||
msgstr "Tableau de bord"
|
||||
|
@ -1163,7 +1207,7 @@ msgctxt "title"
|
|||
msgid "Home Page"
|
||||
msgstr "Page d'accueil"
|
||||
|
||||
#: web/templates/admin/layout.gohtml:65
|
||||
#: web/templates/admin/layout.gohtml:68
|
||||
msgctxt "action"
|
||||
msgid "Logout"
|
||||
msgstr "Déconnexion"
|
||||
|
@ -1233,6 +1277,19 @@ msgctxt "title"
|
|||
msgid "Upload Media"
|
||||
msgstr "Envoyer un fichier"
|
||||
|
||||
#: pkg/legal/admin.go:255 pkg/app/user.go:249 pkg/campsite/types/l10n.go:87
|
||||
#: pkg/campsite/types/l10n.go:144 pkg/campsite/types/l10n.go:268
|
||||
#: pkg/campsite/types/option.go:350 pkg/campsite/types/feature.go:253
|
||||
#: pkg/campsite/types/admin.go:447 pkg/season/l10n.go:69
|
||||
#: pkg/season/admin.go:405 pkg/services/l10n.go:73 pkg/services/admin.go:266
|
||||
msgid "Name can not be empty."
|
||||
msgstr "Le nom ne peut pas être laissé vide."
|
||||
|
||||
#: pkg/legal/admin.go:256 pkg/campsite/types/option.go:351
|
||||
#: pkg/campsite/types/feature.go:254 pkg/campsite/types/admin.go:448
|
||||
msgid "Name must have at least one letter."
|
||||
msgstr "Le nom doit comporter au moins une lettre."
|
||||
|
||||
#: pkg/carousel/admin.go:285 pkg/campsite/types/carousel.go:242
|
||||
msgctxt "input"
|
||||
msgid "Slide image"
|
||||
|
@ -1274,14 +1331,6 @@ msgctxt "language option"
|
|||
msgid "Automatic"
|
||||
msgstr "Automatique"
|
||||
|
||||
#: pkg/app/user.go:249 pkg/campsite/types/l10n.go:87
|
||||
#: pkg/campsite/types/l10n.go:144 pkg/campsite/types/l10n.go:268
|
||||
#: pkg/campsite/types/option.go:350 pkg/campsite/types/feature.go:253
|
||||
#: pkg/campsite/types/admin.go:447 pkg/season/l10n.go:69
|
||||
#: pkg/season/admin.go:404 pkg/services/l10n.go:73 pkg/services/admin.go:266
|
||||
msgid "Name can not be empty."
|
||||
msgstr "Le nom ne peut pas être laissé vide."
|
||||
|
||||
#: pkg/app/user.go:250
|
||||
msgid "Confirmation does not match password."
|
||||
msgstr "La confirmation ne correspond pas au mot de passe."
|
||||
|
@ -1294,15 +1343,10 @@ 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:59
|
||||
#: pkg/app/admin.go:62
|
||||
msgid "Access forbidden"
|
||||
msgstr "Accès interdit"
|
||||
|
||||
#: pkg/campsite/types/option.go:351 pkg/campsite/types/feature.go:254
|
||||
#: pkg/campsite/types/admin.go:448
|
||||
msgid "Name must have at least one letter."
|
||||
msgstr "Le nom doit comporter au moins une lettre."
|
||||
|
||||
#: pkg/campsite/types/option.go:354
|
||||
msgid "Minimum can not be empty."
|
||||
msgstr "Le minimum ne peut pas être vide."
|
||||
|
@ -1458,32 +1502,32 @@ msgctxt "month"
|
|||
msgid "December"
|
||||
msgstr "Décembre"
|
||||
|
||||
#: pkg/season/admin.go:405
|
||||
#: pkg/season/admin.go:406
|
||||
msgid "Color can not be empty."
|
||||
msgstr "La couleur ne peut pas être vide."
|
||||
|
||||
#: pkg/season/admin.go:406
|
||||
#: pkg/season/admin.go:407
|
||||
msgid "This color is not valid. It must be like #123abc."
|
||||
msgstr "Cette couleur n’est pas valide. Il doit être comme #123abc."
|
||||
|
||||
#: pkg/season/admin.go:506
|
||||
#: pkg/season/admin.go:507
|
||||
msgctxt "action"
|
||||
msgid "Unset"
|
||||
msgstr "Unset"
|
||||
|
||||
#: pkg/season/admin.go:537
|
||||
#: pkg/season/admin.go:538
|
||||
msgid "Start date can not be empty."
|
||||
msgstr "La date de début ne peut pas être vide."
|
||||
|
||||
#: pkg/season/admin.go:538
|
||||
#: pkg/season/admin.go:539
|
||||
msgid "Start date must be a valid date."
|
||||
msgstr "La date de début doit être une date valide."
|
||||
|
||||
#: pkg/season/admin.go:540
|
||||
#: pkg/season/admin.go:541
|
||||
msgid "End date can not be empty."
|
||||
msgstr "La date de fin ne peut pas être vide."
|
||||
|
||||
#: pkg/season/admin.go:541
|
||||
#: pkg/season/admin.go:542
|
||||
msgid "End date must be a valid date."
|
||||
msgstr "La date de fin doit être une date valide."
|
||||
|
||||
|
@ -1666,7 +1710,3 @@ 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"
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
-- Revert camper:legal_text from pg
|
||||
|
||||
begin;
|
||||
|
||||
drop table if exists camper.legal_text;
|
||||
|
||||
commit;
|
|
@ -0,0 +1,7 @@
|
|||
-- Revert camper:legal_text_i18n from pg
|
||||
|
||||
begin;
|
||||
|
||||
drop table if exists camper.legal_text_i18n;
|
||||
|
||||
commit;
|
|
@ -0,0 +1,7 @@
|
|||
-- Revert camper:translate_legal_text from pg
|
||||
|
||||
begin;
|
||||
|
||||
drop function if exists camper.translate_legal_text(integer, text, text, text, text);
|
||||
|
||||
commit;
|
|
@ -128,3 +128,6 @@ location [schema_camper roles company user_profile] 2023-12-21T17:01:28Z jordi f
|
|||
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
|
||||
legal_text [roles schema_camper company user_profile] 2023-12-21T23:29:28Z jordi fita mas <jordi@tandem.blog> # Add relation for legal documents
|
||||
legal_text_i18n [roles schema_camper legal_text language] 2023-12-21T23:51:09Z jordi fita mas <jordi@tandem.blog> # Add relation for legal text internationalization
|
||||
translate_legal_text [roles schema_camper legal_text_i18n] 2023-12-22T00:10:05Z jordi fita mas <jordi@tandem.blog> # Add function to translate legal texts
|
||||
|
|
|
@ -0,0 +1,198 @@
|
|||
-- Test legal_text
|
||||
set client_min_messages to warning;
|
||||
create extension if not exists pgtap;
|
||||
reset client_min_messages;
|
||||
|
||||
begin;
|
||||
|
||||
select plan(41);
|
||||
|
||||
set search_path to camper, public;
|
||||
|
||||
select has_table('legal_text');
|
||||
select has_pk('legal_text');
|
||||
select col_is_pk('legal_text', array['company_id', 'slug']);
|
||||
select table_privs_are('legal_text', 'guest', array['SELECT']);
|
||||
select table_privs_are('legal_text', 'employee', array['SELECT']);
|
||||
select table_privs_are('legal_text', 'admin', array['SELECT', 'INSERT', 'UPDATE', 'DELETE']);
|
||||
select table_privs_are('legal_text', 'authenticator', array[]::text[]);
|
||||
|
||||
select has_column('legal_text', 'slug');
|
||||
select col_type_is('legal_text', 'slug', 'text');
|
||||
select col_not_null('legal_text', 'slug');
|
||||
select col_hasnt_default('legal_text', 'slug');
|
||||
|
||||
select has_column('legal_text', 'company_id');
|
||||
select col_is_fk('legal_text', 'company_id');
|
||||
select fk_ok('legal_text', 'company_id', 'company', 'company_id');
|
||||
select col_type_is('legal_text', 'company_id', 'integer');
|
||||
select col_not_null('legal_text', 'company_id');
|
||||
select col_hasnt_default('legal_text', 'company_id');
|
||||
|
||||
select has_column('legal_text', 'name');
|
||||
select col_type_is('legal_text', 'name', 'text');
|
||||
select col_not_null('legal_text', 'name');
|
||||
select col_hasnt_default('legal_text', 'name');
|
||||
|
||||
select has_column('legal_text', 'content');
|
||||
select col_type_is('legal_text', 'content', 'xml');
|
||||
select col_not_null('legal_text', 'content');
|
||||
select col_hasnt_default('legal_text', 'content');
|
||||
|
||||
|
||||
set client_min_messages to warning;
|
||||
truncate legal_text 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')
|
||||
;
|
||||
|
||||
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 legal_text (company_id, slug, name, content)
|
||||
values (2, 'reservation', 'Reservation', '')
|
||||
, (4, 'cookies', 'Cookies', '')
|
||||
;
|
||||
|
||||
prepare legal_data as
|
||||
select company_id, slug
|
||||
from legal_text
|
||||
order by company_id, slug;
|
||||
|
||||
set role guest;
|
||||
select bag_eq(
|
||||
'legal_data',
|
||||
$$ values (2, 'reservation')
|
||||
, (4, 'cookies')
|
||||
$$,
|
||||
'Everyone should be able to list all legal texts across all companies'
|
||||
);
|
||||
reset role;
|
||||
|
||||
select set_cookie('44facbb30d8a419dfd4bfbc44a4b5539d4970148dfc84bed0e/demo@tandem.blog', 'co2');
|
||||
|
||||
select lives_ok(
|
||||
$$ insert into legal_text(company_id, slug, name, content) values (2, 'tos', 'Terms of Service', '') $$,
|
||||
'Admin from company 2 should be able to insert a new legal text to that company.'
|
||||
);
|
||||
|
||||
select bag_eq(
|
||||
'legal_data',
|
||||
$$ values (2, 'tos')
|
||||
, (2, 'reservation')
|
||||
, (4, 'cookies')
|
||||
$$,
|
||||
'The new row should have been added'
|
||||
);
|
||||
|
||||
select lives_ok(
|
||||
$$ update legal_text set slug = 'terms' where company_id = 2 and slug = 'tos' $$,
|
||||
'Admin from company 2 should be able to update legal text of that company.'
|
||||
);
|
||||
|
||||
select bag_eq(
|
||||
'legal_data',
|
||||
$$ values (2, 'terms')
|
||||
, (2, 'reservation')
|
||||
, (4, 'cookies')
|
||||
$$,
|
||||
'The row should have been updated.'
|
||||
);
|
||||
|
||||
select lives_ok(
|
||||
$$ delete from legal_text where company_id = 2 and slug = 'terms' $$,
|
||||
'Admin from company 2 should be able to delete legal text from that company.'
|
||||
);
|
||||
|
||||
select bag_eq(
|
||||
'legal_data',
|
||||
$$ values (2, 'reservation')
|
||||
, (4, 'cookies')
|
||||
$$,
|
||||
'The row should have been deleted.'
|
||||
);
|
||||
|
||||
select throws_ok(
|
||||
$$ insert into legal_text (company_id, slug, name, content) values (4, 'terms', 'Terms', '') $$,
|
||||
'42501', 'new row violates row-level security policy for table "legal_text"',
|
||||
'Admin from company 2 should NOT be able to insert new legal texts to company 4.'
|
||||
);
|
||||
|
||||
select lives_ok(
|
||||
$$ update legal_text set slug = 'nope' where company_id = 4 $$,
|
||||
'Admin from company 2 should not be able to update new legal texts of company 4, but no error if company_id is not changed.'
|
||||
);
|
||||
|
||||
select bag_eq(
|
||||
'legal_data',
|
||||
$$ values (2, 'reservation')
|
||||
, (4, 'cookies')
|
||||
$$,
|
||||
'No row should have been changed.'
|
||||
);
|
||||
|
||||
select throws_ok(
|
||||
$$ update legal_text set company_id = 4 where company_id = 2 $$,
|
||||
'42501', 'new row violates row-level security policy for table "legal_text"',
|
||||
'Admin from company 2 should NOT be able to move legal texts to company 4'
|
||||
);
|
||||
|
||||
select lives_ok(
|
||||
$$ delete from legal_text where company_id = 4 $$,
|
||||
'Admin from company 2 should NOT be able to delete legal texts from company 4, but not error is thrown'
|
||||
);
|
||||
|
||||
select bag_eq(
|
||||
'legal_data',
|
||||
$$ values (2, 'reservation')
|
||||
, (4, 'cookies')
|
||||
$$,
|
||||
'No row should have been changed'
|
||||
);
|
||||
|
||||
select throws_ok(
|
||||
$$ insert into legal_text (company_id, slug, name, content) values (2, 'ToS', 'Term of Services', '') $$,
|
||||
'23514', 'new row for relation "legal_text" violates check constraint "valid_slug"',
|
||||
'Should not be able to insert legal texts with a invalid slug.'
|
||||
);
|
||||
|
||||
select throws_ok(
|
||||
$$ insert into legal_text (company_id, slug, name, content) values (2, 'terms of service', 'Term of Services', '') $$,
|
||||
'23514', 'new row for relation "legal_text" violates check constraint "valid_slug"',
|
||||
'Should not be able to insert legal texts with a spaces in the slug.'
|
||||
);
|
||||
|
||||
select throws_ok(
|
||||
$$ insert into legal_text (company_id, slug, name, content) values (2, 'tos', ' ', '') $$,
|
||||
'23514', 'new row for relation "legal_text" violates check constraint "name_not_empty"',
|
||||
'Should not be able to insert legal texts with a blank name.'
|
||||
);
|
||||
|
||||
|
||||
reset role;
|
||||
|
||||
|
||||
select *
|
||||
from finish();
|
||||
|
||||
rollback;
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
-- Test legal_text_i18n
|
||||
set client_min_messages to warning;
|
||||
create extension if not exists pgtap;
|
||||
reset client_min_messages;
|
||||
|
||||
begin;
|
||||
|
||||
select plan(31);
|
||||
|
||||
set search_path to camper, public;
|
||||
|
||||
select has_table('legal_text_i18n');
|
||||
select has_pk('legal_text_i18n');
|
||||
select col_is_pk('legal_text_i18n', array['company_id', 'slug', 'lang_tag']);
|
||||
select col_is_fk('legal_text_i18n', array['company_id', 'slug']);
|
||||
select fk_ok('legal_text_i18n', array['company_id', 'slug'], 'legal_text', array['company_id', 'slug']);
|
||||
select table_privs_are('legal_text_i18n', 'guest', array['SELECT']);
|
||||
select table_privs_are('legal_text_i18n', 'employee', array['SELECT']);
|
||||
select table_privs_are('legal_text_i18n', 'admin', array['SELECT', 'INSERT', 'UPDATE', 'DELETE']);
|
||||
select table_privs_are('legal_text_i18n', 'authenticator', array[]::text[]);
|
||||
|
||||
select has_column('legal_text_i18n', 'company_id');
|
||||
select col_type_is('legal_text_i18n', 'company_id', 'integer');
|
||||
select col_not_null('legal_text_i18n', 'company_id');
|
||||
select col_hasnt_default('legal_text_i18n', 'company_id');
|
||||
|
||||
select has_column('legal_text_i18n', 'slug');
|
||||
select col_type_is('legal_text_i18n', 'slug', 'text');
|
||||
select col_not_null('legal_text_i18n', 'slug');
|
||||
select col_hasnt_default('legal_text_i18n', 'slug');
|
||||
|
||||
select has_column('legal_text_i18n', 'lang_tag');
|
||||
select col_is_fk('legal_text_i18n', 'lang_tag');
|
||||
select fk_ok('legal_text_i18n', 'lang_tag', 'language', 'lang_tag');
|
||||
select col_type_is('legal_text_i18n', 'lang_tag', 'text');
|
||||
select col_not_null('legal_text_i18n', 'lang_tag');
|
||||
select col_hasnt_default('legal_text_i18n', 'lang_tag');
|
||||
|
||||
select has_column('legal_text_i18n', 'name');
|
||||
select col_type_is('legal_text_i18n', 'name', 'text');
|
||||
select col_not_null('legal_text_i18n', 'name');
|
||||
select col_hasnt_default('legal_text_i18n', 'name');
|
||||
|
||||
select has_column('legal_text_i18n', 'content');
|
||||
select col_type_is('legal_text_i18n', 'content', 'xml');
|
||||
select col_not_null('legal_text_i18n', 'content');
|
||||
select col_hasnt_default('legal_text_i18n', 'content');
|
||||
|
||||
|
||||
select *
|
||||
from finish();
|
||||
|
||||
rollback;
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
-- Test translate_legal_text
|
||||
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_legal_text', array['integer', 'text', 'text', 'text', 'text']);
|
||||
select function_lang_is('camper', 'translate_legal_text', array['integer', 'text', 'text', 'text', 'text'], 'sql');
|
||||
select function_returns('camper', 'translate_legal_text', array['integer', 'text', 'text', 'text', 'text'], 'void');
|
||||
select isnt_definer('camper', 'translate_legal_text', array['integer', 'text', 'text', 'text', 'text']);
|
||||
select volatility_is('camper', 'translate_legal_text', array['integer', 'text', 'text', 'text', 'text'], 'volatile');
|
||||
select function_privs_are('camper', 'translate_legal_text', array['integer', 'text', 'text', 'text', 'text'], 'guest', array[]::text[]);
|
||||
select function_privs_are('camper', 'translate_legal_text', array['integer', 'text', 'text', 'text', 'text'], 'employee', array[]::text[]);
|
||||
select function_privs_are('camper', 'translate_legal_text', array['integer', 'text', 'text', 'text', 'text'], 'admin', array['EXECUTE']);
|
||||
select function_privs_are('camper', 'translate_legal_text', array['integer', 'text', 'text', 'text', 'text'], 'authenticator', array[]::text[]);
|
||||
|
||||
set client_min_messages to warning;
|
||||
truncate legal_text_i18n cascade;
|
||||
truncate legal_text 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 legal_text (company_id, slug, name, content)
|
||||
values (2, 'tos', 'Terms of Service', '<p>Go away</p>')
|
||||
, (4, 'cookies', 'Cookies', '<p>Yummy</p>')
|
||||
;
|
||||
|
||||
insert into legal_text_i18n (company_id, slug, lang_tag, name, content)
|
||||
values (2, 'tos', 'ca', '<p>Termes i condicions</p>', '<p>Uh?</p>')
|
||||
, (4, 'cookies', 'ca', '<p>Galetes</p>', '<p>Uh?</p>')
|
||||
;
|
||||
|
||||
select lives_ok(
|
||||
$$ select translate_legal_text(2, 'tos', 'es', 'Términos', '<p>Adiós</p>') $$,
|
||||
'Should be able to translate the legal text of the first company to a new language'
|
||||
);
|
||||
|
||||
select lives_ok(
|
||||
$$ select translate_legal_text(2, 'tos', 'ca', 'Termes', '<p>Adéu</p>') $$,
|
||||
'Should be able to overwrite a legal text’s translation'
|
||||
);
|
||||
|
||||
select lives_ok(
|
||||
$$ select translate_legal_text(4, 'cookies', 'ca', null, null) $$,
|
||||
'Should be able to “translate” a legal_text to empty strings'
|
||||
);
|
||||
|
||||
|
||||
select bag_eq(
|
||||
$$ select company_id, slug, lang_tag, name, content::text from legal_text_i18n $$,
|
||||
$$ values (2, 'tos', 'ca', 'Termes', '<p>Adéu</p>')
|
||||
, (2, 'tos', 'es', 'Términos', '<p>Adiós</p>')
|
||||
, (4, 'cookies', 'ca', '', '')
|
||||
$$,
|
||||
'Should have translated all legal texts'
|
||||
);
|
||||
|
||||
|
||||
select *
|
||||
from finish();
|
||||
|
||||
rollback;
|
|
@ -0,0 +1,18 @@
|
|||
-- Verify camper:legal_text on pg
|
||||
|
||||
begin;
|
||||
|
||||
select company_id
|
||||
, slug
|
||||
, name
|
||||
, content
|
||||
from camper.legal_text
|
||||
where false;
|
||||
|
||||
select 1 / count(*) from pg_class where oid = 'camper.legal_text'::regclass and relrowsecurity;
|
||||
select 1 / count(*) from pg_policy where polname = 'guest_ok' and polrelid = 'camper.legal_text'::regclass;
|
||||
select 1 / count(*) from pg_policy where polname = 'insert_to_company' and polrelid = 'camper.legal_text'::regclass;
|
||||
select 1 / count(*) from pg_policy where polname = 'update_company' and polrelid = 'camper.legal_text'::regclass;
|
||||
select 1 / count(*) from pg_policy where polname = 'delete_from_company' and polrelid = 'camper.legal_text'::regclass;
|
||||
|
||||
rollback;
|
|
@ -0,0 +1,13 @@
|
|||
-- Verify camper:legal_text_i18n on pg
|
||||
|
||||
begin;
|
||||
|
||||
select company_id
|
||||
, slug
|
||||
, lang_tag
|
||||
, name
|
||||
, content
|
||||
from camper.legal_text_i18n
|
||||
where false;
|
||||
|
||||
rollback;
|
|
@ -0,0 +1,7 @@
|
|||
-- Verify camper:translate_legal_text on pg
|
||||
|
||||
begin;
|
||||
|
||||
select has_function_privilege('camper.translate_legal_text(integer, text, text, text, text)', 'execute');
|
||||
|
||||
rollback;
|
|
@ -59,6 +59,9 @@
|
|||
<li>
|
||||
<a href="/admin/location">{{( pgettext "Location" "title" )}}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/admin/legal">{{( pgettext "Legal Texts" "title" )}}</a>
|
||||
</li>
|
||||
{{- end }}
|
||||
<li class="icon_logout">
|
||||
<button data-hx-delete="/me/session" data-hx-headers='{ {{ CSRFHeader }} }'
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
<!--
|
||||
SPDX-FileCopyrightText: 2023 jordi fita mas <jordi@tandem.blog>
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
{{ define "title" -}}
|
||||
{{- /*gotype: dev.tandem.ws/tandem/camper/pkg/legal.legalForm*/ -}}
|
||||
{{ if .URL }}
|
||||
{{( pgettext "Edit Legal Text" "title" )}}
|
||||
{{ else }}
|
||||
{{( pgettext "New Legal Text" "title" )}}
|
||||
{{ end }}
|
||||
{{- end }}
|
||||
|
||||
{{ define "content" -}}
|
||||
{{- /*gotype: dev.tandem.ws/tandem/camper/pkg/legal.legalForm*/ -}}
|
||||
<form
|
||||
{{ if .URL }}
|
||||
data-hx-put="{{ .URL }}"
|
||||
{{ else }}
|
||||
action="/admin/legal" method="post"
|
||||
{{ end }}
|
||||
>
|
||||
<h2>
|
||||
{{ if .URL }}
|
||||
{{( pgettext "Edit Legal Text" "title" )}}
|
||||
{{ else }}
|
||||
{{( pgettext "New Legal Text" "title" )}}
|
||||
{{ end }}
|
||||
</h2>
|
||||
{{ CSRFInput }}
|
||||
<fieldset x-data="{ lang: 'ca' }">
|
||||
{{ if .URL }}
|
||||
<input type="hidden" name="{{ .Slug.Name }}" value="{{ .Slug.Val }}">
|
||||
{{ else }}
|
||||
{{ with .Slug -}}
|
||||
<label>
|
||||
{{( pgettext "Slug" "input")}}<br>
|
||||
<input type="text" name="{{ .Name }}" value="{{ .Val }}"
|
||||
required {{ template "error-attrs" . }}><br>
|
||||
</label>
|
||||
{{ template "error-message" . }}
|
||||
{{- end }}
|
||||
{{ end }}
|
||||
{{ with .Name -}}
|
||||
<fieldset>
|
||||
<legend>{{( pgettext "Name" "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>
|
||||
<input type="text" name="{{ $input.Name }}" value="{{ $input.Val }}"
|
||||
{{ template "error-attrs" . }}><br>
|
||||
</label>
|
||||
{{- end }}
|
||||
{{ template "error-message" . }}
|
||||
</fieldset>
|
||||
{{- end }}
|
||||
{{ with .Content -}}
|
||||
<fieldset>
|
||||
<legend>{{( pgettext "Content" "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 }}
|
||||
</fieldset>
|
||||
<footer>
|
||||
<button type="submit">
|
||||
{{ if .URL }}
|
||||
{{( pgettext "Update" "action" )}}
|
||||
{{ else }}
|
||||
{{( pgettext "Add" "action" )}}
|
||||
{{ end }}
|
||||
</button>
|
||||
</footer>
|
||||
</form>
|
||||
{{- end }}
|
|
@ -0,0 +1,31 @@
|
|||
<!--
|
||||
SPDX-FileCopyrightText: 2023 jordi fita mas <jordi@tandem.blog>
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
{{ define "title" -}}
|
||||
{{( pgettext "Legal Texts" "title" )}}
|
||||
{{- end }}
|
||||
|
||||
{{ define "content" -}}
|
||||
{{- /*gotype: dev.tandem.ws/tandem/camper/pkg/legal.legalIndex*/ -}}
|
||||
<a href="/admin/legal/new">{{( pgettext "Add Legal Text" "action" )}}</a>
|
||||
<h2>{{( pgettext "Legal Texts" "title" )}}</h2>
|
||||
{{ if .Texts -}}
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">{{( pgettext "Name" "header" )}}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{ range $text := .Texts -}}
|
||||
<tr>
|
||||
<td><a href="{{ .URL }}">{{ .Name }}</a></td>
|
||||
</tr>
|
||||
{{- end }}
|
||||
</tbody>
|
||||
</table>
|
||||
{{ else -}}
|
||||
<p>{{( gettext "No legal texts added yet." )}}</p>
|
||||
{{- end }}
|
||||
{{- end }}
|
|
@ -0,0 +1,17 @@
|
|||
<!--
|
||||
SPDX-FileCopyrightText: 2023 jordi fita mas <jordi@tandem.blog>
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
-->
|
||||
{{ define "title" -}}
|
||||
{{- /*gotype: dev.tandem.ws/tandem/camper/pkg/legal.legalPage*/ -}}
|
||||
{{ .Name }}
|
||||
{{- end }}
|
||||
|
||||
{{ define "content" -}}
|
||||
{{- /*gotype: dev.tandem.ws/tandem/camper/pkg/legal.legalPage*/ -}}
|
||||
|
||||
<h2>{{ .Name }}</h2>
|
||||
<div class="legal-page">
|
||||
{{ .Content }}
|
||||
</div>
|
||||
{{- end }}
|
Loading…
Reference in New Issue