Add the edit form for services

This one has an input to select the icon.  It makes no sense to choose
an icon only by name, thus a <select> is not appropriate, and had to
use a hidden input with a row of button to choose the icon from.  This
works now only because there are very few icons; we’ll need to choose
a different approach when there are many more icons.

Since now the icons have to be defined in CSS for both the public and
admin sections, i had to split it into a separate file that both sites
can use.  I considered the option to “include” that CSS with m4, like
i do for images in demo.sql, but it made everything too complicated
(e.g., having to call make for each change in the CSS), and decided to
load that CSS in a separate <link>.
This commit is contained in:
jordi fita mas 2023-09-25 20:10:33 +02:00
parent d79a05a619
commit 44526b1efb
20 changed files with 1002 additions and 351 deletions

14
deploy/translation.sql Normal file
View File

@ -0,0 +1,14 @@
-- Deploy camper:translation to pg
-- requires: schema_camper
begin;
set search_path to camper, public;
create type translation as (
lang_tag text,
endonym text,
missing boolean
);
commit;

View File

@ -39,3 +39,26 @@ type MultipartForm interface {
ParseMultipart(w http.ResponseWriter, r *http.Request) error
Valid(l *locale.Locale) bool
}
func Handle(f Form, w http.ResponseWriter, r *http.Request, user *auth.User) (bool, error) {
if err := f.Parse(r); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return false, err
}
if err := user.VerifyCSRFToken(r); err != nil {
http.Error(w, err.Error(), http.StatusForbidden)
return false, err
}
if !f.Valid(user.Locale) {
if !httplib.IsHTMxRequest(r) {
w.WriteHeader(http.StatusUnprocessableEntity)
}
return false, nil
}
return true, nil
}
type Form interface {
Parse(r *http.Request) error
Valid(l *locale.Locale) bool
}

12
pkg/locale/translation.go Normal file
View File

@ -0,0 +1,12 @@
/*
* SPDX-FileCopyrightText: 2023 jordi fita mas <jfita@peritasoft.com>
* SPDX-License-Identifier: AGPL-3.0-only
*/
package locale
type Translation struct {
URL string
Endonym string
Missing bool
}

View File

@ -6,11 +6,16 @@
package services
import (
"context"
"net/http"
"strconv"
"github.com/jackc/pgx/v4"
"dev.tandem.ws/tandem/camper/pkg/auth"
"dev.tandem.ws/tandem/camper/pkg/carousel"
"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"
@ -46,7 +51,52 @@ func (h *AdminHandler) Handler(user *auth.User, company *auth.Company, conn *dat
case "slides":
h.carousel.Handler(user, company, conn).ServeHTTP(w, r)
default:
id, err := strconv.Atoi(head)
if err != nil {
http.NotFound(w, r)
return
}
f := newServiceForm(r.Context(), conn)
if err := f.FillFromDatabase(r.Context(), conn, id); err != nil {
if database.ErrorIsNotFound(err) {
http.NotFound(w, r)
return
}
panic(err)
}
var langTag string
langTag, r.URL.Path = httplib.ShiftPath(r.URL.Path)
switch langTag {
case "":
switch r.Method {
case http.MethodGet:
f.MustRender(w, r, user, company)
case http.MethodPut:
editService(w, r, user, company, conn, f)
default:
httplib.MethodNotAllowed(w, r, http.MethodGet, http.MethodPut)
}
default:
loc, ok := h.locales.Get(langTag)
if !ok {
http.NotFound(w, r)
return
}
l10n := newServiceL10nForm(f, loc)
if err := l10n.FillFromDatabase(r.Context(), conn); err != nil {
panic(err)
}
switch r.Method {
case http.MethodGet:
l10n.MustRender(w, r, user, company)
case http.MethodPut:
editServiceL10n(w, r, user, company, conn, l10n)
default:
httplib.MethodNotAllowed(w, r, http.MethodGet, http.MethodPut)
}
}
}
})
}
@ -56,16 +106,134 @@ func serveHomeIndex(w http.ResponseWriter, r *http.Request, user *auth.User, com
if err != nil {
panic(err)
}
services, err := collectServiceEntries(r.Context(), company, conn)
page := &servicesIndex{
Services: services,
Slides: slides,
}
page.MustRender(w, r, user, company)
}
type servicesIndex struct {
Services []*serviceEntry
Slides []*carousel.SlideEntry
}
func (page *servicesIndex) MustRender(w http.ResponseWriter, r *http.Request, user *auth.User, company *auth.Company) {
template.MustRenderAdmin(w, r, user, company, "services/index.gohtml", page)
}
type serviceEntry struct {
URL string
Icon string
Name string
Translations []*locale.Translation
}
func collectServiceEntries(ctx context.Context, company *auth.Company, conn *database.Conn) ([]*serviceEntry, error) {
rows, err := conn.Query(ctx, `
select '/admin/services/' || service_id
, icon_name
, service.name
, array_agg((lang_tag, endonym, not exists (select 1 from service_i18n as i18n where i18n.service_id = service.service_id and i18n.lang_tag = language.lang_tag))::translation order by endonym)
from service
join company using (company_id)
, language
where lang_tag <> default_lang_tag
and language.selectable
and service.company_id = $1
group by service_id
, icon_name
, service.name
order by service.name
`, pgx.QueryResultFormats{pgx.BinaryFormatCode}, company.ID)
if err != nil {
return nil, err
}
defer rows.Close()
var services []*serviceEntry
for rows.Next() {
entry := &serviceEntry{}
var translations database.RecordArray
if err = rows.Scan(&entry.URL, &entry.Icon, &entry.Name, &translations); err != nil {
return nil, err
}
for _, el := range translations.Elements {
entry.Translations = append(entry.Translations, &locale.Translation{
URL: entry.URL + "/" + el.Fields[0].Get().(string),
Endonym: el.Fields[1].Get().(string),
Missing: el.Fields[2].Get().(bool),
})
}
services = append(services, entry)
}
return services, nil
}
func editService(w http.ResponseWriter, r *http.Request, user *auth.User, company *auth.Company, conn *database.Conn, f *serviceForm) {
if ok, err := form.Handle(f, w, r, user); err != nil {
return
} else if !ok {
f.MustRender(w, r, user, company)
return
}
conn.MustExec(r.Context(), "select edit_service($1, $2, $3, $4)", f.ID, f.Icon, f.Name, f.Description)
httplib.Redirect(w, r, "/admin/services", http.StatusSeeOther)
}
type serviceForm struct {
ID int
Icon *form.Select
Name *form.Input
Description *form.Input
}
func newServiceForm(ctx context.Context, conn *database.Conn) *serviceForm {
return &serviceForm{
Icon: &form.Select{
Name: "icon",
Options: form.MustGetOptions(ctx, conn, "select icon_name, icon_name from icon order by 1"),
},
Name: &form.Input{
Name: "name",
},
Description: &form.Input{
Name: "description",
},
}
}
func (f *serviceForm) FillFromDatabase(ctx context.Context, conn *database.Conn, id int) error {
f.ID = id
row := conn.QueryRow(ctx, `
select array[icon_name]
, name
, description
from service
where service_id = $1
`, id)
return row.Scan(&f.Icon.Selected, &f.Name.Val, &f.Description.Val)
}
func (f *serviceForm) Parse(r *http.Request) error {
if err := r.ParseForm(); err != nil {
return err
}
f.Icon.FillValue(r)
f.Name.FillValue(r)
f.Description.FillValue(r)
return nil
}
func (f *serviceForm) Valid(l *locale.Locale) bool {
v := form.NewValidator(l)
v.CheckSelectedOptions(f.Icon, l.GettextNoop("Selected icon is not valid."))
v.CheckRequired(f.Name, l.GettextNoop("Name can not be empty."))
return v.AllOK
}
func (f *serviceForm) MustRender(w http.ResponseWriter, r *http.Request, user *auth.User, company *auth.Company) {
template.MustRenderAdmin(w, r, user, company, "services/form.gohtml", f)
}

75
pkg/services/l10n.go Normal file
View File

@ -0,0 +1,75 @@
/*
* SPDX-FileCopyrightText: 2023 jordi fita mas <jfita@peritasoft.com>
* SPDX-License-Identifier: AGPL-3.0-only
*/
package services
import (
"context"
"net/http"
"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 serviceL10nForm struct {
Locale *locale.Locale
ID int
Name *form.L10nInput
Description *form.L10nInput
}
func newServiceL10nForm(f *serviceForm, loc *locale.Locale) *serviceL10nForm {
return &serviceL10nForm{
Locale: loc,
ID: f.ID,
Name: f.Name.L10nInput(),
Description: f.Description.L10nInput(),
}
}
func (l10n *serviceL10nForm) FillFromDatabase(ctx context.Context, conn *database.Conn) error {
row := conn.QueryRow(ctx, `
select coalesce(i18n.name, '') as l10n_name
, coalesce(i18n.description, '') as l10n_description
from service
left join service_i18n as i18n on service.service_id = i18n.service_id and i18n.lang_tag = $1
where service.service_id = $2
`, l10n.Locale.Language, l10n.ID)
return row.Scan(&l10n.Name.Val, &l10n.Description.Val)
}
func (l10n *serviceL10nForm) MustRender(w http.ResponseWriter, r *http.Request, user *auth.User, company *auth.Company) {
template.MustRenderAdmin(w, r, user, company, "services/l10n.gohtml", l10n)
}
func editServiceL10n(w http.ResponseWriter, r *http.Request, user *auth.User, company *auth.Company, conn *database.Conn, l10n *serviceL10nForm) {
if ok, err := form.Handle(l10n, w, r, user); err != nil {
return
} else if !ok {
l10n.MustRender(w, r, user, company)
return
}
conn.MustExec(r.Context(), "select translate_service($1, $2, $3, $4)", l10n.ID, l10n.Locale.Language, l10n.Name, l10n.Description)
httplib.Redirect(w, r, "/admin/services", http.StatusSeeOther)
}
func (l10n *serviceL10nForm) Parse(r *http.Request) error {
if err := r.ParseForm(); err != nil {
return err
}
l10n.Name.FillValue(r)
l10n.Description.FillValue(r)
return nil
}
func (l10n *serviceL10nForm) Valid(l *locale.Locale) bool {
v := form.NewValidator(l)
v.CheckRequired(&l10n.Name.Input, l.GettextNoop("Name can not be empty."))
return v.AllOK
}

319
po/ca.po
View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: camper\n"
"Report-Msgid-Bugs-To: jordi@tandem.blog\n"
"POT-Creation-Date: 2023-09-24 03:04+0200\n"
"POT-Creation-Date: 2023-09-25 20:03+0200\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"
@ -20,6 +20,7 @@ msgstr ""
#: web/templates/public/services.gohtml:6
#: web/templates/public/services.gohtml:15
#: web/templates/admin/services/index.gohtml:50
msgctxt "title"
msgid "Services"
msgstr "Serveis"
@ -28,7 +29,7 @@ msgstr "Serveis"
msgid "The campsite offers many different services."
msgstr "El càmping disposa de diversos serveis."
#: web/templates/public/home.gohtml:6 web/templates/public/layout.gohtml:28
#: web/templates/public/home.gohtml:6 web/templates/public/layout.gohtml:29
msgctxt "title"
msgid "Home"
msgstr "Inici"
@ -131,262 +132,274 @@ msgstr "Caiac"
msgid "There are several points where you can go by kayak, from sections of the Ter river as well as on the coast…."
msgstr "Hi ha diversos punts on poder anar amb caiac, des de trams del riu Ter com també a la costa…."
#: web/templates/public/layout.gohtml:11 web/templates/public/layout.gohtml:23
#: web/templates/public/layout.gohtml:58
#: web/templates/public/layout.gohtml:11 web/templates/public/layout.gohtml:24
#: web/templates/public/layout.gohtml:59
msgid "Campsite Montagut"
msgstr "Càmping Montagut"
#: web/templates/public/layout.gohtml:21 web/templates/admin/layout.gohtml:18
#: web/templates/public/layout.gohtml:22 web/templates/admin/layout.gohtml:19
msgid "Skip to main content"
msgstr "Salta al contingut principal"
#: web/templates/public/layout.gohtml:32
#: web/templates/public/layout.gohtml:33
msgid "Singular Lodges"
msgstr "Allotjaments singulars"
#: web/templates/admin/carousel/form.gohtml:8
#: web/templates/admin/carousel/form.gohtml:26
#: web/templates/admin/carousel/form.gohtml:25
msgctxt "title"
msgid "Edit Carousel Slide"
msgstr "Edició de la diapositiva del carrusel"
#: web/templates/admin/carousel/form.gohtml:10
#: web/templates/admin/carousel/form.gohtml:28
#: web/templates/admin/carousel/form.gohtml:27
msgctxt "title"
msgid "New Carousel Slide"
msgstr "Nova diapositiva del carrusel"
#: web/templates/admin/carousel/form.gohtml:38
#: web/templates/admin/carousel/l10n.gohtml:21
#: web/templates/admin/carousel/form.gohtml:37
#: web/templates/admin/carousel/l10n.gohtml:20
msgctxt "input"
msgid "Caption"
msgstr "Llegenda"
#: web/templates/admin/carousel/form.gohtml:48
#: web/templates/admin/campsite/form.gohtml:71
#: web/templates/admin/campsite/type/form.gohtml:67
#: web/templates/admin/season/form.gohtml:65
#: web/templates/admin/media/form.gohtml:36
#: web/templates/admin/carousel/form.gohtml:47
#: web/templates/admin/campsite/form.gohtml:70
#: web/templates/admin/campsite/type/form.gohtml:66
#: 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:50
#: web/templates/admin/campsite/form.gohtml:73
#: web/templates/admin/campsite/type/form.gohtml:69
#: web/templates/admin/season/form.gohtml:67
#: web/templates/admin/carousel/form.gohtml:49
#: web/templates/admin/campsite/form.gohtml:72
#: web/templates/admin/campsite/type/form.gohtml:68
#: 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:15
#: web/templates/admin/carousel/l10n.gohtml:14
msgctxt "title"
msgid "Translate Carousel Slide to %s"
msgstr "Traducció de la diapositiva del carrusel a %s"
#: web/templates/admin/carousel/l10n.gohtml:22
#: web/templates/admin/campsite/type/l10n.gohtml:22
#: web/templates/admin/campsite/type/l10n.gohtml:34
#: web/templates/admin/carousel/l10n.gohtml:21
#: web/templates/admin/campsite/type/l10n.gohtml:21
#: web/templates/admin/campsite/type/l10n.gohtml:33
#: web/templates/admin/services/l10n.gohtml:21
#: web/templates/admin/services/l10n.gohtml:33
msgid "Source:"
msgstr "Origen:"
#: web/templates/admin/carousel/l10n.gohtml:24
#: web/templates/admin/campsite/type/l10n.gohtml:24
#: web/templates/admin/campsite/type/l10n.gohtml:37
#: web/templates/admin/carousel/l10n.gohtml:23
#: web/templates/admin/campsite/type/l10n.gohtml:23
#: web/templates/admin/campsite/type/l10n.gohtml:36
#: web/templates/admin/services/l10n.gohtml:23
#: web/templates/admin/services/l10n.gohtml:36
msgctxt "input"
msgid "Translation:"
msgstr "Traducció:"
#: web/templates/admin/carousel/l10n.gohtml:33
#: web/templates/admin/campsite/type/l10n.gohtml:46
#: web/templates/admin/carousel/l10n.gohtml:32
#: web/templates/admin/campsite/type/l10n.gohtml:45
#: web/templates/admin/services/l10n.gohtml:45
msgctxt "action"
msgid "Translate"
msgstr "Tradueix"
#: web/templates/admin/campsite/form.gohtml:8
#: web/templates/admin/campsite/form.gohtml:26
#: web/templates/admin/campsite/form.gohtml:25
msgctxt "title"
msgid "Edit Campsite"
msgstr "Edició de lallotjament"
#: web/templates/admin/campsite/form.gohtml:10
#: web/templates/admin/campsite/form.gohtml:28
#: web/templates/admin/campsite/form.gohtml:27
msgctxt "title"
msgid "New Campsite"
msgstr "Nou allotjament"
#: web/templates/admin/campsite/form.gohtml:38
#: web/templates/admin/campsite/index.gohtml:21
#: web/templates/admin/campsite/form.gohtml:37
#: web/templates/admin/campsite/index.gohtml:20
msgctxt "campsite"
msgid "Active"
msgstr "Actiu"
#: web/templates/admin/campsite/form.gohtml:47
#: web/templates/admin/campsite/form.gohtml:46
msgctxt "input"
msgid "Campsite Type"
msgstr "Tipus dallotjament"
#: web/templates/admin/campsite/form.gohtml:52
#: web/templates/admin/campsite/form.gohtml:51
msgid "Select campsite type"
msgstr "Escolliu un tipus dallotjament"
#: web/templates/admin/campsite/form.gohtml:61
#: web/templates/admin/campsite/form.gohtml:60
msgctxt "input"
msgid "Label"
msgstr "Etiqueta"
#: web/templates/admin/campsite/index.gohtml:6
#: web/templates/admin/campsite/index.gohtml:13
#: web/templates/admin/layout.gohtml:52 web/templates/admin/layout.gohtml:73
#: web/templates/admin/campsite/index.gohtml:12
#: web/templates/admin/layout.gohtml:40 web/templates/admin/layout.gohtml:71
msgctxt "title"
msgid "Campsites"
msgstr "Allotjaments"
#: web/templates/admin/campsite/index.gohtml:12
#: web/templates/admin/campsite/index.gohtml:11
msgctxt "action"
msgid "Add Campsite"
msgstr "Afegeix allotjament"
#: web/templates/admin/campsite/index.gohtml:19
#: web/templates/admin/campsite/index.gohtml:18
msgctxt "header"
msgid "Label"
msgstr "Etiqueta"
#: web/templates/admin/campsite/index.gohtml:20
#: web/templates/admin/campsite/index.gohtml:19
msgctxt "header"
msgid "Type"
msgstr "Tipus"
#: web/templates/admin/campsite/index.gohtml:29
#: web/templates/admin/campsite/type/index.gohtml:36
#: web/templates/admin/season/index.gohtml:32
#: web/templates/admin/campsite/index.gohtml:28
#: web/templates/admin/campsite/type/index.gohtml:35
#: web/templates/admin/season/index.gohtml:31
msgid "Yes"
msgstr "Sí"
#: web/templates/admin/campsite/index.gohtml:29
#: web/templates/admin/campsite/type/index.gohtml:36
#: web/templates/admin/season/index.gohtml:32
#: web/templates/admin/campsite/index.gohtml:28
#: web/templates/admin/campsite/type/index.gohtml:35
#: web/templates/admin/season/index.gohtml:31
msgid "No"
msgstr "No"
#: web/templates/admin/campsite/index.gohtml:35
#: web/templates/admin/campsite/index.gohtml:34
msgid "No campsites added yet."
msgstr "No sha afegit cap allotjament encara."
#: web/templates/admin/campsite/type/form.gohtml:8
#: web/templates/admin/campsite/type/form.gohtml:26
#: web/templates/admin/campsite/type/form.gohtml:25
msgctxt "title"
msgid "Edit Campsite Type"
msgstr "Edició del tipus dallotjament"
#: web/templates/admin/campsite/type/form.gohtml:10
#: web/templates/admin/campsite/type/form.gohtml:28
#: web/templates/admin/campsite/type/form.gohtml:27
msgctxt "title"
msgid "New Campsite Type"
msgstr "Nou tipus dallotjament"
#: web/templates/admin/campsite/type/form.gohtml:38
#: web/templates/admin/campsite/type/index.gohtml:20
#: web/templates/admin/campsite/type/form.gohtml:37
#: web/templates/admin/campsite/type/index.gohtml:19
msgctxt "campsite type"
msgid "Active"
msgstr "Actiu"
#: web/templates/admin/campsite/type/form.gohtml:47
#: web/templates/admin/campsite/type/l10n.gohtml:21
#: web/templates/admin/season/form.gohtml:47
#: 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/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/type/form.gohtml:58
#: web/templates/admin/campsite/type/l10n.gohtml:33
#: web/templates/admin/campsite/type/form.gohtml:57
#: web/templates/admin/campsite/type/l10n.gohtml:32
#: web/templates/admin/services/form.gohtml:60
#: web/templates/admin/services/l10n.gohtml:32
msgctxt "input"
msgid "Description"
msgstr "Descripció"
#: web/templates/admin/campsite/type/index.gohtml:6
#: web/templates/admin/campsite/type/index.gohtml:13
#: web/templates/admin/layout.gohtml:70
#: web/templates/admin/campsite/type/index.gohtml:12
#: web/templates/admin/layout.gohtml:37
msgctxt "title"
msgid "Campsite Types"
msgstr "Tipus dallotjaments"
#: web/templates/admin/campsite/type/index.gohtml:12
#: web/templates/admin/campsite/type/index.gohtml:11
msgctxt "action"
msgid "Add Type"
msgstr "Afegeix tipus"
#: web/templates/admin/campsite/type/index.gohtml:18
#: web/templates/admin/season/index.gohtml:18
#: web/templates/admin/campsite/type/index.gohtml:17
#: web/templates/admin/season/index.gohtml:17
msgctxt "header"
msgid "Name"
msgstr "Nom"
#: web/templates/admin/campsite/type/index.gohtml:19
#: web/templates/admin/services/index.gohtml:20
#: web/templates/admin/home/index.gohtml:20
#: web/templates/admin/campsite/type/index.gohtml:18
#: web/templates/admin/services/index.gohtml:19
#: web/templates/admin/services/index.gohtml:56
#: web/templates/admin/home/index.gohtml:19
msgctxt "campsite type"
msgid "Translations"
msgstr "Traduccions"
#: web/templates/admin/campsite/type/index.gohtml:42
#: web/templates/admin/campsite/type/index.gohtml:41
msgid "No campsite types added yet."
msgstr "No sha afegit cap tipus dallotjament encara."
#: web/templates/admin/campsite/type/l10n.gohtml:7
#: web/templates/admin/campsite/type/l10n.gohtml:15
#: web/templates/admin/campsite/type/l10n.gohtml:14
msgctxt "title"
msgid "Translate Campsite Type to %s"
msgstr "Traducció del tipus dallotjament a %s"
#: web/templates/admin/season/form.gohtml:8
#: web/templates/admin/season/form.gohtml:26
#: web/templates/admin/season/form.gohtml:25
msgctxt "title"
msgid "Edit Season"
msgstr "Edició de la temporada"
#: web/templates/admin/season/form.gohtml:10
#: web/templates/admin/season/form.gohtml:28
#: web/templates/admin/season/form.gohtml:27
msgctxt "title"
msgid "New Season"
msgstr "Nova temporada"
#: web/templates/admin/season/form.gohtml:38
#: web/templates/admin/season/index.gohtml:20
#: web/templates/admin/season/form.gohtml:37
#: web/templates/admin/season/index.gohtml:19
msgctxt "season"
msgid "Active"
msgstr "Activa"
#: web/templates/admin/season/form.gohtml:55
#: web/templates/admin/season/form.gohtml:54
msgctxt "input"
msgid "Color"
msgstr "Color"
#: web/templates/admin/season/index.gohtml:6
#: web/templates/admin/season/index.gohtml:13
#: web/templates/admin/layout.gohtml:76
#: web/templates/admin/season/index.gohtml:12
#: web/templates/admin/layout.gohtml:43
msgctxt "title"
msgid "Seasons"
msgstr "Temporades"
#: web/templates/admin/season/index.gohtml:12
#: web/templates/admin/season/index.gohtml:11
msgctxt "action"
msgid "Add Season"
msgstr "Afegeix temporada"
#: web/templates/admin/season/index.gohtml:19
#: web/templates/admin/season/index.gohtml:18
msgctxt "header"
msgid "Color"
msgstr "Color"
#: web/templates/admin/season/index.gohtml:38
#: web/templates/admin/season/index.gohtml:37
msgid "No seasons added yet."
msgstr "No sha afegit cap temporada encara."
#: web/templates/admin/dashboard.gohtml:6
#: web/templates/admin/dashboard.gohtml:10 web/templates/admin/layout.gohtml:49
#: web/templates/admin/dashboard.gohtml:10 web/templates/admin/layout.gohtml:68
msgctxt "title"
msgid "Dashboard"
msgstr "Tauler"
@ -397,7 +410,7 @@ msgid "Login"
msgstr "Entrada"
#: web/templates/admin/login.gohtml:22 web/templates/admin/profile.gohtml:35
#: web/templates/admin/taxDetails.gohtml:51
#: web/templates/admin/taxDetails.gohtml:50
msgctxt "input"
msgid "Email"
msgstr "Correu-e"
@ -412,55 +425,89 @@ msgctxt "action"
msgid "Login"
msgstr "Entra"
#: web/templates/admin/services/form.gohtml:8
#: web/templates/admin/services/form.gohtml:25
msgctxt "title"
msgid "Edit Service"
msgstr "Edició de servei"
#: web/templates/admin/services/form.gohtml:10
#: web/templates/admin/services/form.gohtml:27
msgctxt "title"
msgid "New Service"
msgstr "Nou servei"
#: web/templates/admin/services/form.gohtml:34
msgctxt "input"
msgid "Icon"
msgstr "Icona"
#: web/templates/admin/services/index.gohtml:6
#: web/templates/admin/layout.gohtml:82
#: web/templates/admin/layout.gohtml:52
msgctxt "title"
msgid "Services Page"
msgstr "Pàgina de serveis"
#: web/templates/admin/services/index.gohtml:12
#: web/templates/admin/home/index.gohtml:12
#: web/templates/admin/services/index.gohtml:11
#: web/templates/admin/home/index.gohtml:11
msgctxt "title"
msgid "Carousel"
msgstr "Carrusel"
#: web/templates/admin/services/index.gohtml:13
#: web/templates/admin/home/index.gohtml:13
#: web/templates/admin/services/index.gohtml:12
#: web/templates/admin/home/index.gohtml:12
msgctxt "action"
msgid "Add slide"
msgstr "Afegeix diapositiva"
#: web/templates/admin/services/index.gohtml:18
#: web/templates/admin/home/index.gohtml:18
#: web/templates/admin/services/index.gohtml:17
#: web/templates/admin/home/index.gohtml:17
msgctxt "header"
msgid "Image"
msgstr "Imatge"
#: web/templates/admin/services/index.gohtml:19
#: web/templates/admin/home/index.gohtml:19
#: web/templates/admin/services/index.gohtml:18
#: web/templates/admin/home/index.gohtml:18
msgctxt "header"
msgid "Caption"
msgstr "Llegenda"
#: web/templates/admin/services/index.gohtml:21
#: web/templates/admin/home/index.gohtml:21
#: web/templates/admin/services/index.gohtml:20
#: web/templates/admin/services/index.gohtml:57
#: web/templates/admin/home/index.gohtml:20
msgctxt "campsite type"
msgid "Actions"
msgstr "Accions"
#: web/templates/admin/services/index.gohtml:40
#: web/templates/admin/home/index.gohtml:40
#: web/templates/admin/services/index.gohtml:39
#: web/templates/admin/services/index.gohtml:73
#: web/templates/admin/home/index.gohtml:39
msgctxt "action"
msgid "Delete"
msgstr "Esborra"
#: web/templates/admin/services/index.gohtml:48
#: web/templates/admin/home/index.gohtml:48
#: web/templates/admin/services/index.gohtml:47
#: web/templates/admin/home/index.gohtml:47
msgid "No slides added yet."
msgstr "No sha afegit cap diapositiva encara."
#: web/templates/admin/services/index.gohtml:55
msgctxt "header"
msgid "Service"
msgstr "Servei"
#: web/templates/admin/services/index.gohtml:81
msgid "No services added yet."
msgstr "No sha afegit cap servei encara."
#: web/templates/admin/services/l10n.gohtml:7
#: web/templates/admin/services/l10n.gohtml:14
msgctxt "title"
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:29
#: web/templates/admin/layout.gohtml:30
msgctxt "title"
msgid "Profile"
msgstr "Perfil"
@ -486,110 +533,109 @@ msgid "Language"
msgstr "Idioma"
#: web/templates/admin/profile.gohtml:75
#: web/templates/admin/taxDetails.gohtml:145
#: web/templates/admin/taxDetails.gohtml:144
msgctxt "action"
msgid "Save changes"
msgstr "Desa els canvis"
#: web/templates/admin/taxDetails.gohtml:6
#: web/templates/admin/taxDetails.gohtml:13
#: web/templates/admin/layout.gohtml:67
#: web/templates/admin/taxDetails.gohtml:12
msgctxt "title"
msgid "Tax Details"
msgstr "Configuració fiscal"
#: web/templates/admin/taxDetails.gohtml:18
#: web/templates/admin/taxDetails.gohtml:59
#: web/templates/admin/taxDetails.gohtml:17
#: web/templates/admin/taxDetails.gohtml:58
msgctxt "input"
msgid "Business Name"
msgstr "Nom de lempresa"
#: web/templates/admin/taxDetails.gohtml:27
#: web/templates/admin/taxDetails.gohtml:26
msgctxt "input"
msgid "VAT Number"
msgstr "NIF"
#: web/templates/admin/taxDetails.gohtml:35
#: web/templates/admin/taxDetails.gohtml:34
msgctxt "input"
msgid "Trade Name"
msgstr "Nom comercial"
#: web/templates/admin/taxDetails.gohtml:43
#: web/templates/admin/taxDetails.gohtml:42
msgctxt "input"
msgid "Phone"
msgstr "Telèfon"
#: web/templates/admin/taxDetails.gohtml:67
#: web/templates/admin/taxDetails.gohtml:66
msgctxt "input"
msgid "Address"
msgstr "Adreça"
#: web/templates/admin/taxDetails.gohtml:75
#: web/templates/admin/taxDetails.gohtml:74
msgctxt "input"
msgid "City"
msgstr "Població"
#: web/templates/admin/taxDetails.gohtml:83
#: web/templates/admin/taxDetails.gohtml:82
msgctxt "input"
msgid "Province"
msgstr "Província"
#: web/templates/admin/taxDetails.gohtml:91
#: web/templates/admin/taxDetails.gohtml:90
msgctxt "input"
msgid "Postal Code"
msgstr "Codi postal"
#: web/templates/admin/taxDetails.gohtml:99
#: web/templates/admin/taxDetails.gohtml:98
msgctxt "input"
msgid "Country"
msgstr "País"
#: web/templates/admin/taxDetails.gohtml:109
#: web/templates/admin/taxDetails.gohtml:108
msgctxt "input"
msgid "Currency"
msgstr "Moneda"
#: web/templates/admin/taxDetails.gohtml:119
#: web/templates/admin/taxDetails.gohtml:118
msgctxt "input"
msgid "Default Language"
msgstr "Idioma per defecte"
#: web/templates/admin/taxDetails.gohtml:129
#: web/templates/admin/taxDetails.gohtml:128
msgctxt "input"
msgid "Invoice Number Format"
msgstr "Format del número de factura"
#: web/templates/admin/taxDetails.gohtml:137
#: web/templates/admin/taxDetails.gohtml:136
msgctxt "input"
msgid "Legal Disclaimer"
msgstr "Nota legal"
#: web/templates/admin/layout.gohtml:25
#: web/templates/admin/layout.gohtml:26
msgctxt "title"
msgid "User Menu"
msgstr "Menú dusuari"
#: web/templates/admin/layout.gohtml:33
#: web/templates/admin/layout.gohtml:34
msgctxt "title"
msgid "Company Settings"
msgstr "Paràmetres de lempresa"
#: web/templates/admin/layout.gohtml:38
msgctxt "action"
msgid "Logout"
msgstr "Surt"
#: web/templates/admin/layout.gohtml:46
#: 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:79 web/templates/admin/home/index.gohtml:6
#: web/templates/admin/layout.gohtml:49 web/templates/admin/home/index.gohtml:6
msgctxt "title"
msgid "Home Page"
msgstr "Pàgina dinici"
#: web/templates/admin/layout.gohtml:85
#: web/templates/admin/media/index.gohtml:6
#: web/templates/admin/media/index.gohtml:12
msgctxt "title"
msgid "Media"
msgstr "Mèdia"
#: web/templates/admin/layout.gohtml:57
msgctxt "action"
msgid "Logout"
msgstr "Surt"
#: web/templates/admin/media/picker.gohtml:8
msgctxt "title"
@ -602,19 +648,19 @@ msgid "Upload New Media"
msgstr "Pujada de nou mèdia"
#: web/templates/admin/media/picker.gohtml:22
#: web/templates/admin/media/upload.gohtml:18
#: web/templates/admin/media/upload.gohtml:17
msgctxt "input"
msgid "File"
msgstr "Fitxer"
#: web/templates/admin/media/picker.gohtml:26
#: web/templates/admin/media/form.gohtml:23
#: web/templates/admin/media/upload.gohtml:22
#: web/templates/admin/media/form.gohtml:22
#: web/templates/admin/media/upload.gohtml:21
msgid "Maximum upload file size: %s"
msgstr "Mida màxima del fitxer a pujar: %s"
#: web/templates/admin/media/picker.gohtml:31
#: web/templates/admin/media/upload.gohtml:27
#: web/templates/admin/media/upload.gohtml:26
msgctxt "action"
msgid "Upload"
msgstr "Puja"
@ -625,7 +671,7 @@ msgid "Choose Existing Media"
msgstr "Elecció dun mèdia existent"
#: web/templates/admin/media/picker.gohtml:58
#: web/templates/admin/media/index.gohtml:21
#: web/templates/admin/media/index.gohtml:20
msgid "No media uploaded yet."
msgstr "No sha pujat cap mèdia encara."
@ -635,28 +681,28 @@ msgid "Cancel"
msgstr "Canceŀla"
#: web/templates/admin/media/form.gohtml:6
#: web/templates/admin/media/form.gohtml:13
#: web/templates/admin/media/form.gohtml:12
msgctxt "title"
msgid "Edit Media"
msgstr "Edició de mèdia"
#: web/templates/admin/media/form.gohtml:19
#: web/templates/admin/media/form.gohtml:18
msgctxt "input"
msgid "Updated file"
msgstr "Fitxer actualitzat"
#: web/templates/admin/media/form.gohtml:28
#: web/templates/admin/media/form.gohtml:27
msgctxt "input"
msgid "Filename"
msgstr "Nom del fitxer"
#: web/templates/admin/media/index.gohtml:13
#: web/templates/admin/media/index.gohtml:12
msgctxt "action"
msgid "Upload media"
msgstr "Puja mèdia"
#: web/templates/admin/media/upload.gohtml:6
#: web/templates/admin/media/upload.gohtml:13
#: web/templates/admin/media/upload.gohtml:12
msgctxt "title"
msgid "Upload Media"
msgstr "Pujada de mèdia"
@ -702,6 +748,7 @@ msgstr "Automàtic"
#: pkg/app/user.go:249 pkg/campsite/types/l10n.go:82
#: pkg/campsite/types/admin.go:274 pkg/season/admin.go:203
#: pkg/services/l10n.go:73 pkg/services/admin.go:232
msgid "Name can not be empty."
msgstr "No podeu deixar el nom en blanc."
@ -755,6 +802,10 @@ msgstr "No podeu deixar el color en blanc."
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/services/admin.go:231
msgid "Selected icon is not valid."
msgstr "La icona escollida no és vàlida."
#: pkg/company/admin.go:186
msgid "Selected country is not valid."
msgstr "El país escollit no és vàlid."

319
po/es.po
View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: camper\n"
"Report-Msgid-Bugs-To: jordi@tandem.blog\n"
"POT-Creation-Date: 2023-09-24 03:04+0200\n"
"POT-Creation-Date: 2023-09-25 20:03+0200\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"
@ -20,6 +20,7 @@ msgstr ""
#: web/templates/public/services.gohtml:6
#: web/templates/public/services.gohtml:15
#: web/templates/admin/services/index.gohtml:50
msgctxt "title"
msgid "Services"
msgstr "Servicios"
@ -28,7 +29,7 @@ msgstr "Servicios"
msgid "The campsite offers many different services."
msgstr "El camping dispone de varios servicios."
#: web/templates/public/home.gohtml:6 web/templates/public/layout.gohtml:28
#: web/templates/public/home.gohtml:6 web/templates/public/layout.gohtml:29
msgctxt "title"
msgid "Home"
msgstr "Inicio"
@ -131,262 +132,274 @@ msgstr "Kayak"
msgid "There are several points where you can go by kayak, from sections of the Ter river as well as on the coast…."
msgstr "Hay diversos puntos dónde podéis ir en kayak, desde tramos del río Ter como también en la costa…."
#: web/templates/public/layout.gohtml:11 web/templates/public/layout.gohtml:23
#: web/templates/public/layout.gohtml:58
#: web/templates/public/layout.gohtml:11 web/templates/public/layout.gohtml:24
#: web/templates/public/layout.gohtml:59
msgid "Campsite Montagut"
msgstr "Camping Montagut"
#: web/templates/public/layout.gohtml:21 web/templates/admin/layout.gohtml:18
#: web/templates/public/layout.gohtml:22 web/templates/admin/layout.gohtml:19
msgid "Skip to main content"
msgstr "Saltar al contenido principal"
#: web/templates/public/layout.gohtml:32
#: web/templates/public/layout.gohtml:33
msgid "Singular Lodges"
msgstr "Alojamientos singulares"
#: web/templates/admin/carousel/form.gohtml:8
#: web/templates/admin/carousel/form.gohtml:26
#: web/templates/admin/carousel/form.gohtml:25
msgctxt "title"
msgid "Edit Carousel Slide"
msgstr "Edición de la diapositiva del carrusel"
#: web/templates/admin/carousel/form.gohtml:10
#: web/templates/admin/carousel/form.gohtml:28
#: web/templates/admin/carousel/form.gohtml:27
msgctxt "title"
msgid "New Carousel Slide"
msgstr "Nueva diapositiva del carrusel"
#: web/templates/admin/carousel/form.gohtml:38
#: web/templates/admin/carousel/l10n.gohtml:21
#: web/templates/admin/carousel/form.gohtml:37
#: web/templates/admin/carousel/l10n.gohtml:20
msgctxt "input"
msgid "Caption"
msgstr "Leyenda"
#: web/templates/admin/carousel/form.gohtml:48
#: web/templates/admin/campsite/form.gohtml:71
#: web/templates/admin/campsite/type/form.gohtml:67
#: web/templates/admin/season/form.gohtml:65
#: web/templates/admin/media/form.gohtml:36
#: web/templates/admin/carousel/form.gohtml:47
#: web/templates/admin/campsite/form.gohtml:70
#: web/templates/admin/campsite/type/form.gohtml:66
#: 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:50
#: web/templates/admin/campsite/form.gohtml:73
#: web/templates/admin/campsite/type/form.gohtml:69
#: web/templates/admin/season/form.gohtml:67
#: web/templates/admin/carousel/form.gohtml:49
#: web/templates/admin/campsite/form.gohtml:72
#: web/templates/admin/campsite/type/form.gohtml:68
#: 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:15
#: web/templates/admin/carousel/l10n.gohtml:14
msgctxt "title"
msgid "Translate Carousel Slide to %s"
msgstr "Traducción de la diapositiva de carrusel a %s"
#: web/templates/admin/carousel/l10n.gohtml:22
#: web/templates/admin/campsite/type/l10n.gohtml:22
#: web/templates/admin/campsite/type/l10n.gohtml:34
#: web/templates/admin/carousel/l10n.gohtml:21
#: web/templates/admin/campsite/type/l10n.gohtml:21
#: web/templates/admin/campsite/type/l10n.gohtml:33
#: web/templates/admin/services/l10n.gohtml:21
#: web/templates/admin/services/l10n.gohtml:33
msgid "Source:"
msgstr "Origen:"
#: web/templates/admin/carousel/l10n.gohtml:24
#: web/templates/admin/campsite/type/l10n.gohtml:24
#: web/templates/admin/campsite/type/l10n.gohtml:37
#: web/templates/admin/carousel/l10n.gohtml:23
#: web/templates/admin/campsite/type/l10n.gohtml:23
#: web/templates/admin/campsite/type/l10n.gohtml:36
#: web/templates/admin/services/l10n.gohtml:23
#: web/templates/admin/services/l10n.gohtml:36
msgctxt "input"
msgid "Translation:"
msgstr "Traducción"
#: web/templates/admin/carousel/l10n.gohtml:33
#: web/templates/admin/campsite/type/l10n.gohtml:46
#: web/templates/admin/carousel/l10n.gohtml:32
#: web/templates/admin/campsite/type/l10n.gohtml:45
#: web/templates/admin/services/l10n.gohtml:45
msgctxt "action"
msgid "Translate"
msgstr "Traducir"
#: web/templates/admin/campsite/form.gohtml:8
#: web/templates/admin/campsite/form.gohtml:26
#: web/templates/admin/campsite/form.gohtml:25
msgctxt "title"
msgid "Edit Campsite"
msgstr "Edición del alojamientos"
#: web/templates/admin/campsite/form.gohtml:10
#: web/templates/admin/campsite/form.gohtml:28
#: web/templates/admin/campsite/form.gohtml:27
msgctxt "title"
msgid "New Campsite"
msgstr "Nuevo alojamiento"
#: web/templates/admin/campsite/form.gohtml:38
#: web/templates/admin/campsite/index.gohtml:21
#: web/templates/admin/campsite/form.gohtml:37
#: web/templates/admin/campsite/index.gohtml:20
msgctxt "campsite"
msgid "Active"
msgstr "Activo"
#: web/templates/admin/campsite/form.gohtml:47
#: web/templates/admin/campsite/form.gohtml:46
msgctxt "input"
msgid "Campsite Type"
msgstr "Tipo de alojamiento"
#: web/templates/admin/campsite/form.gohtml:52
#: web/templates/admin/campsite/form.gohtml:51
msgid "Select campsite type"
msgstr "Escoged un tipo de alojamiento"
#: web/templates/admin/campsite/form.gohtml:61
#: web/templates/admin/campsite/form.gohtml:60
msgctxt "input"
msgid "Label"
msgstr "Etiqueta"
#: web/templates/admin/campsite/index.gohtml:6
#: web/templates/admin/campsite/index.gohtml:13
#: web/templates/admin/layout.gohtml:52 web/templates/admin/layout.gohtml:73
#: web/templates/admin/campsite/index.gohtml:12
#: web/templates/admin/layout.gohtml:40 web/templates/admin/layout.gohtml:71
msgctxt "title"
msgid "Campsites"
msgstr "Alojamientos"
#: web/templates/admin/campsite/index.gohtml:12
#: web/templates/admin/campsite/index.gohtml:11
msgctxt "action"
msgid "Add Campsite"
msgstr "Añadir alojamiento"
#: web/templates/admin/campsite/index.gohtml:19
#: web/templates/admin/campsite/index.gohtml:18
msgctxt "header"
msgid "Label"
msgstr "Etiqueta"
#: web/templates/admin/campsite/index.gohtml:20
#: web/templates/admin/campsite/index.gohtml:19
msgctxt "header"
msgid "Type"
msgstr "Tipo"
#: web/templates/admin/campsite/index.gohtml:29
#: web/templates/admin/campsite/type/index.gohtml:36
#: web/templates/admin/season/index.gohtml:32
#: web/templates/admin/campsite/index.gohtml:28
#: web/templates/admin/campsite/type/index.gohtml:35
#: web/templates/admin/season/index.gohtml:31
msgid "Yes"
msgstr "Sí"
#: web/templates/admin/campsite/index.gohtml:29
#: web/templates/admin/campsite/type/index.gohtml:36
#: web/templates/admin/season/index.gohtml:32
#: web/templates/admin/campsite/index.gohtml:28
#: web/templates/admin/campsite/type/index.gohtml:35
#: web/templates/admin/season/index.gohtml:31
msgid "No"
msgstr "No"
#: web/templates/admin/campsite/index.gohtml:35
#: web/templates/admin/campsite/index.gohtml:34
msgid "No campsites added yet."
msgstr "No se ha añadido ningún alojamiento todavía."
#: web/templates/admin/campsite/type/form.gohtml:8
#: web/templates/admin/campsite/type/form.gohtml:26
#: web/templates/admin/campsite/type/form.gohtml:25
msgctxt "title"
msgid "Edit Campsite Type"
msgstr "Edición del tipo de alojamientos"
#: web/templates/admin/campsite/type/form.gohtml:10
#: web/templates/admin/campsite/type/form.gohtml:28
#: web/templates/admin/campsite/type/form.gohtml:27
msgctxt "title"
msgid "New Campsite Type"
msgstr "Nuevo tipo de alojamiento"
#: web/templates/admin/campsite/type/form.gohtml:38
#: web/templates/admin/campsite/type/index.gohtml:20
#: web/templates/admin/campsite/type/form.gohtml:37
#: web/templates/admin/campsite/type/index.gohtml:19
msgctxt "campsite type"
msgid "Active"
msgstr "Activo"
#: web/templates/admin/campsite/type/form.gohtml:47
#: web/templates/admin/campsite/type/l10n.gohtml:21
#: web/templates/admin/season/form.gohtml:47
#: 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/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/type/form.gohtml:58
#: web/templates/admin/campsite/type/l10n.gohtml:33
#: web/templates/admin/campsite/type/form.gohtml:57
#: web/templates/admin/campsite/type/l10n.gohtml:32
#: web/templates/admin/services/form.gohtml:60
#: web/templates/admin/services/l10n.gohtml:32
msgctxt "input"
msgid "Description"
msgstr "Descripción"
#: web/templates/admin/campsite/type/index.gohtml:6
#: web/templates/admin/campsite/type/index.gohtml:13
#: web/templates/admin/layout.gohtml:70
#: web/templates/admin/campsite/type/index.gohtml:12
#: web/templates/admin/layout.gohtml:37
msgctxt "title"
msgid "Campsite Types"
msgstr "Tipos de alojamientos"
#: web/templates/admin/campsite/type/index.gohtml:12
#: web/templates/admin/campsite/type/index.gohtml:11
msgctxt "action"
msgid "Add Type"
msgstr "Añadir tipo"
#: web/templates/admin/campsite/type/index.gohtml:18
#: web/templates/admin/season/index.gohtml:18
#: web/templates/admin/campsite/type/index.gohtml:17
#: web/templates/admin/season/index.gohtml:17
msgctxt "header"
msgid "Name"
msgstr "Nombre"
#: web/templates/admin/campsite/type/index.gohtml:19
#: web/templates/admin/services/index.gohtml:20
#: web/templates/admin/home/index.gohtml:20
#: web/templates/admin/campsite/type/index.gohtml:18
#: web/templates/admin/services/index.gohtml:19
#: web/templates/admin/services/index.gohtml:56
#: web/templates/admin/home/index.gohtml:19
msgctxt "campsite type"
msgid "Translations"
msgstr "Traducciones"
#: web/templates/admin/campsite/type/index.gohtml:42
#: web/templates/admin/campsite/type/index.gohtml:41
msgid "No campsite types added yet."
msgstr "No se ha añadido ningún tipo de alojamiento todavía."
#: web/templates/admin/campsite/type/l10n.gohtml:7
#: web/templates/admin/campsite/type/l10n.gohtml:15
#: web/templates/admin/campsite/type/l10n.gohtml:14
msgctxt "title"
msgid "Translate Campsite Type to %s"
msgstr "Traducción de tipo de alojamiento a %s"
#: web/templates/admin/season/form.gohtml:8
#: web/templates/admin/season/form.gohtml:26
#: web/templates/admin/season/form.gohtml:25
msgctxt "title"
msgid "Edit Season"
msgstr "Edición de temporada"
#: web/templates/admin/season/form.gohtml:10
#: web/templates/admin/season/form.gohtml:28
#: web/templates/admin/season/form.gohtml:27
msgctxt "title"
msgid "New Season"
msgstr "Nueva temporada"
#: web/templates/admin/season/form.gohtml:38
#: web/templates/admin/season/index.gohtml:20
#: web/templates/admin/season/form.gohtml:37
#: web/templates/admin/season/index.gohtml:19
msgctxt "season"
msgid "Active"
msgstr "Activa"
#: web/templates/admin/season/form.gohtml:55
#: web/templates/admin/season/form.gohtml:54
msgctxt "input"
msgid "Color"
msgstr "Color"
#: web/templates/admin/season/index.gohtml:6
#: web/templates/admin/season/index.gohtml:13
#: web/templates/admin/layout.gohtml:76
#: web/templates/admin/season/index.gohtml:12
#: web/templates/admin/layout.gohtml:43
msgctxt "title"
msgid "Seasons"
msgstr "Temporadas"
#: web/templates/admin/season/index.gohtml:12
#: web/templates/admin/season/index.gohtml:11
msgctxt "action"
msgid "Add Season"
msgstr "Añadir temporada"
#: web/templates/admin/season/index.gohtml:19
#: web/templates/admin/season/index.gohtml:18
msgctxt "header"
msgid "Color"
msgstr "Color"
#: web/templates/admin/season/index.gohtml:38
#: web/templates/admin/season/index.gohtml:37
msgid "No seasons added yet."
msgstr "No se ha añadido ninguna temporada todavía."
#: web/templates/admin/dashboard.gohtml:6
#: web/templates/admin/dashboard.gohtml:10 web/templates/admin/layout.gohtml:49
#: web/templates/admin/dashboard.gohtml:10 web/templates/admin/layout.gohtml:68
msgctxt "title"
msgid "Dashboard"
msgstr "Panel"
@ -397,7 +410,7 @@ msgid "Login"
msgstr "Entrada"
#: web/templates/admin/login.gohtml:22 web/templates/admin/profile.gohtml:35
#: web/templates/admin/taxDetails.gohtml:51
#: web/templates/admin/taxDetails.gohtml:50
msgctxt "input"
msgid "Email"
msgstr "Correo-e"
@ -412,55 +425,89 @@ msgctxt "action"
msgid "Login"
msgstr "Entrar"
#: web/templates/admin/services/form.gohtml:8
#: web/templates/admin/services/form.gohtml:25
msgctxt "title"
msgid "Edit Service"
msgstr "Edición de servicio"
#: web/templates/admin/services/form.gohtml:10
#: web/templates/admin/services/form.gohtml:27
msgctxt "title"
msgid "New Service"
msgstr "Nuevo servicio"
#: web/templates/admin/services/form.gohtml:34
msgctxt "input"
msgid "Icon"
msgstr "Icono"
#: web/templates/admin/services/index.gohtml:6
#: web/templates/admin/layout.gohtml:82
#: web/templates/admin/layout.gohtml:52
msgctxt "title"
msgid "Services Page"
msgstr "Página de servicios"
#: web/templates/admin/services/index.gohtml:12
#: web/templates/admin/home/index.gohtml:12
#: web/templates/admin/services/index.gohtml:11
#: web/templates/admin/home/index.gohtml:11
msgctxt "title"
msgid "Carousel"
msgstr "Carrusel"
#: web/templates/admin/services/index.gohtml:13
#: web/templates/admin/home/index.gohtml:13
#: web/templates/admin/services/index.gohtml:12
#: web/templates/admin/home/index.gohtml:12
msgctxt "action"
msgid "Add slide"
msgstr "Añadir diapositiva"
#: web/templates/admin/services/index.gohtml:18
#: web/templates/admin/home/index.gohtml:18
#: web/templates/admin/services/index.gohtml:17
#: web/templates/admin/home/index.gohtml:17
msgctxt "header"
msgid "Image"
msgstr "Imagen"
#: web/templates/admin/services/index.gohtml:19
#: web/templates/admin/home/index.gohtml:19
#: web/templates/admin/services/index.gohtml:18
#: web/templates/admin/home/index.gohtml:18
msgctxt "header"
msgid "Caption"
msgstr "Leyenda"
#: web/templates/admin/services/index.gohtml:21
#: web/templates/admin/home/index.gohtml:21
#: web/templates/admin/services/index.gohtml:20
#: web/templates/admin/services/index.gohtml:57
#: web/templates/admin/home/index.gohtml:20
msgctxt "campsite type"
msgid "Actions"
msgstr "Acciones"
#: web/templates/admin/services/index.gohtml:40
#: web/templates/admin/home/index.gohtml:40
#: web/templates/admin/services/index.gohtml:39
#: web/templates/admin/services/index.gohtml:73
#: web/templates/admin/home/index.gohtml:39
msgctxt "action"
msgid "Delete"
msgstr "Borrar"
#: web/templates/admin/services/index.gohtml:48
#: web/templates/admin/home/index.gohtml:48
#: web/templates/admin/services/index.gohtml:47
#: web/templates/admin/home/index.gohtml:47
msgid "No slides added yet."
msgstr "No se ha añadido ninguna diapositiva todavía."
#: web/templates/admin/services/index.gohtml:55
msgctxt "header"
msgid "Service"
msgstr "Servicio"
#: web/templates/admin/services/index.gohtml:81
msgid "No services added yet."
msgstr "No se ha añadido ningún servicio todavía."
#: web/templates/admin/services/l10n.gohtml:7
#: web/templates/admin/services/l10n.gohtml:14
msgctxt "title"
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:29
#: web/templates/admin/layout.gohtml:30
msgctxt "title"
msgid "Profile"
msgstr "Perfil"
@ -486,110 +533,109 @@ msgid "Language"
msgstr "Idioma"
#: web/templates/admin/profile.gohtml:75
#: web/templates/admin/taxDetails.gohtml:145
#: web/templates/admin/taxDetails.gohtml:144
msgctxt "action"
msgid "Save changes"
msgstr "Guardar los cambios"
#: web/templates/admin/taxDetails.gohtml:6
#: web/templates/admin/taxDetails.gohtml:13
#: web/templates/admin/layout.gohtml:67
#: web/templates/admin/taxDetails.gohtml:12
msgctxt "title"
msgid "Tax Details"
msgstr "Configuración fiscal"
#: web/templates/admin/taxDetails.gohtml:18
#: web/templates/admin/taxDetails.gohtml:59
#: web/templates/admin/taxDetails.gohtml:17
#: web/templates/admin/taxDetails.gohtml:58
msgctxt "input"
msgid "Business Name"
msgstr "Nombre de empresa"
#: web/templates/admin/taxDetails.gohtml:27
#: web/templates/admin/taxDetails.gohtml:26
msgctxt "input"
msgid "VAT Number"
msgstr "NIF"
#: web/templates/admin/taxDetails.gohtml:35
#: web/templates/admin/taxDetails.gohtml:34
msgctxt "input"
msgid "Trade Name"
msgstr "Nombre comercial"
#: web/templates/admin/taxDetails.gohtml:43
#: web/templates/admin/taxDetails.gohtml:42
msgctxt "input"
msgid "Phone"
msgstr "Teléfono"
#: web/templates/admin/taxDetails.gohtml:67
#: web/templates/admin/taxDetails.gohtml:66
msgctxt "input"
msgid "Address"
msgstr "Dirección"
#: web/templates/admin/taxDetails.gohtml:75
#: web/templates/admin/taxDetails.gohtml:74
msgctxt "input"
msgid "City"
msgstr "Población"
#: web/templates/admin/taxDetails.gohtml:83
#: web/templates/admin/taxDetails.gohtml:82
msgctxt "input"
msgid "Province"
msgstr "Provincia"
#: web/templates/admin/taxDetails.gohtml:91
#: web/templates/admin/taxDetails.gohtml:90
msgctxt "input"
msgid "Postal Code"
msgstr "Código postal"
#: web/templates/admin/taxDetails.gohtml:99
#: web/templates/admin/taxDetails.gohtml:98
msgctxt "input"
msgid "Country"
msgstr "País"
#: web/templates/admin/taxDetails.gohtml:109
#: web/templates/admin/taxDetails.gohtml:108
msgctxt "input"
msgid "Currency"
msgstr "Moneda"
#: web/templates/admin/taxDetails.gohtml:119
#: web/templates/admin/taxDetails.gohtml:118
msgctxt "input"
msgid "Default Language"
msgstr "Idioma por defecto"
#: web/templates/admin/taxDetails.gohtml:129
#: web/templates/admin/taxDetails.gohtml:128
msgctxt "input"
msgid "Invoice Number Format"
msgstr "Formato de número de factura"
#: web/templates/admin/taxDetails.gohtml:137
#: web/templates/admin/taxDetails.gohtml:136
msgctxt "input"
msgid "Legal Disclaimer"
msgstr "Nota legal"
#: web/templates/admin/layout.gohtml:25
#: web/templates/admin/layout.gohtml:26
msgctxt "title"
msgid "User Menu"
msgstr "Menú de usuario"
#: web/templates/admin/layout.gohtml:33
#: web/templates/admin/layout.gohtml:34
msgctxt "title"
msgid "Company Settings"
msgstr "Parámetros de la empresa"
#: web/templates/admin/layout.gohtml:38
msgctxt "action"
msgid "Logout"
msgstr "Salir"
#: web/templates/admin/layout.gohtml:46
#: 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:79 web/templates/admin/home/index.gohtml:6
#: web/templates/admin/layout.gohtml:49 web/templates/admin/home/index.gohtml:6
msgctxt "title"
msgid "Home Page"
msgstr "Página de inicio"
#: web/templates/admin/layout.gohtml:85
#: web/templates/admin/media/index.gohtml:6
#: web/templates/admin/media/index.gohtml:12
msgctxt "title"
msgid "Media"
msgstr "Medios"
#: web/templates/admin/layout.gohtml:57
msgctxt "action"
msgid "Logout"
msgstr "Salir"
#: web/templates/admin/media/picker.gohtml:8
msgctxt "title"
@ -602,19 +648,19 @@ msgid "Upload New Media"
msgstr "Subida de un nuevo medio"
#: web/templates/admin/media/picker.gohtml:22
#: web/templates/admin/media/upload.gohtml:18
#: web/templates/admin/media/upload.gohtml:17
msgctxt "input"
msgid "File"
msgstr "Archivo"
#: web/templates/admin/media/picker.gohtml:26
#: web/templates/admin/media/form.gohtml:23
#: web/templates/admin/media/upload.gohtml:22
#: web/templates/admin/media/form.gohtml:22
#: web/templates/admin/media/upload.gohtml:21
msgid "Maximum upload file size: %s"
msgstr "Tamaño máximo del archivos a subir: %s"
#: web/templates/admin/media/picker.gohtml:31
#: web/templates/admin/media/upload.gohtml:27
#: web/templates/admin/media/upload.gohtml:26
msgctxt "action"
msgid "Upload"
msgstr "Subir"
@ -625,7 +671,7 @@ msgid "Choose Existing Media"
msgstr "Elección de un medio existente"
#: web/templates/admin/media/picker.gohtml:58
#: web/templates/admin/media/index.gohtml:21
#: web/templates/admin/media/index.gohtml:20
msgid "No media uploaded yet."
msgstr "No se ha subido ningún medio todavía."
@ -635,28 +681,28 @@ msgid "Cancel"
msgstr "Cancelar"
#: web/templates/admin/media/form.gohtml:6
#: web/templates/admin/media/form.gohtml:13
#: web/templates/admin/media/form.gohtml:12
msgctxt "title"
msgid "Edit Media"
msgstr "Edición de medio"
#: web/templates/admin/media/form.gohtml:19
#: web/templates/admin/media/form.gohtml:18
msgctxt "input"
msgid "Updated file"
msgstr "Archivo actualizado"
#: web/templates/admin/media/form.gohtml:28
#: web/templates/admin/media/form.gohtml:27
msgctxt "input"
msgid "Filename"
msgstr "Nombre de archivo"
#: web/templates/admin/media/index.gohtml:13
#: web/templates/admin/media/index.gohtml:12
msgctxt "action"
msgid "Upload media"
msgstr "Subir medio"
#: web/templates/admin/media/upload.gohtml:6
#: web/templates/admin/media/upload.gohtml:13
#: web/templates/admin/media/upload.gohtml:12
msgctxt "title"
msgid "Upload Media"
msgstr "Subida de medio"
@ -702,6 +748,7 @@ msgstr "Automático"
#: pkg/app/user.go:249 pkg/campsite/types/l10n.go:82
#: pkg/campsite/types/admin.go:274 pkg/season/admin.go:203
#: pkg/services/l10n.go:73 pkg/services/admin.go:232
msgid "Name can not be empty."
msgstr "No podéis dejar el nombre en blanco."
@ -755,6 +802,10 @@ msgstr "No podéis dejar el color en blanco."
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/services/admin.go:231
msgid "Selected icon is not valid."
msgstr "El icono escogido no es válido."
#: pkg/company/admin.go:186
msgid "Selected country is not valid."
msgstr "El país escogido no es válido."

7
revert/translation.sql Normal file
View File

@ -0,0 +1,7 @@
-- Revert camper:translation from pg
begin;
drop type if exists camper.translation;
commit;

View File

@ -78,3 +78,4 @@ add_service [roles schema_camper service] 2023-09-17T00:00:00Z jordi fita mas <j
edit_service [roles schema_camper service] 2023-09-17T00:01:16Z jordi fita mas <jordi@tandem.blog> # Add function to edit services
service_i18n [roles schema_camper service language] 2023-09-17T00:13:42Z jordi fita mas <jordi@tandem.blog> # Add relation for service translations
translate_service [roles schema_camper service_i18n] 2023-09-17T00:17:00Z jordi fita mas <jordi@tandem.blog> # Add function to translate a service
translation [schema_camper] 2023-09-25T16:27:50Z jordi fita mas <jordi@tandem.blog> # Add the type for a translation

22
test/translation.sql Normal file
View File

@ -0,0 +1,22 @@
-- Test translation
set client_min_messages to warning;
create extension if not exists pgtap;
reset client_min_messages;
begin;
select plan(5);
set search_path to camper, public;
select has_composite('camper', 'translation', 'Composite type camper.translation should exist');
select columns_are('camper', 'translation', array['lang_tag', 'endonym', 'missing']);
select col_type_is('camper'::name, 'translation'::name, 'lang_tag'::name, 'text');
select col_type_is('camper'::name, 'translation'::name, 'endonym'::name, 'text');
select col_type_is('camper'::name, 'translation'::name, 'missing'::name, 'boolean');
select *
from finish();
rollback;

7
verify/translation.sql Normal file
View File

@ -0,0 +1,7 @@
-- Verify camper:translation on pg
begin;
select pg_catalog.has_type_privilege('camper.translation', 'usage');
rollback;

View File

@ -97,3 +97,29 @@ a.missing-translation {
#campground-map a:hover {
fill: #ffeeaa;
}
[class^="icon_"] {
background-size: 2em 2em;
background-repeat: no-repeat;
background-position: center left;
}
.services [class^="icon_"] {
padding-left: 2.5em;
}
.icon-input ul {
padding: 0;
list-style: none;
display: flex;
flex-wrap: wrap;
gap: .25em;
}
.icon-input button {
padding: 1em;
}
.icon-input button[aria-pressed="true"] {
background-color: #ffeeaa;
}

View File

@ -152,6 +152,29 @@ export function setupCampgroundMap(map) {
}
}
export function setupIconInput(icon) {
if (!icon) {
return;
}
const input = icon.querySelector('input[type="hidden"]')
if (!input) {
return;
}
const buttons = Array.from(icon.querySelectorAll('button[data-icon-name]'));
const updateValue = function (iconName) {
input.value = iconName;
for (const button of buttons) {
button.setAttribute('aria-pressed', button.dataset.iconName === iconName);
}
}
for (const button of buttons) {
button.addEventListener('click', function (e) {
updateValue(e.target.dataset.iconName);
})
}
updateValue(input.value);
}
htmx.onLoad((target) => {
if (target.tagName === 'DIALOG') {
target.showModal();

85
web/static/icons.css Normal file
View File

@ -0,0 +1,85 @@
/**
* SPDX-FileCopyrightText: 2023 jordi fita mas <jordi@tandem.blog>
* SPDX-License-Identifier: AGPL-3.0-only
*/
.icon_baby {
background-image: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="%23000000" height="32" width="32"%3E%3Cpath d="M92,136a8,8,0,1,1,8-8A8,8,0,0,1,92,136Zm72-16a8,8,0,1,0,8,8A8,8,0,0,0,164,120Zm-10.13,44.62a49,49,0,0,1-51.74,0,4,4,0,0,0-4.26,6.76,57,57,0,0,0,60.26,0,4,4,0,1,0-4.26-6.76ZM228,128A100,100,0,1,1,128,28,100.11,100.11,0,0,1,228,128Zm-8,0a92.11,92.11,0,0,0-90.06-92C116.26,54.07,116,71.83,116,72a12,12,0,0,0,24,0,4,4,0,0,1,8,0,20,20,0,0,1-40,0c0-.78.16-17.31,12-35.64A92,92,0,1,0,220,128Z"/%3E%3C/svg%3E');
}
.icon_ball {
background-image: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="%23000000" height="32" width="32"%3E%3Cpath d="M128,28A100,100,0,1,0,228,128,100.11,100.11,0,0,0,128,28Zm85,135.19a92,92,0,0,1-102.18,2.57L130.31,132h89.6A91.61,91.61,0,0,1,213,163.19ZM85.52,46.42A91.11,91.11,0,0,1,116,36.79,92,92,0,0,1,169.29,124h-39ZM219.91,124H177.29a100.06,100.06,0,0,0-46-87.93A92.11,92.11,0,0,1,219.91,124ZM78.59,50.42l21.3,36.89a100.09,100.09,0,0,0-53.16,83.77A91.92,91.92,0,0,1,78.59,50.42ZM55,183.94a92,92,0,0,1,48.87-89.7L123.38,128,78.59,205.58A92.75,92.75,0,0,1,55,183.94ZM128,220a91.37,91.37,0,0,1-42.48-10.42l21.3-36.89a100.07,100.07,0,0,0,99.1,4.16A92,92,0,0,1,128,220Z"/%3E%3C/svg%3E');
}
.icon_bicycle {
background-image: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="%23000000" height="32" width="32"%3E%3Cpath d="M208,116a43.66,43.66,0,0,0-18.62,4.15L159,68h33a12,12,0,0,1,12,12,4,4,0,0,0,8,0,20,20,0,0,0-20-20H152a4,4,0,0,0-3.46,6L163.7,92H97L79.46,62A4,4,0,0,0,76,60H48a4,4,0,0,0,0,8H73.7L89.89,95.76,70.57,122.25A44.21,44.21,0,1,0,77,127L94.29,103.3,128.54,162a4,4,0,0,0,3.46,2,4.11,4.11,0,0,0,2-.54,4,4,0,0,0,1.44-5.48l-33.83-58h66.74l14.11,24.19A44,44,0,1,0,208,116ZM84,160a36,36,0,1,1-18.16-31.25L44.77,157.64a4,4,0,0,0,6.46,4.72l21.07-28.9A35.92,35.92,0,0,1,84,160Zm124,36a36,36,0,0,1-21.47-64.88l18,30.9a4,4,0,0,0,3.46,2,4.11,4.11,0,0,0,2-.54,4,4,0,0,0,1.44-5.48l-18-30.89A36,36,0,1,1,208,196Z"/%3E%3C/svg%3E');
}
.icon_campfire {
background-image: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="%23000000" height="32" width="32"%3E%3Cpath d="M219.81,225.21A4,4,0,0,1,216,228a3.92,3.92,0,0,1-1.21-.19L128,200.2,41.21,227.81A3.92,3.92,0,0,1,40,228a4,4,0,0,1-1.21-7.81l76-24.19-76-24.19a4,4,0,1,1,2.42-7.62L128,191.8l86.79-27.61a4,4,0,1,1,2.42,7.62l-76,24.19,76,24.19A4,4,0,0,1,219.81,225.21ZM72,108c0-19,9.38-38.85,27.12-57.27A152,152,0,0,1,125.9,28.59a4,4,0,0,1,4.2,0,152,152,0,0,1,26.78,22.14C174.62,69.15,184,89,184,108a56,56,0,0,1-54.56,56c-.48,0-1,0-1.44,0s-1,0-1.44,0A56,56,0,0,1,72,108Zm56,48a20,20,0,0,0,20-20c0-17.39-14.37-30.53-20-35-5.63,4.48-20,17.62-20,35A20,20,0,0,0,128,156ZM80,108a48,48,0,0,0,23.28,41.13A27.83,27.83,0,0,1,100,136c0-25.84,24.73-42.63,25.78-43.33a4,4,0,0,1,4.44,0c1.05.7,25.78,17.49,25.78,43.33a27.83,27.83,0,0,1-3.28,13.13A48,48,0,0,0,176,108c0-36.37-38.49-64.76-48-71.21C118.5,43.25,80,71.68,80,108Z"/%3E%3C/svg%3E');
}
.icon_castle {
background-image: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="%23000000" height="32" width="32"%3E%3Cpath d="M200,28H184a12,12,0,0,0-12,12V56a4,4,0,0,1-4,4H152a4,4,0,0,1-4-4V40a12,12,0,0,0-12-12H120a12,12,0,0,0-12,12V56a4,4,0,0,1-4,4H88a4,4,0,0,1-4-4V40A12,12,0,0,0,72,28H56A12,12,0,0,0,44,40V84.69a11.93,11.93,0,0,0,3.51,8.48l11.32,11.32A4,4,0,0,1,60,107.31V216a12,12,0,0,0,12,12H184a12,12,0,0,0,12-12V107.31a4,4,0,0,1,1.17-2.82l11.32-11.32A11.93,11.93,0,0,0,212,84.69V40A12,12,0,0,0,200,28ZM148,220H108V152a20,20,0,0,1,40,0ZM204,84.69a4,4,0,0,1-1.17,2.82L191.51,98.83a11.93,11.93,0,0,0-3.51,8.48V216a4,4,0,0,1-4,4H156V152a28,28,0,0,0-56,0v68H72a4,4,0,0,1-4-4V107.31a11.93,11.93,0,0,0-3.51-8.48L53.17,87.51A4,4,0,0,1,52,84.69V40a4,4,0,0,1,4-4H72a4,4,0,0,1,4,4V56A12,12,0,0,0,88,68h16a12,12,0,0,0,12-12V40a4,4,0,0,1,4-4h16a4,4,0,0,1,4,4V56a12,12,0,0,0,12,12h16a12,12,0,0,0,12-12V40a4,4,0,0,1,4-4h16a4,4,0,0,1,4,4Z"/%3E%3C/svg%3E');
}
.icon_fridge {
background-image: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 17.57617 28.04395"%3E%3Cpath stroke-width="0" d="m15.62988,0H1.94629C.87305,0,0,.87305,0,1.94629v25.59766c0,.27637.22363.5.5.5h16.57617c.27637,0,.5-.22363.5-.5V1.94629c0-1.07324-.87305-1.94629-1.94629-1.94629ZM1.94629,1h13.68359c.52148,0,.94629.42432.94629.94629v7.41357H1V1.94629c0-.52197.42432-.94629.94629-.94629Zm-.94629,26.04395V10.35986h15.57617v16.68408H1Z"/%3E%3Cpath stroke-width="0" d="m3.64453,5.36426h2.04248c.27637,0,.5-.22363.5-.5s-.22363-.5-.5-.5h-2.04248c-.27637,0-.5.22363-.5.5s.22363.5.5.5Z"/%3E%3Cpath stroke-width="0" d="m5.68701,13.271h-2.04248c-.27637,0-.5.22363-.5.5s.22363.5.5.5h2.04248c.27637,0,.5-.22363.5-.5s-.22363-.5-.5-.5Z"/%3E%3C/svg%3E');
}
.icon_information {
background-image: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="%23000000" height="32" width="32"%3E%3Cpath d="M140,176a4,4,0,0,1-4,4,12,12,0,0,1-12-12V128a4,4,0,0,0-4-4,4,4,0,0,1,0-8,12,12,0,0,1,12,12v40a4,4,0,0,0,4,4A4,4,0,0,1,140,176ZM124,92a8,8,0,1,0-8-8A8,8,0,0,0,124,92Zm104,36A100,100,0,1,1,128,28,100.11,100.11,0,0,1,228,128Zm-8,0a92,92,0,1,0-92,92A92.1,92.1,0,0,0,220,128Z"/%3E%3C/svg%3E');
}
.icon_kayak {
background-image: url('data:image/svg+xml,%3Csvg viewBox="0 0 29.52905 28.08545" xmlns="http://www.w3.org/2000/svg" id="uuid-87ec619a-4896-40b8-8478-aa076dee3f7c"%3E%3Cpath stroke-width="0" d="m29.46728,11.26074l-.57617-2.15186c-.08398-.31299-.24609-.59229-.45801-.78613-.26758-.24658-.59863-.3418-.90625-.25879l-3.4834.93213c-.26953.07227-.48535.26807-.6084.54932l-.5752,1.30713c-.0719.16376-.10333.34686-.10742.53485l-3.05627.81787c-.23956-3.37067-1.03204-8.79126-2.35193-10.66425l-.22363-.31836C16.58057.45752,15.69971.00049,14.76318,0h-.00049c-.94873,0-1.80566.44434-2.35156,1.21875-1.71973,2.44043-2.65771,9.75146-2.65771,12.82422,0,.24457.00812.52399.0199.81769l-3.25604.87134c-.09741-.16071-.21613-.30347-.36005-.40924l-1.15088-.84424c-.24854-.18213-.53125-.24463-.80127-.17236l-3.48389.93164c-.56689.15234-.85693.84961-.65918,1.58691l.57617,2.15137c.0835.31348.24561.59277.45654.78613.20508.18848.4458.28809.68506.28809.07471,0,.14893-.00879.22168-.02832l3.48486-.93359c.26807-.07227.48389-.26758.60693-.54883l.57568-1.30664c.07172-.16357.10309-.3465.10718-.5343l3.05591-.81793c.25531,3.52673,1.14368,8.94983,2.5791,10.98602.5459.77441,1.40332,1.21875,2.35205,1.21875.93652,0,1.81738-.45703,2.35645-1.22266l.22461-.31738c1.60352-2.27637,2.43066-9.79492,2.43066-12.50244,0-.23499-.00854-.51709-.021-.81805l3.25732-.87183c.09747.16071.21625.30347.36035.40912l1.15039.84473c.18066.13281.38086.20166.5791.20166.07422,0,.14941-.00977.22168-.0293l3.48535-.93262c.56641-.15234.85645-.84863.65918-1.58594Zm-24.24072,6.86182l-3.41602.93262c-.03516-.01465-.14844-.12109-.20654-.33691l-.57617-2.15137c-.05713-.21484-.01318-.3623-.04688-.3623h-.00098l3.4165-.93164s.00586.00293.01709.01074c.00049,0,.00098.00098.00098.00098l1.00842.74017-1.90881.5108c-.2666.07227-.4248.3457-.35352.6123.05957.22363.26172.37109.48242.37109.04297,0,.08643-.00586.12988-.0166l1.91559-.5127-.46198,1.13281Zm5.52686-4.07959c0-3.07959.93994-10.06934,2.4751-12.24805.35596-.50488.91504-.79492,1.53418-.79492.62109.00049,1.18213.2915,1.54053.79932l.22266.31689c1.17902,1.67261,1.96533,7.08936,2.18457,10.35278l-1.50305.40228c-.19397-2.55505-1.02423-4.83514-2.44324-4.83514-1.63379,0-2.48828,3.02197-2.48828,6.00684,0,.04913.00214.09814.00262.14728l-1.51538.40552c-.00574-.19403-.0097-.38147-.0097-.5528Zm2.52692-.12079c.02441-2.93951.89984-4.88605,1.48383-4.88605.53003,0,1.29828,1.6062,1.45496,4.09961l-2.93878.78644Zm2.96765.24115c-.02441,2.93933-.89978,4.88599-1.48383,4.88599-.53003,0-1.29834-1.60632-1.45496-4.09937l2.93878-.78662Zm2.52692-.12036c0,2.66846-.84961,9.94092-2.24902,11.92725l-.22363.31641c-.71387,1.01367-2.36084,1.01562-3.07373.00391-1.31152-1.86127-2.18622-7.22681-2.414-10.67285l1.50641-.4032c.19397,2.55505,1.02417,4.83484,2.44324,4.83484,1.63379,0,2.48828-3.02148,2.48828-6.00635,0-.04926-.00214-.09845-.00262-.14777l1.51514-.40558c.00659.20087.00995.38617.00995.55334Zm6.35742-1.23047s-.00684-.00293-.01855-.01123l-1.00897-.74091,1.90936-.51105c.26758-.07129.42578-.34521.35449-.6123-.07227-.26562-.3418-.42725-.6123-.35352l-1.91577.5127.46069-1.13379,3.41699-.93164c.03516.01416.14844.12012.20605.33691l.57617,2.15186c.05957.21973.01953.36816.04883.36133l-3.41699.93164Z"/%3E%3C/svg%3E');
}
.icon_outing {
background-image: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="%23000000" height="32" width="32"%3E%3Cpath d="M164,44.17V32a20,20,0,0,0-20-20H112A20,20,0,0,0,92,32V44.17A52.05,52.05,0,0,0,44,96V216a12,12,0,0,0,12,12H200a12,12,0,0,0,12-12V96A52.05,52.05,0,0,0,164,44.17ZM112,20h32a12,12,0,0,1,12,12V44H100V32A12,12,0,0,1,112,20Zm60,144H84V152a12,12,0,0,1,12-12h64a12,12,0,0,1,12,12Zm-88,8h56v12a4,4,0,0,0,8,0V172h24v48H84Zm120,44a4,4,0,0,1-4,4H180V152a20,20,0,0,0-20-20H96a20,20,0,0,0-20,20v68H56a4,4,0,0,1-4-4V96A44.05,44.05,0,0,1,96,52h64a44.05,44.05,0,0,1,44,44ZM148,88a4,4,0,0,1-4,4H112a4,4,0,0,1,0-8h32A4,4,0,0,1,148,88Z"/%3E%3C/svg%3E');
}
.icon_pool {
background-image: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="%23000000" height="32" width="32"%3E%3Cpath d="M88,145.39a4,4,0,0,0,4-4V124h72v19.29a4,4,0,0,0,8,0V32a4,4,0,0,0-8,0V52H92V32a4,4,0,0,0-8,0V141.39A4,4,0,0,0,88,145.39ZM92,116V92h72v24Zm72-56V84H92V60ZM28,168a4,4,0,0,1,4-4c13.21,0,20.12,4.61,26.22,8.67,5.9,3.93,11,7.33,21.78,7.33s15.88-3.4,21.78-7.33c6.09-4.06,13-8.67,26.21-8.67s20.13,4.61,26.22,8.67c5.9,3.93,11,7.33,21.79,7.33s15.88-3.4,21.78-7.33c6.1-4.06,13-8.67,26.22-8.67a4,4,0,0,1,0,8c-10.79,0-15.88,3.4-21.78,7.33-6.1,4.06-13,8.67-26.22,8.67s-20.13-4.61-26.22-8.67c-5.9-3.93-11-7.33-21.79-7.33s-15.88,3.4-21.78,7.33c-6.09,4.06-13,8.67-26.21,8.67s-20.12-4.61-26.22-8.67C47.88,175.4,42.79,172,32,172A4,4,0,0,1,28,168Zm200,40a4,4,0,0,1-4,4c-10.79,0-15.88,3.4-21.78,7.33-6.1,4.06-13,8.67-26.22,8.67s-20.13-4.61-26.22-8.67c-5.9-3.93-11-7.33-21.79-7.33s-15.88,3.4-21.78,7.33c-6.09,4.06-13,8.67-26.21,8.67s-20.12-4.61-26.22-8.67C47.88,215.4,42.79,212,32,212a4,4,0,0,1,0-8c13.21,0,20.12,4.61,26.22,8.67,5.9,3.93,11,7.33,21.78,7.33s15.88-3.4,21.78-7.33c6.09-4.06,13-8.67,26.21-8.67s20.13,4.61,26.22,8.67c5.9,3.93,11,7.33,21.79,7.33s15.88-3.4,21.78-7.33c6.1-4.06,13-8.67,26.22-8.67A4,4,0,0,1,228,208Z"/%3E%3C/svg%3E');
}
.icon_puzzle {
background-image: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="%23000000" height="32" width="32"%3E%3Cpath d="M218.14,161.93a4,4,0,0,0-3.86-.24,24,24,0,0,1-34.23-23.25,24,24,0,0,1,34.23-20.13A4,4,0,0,0,220,114.7V72a12,12,0,0,0-12-12H167a32,32,0,1,0-62.91-10.33A32.57,32.57,0,0,0,105,60H64A12,12,0,0,0,52,72v37a32,32,0,1,0-10.33,62.91A32.28,32.28,0,0,0,52,171v37a12,12,0,0,0,12,12H208a12,12,0,0,0,12-12V165.31A4,4,0,0,0,218.14,161.93ZM212,208a4,4,0,0,1-4,4H64a4,4,0,0,1-4-4V165.31a4,4,0,0,0-1.86-3.38,4,4,0,0,0-3.85-.24,24,24,0,0,1-34.24-20.13,24,24,0,0,1,34.24-23.25A4,4,0,0,0,60,114.7V72a4,4,0,0,1,4-4h46.69a4,4,0,0,0,3.62-5.71,24,24,0,0,1,20.13-34.24,24,24,0,0,1,23.25,34.24A4,4,0,0,0,161.31,68H208a4,4,0,0,1,4,4v37a32.57,32.57,0,0,0-10.33-.94A32,32,0,1,0,212,171Z"/%3E%3C/svg%3E');
}
.icon_restaurant {
background-image: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="%23000000" height="32" width="32"%3E%3Cpath d="M76,88V40a4,4,0,0,1,8,0V88a4,4,0,0,1-8,0ZM212,40V224a4,4,0,0,1-8,0V172H152a4,4,0,0,1-4-4,264.27,264.27,0,0,1,7.11-55.94c9.47-39.22,27.21-65.41,51.31-75.74A4,4,0,0,1,212,40Zm-8,6.46C162.25,70.33,156.81,145.75,156.1,164H204Zm-88-7.12a4,4,0,0,0-7.9,1.32l8,47.66a36,36,0,0,1-72,0l8-47.66a4,4,0,0,0-7.9-1.32l-8,48A4.89,4.89,0,0,0,36,88a44.06,44.06,0,0,0,40,43.81V224a4,4,0,0,0,8,0V131.81A44.06,44.06,0,0,0,124,88a4.89,4.89,0,0,0,0-.66Z"/%3E%3C/svg%3E');
}
.icon_route {
background-image: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="%23000000" height="32" width="32"%3E%3Cpath d="M226.46,52.85a4,4,0,0,0-3.43-.73L160.47,67.76,97.79,36.42a4,4,0,0,0-2.76-.3l-64,16A4,4,0,0,0,28,56V200a4,4,0,0,0,5,3.88l62.56-15.64,62.68,31.34a4,4,0,0,0,2.76.3l64-16a4,4,0,0,0,3-3.88V56A4,4,0,0,0,226.46,52.85ZM100,46.47l56,28V209.53l-56-28ZM36,59.12l56-14V180.88l-56,14ZM220,196.88l-56,14V75.12l56-14Z"/%3E%3C/svg%3E');
}
.icon_rv {
background-image: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 29 23.832"%3E%3Cpath stroke-width="0" d="m15.6527,16.65094h-3.92455c-.68449,0-1.23939-.55489-1.23939-1.23939V6.08515c0-.68422.55467-1.2389,1.2389-1.2389h3.92406c.68476,0,1.23987.55511,1.23987,1.23987v9.32592c0,.68422-.55467,1.2389-1.2389,1.2389Zm-3.92504-10.80469c-.13139,0-.2389.1075-.2389.2389v9.32689c0,.13194.10696.2389.2389.2389h3.92406c.13248,0,.23987-.1074.23987-.23987V6.08515c0-.13194-.10696-.2389-.2389-.2389h-3.92504Z"/%3E%3Cpath stroke-width="0" d="m7.83386,11.2486H3.45423c-.68422,0-1.2389-.55467-1.2389-1.2389v-3.92455c0-.68422.55467-1.2389,1.2389-1.2389h4.38012c.68422,0,1.2389.55467,1.2389,1.2389v3.92406c0,.68449-.55489,1.23939-1.23939,1.23939ZM3.45423,5.84626c-.13194,0-.2389.10696-.2389.2389v3.92406c0,.13166.10772.23939.23939.23939h4.37914c.13166,0,.23939-.10772.23939-.23939v-3.92406c0-.13194-.10696-.2389-.2389-.2389H3.45423Z"/%3E%3Cpath stroke-width="0" d="m28.875,11.00897l-3.31604-5.19989h.18054c.72272,0,1.3103-.58594,1.3103-1.30615,0-3.03418-2.47571-4.50293-5.51849-4.50293H1.30981C.58759,0,0,.58594,0,1.30615v18.02783c0,.82843.67157,1.5,1.5,1.5h2.53625c.27747,1.91296,2.05322,3.23883,3.96619,2.9613,1.53394-.22247,2.73883-1.42737,2.9613-2.9613h7.07251c.27747,1.91296,2.05322,3.23883,3.96619,2.9613,1.53394-.22247,2.73883-1.42737,2.9613-2.9613h2.53625c.82843,0,1.5-.67157,1.5-1.5v-8c-.0014-.11981-.04572-.23511-.125-.32501Zm-1.46252-.17499h-8.41248v-4.20093c0-.44131.35776-.79907.79907-.79907h4.2334c.15027-.00006.29254.06744.38751.18378l2.99249,4.81622ZM7.5,22.83398c-1.38074,0-2.5-1.11926-2.5-2.5s1.11926-2.5,2.5-2.5,2.5,1.11932,2.5,2.5-1.11926,2.5-2.5,2.5Zm14,0c-1.38074,0-2.5-1.11926-2.5-2.5s1.11926-2.5,2.5-2.5,2.5,1.11932,2.5,2.5-1.11926,2.5-2.5,2.5Zm6.5-3.5c0,.27614-.22386.5-.5.5h-2.53625c-.27747-1.91296-2.05322-3.23877-3.96619-2.9613-1.53394.22247-2.73883,1.42737-2.9613,2.9613h-7.07251c-.27747-1.91296-2.05322-3.23877-3.96619-2.9613-1.53394.22247-2.73883,1.42737-2.9613,2.9613H1.49993c-.27613,0-.49997-.22387-.49993-.5l.00281-18.02702c.00002-.16883.13818-.30696.30701-.30696h20.2215c2.49295,0,4.51981,1.02413,4.51563,3.51052-.00028.16481-.14263.29856-.30744.29856h-6.07078c-.91711,0-1.66082.74301-1.66169,1.66012l-.00898,9.43901c0,.27637.22363.5.5.5s.5-.22363.5-.5v-4.07422h9.00195v7.5Z"/%3E%3C/svg%3E');
}
.icon_shower {
background-image: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="%23000000" height="32" width="32"%3E%3Cpath d="M60,236a8,8,0,1,1-8-8A8,8,0,0,1,60,236Zm24-40a8,8,0,1,0,8,8A8,8,0,0,0,84,196Zm-64,0a8,8,0,1,0,8,8A8,8,0,0,0,20,196Zm32-32a8,8,0,1,0,8,8A8,8,0,0,0,52,164ZM252,40a4,4,0,0,1-4,4H219.31a4,4,0,0,0-2.82,1.17L187.73,73.93,165.86,202a12,12,0,0,1-8.17,9.44A12.09,12.09,0,0,1,154,212a12,12,0,0,1-8.46-3.52l-98-98A12,12,0,0,1,54,90.14l128-21.87,28.76-28.76A11.93,11.93,0,0,1,219.31,36H248A4,4,0,0,1,252,40ZM179.11,76.89,55.37,98a4,4,0,0,0-2.19,6.78l98,98a4,4,0,0,0,6.78-2.17Z"/%3E%3C/svg%3E');
}
.icon_store {
background-image: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="%23000000" height="32" width="32"%3E%3Cpath d="M28,112a36,36,0,0,0,16,29.92V208a12,12,0,0,0,12,12H200a12,12,0,0,0,12-12V141.92A36,36,0,0,0,228,112l0-16a4.09,4.09,0,0,0-.13-1.1L213.5,44.7A12,12,0,0,0,202,36H54A12,12,0,0,0,42.5,44.7L28.15,94.9A4.09,4.09,0,0,0,28,96ZM50.19,46.9A4,4,0,0,1,54,44H202a4,4,0,0,1,3.84,2.9L218.7,92H37.3ZM100,100h56v12a28,28,0,0,1-56,0ZM36,112V100H92v12a28,28,0,0,1-56,0Zm168,96a4,4,0,0,1-4,4H56a4,4,0,0,1-4-4V145.94a36,36,0,0,0,44-17.48,36,36,0,0,0,64,0,36,36,0,0,0,44,17.48Zm-12-68a28,28,0,0,1-28-28V100h56v12A28,28,0,0,1,192,140Z"/%3E%3C/svg%3E');
}
.icon_toilet {
background-image: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="%23000000" height="32" width="32"%3E%3Cpath d="M116,64a4,4,0,0,1-4,4H96a4,4,0,0,1,0-8h16A4,4,0,0,1,116,64Zm52,130.86,3.92,27.44A12,12,0,0,1,160,236H96a12,12,0,0,1-11.88-13.7L88,194.86A92.11,92.11,0,0,1,36,112a4,4,0,0,1,4-4H60V40A12,12,0,0,1,72,28H184a12,12,0,0,1,12,12v68h20a4,4,0,0,1,4,4A92.11,92.11,0,0,1,168,194.86ZM68,108H188V40a4,4,0,0,0-4-4H72a4,4,0,0,0-4,4Zm92.34,90.13a92,92,0,0,1-64.68,0L92,223.43a4,4,0,0,0,.94,3.19A3.93,3.93,0,0,0,96,228h64a3.93,3.93,0,0,0,3-1.38,4,4,0,0,0,.94-3.19ZM211.91,116H44.09a84,84,0,0,0,167.82,0Z"/%3E%3C/svg%3E');
}
.icon_washer {
background-image: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24.57617 28.04346"%3E%3Cpath stroke-width="0" d="m22.62988,0H1.94629C.87305,0,0,.87354,0,1.94678v25.59668c0,.27637.22363.5.5.5h23.57617c.27637,0,.5-.22363.5-.5V1.94678c0-1.07324-.87305-1.94678-1.94629-1.94678ZM1.94629,1h20.68359c.52148,0,.94629.4248.94629.94678v3.74756H1V1.94678c0-.52197.42432-.94678.94629-.94678Zm-.94629,26.04346V6.69434h22.57617v20.34912H1Z"/%3E%3Cpath stroke-width="0" d="m3.92139,4.02881h.55273c.27637,0,.5-.22363.5-.5s-.22363-.5-.5-.5h-.55273c-.27637,0-.5.22363-.5.5s.22363.5.5.5Z"/%3E%3Cpath stroke-width="0" d="m6.99805,4.02881h.55322c.27637,0,.5-.22363.5-.5s-.22363-.5-.5-.5h-.55322c-.27637,0-.5.22363-.5.5s.22363.5.5.5Z"/%3E%3Cpath stroke-width="0" d="m12.28809,8.35986c-4.63818,0-8.41162,3.77344-8.41162,8.41211,0,4.6377,3.77344,8.41113,8.41162,8.41113,4.6377,0,8.41113-3.77344,8.41113-8.41113,0-4.63867-3.77344-8.41211-8.41113-8.41211Zm0,1c3.78308,0,6.9071,2.85101,7.3515,6.51611-.02045.01282-.04352.01862-.06244.03467-.01562.01367-1.58887,1.35449-3.57617,1.35645h-.00391c-1.39941,0-2.19141-.55273-3.02979-1.1377-.83887-.58496-1.70703-1.19043-3.1167-1.19043-2.3396,0-4.15607,1.26996-4.96783,1.95667-.00067-.04156-.00629-.08191-.00629-.12366,0-4.08691,3.32471-7.41211,7.41162-7.41211Zm0,14.82324c-3.62976,0-6.6524-2.62415-7.28448-6.07397.05127-.02527.10077-.05597.1424-.09985.01953-.02051,1.99365-2.07031,4.70459-2.07031,1.0957,0,1.76709.46875,2.54492,1.01074.88477.61816,1.8877,1.31738,3.60156,1.31738h.00391c1.63293-.00134,2.9729-.72321,3.68317-1.19769-.15778,3.94849-3.40955,7.11371-7.39606,7.11371Z"/%3E%3C/svg%3E');
}
.icon_wheelchair {
background-image: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="%23000000" height="32" width="32"%3E%3Cpath d="M176,76a28,28,0,1,0-28-28A28,28,0,0,0,176,76Zm0-48a20,20,0,1,1-20,20A20,20,0,0,1,176,28ZM164,168a60,60,0,1,1-60-60,4,4,0,0,1,0,8,52,52,0,1,0,52,52,4,4,0,0,1,8,0Zm39.09-34.54a4,4,0,0,1,.83,3.32l-16,80A4,4,0,0,1,184,220a3.44,3.44,0,0,1-.78-.08,4,4,0,0,1-3.14-4.7l15-75.22H128a4,4,0,0,1-3.47-6l22.08-38.42a84.05,84.05,0,0,0-96.06,7.61A4,4,0,0,1,45.45,97a92,92,0,0,1,108.73-6.15,4,4,0,0,1,1.29,5.34L134.91,132H200A4,4,0,0,1,203.09,133.46Z"/%3E%3C/svg%3E');
}
.icon_wifi {
background-image: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="%23000000" height="32" width="32"%3E%3Cpath d="M136,204a8,8,0,1,1-8-8A8,8,0,0,1,136,204ZM234.54,90.1a168,168,0,0,0-213.08,0,4,4,0,1,0,5.08,6.18,160,160,0,0,1,202.92,0,4,4,0,0,0,5.08-6.18Zm-32.06,35.81a120,120,0,0,0-149,0,4,4,0,0,0,5,6.27,112,112,0,0,1,139,0,4,4,0,0,0,5-6.27Zm-32.13,35.86a72,72,0,0,0-84.7,0,4,4,0,1,0,4.7,6.46,64.07,64.07,0,0,1,75.3,0,4,4,0,0,0,5.58-.87A4,4,0,0,0,170.35,161.77Z"/%3E%3C/svg%3E');
}

View File

@ -559,86 +559,6 @@ dt {
}
}
.icon_baby {
background-image: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="%23000000" height="32" width="32"%3E%3Cpath d="M92,136a8,8,0,1,1,8-8A8,8,0,0,1,92,136Zm72-16a8,8,0,1,0,8,8A8,8,0,0,0,164,120Zm-10.13,44.62a49,49,0,0,1-51.74,0,4,4,0,0,0-4.26,6.76,57,57,0,0,0,60.26,0,4,4,0,1,0-4.26-6.76ZM228,128A100,100,0,1,1,128,28,100.11,100.11,0,0,1,228,128Zm-8,0a92.11,92.11,0,0,0-90.06-92C116.26,54.07,116,71.83,116,72a12,12,0,0,0,24,0,4,4,0,0,1,8,0,20,20,0,0,1-40,0c0-.78.16-17.31,12-35.64A92,92,0,1,0,220,128Z"/%3E%3C/svg%3E');
}
.icon_ball {
background-image: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="%23000000" height="32" width="32"%3E%3Cpath d="M128,28A100,100,0,1,0,228,128,100.11,100.11,0,0,0,128,28Zm85,135.19a92,92,0,0,1-102.18,2.57L130.31,132h89.6A91.61,91.61,0,0,1,213,163.19ZM85.52,46.42A91.11,91.11,0,0,1,116,36.79,92,92,0,0,1,169.29,124h-39ZM219.91,124H177.29a100.06,100.06,0,0,0-46-87.93A92.11,92.11,0,0,1,219.91,124ZM78.59,50.42l21.3,36.89a100.09,100.09,0,0,0-53.16,83.77A91.92,91.92,0,0,1,78.59,50.42ZM55,183.94a92,92,0,0,1,48.87-89.7L123.38,128,78.59,205.58A92.75,92.75,0,0,1,55,183.94ZM128,220a91.37,91.37,0,0,1-42.48-10.42l21.3-36.89a100.07,100.07,0,0,0,99.1,4.16A92,92,0,0,1,128,220Z"/%3E%3C/svg%3E');
}
.icon_bicycle {
background-image: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="%23000000" height="32" width="32"%3E%3Cpath d="M208,116a43.66,43.66,0,0,0-18.62,4.15L159,68h33a12,12,0,0,1,12,12,4,4,0,0,0,8,0,20,20,0,0,0-20-20H152a4,4,0,0,0-3.46,6L163.7,92H97L79.46,62A4,4,0,0,0,76,60H48a4,4,0,0,0,0,8H73.7L89.89,95.76,70.57,122.25A44.21,44.21,0,1,0,77,127L94.29,103.3,128.54,162a4,4,0,0,0,3.46,2,4.11,4.11,0,0,0,2-.54,4,4,0,0,0,1.44-5.48l-33.83-58h66.74l14.11,24.19A44,44,0,1,0,208,116ZM84,160a36,36,0,1,1-18.16-31.25L44.77,157.64a4,4,0,0,0,6.46,4.72l21.07-28.9A35.92,35.92,0,0,1,84,160Zm124,36a36,36,0,0,1-21.47-64.88l18,30.9a4,4,0,0,0,3.46,2,4.11,4.11,0,0,0,2-.54,4,4,0,0,0,1.44-5.48l-18-30.89A36,36,0,1,1,208,196Z"/%3E%3C/svg%3E');
}
.icon_campfire {
background-image: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="%23000000" height="32" width="32"%3E%3Cpath d="M219.81,225.21A4,4,0,0,1,216,228a3.92,3.92,0,0,1-1.21-.19L128,200.2,41.21,227.81A3.92,3.92,0,0,1,40,228a4,4,0,0,1-1.21-7.81l76-24.19-76-24.19a4,4,0,1,1,2.42-7.62L128,191.8l86.79-27.61a4,4,0,1,1,2.42,7.62l-76,24.19,76,24.19A4,4,0,0,1,219.81,225.21ZM72,108c0-19,9.38-38.85,27.12-57.27A152,152,0,0,1,125.9,28.59a4,4,0,0,1,4.2,0,152,152,0,0,1,26.78,22.14C174.62,69.15,184,89,184,108a56,56,0,0,1-54.56,56c-.48,0-1,0-1.44,0s-1,0-1.44,0A56,56,0,0,1,72,108Zm56,48a20,20,0,0,0,20-20c0-17.39-14.37-30.53-20-35-5.63,4.48-20,17.62-20,35A20,20,0,0,0,128,156ZM80,108a48,48,0,0,0,23.28,41.13A27.83,27.83,0,0,1,100,136c0-25.84,24.73-42.63,25.78-43.33a4,4,0,0,1,4.44,0c1.05.7,25.78,17.49,25.78,43.33a27.83,27.83,0,0,1-3.28,13.13A48,48,0,0,0,176,108c0-36.37-38.49-64.76-48-71.21C118.5,43.25,80,71.68,80,108Z"/%3E%3C/svg%3E');
}
.icon_castle {
background-image: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="%23000000" height="32" width="32"%3E%3Cpath d="M200,28H184a12,12,0,0,0-12,12V56a4,4,0,0,1-4,4H152a4,4,0,0,1-4-4V40a12,12,0,0,0-12-12H120a12,12,0,0,0-12,12V56a4,4,0,0,1-4,4H88a4,4,0,0,1-4-4V40A12,12,0,0,0,72,28H56A12,12,0,0,0,44,40V84.69a11.93,11.93,0,0,0,3.51,8.48l11.32,11.32A4,4,0,0,1,60,107.31V216a12,12,0,0,0,12,12H184a12,12,0,0,0,12-12V107.31a4,4,0,0,1,1.17-2.82l11.32-11.32A11.93,11.93,0,0,0,212,84.69V40A12,12,0,0,0,200,28ZM148,220H108V152a20,20,0,0,1,40,0ZM204,84.69a4,4,0,0,1-1.17,2.82L191.51,98.83a11.93,11.93,0,0,0-3.51,8.48V216a4,4,0,0,1-4,4H156V152a28,28,0,0,0-56,0v68H72a4,4,0,0,1-4-4V107.31a11.93,11.93,0,0,0-3.51-8.48L53.17,87.51A4,4,0,0,1,52,84.69V40a4,4,0,0,1,4-4H72a4,4,0,0,1,4,4V56A12,12,0,0,0,88,68h16a12,12,0,0,0,12-12V40a4,4,0,0,1,4-4h16a4,4,0,0,1,4,4V56a12,12,0,0,0,12,12h16a12,12,0,0,0,12-12V40a4,4,0,0,1,4-4h16a4,4,0,0,1,4,4Z"/%3E%3C/svg%3E');
}
.icon_fridge {
background-image: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 17.57617 28.04395"%3E%3Cpath stroke-width="0" d="m15.62988,0H1.94629C.87305,0,0,.87305,0,1.94629v25.59766c0,.27637.22363.5.5.5h16.57617c.27637,0,.5-.22363.5-.5V1.94629c0-1.07324-.87305-1.94629-1.94629-1.94629ZM1.94629,1h13.68359c.52148,0,.94629.42432.94629.94629v7.41357H1V1.94629c0-.52197.42432-.94629.94629-.94629Zm-.94629,26.04395V10.35986h15.57617v16.68408H1Z"/%3E%3Cpath stroke-width="0" d="m3.64453,5.36426h2.04248c.27637,0,.5-.22363.5-.5s-.22363-.5-.5-.5h-2.04248c-.27637,0-.5.22363-.5.5s.22363.5.5.5Z"/%3E%3Cpath stroke-width="0" d="m5.68701,13.271h-2.04248c-.27637,0-.5.22363-.5.5s.22363.5.5.5h2.04248c.27637,0,.5-.22363.5-.5s-.22363-.5-.5-.5Z"/%3E%3C/svg%3E');
}
.icon_information {
background-image: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="%23000000" height="32" width="32"%3E%3Cpath d="M140,176a4,4,0,0,1-4,4,12,12,0,0,1-12-12V128a4,4,0,0,0-4-4,4,4,0,0,1,0-8,12,12,0,0,1,12,12v40a4,4,0,0,0,4,4A4,4,0,0,1,140,176ZM124,92a8,8,0,1,0-8-8A8,8,0,0,0,124,92Zm104,36A100,100,0,1,1,128,28,100.11,100.11,0,0,1,228,128Zm-8,0a92,92,0,1,0-92,92A92.1,92.1,0,0,0,220,128Z"/%3E%3C/svg%3E');
}
.icon_kayak {
background-image: url('data:image/svg+xml,%3Csvg viewBox="0 0 29.52905 28.08545" xmlns="http://www.w3.org/2000/svg" id="uuid-87ec619a-4896-40b8-8478-aa076dee3f7c"%3E%3Cpath stroke-width="0" d="m29.46728,11.26074l-.57617-2.15186c-.08398-.31299-.24609-.59229-.45801-.78613-.26758-.24658-.59863-.3418-.90625-.25879l-3.4834.93213c-.26953.07227-.48535.26807-.6084.54932l-.5752,1.30713c-.0719.16376-.10333.34686-.10742.53485l-3.05627.81787c-.23956-3.37067-1.03204-8.79126-2.35193-10.66425l-.22363-.31836C16.58057.45752,15.69971.00049,14.76318,0h-.00049c-.94873,0-1.80566.44434-2.35156,1.21875-1.71973,2.44043-2.65771,9.75146-2.65771,12.82422,0,.24457.00812.52399.0199.81769l-3.25604.87134c-.09741-.16071-.21613-.30347-.36005-.40924l-1.15088-.84424c-.24854-.18213-.53125-.24463-.80127-.17236l-3.48389.93164c-.56689.15234-.85693.84961-.65918,1.58691l.57617,2.15137c.0835.31348.24561.59277.45654.78613.20508.18848.4458.28809.68506.28809.07471,0,.14893-.00879.22168-.02832l3.48486-.93359c.26807-.07227.48389-.26758.60693-.54883l.57568-1.30664c.07172-.16357.10309-.3465.10718-.5343l3.05591-.81793c.25531,3.52673,1.14368,8.94983,2.5791,10.98602.5459.77441,1.40332,1.21875,2.35205,1.21875.93652,0,1.81738-.45703,2.35645-1.22266l.22461-.31738c1.60352-2.27637,2.43066-9.79492,2.43066-12.50244,0-.23499-.00854-.51709-.021-.81805l3.25732-.87183c.09747.16071.21625.30347.36035.40912l1.15039.84473c.18066.13281.38086.20166.5791.20166.07422,0,.14941-.00977.22168-.0293l3.48535-.93262c.56641-.15234.85645-.84863.65918-1.58594Zm-24.24072,6.86182l-3.41602.93262c-.03516-.01465-.14844-.12109-.20654-.33691l-.57617-2.15137c-.05713-.21484-.01318-.3623-.04688-.3623h-.00098l3.4165-.93164s.00586.00293.01709.01074c.00049,0,.00098.00098.00098.00098l1.00842.74017-1.90881.5108c-.2666.07227-.4248.3457-.35352.6123.05957.22363.26172.37109.48242.37109.04297,0,.08643-.00586.12988-.0166l1.91559-.5127-.46198,1.13281Zm5.52686-4.07959c0-3.07959.93994-10.06934,2.4751-12.24805.35596-.50488.91504-.79492,1.53418-.79492.62109.00049,1.18213.2915,1.54053.79932l.22266.31689c1.17902,1.67261,1.96533,7.08936,2.18457,10.35278l-1.50305.40228c-.19397-2.55505-1.02423-4.83514-2.44324-4.83514-1.63379,0-2.48828,3.02197-2.48828,6.00684,0,.04913.00214.09814.00262.14728l-1.51538.40552c-.00574-.19403-.0097-.38147-.0097-.5528Zm2.52692-.12079c.02441-2.93951.89984-4.88605,1.48383-4.88605.53003,0,1.29828,1.6062,1.45496,4.09961l-2.93878.78644Zm2.96765.24115c-.02441,2.93933-.89978,4.88599-1.48383,4.88599-.53003,0-1.29834-1.60632-1.45496-4.09937l2.93878-.78662Zm2.52692-.12036c0,2.66846-.84961,9.94092-2.24902,11.92725l-.22363.31641c-.71387,1.01367-2.36084,1.01562-3.07373.00391-1.31152-1.86127-2.18622-7.22681-2.414-10.67285l1.50641-.4032c.19397,2.55505,1.02417,4.83484,2.44324,4.83484,1.63379,0,2.48828-3.02148,2.48828-6.00635,0-.04926-.00214-.09845-.00262-.14777l1.51514-.40558c.00659.20087.00995.38617.00995.55334Zm6.35742-1.23047s-.00684-.00293-.01855-.01123l-1.00897-.74091,1.90936-.51105c.26758-.07129.42578-.34521.35449-.6123-.07227-.26562-.3418-.42725-.6123-.35352l-1.91577.5127.46069-1.13379,3.41699-.93164c.03516.01416.14844.12012.20605.33691l.57617,2.15186c.05957.21973.01953.36816.04883.36133l-3.41699.93164Z"/%3E%3C/svg%3E');
}
.icon_outing {
background-image: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="%23000000" height="32" width="32"%3E%3Cpath d="M164,44.17V32a20,20,0,0,0-20-20H112A20,20,0,0,0,92,32V44.17A52.05,52.05,0,0,0,44,96V216a12,12,0,0,0,12,12H200a12,12,0,0,0,12-12V96A52.05,52.05,0,0,0,164,44.17ZM112,20h32a12,12,0,0,1,12,12V44H100V32A12,12,0,0,1,112,20Zm60,144H84V152a12,12,0,0,1,12-12h64a12,12,0,0,1,12,12Zm-88,8h56v12a4,4,0,0,0,8,0V172h24v48H84Zm120,44a4,4,0,0,1-4,4H180V152a20,20,0,0,0-20-20H96a20,20,0,0,0-20,20v68H56a4,4,0,0,1-4-4V96A44.05,44.05,0,0,1,96,52h64a44.05,44.05,0,0,1,44,44ZM148,88a4,4,0,0,1-4,4H112a4,4,0,0,1,0-8h32A4,4,0,0,1,148,88Z"/%3E%3C/svg%3E');
}
.icon_pool {
background-image: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="%23000000" height="32" width="32"%3E%3Cpath d="M88,145.39a4,4,0,0,0,4-4V124h72v19.29a4,4,0,0,0,8,0V32a4,4,0,0,0-8,0V52H92V32a4,4,0,0,0-8,0V141.39A4,4,0,0,0,88,145.39ZM92,116V92h72v24Zm72-56V84H92V60ZM28,168a4,4,0,0,1,4-4c13.21,0,20.12,4.61,26.22,8.67,5.9,3.93,11,7.33,21.78,7.33s15.88-3.4,21.78-7.33c6.09-4.06,13-8.67,26.21-8.67s20.13,4.61,26.22,8.67c5.9,3.93,11,7.33,21.79,7.33s15.88-3.4,21.78-7.33c6.1-4.06,13-8.67,26.22-8.67a4,4,0,0,1,0,8c-10.79,0-15.88,3.4-21.78,7.33-6.1,4.06-13,8.67-26.22,8.67s-20.13-4.61-26.22-8.67c-5.9-3.93-11-7.33-21.79-7.33s-15.88,3.4-21.78,7.33c-6.09,4.06-13,8.67-26.21,8.67s-20.12-4.61-26.22-8.67C47.88,175.4,42.79,172,32,172A4,4,0,0,1,28,168Zm200,40a4,4,0,0,1-4,4c-10.79,0-15.88,3.4-21.78,7.33-6.1,4.06-13,8.67-26.22,8.67s-20.13-4.61-26.22-8.67c-5.9-3.93-11-7.33-21.79-7.33s-15.88,3.4-21.78,7.33c-6.09,4.06-13,8.67-26.21,8.67s-20.12-4.61-26.22-8.67C47.88,215.4,42.79,212,32,212a4,4,0,0,1,0-8c13.21,0,20.12,4.61,26.22,8.67,5.9,3.93,11,7.33,21.78,7.33s15.88-3.4,21.78-7.33c6.09-4.06,13-8.67,26.21-8.67s20.13,4.61,26.22,8.67c5.9,3.93,11,7.33,21.79,7.33s15.88-3.4,21.78-7.33c6.1-4.06,13-8.67,26.22-8.67A4,4,0,0,1,228,208Z"/%3E%3C/svg%3E');
}
.icon_puzzle {
background-image: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="%23000000" height="32" width="32"%3E%3Cpath d="M218.14,161.93a4,4,0,0,0-3.86-.24,24,24,0,0,1-34.23-23.25,24,24,0,0,1,34.23-20.13A4,4,0,0,0,220,114.7V72a12,12,0,0,0-12-12H167a32,32,0,1,0-62.91-10.33A32.57,32.57,0,0,0,105,60H64A12,12,0,0,0,52,72v37a32,32,0,1,0-10.33,62.91A32.28,32.28,0,0,0,52,171v37a12,12,0,0,0,12,12H208a12,12,0,0,0,12-12V165.31A4,4,0,0,0,218.14,161.93ZM212,208a4,4,0,0,1-4,4H64a4,4,0,0,1-4-4V165.31a4,4,0,0,0-1.86-3.38,4,4,0,0,0-3.85-.24,24,24,0,0,1-34.24-20.13,24,24,0,0,1,34.24-23.25A4,4,0,0,0,60,114.7V72a4,4,0,0,1,4-4h46.69a4,4,0,0,0,3.62-5.71,24,24,0,0,1,20.13-34.24,24,24,0,0,1,23.25,34.24A4,4,0,0,0,161.31,68H208a4,4,0,0,1,4,4v37a32.57,32.57,0,0,0-10.33-.94A32,32,0,1,0,212,171Z"/%3E%3C/svg%3E');
}
.icon_restaurant {
background-image: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="%23000000" height="32" width="32"%3E%3Cpath d="M76,88V40a4,4,0,0,1,8,0V88a4,4,0,0,1-8,0ZM212,40V224a4,4,0,0,1-8,0V172H152a4,4,0,0,1-4-4,264.27,264.27,0,0,1,7.11-55.94c9.47-39.22,27.21-65.41,51.31-75.74A4,4,0,0,1,212,40Zm-8,6.46C162.25,70.33,156.81,145.75,156.1,164H204Zm-88-7.12a4,4,0,0,0-7.9,1.32l8,47.66a36,36,0,0,1-72,0l8-47.66a4,4,0,0,0-7.9-1.32l-8,48A4.89,4.89,0,0,0,36,88a44.06,44.06,0,0,0,40,43.81V224a4,4,0,0,0,8,0V131.81A44.06,44.06,0,0,0,124,88a4.89,4.89,0,0,0,0-.66Z"/%3E%3C/svg%3E');
}
.icon_route {
background-image: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="%23000000" height="32" width="32"%3E%3Cpath d="M226.46,52.85a4,4,0,0,0-3.43-.73L160.47,67.76,97.79,36.42a4,4,0,0,0-2.76-.3l-64,16A4,4,0,0,0,28,56V200a4,4,0,0,0,5,3.88l62.56-15.64,62.68,31.34a4,4,0,0,0,2.76.3l64-16a4,4,0,0,0,3-3.88V56A4,4,0,0,0,226.46,52.85ZM100,46.47l56,28V209.53l-56-28ZM36,59.12l56-14V180.88l-56,14ZM220,196.88l-56,14V75.12l56-14Z"/%3E%3C/svg%3E');
}
.icon_rv {
background-image: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 29 23.832"%3E%3Cpath stroke-width="0" d="m15.6527,16.65094h-3.92455c-.68449,0-1.23939-.55489-1.23939-1.23939V6.08515c0-.68422.55467-1.2389,1.2389-1.2389h3.92406c.68476,0,1.23987.55511,1.23987,1.23987v9.32592c0,.68422-.55467,1.2389-1.2389,1.2389Zm-3.92504-10.80469c-.13139,0-.2389.1075-.2389.2389v9.32689c0,.13194.10696.2389.2389.2389h3.92406c.13248,0,.23987-.1074.23987-.23987V6.08515c0-.13194-.10696-.2389-.2389-.2389h-3.92504Z"/%3E%3Cpath stroke-width="0" d="m7.83386,11.2486H3.45423c-.68422,0-1.2389-.55467-1.2389-1.2389v-3.92455c0-.68422.55467-1.2389,1.2389-1.2389h4.38012c.68422,0,1.2389.55467,1.2389,1.2389v3.92406c0,.68449-.55489,1.23939-1.23939,1.23939ZM3.45423,5.84626c-.13194,0-.2389.10696-.2389.2389v3.92406c0,.13166.10772.23939.23939.23939h4.37914c.13166,0,.23939-.10772.23939-.23939v-3.92406c0-.13194-.10696-.2389-.2389-.2389H3.45423Z"/%3E%3Cpath stroke-width="0" d="m28.875,11.00897l-3.31604-5.19989h.18054c.72272,0,1.3103-.58594,1.3103-1.30615,0-3.03418-2.47571-4.50293-5.51849-4.50293H1.30981C.58759,0,0,.58594,0,1.30615v18.02783c0,.82843.67157,1.5,1.5,1.5h2.53625c.27747,1.91296,2.05322,3.23883,3.96619,2.9613,1.53394-.22247,2.73883-1.42737,2.9613-2.9613h7.07251c.27747,1.91296,2.05322,3.23883,3.96619,2.9613,1.53394-.22247,2.73883-1.42737,2.9613-2.9613h2.53625c.82843,0,1.5-.67157,1.5-1.5v-8c-.0014-.11981-.04572-.23511-.125-.32501Zm-1.46252-.17499h-8.41248v-4.20093c0-.44131.35776-.79907.79907-.79907h4.2334c.15027-.00006.29254.06744.38751.18378l2.99249,4.81622ZM7.5,22.83398c-1.38074,0-2.5-1.11926-2.5-2.5s1.11926-2.5,2.5-2.5,2.5,1.11932,2.5,2.5-1.11926,2.5-2.5,2.5Zm14,0c-1.38074,0-2.5-1.11926-2.5-2.5s1.11926-2.5,2.5-2.5,2.5,1.11932,2.5,2.5-1.11926,2.5-2.5,2.5Zm6.5-3.5c0,.27614-.22386.5-.5.5h-2.53625c-.27747-1.91296-2.05322-3.23877-3.96619-2.9613-1.53394.22247-2.73883,1.42737-2.9613,2.9613h-7.07251c-.27747-1.91296-2.05322-3.23877-3.96619-2.9613-1.53394.22247-2.73883,1.42737-2.9613,2.9613H1.49993c-.27613,0-.49997-.22387-.49993-.5l.00281-18.02702c.00002-.16883.13818-.30696.30701-.30696h20.2215c2.49295,0,4.51981,1.02413,4.51563,3.51052-.00028.16481-.14263.29856-.30744.29856h-6.07078c-.91711,0-1.66082.74301-1.66169,1.66012l-.00898,9.43901c0,.27637.22363.5.5.5s.5-.22363.5-.5v-4.07422h9.00195v7.5Z"/%3E%3C/svg%3E');
}
.icon_shower {
background-image: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="%23000000" height="32" width="32"%3E%3Cpath d="M60,236a8,8,0,1,1-8-8A8,8,0,0,1,60,236Zm24-40a8,8,0,1,0,8,8A8,8,0,0,0,84,196Zm-64,0a8,8,0,1,0,8,8A8,8,0,0,0,20,196Zm32-32a8,8,0,1,0,8,8A8,8,0,0,0,52,164ZM252,40a4,4,0,0,1-4,4H219.31a4,4,0,0,0-2.82,1.17L187.73,73.93,165.86,202a12,12,0,0,1-8.17,9.44A12.09,12.09,0,0,1,154,212a12,12,0,0,1-8.46-3.52l-98-98A12,12,0,0,1,54,90.14l128-21.87,28.76-28.76A11.93,11.93,0,0,1,219.31,36H248A4,4,0,0,1,252,40ZM179.11,76.89,55.37,98a4,4,0,0,0-2.19,6.78l98,98a4,4,0,0,0,6.78-2.17Z"/%3E%3C/svg%3E');
}
.icon_store {
background-image: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="%23000000" height="32" width="32"%3E%3Cpath d="M28,112a36,36,0,0,0,16,29.92V208a12,12,0,0,0,12,12H200a12,12,0,0,0,12-12V141.92A36,36,0,0,0,228,112l0-16a4.09,4.09,0,0,0-.13-1.1L213.5,44.7A12,12,0,0,0,202,36H54A12,12,0,0,0,42.5,44.7L28.15,94.9A4.09,4.09,0,0,0,28,96ZM50.19,46.9A4,4,0,0,1,54,44H202a4,4,0,0,1,3.84,2.9L218.7,92H37.3ZM100,100h56v12a28,28,0,0,1-56,0ZM36,112V100H92v12a28,28,0,0,1-56,0Zm168,96a4,4,0,0,1-4,4H56a4,4,0,0,1-4-4V145.94a36,36,0,0,0,44-17.48,36,36,0,0,0,64,0,36,36,0,0,0,44,17.48Zm-12-68a28,28,0,0,1-28-28V100h56v12A28,28,0,0,1,192,140Z"/%3E%3C/svg%3E');
}
.icon_toilet {
background-image: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="%23000000" height="32" width="32"%3E%3Cpath d="M116,64a4,4,0,0,1-4,4H96a4,4,0,0,1,0-8h16A4,4,0,0,1,116,64Zm52,130.86,3.92,27.44A12,12,0,0,1,160,236H96a12,12,0,0,1-11.88-13.7L88,194.86A92.11,92.11,0,0,1,36,112a4,4,0,0,1,4-4H60V40A12,12,0,0,1,72,28H184a12,12,0,0,1,12,12v68h20a4,4,0,0,1,4,4A92.11,92.11,0,0,1,168,194.86ZM68,108H188V40a4,4,0,0,0-4-4H72a4,4,0,0,0-4,4Zm92.34,90.13a92,92,0,0,1-64.68,0L92,223.43a4,4,0,0,0,.94,3.19A3.93,3.93,0,0,0,96,228h64a3.93,3.93,0,0,0,3-1.38,4,4,0,0,0,.94-3.19ZM211.91,116H44.09a84,84,0,0,0,167.82,0Z"/%3E%3C/svg%3E');
}
.icon_washer {
background-image: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24.57617 28.04346"%3E%3Cpath stroke-width="0" d="m22.62988,0H1.94629C.87305,0,0,.87354,0,1.94678v25.59668c0,.27637.22363.5.5.5h23.57617c.27637,0,.5-.22363.5-.5V1.94678c0-1.07324-.87305-1.94678-1.94629-1.94678ZM1.94629,1h20.68359c.52148,0,.94629.4248.94629.94678v3.74756H1V1.94678c0-.52197.42432-.94678.94629-.94678Zm-.94629,26.04346V6.69434h22.57617v20.34912H1Z"/%3E%3Cpath stroke-width="0" d="m3.92139,4.02881h.55273c.27637,0,.5-.22363.5-.5s-.22363-.5-.5-.5h-.55273c-.27637,0-.5.22363-.5.5s.22363.5.5.5Z"/%3E%3Cpath stroke-width="0" d="m6.99805,4.02881h.55322c.27637,0,.5-.22363.5-.5s-.22363-.5-.5-.5h-.55322c-.27637,0-.5.22363-.5.5s.22363.5.5.5Z"/%3E%3Cpath stroke-width="0" d="m12.28809,8.35986c-4.63818,0-8.41162,3.77344-8.41162,8.41211,0,4.6377,3.77344,8.41113,8.41162,8.41113,4.6377,0,8.41113-3.77344,8.41113-8.41113,0-4.63867-3.77344-8.41211-8.41113-8.41211Zm0,1c3.78308,0,6.9071,2.85101,7.3515,6.51611-.02045.01282-.04352.01862-.06244.03467-.01562.01367-1.58887,1.35449-3.57617,1.35645h-.00391c-1.39941,0-2.19141-.55273-3.02979-1.1377-.83887-.58496-1.70703-1.19043-3.1167-1.19043-2.3396,0-4.15607,1.26996-4.96783,1.95667-.00067-.04156-.00629-.08191-.00629-.12366,0-4.08691,3.32471-7.41211,7.41162-7.41211Zm0,14.82324c-3.62976,0-6.6524-2.62415-7.28448-6.07397.05127-.02527.10077-.05597.1424-.09985.01953-.02051,1.99365-2.07031,4.70459-2.07031,1.0957,0,1.76709.46875,2.54492,1.01074.88477.61816,1.8877,1.31738,3.60156,1.31738h.00391c1.63293-.00134,2.9729-.72321,3.68317-1.19769-.15778,3.94849-3.40955,7.11371-7.39606,7.11371Z"/%3E%3C/svg%3E');
}
.icon_wheelchair {
background-image: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="%23000000" height="32" width="32"%3E%3Cpath d="M176,76a28,28,0,1,0-28-28A28,28,0,0,0,176,76Zm0-48a20,20,0,1,1-20,20A20,20,0,0,1,176,28ZM164,168a60,60,0,1,1-60-60,4,4,0,0,1,0,8,52,52,0,1,0,52,52,4,4,0,0,1,8,0Zm39.09-34.54a4,4,0,0,1,.83,3.32l-16,80A4,4,0,0,1,184,220a3.44,3.44,0,0,1-.78-.08,4,4,0,0,1-3.14-4.7l15-75.22H128a4,4,0,0,1-3.47-6l22.08-38.42a84.05,84.05,0,0,0-96.06,7.61A4,4,0,0,1,45.45,97a92,92,0,0,1,108.73-6.15,4,4,0,0,1,1.29,5.34L134.91,132H200A4,4,0,0,1,203.09,133.46Z"/%3E%3C/svg%3E');
}
.icon_wifi {
background-image: url('data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="%23000000" height="32" width="32"%3E%3Cpath d="M136,204a8,8,0,1,1-8-8A8,8,0,0,1,136,204ZM234.54,90.1a168,168,0,0,0-213.08,0,4,4,0,1,0,5.08,6.18,160,160,0,0,1,202.92,0,4,4,0,0,0,5.08-6.18Zm-32.06,35.81a120,120,0,0,0-149,0,4,4,0,0,0,5,6.27,112,112,0,0,1,139,0,4,4,0,0,0,5-6.27Zm-32.13,35.86a72,72,0,0,0-84.7,0,4,4,0,1,0,4.7,6.46,64.07,64.07,0,0,1,75.3,0,4,4,0,0,0,5.58-.87A4,4,0,0,0,170.35,161.77Z"/%3E%3C/svg%3E');
}
.outside_activities {
margin-top: 2rem;
}

View File

@ -9,6 +9,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{ template "title" . }} — Camper</title>
<link rel="stylesheet" media="screen" href="/static/camper.css">
<link rel="stylesheet" media="screen" href="/static/icons.css">
<script type="module" src="/static/camper.js"></script>
<script src="/static/htmx@1.9.3.min.js"></script>
{{ block "head" . }}{{ end }}

View File

@ -0,0 +1,82 @@
<!--
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/service.serviceForm*/ -}}
{{ if .ID }}
{{( pgettext "Edit Service" "title" )}}
{{ else }}
{{( pgettext "New Service" "title" )}}
{{ end }}
{{- end }}
{{ define "content" -}}
{{- /*gotype: dev.tandem.ws/tandem/camper/pkg/services.serviceForm*/ -}}
<form
{{ if .ID }}
data-hx-put="/admin/services/{{ .ID }}"
{{ else }}
action="/admin/services" method="post"
{{ end }}
>
<h2>
{{ if .ID }}
{{( pgettext "Edit Service" "title" )}}
{{ else }}
{{( pgettext "New Service" "title" )}}
{{ end }}
</h2>
{{ CSRFInput }}
<fieldset>
{{ with $field := .Icon -}}
<fieldset class="icon-input">
<legend>{{( pgettext "Icon" "input")}}</legend>
<input type="hidden" name="{{ .Name }}"
{{- range .Options }}
{{ if $field.IsSelected .Value }} value="{{ .Value }}"{{ end }}
{{- end }}
>
<ul>
{{- range .Options }}
<li>
<button type="button" data-icon-name="{{ .Value }}" class="icon_{{ .Value }}"></button>
</li>
{{- end }}
</ul>
{{ template "error-message" . }}
</fieldset>
{{- end }}
{{ with .Name -}}
<label>
{{( pgettext "Name" "input")}}<br>
<input type="text" name="{{ .Name }}" value="{{ .Val }}"
required {{ template "error-attrs" . }}><br>
</label>
{{ template "error-message" . }}
{{- end }}
{{ with .Description -}}
<label>
{{( pgettext "Description" "input")}}<br>
<textarea class="html" name="{{ .Name }}" {{ template "error-attrs" . }}>{{ .Val }}</textarea><br>
</label>
{{ template "error-message" . }}
{{- end }}
</fieldset>
<footer>
<button type="submit">
{{ if .ID }}
{{( pgettext "Update" "action" )}}
{{ else }}
{{( pgettext "Add" "action" )}}
{{ end }}
</button>
</footer>
</form>
<script type="module">
import {setupIconInput} from "/static/camper.js";
setupIconInput(document.querySelector('.icon-input'));
</script>
{{- end }}

View File

@ -46,4 +46,38 @@
{{ else -}}
<p>{{( gettext "No slides added yet." )}}</p>
{{- end }}
<h2>{{( pgettext "Services" "title" )}}</h2>
{{ if .Services -}}
<table class="services">
<thead>
<tr>
<th scope="col">{{( pgettext "Service" "header" )}}</th>
<th scope="col">{{( pgettext "Translations" "campsite type" )}}</th>
<th scope="col">{{( pgettext "Actions" "campsite type" )}}</th>
</tr>
</thead>
<tbody>
{{ range .Services -}}
<tr>
<td class="icon_{{ .Icon }}"><a href="{{ .URL }}">{{ .Name }}</a></td>
<td>
{{ range .Translations }}
<a
{{ if .Missing }}class="missing-translation"{{ end }}
href="{{ .URL }}">{{ .Endonym }}</a>
{{ end }}
</td>
<td>
<form data-hx-delete="{{ .URL }}" data-hx-headers='{ {{ CSRFHeader }} }'>
<button type="submit">{{( pgettext "Delete" "action" )}}</button>
</form>
</td>
</tr>
{{- end }}
</tbody>
</table>
{{ else -}}
<p>{{( gettext "No services added yet." )}}</p>
{{- end }}
{{- end }}

View File

@ -0,0 +1,48 @@
<!--
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/services.serviceL10nForm*/ -}}
{{printf (pgettext "Translate Service to %s" "title") .Locale.Endonym }}
{{- end }}
{{ define "content" -}}
{{- /*gotype: dev.tandem.ws/tandem/camper/pkg/services.serviceL10nForm*/ -}}
<form data-hx-put="/admin/services/{{ .ID }}/{{ .Locale.Language }}">
<h2>
{{printf (pgettext "Translate Service to %s" "title") .Locale.Endonym }}
</h2>
{{ CSRFInput }}
<fieldset>
{{ with .Name -}}
<fieldset>
<legend>{{( pgettext "Name" "input")}}</legend>
{{( gettext "Source:" )}} {{ .Source }}<br>
<label>
{{( pgettext "Translation:" "input" )}}
<input type="text" name="{{ .Name }}" value="{{ .Val }}"
required {{ template "error-attrs" . }}><br>
</label>
{{ template "error-message" . }}
</fieldset>
{{- end }}
{{ with .Description -}}
<fieldset>
<legend{{( pgettext "Description" "input")}}></legend>
{{( gettext "Source:" )}}<br>
{{ .Source | raw }}<br>
<label>
{{( pgettext "Translation:" "input" )}}
<textarea class="html"
name="{{ .Name }}" {{ template "error-attrs" . }}>{{ .Val }}</textarea><br>
</label>
{{ template "error-message" . }}
</fieldset>
{{- end }}
</fieldset>
<footer>
<button type="submit">{{( pgettext "Translate" "action" )}}</button>
</footer>
</form>
{{- end }}

View File

@ -12,6 +12,7 @@
<link rel="preload" href="/static/fonts/MabryPro-Regular.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/static/fonts/MabryPro-Bold.woff2" as="font" type="font/woff2" crossorigin>
<link rel="stylesheet" media="screen" href="/static/public.css">
<link rel="stylesheet" media="screen" href="/static/icons.css">
{{ range .LocalizedAlternates -}}
<link rel="alternate" hreflang="{{ .Lang }}" href="{{ .HRef }}"/>
{{ end }}