From 584d81f7bdcaeddfbc210a9ffab1c241d3cbdce3 Mon Sep 17 00:00:00 2001 From: Ruidy Date: Fri, 9 Jan 2026 15:53:05 -0400 Subject: [PATCH] feat(i18n): add language toggle and localize views --- .gitignore | 1 + Makefile | 2 +- go.mod | 15 +- go.sum | 40 +- internal/i18n/i18n.go | 129 ++++++ internal/i18n/locales/en.json | 120 ++++++ internal/i18n/locales/fr.json | 120 ++++++ internal/server/handle_auth.go | 4 +- internal/server/handle_bookings.go | 18 +- internal/server/handle_language.go | 41 ++ internal/server/handle_payments.go | 6 +- internal/server/handle_reports.go | 4 +- internal/server/helper.go | 5 +- internal/server/routes.go | 1 + internal/server/server.go | 7 + internal/view/booking_by_id.templ | 63 +-- internal/view/booking_by_id_templ.go | 442 ++++++++++++++++++--- internal/view/booking_form.templ | 26 +- internal/view/booking_form_templ.go | 288 +++++++++++--- internal/view/booking_lines.templ | 10 +- internal/view/booking_lines_templ.go | 92 ++++- internal/view/bookings_list.templ | 11 +- internal/view/bookings_list_templ.go | 48 ++- internal/view/bookings_new.templ | 29 +- internal/view/bookings_new_templ.go | 189 ++++++++- internal/view/item_list.templ | 8 +- internal/view/item_list_templ.go | 47 ++- internal/view/layout/base.templ | 24 +- internal/view/layout/base_templ.go | 197 ++++++++-- internal/view/layout/lang.go | 9 + internal/view/line_item.templ | 6 +- internal/view/line_item_templ.go | 100 +++-- internal/view/login.templ | 9 +- internal/view/login_form.templ | 12 +- internal/view/login_form_templ.go | 109 +++++- internal/view/login_templ.go | 37 +- internal/view/payment.templ | 8 +- internal/view/payment_templ.go | 139 ++++--- internal/view/report_section.templ | 30 +- internal/view/report_section_templ.go | 542 +++++++++++++++++--------- internal/view/reports.templ | 20 +- internal/view/reports_templ.go | 146 ++++++- internal/view/success.templ | 4 +- internal/view/success_templ.go | 19 +- 44 files changed, 2523 insertions(+), 654 deletions(-) create mode 100644 internal/i18n/i18n.go create mode 100644 internal/i18n/locales/en.json create mode 100644 internal/i18n/locales/fr.json create mode 100644 internal/server/handle_language.go create mode 100644 internal/view/layout/lang.go diff --git a/.gitignore b/.gitignore index ea18ce3..2af6a0f 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,4 @@ tmp.pdf token.json .aider* VFNI*.html +.claude diff --git a/Makefile b/Makefile index 155b905..9585a9e 100644 --- a/Makefile +++ b/Makefile @@ -28,7 +28,7 @@ up-deps: ## Update Go dependencies on host go get -u ./... format: ## Generate templ files and format code locally - templ generate internal/view + templ generate -path internal/view templ fmt . go fmt ./... diff --git a/go.mod b/go.mod index c60fcc6..58760cb 100644 --- a/go.mod +++ b/go.mod @@ -3,12 +3,13 @@ module github.com/rjNemo/rentease go 1.25.4 require ( - github.com/a-h/templ v0.3.960 - github.com/getsentry/sentry-go v0.38.0 + github.com/a-h/templ v0.3.977 + github.com/getsentry/sentry-go v0.40.0 github.com/go-chi/chi/v5 v5.2.3 github.com/go-chi/cors v1.2.2 github.com/gorilla/sessions v1.4.0 github.com/joho/godotenv v1.5.1 + github.com/nicksnyder/go-i18n/v2 v2.6.1 github.com/rjNemo/underscore v0.10.0 github.com/stripe/stripe-go/v83 v83.2.1 gorm.io/driver/postgres v1.6.0 @@ -21,20 +22,20 @@ require ( github.com/tidwall/match v1.2.0 // indirect github.com/tidwall/pretty v1.2.1 // indirect github.com/tidwall/sjson v1.2.5 // indirect + golang.org/x/net v0.47.0 // indirect ) require ( github.com/gorilla/securecookie v1.1.2 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect - github.com/jackc/pgx/v5 v5.7.6 // indirect + github.com/jackc/pgx/v5 v5.8.0 // indirect github.com/jackc/puddle/v2 v2.2.2 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect github.com/openai/openai-go v1.12.0 github.com/sethvargo/go-envconfig v1.3.0 - golang.org/x/crypto v0.44.0 // indirect - golang.org/x/sync v0.18.0 // indirect - golang.org/x/sys v0.38.0 // indirect - golang.org/x/text v0.31.0 // indirect + golang.org/x/sync v0.19.0 // indirect + golang.org/x/sys v0.40.0 // indirect + golang.org/x/text v0.32.0 ) diff --git a/go.sum b/go.sum index 31bc023..4ccbf9a 100644 --- a/go.sum +++ b/go.sum @@ -1,10 +1,12 @@ -github.com/a-h/templ v0.3.960 h1:trshEpGa8clF5cdI39iY4ZrZG8Z/QixyzEyUnA7feTM= -github.com/a-h/templ v0.3.960/go.mod h1:oCZcnKRf5jjsGpf2yELzQfodLphd2mwecwG4Crk5HBo= +github.com/BurntSushi/toml v1.6.0 h1:dRaEfpa2VI55EwlIW72hMRHdWouJeRF7TPYhI+AUQjk= +github.com/BurntSushi/toml v1.6.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= +github.com/a-h/templ v0.3.977 h1:kiKAPXTZE2Iaf8JbtM21r54A8bCNsncrfnokZZSrSDg= +github.com/a-h/templ v0.3.977/go.mod h1:oCZcnKRf5jjsGpf2yELzQfodLphd2mwecwG4Crk5HBo= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/getsentry/sentry-go v0.38.0 h1:S8Xui7gLeAvXINVLMOaX94HnsDf1GexnfXGSNC4+KQs= -github.com/getsentry/sentry-go v0.38.0/go.mod h1:eRXCoh3uvmjQLY6qu63BjUZnaBu5L5WhMV1RwYO8W5s= +github.com/getsentry/sentry-go v0.40.0 h1:VTJMN9zbTvqDqPwheRVLcp0qcUcM+8eFivvGocAaSbo= +github.com/getsentry/sentry-go v0.40.0/go.mod h1:eRXCoh3uvmjQLY6qu63BjUZnaBu5L5WhMV1RwYO8W5s= github.com/go-chi/chi/v5 v5.2.3 h1:WQIt9uxdsAbgIYgid+BpYc+liqQZGMHRaUwp0JUcvdE= github.com/go-chi/chi/v5 v5.2.3/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops= github.com/go-chi/cors v1.2.2 h1:Jmey33TE+b+rB7fT8MUy1u0I4L+NARQlK6LhzKPSyQE= @@ -23,8 +25,8 @@ github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsI github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo= github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= -github.com/jackc/pgx/v5 v5.7.6 h1:rWQc5FwZSPX58r1OQmkuaNicxdmExaEz5A2DO2hUuTk= -github.com/jackc/pgx/v5 v5.7.6/go.mod h1:aruU7o91Tc2q2cFp5h4uP3f6ztExVpyVv88Xl/8Vl8M= +github.com/jackc/pgx/v5 v5.8.0 h1:TYPDoleBBme0xGSAX3/+NujXXtpZn9HBONkQC7IEZSo= +github.com/jackc/pgx/v5 v5.8.0/go.mod h1:QVeDInX2m9VyzvNeiCJVjCkNFqzsNb43204HshNSZKw= github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= @@ -33,6 +35,8 @@ github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/nicksnyder/go-i18n/v2 v2.6.1 h1:JDEJraFsQE17Dut9HFDHzCoAWGEQJom5s0TRd17NIEQ= +github.com/nicksnyder/go-i18n/v2 v2.6.1/go.mod h1:Vee0/9RD3Quc/NmwEjzzD7VTZ+Ir7QbXocrkhOzmUKA= github.com/openai/openai-go v1.12.0 h1:NBQCnXzqOTv5wsgNC36PrFEiskGfO5wccfCWDo9S1U0= github.com/openai/openai-go v1.12.0/go.mod h1:g461MYGXEXBVdV5SaR/5tNzNbSfwTBBefwc+LlDCK0Y= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= @@ -48,8 +52,8 @@ github.com/sethvargo/go-envconfig v1.3.0/go.mod h1:JLd0KFWQYzyENqnEPWWZ49i4vzZo/ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/stripe/stripe-go/v83 v83.2.1 h1:8WPhpMjr8VyMWKUsCMoVvlWxYazuL5edajKX/RulfbA= github.com/stripe/stripe-go/v83 v83.2.1/go.mod h1:nRyDcLrJtwPPQUnKAFs9Bt1NnQvNhNiF6V19XHmPISE= github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= @@ -65,16 +69,16 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -golang.org/x/crypto v0.44.0 h1:A97SsFvM3AIwEEmTBiaxPPTYpDC47w720rdiiUvgoAU= -golang.org/x/crypto v0.44.0/go.mod h1:013i+Nw79BMiQiMsOPcVCB5ZIJbYkerPrGnOa00tvmc= -golang.org/x/net v0.46.0 h1:giFlY12I07fugqwPuWJi68oOnpfqFnJIJzaIIm2JVV4= -golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= -golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= -golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= -golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= -golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= +golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= +golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= +golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/internal/i18n/i18n.go b/internal/i18n/i18n.go new file mode 100644 index 0000000..ca011cb --- /dev/null +++ b/internal/i18n/i18n.go @@ -0,0 +1,129 @@ +package i18n + +import ( + "context" + "embed" + "encoding/json" + "net/http" + "strings" + + gi18n "github.com/nicksnyder/go-i18n/v2/i18n" + "golang.org/x/text/language" +) + +//go:embed locales/*.json +var localeFS embed.FS + +const ( + CookieName = "lang" +) + +type ctxKey string + +const ( + ctxKeyLang ctxKey = "lang" + ctxKeyLocalizer ctxKey = "localizer" +) + +// Bundle initializes the go-i18n bundle and loads embedded locale files. +func Bundle() (*gi18n.Bundle, error) { + b := gi18n.NewBundle(language.English) + b.RegisterUnmarshalFunc("json", json.Unmarshal) + + // Load embedded message files + for _, name := range []string{"locales/en.json", "locales/fr.json"} { + data, err := localeFS.ReadFile(name) + if err != nil { + return nil, err + } + if _, err := b.ParseMessageFileBytes(data, name); err != nil { + return nil, err + } + } + return b, nil +} + +// LanguageFromRequest resolves the preferred language from cookie or Accept-Language. +func LanguageFromRequest(r *http.Request) string { + // 1. Cookie preference + if c, err := r.Cookie(CookieName); err == nil { + if c.Value == "fr" { + return "fr" + } + return "en" + } + + // 2. Accept-Language header + al := r.Header.Get("Accept-Language") + if strings.HasPrefix(strings.ToLower(al), "fr") { + return "fr" + } + + return "en" +} + +// LanguageMiddleware injects `lang` and a gi18n.Localizer in the request context. +func LanguageMiddleware(bundle *gi18n.Bundle) func(http.Handler) http.Handler { + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + lang := LanguageFromRequest(r) + loc := gi18n.NewLocalizer(bundle, lang) + + ctx := context.WithValue(r.Context(), ctxKeyLang, lang) + ctx = context.WithValue(ctx, ctxKeyLocalizer, loc) + next.ServeHTTP(w, r.WithContext(ctx)) + }) + } +} + +// FromContext returns (lang, localizer) if present. +func FromContext(ctx context.Context) (string, *gi18n.Localizer) { + var lang string + if v := ctx.Value(ctxKeyLang); v != nil { + if s, ok := v.(string); ok { + lang = s + } + } + var loc *gi18n.Localizer + if v := ctx.Value(ctxKeyLocalizer); v != nil { + if l, ok := v.(*gi18n.Localizer); ok { + loc = l + } + } + if lang == "" { + lang = "en" + } + if loc == nil { + loc = gi18n.NewLocalizer(gi18n.NewBundle(language.English), lang) + } + return lang, loc +} + +// LangFromContext returns the resolved language code from context. +func LangFromContext(ctx context.Context) string { + lang, _ := FromContext(ctx) + return lang +} + +// Localize returns the localized message for a given message ID. +func Localize(ctx context.Context, id string) string { + _, loc := FromContext(ctx) + msg, err := loc.Localize(&gi18n.LocalizeConfig{MessageID: id}) + if err != nil { + return id + } + return msg +} + +// TranslatorFromRequest returns a simple `func(id string) string` based on request context. +func TranslatorFromRequest(r *http.Request) func(string) string { + _, loc := FromContext(r.Context()) + return func(id string) string { + msg, err := loc.Localize(&gi18n.LocalizeConfig{MessageID: id}) + if err != nil { + // Fallback to message id + return id + } + return msg + } +} diff --git a/internal/i18n/locales/en.json b/internal/i18n/locales/en.json new file mode 100644 index 0000000..9b3a6e4 --- /dev/null +++ b/internal/i18n/locales/en.json @@ -0,0 +1,120 @@ +[ + { + "id": "app.title", + "translation": "RentEase | Your Property Management System" + }, + { "id": "nav.bookings", "translation": "Bookings" }, + { "id": "nav.reports", "translation": "Reports" }, + { "id": "nav.new_booking", "translation": "New Booking" }, + { "id": "bookings.heading", "translation": "Bookings" }, + { "id": "bookings.subheading", "translation": "Overview of the activity" }, + { + "id": "search.bookings.placeholder", + "translation": "Search bookings by name…" + }, + { "id": "login.welcome", "translation": "Welcome" }, + { "id": "login.subtitle", "translation": "Manage your rental property" }, + { "id": "login.title", "translation": "Login" }, + { "id": "login.auth_error", "translation": "Authentication error" }, + { "id": "login.password_short", "translation": "Password is too short" }, + { "id": "login.submit", "translation": "Log in" }, + { + "id": "login.registration_disabled", + "translation": "Registration is disabled. Please ask an admin to activate it." + }, + { "id": "booking.new.title", "translation": "New Booking" }, + { "id": "booking.new.subtitle", "translation": "Create a new booking" }, + { "id": "booking.new.customer_name", "translation": "Customer name" }, + { "id": "booking.new.phone_number", "translation": "Phone number" }, + { "id": "booking.new.customer_number", "translation": "Customer number" }, + { "id": "booking.new.email", "translation": "Email" }, + { "id": "booking.new.from", "translation": "From" }, + { "id": "booking.new.to", "translation": "To" }, + { "id": "booking.new.platform", "translation": "Platform" }, + { "id": "booking.new.fees", "translation": "Fees" }, + { "id": "booking.new.platform_id", "translation": "Platform ID" }, + { "id": "booking.new.submit", "translation": "Submit" }, + { "id": "booking.form.customer_info", "translation": "Customer Information" }, + { "id": "booking.form.name", "translation": "Name" }, + { "id": "booking.form.phone_number", "translation": "Phone number" }, + { "id": "booking.form.email", "translation": "Email" }, + { "id": "booking.form.guests", "translation": "Number of guests" }, + { "id": "booking.form.details", "translation": "Booking Details" }, + { "id": "booking.form.from", "translation": "From" }, + { "id": "booking.form.to", "translation": "To" }, + { "id": "booking.form.platform", "translation": "Platform" }, + { "id": "booking.form.platform_id", "translation": "Platform ID" }, + { "id": "booking.form.platform_fees", "translation": "Platform Fees" }, + { "id": "action.update", "translation": "Update" }, + { "id": "action.edit", "translation": "Edit" }, + { "id": "action.save", "translation": "Save" }, + { "id": "booking.view.create_pdf", "translation": "Create PDF" }, + { "id": "booking.view.canceled", "translation": "Canceled" }, + { "id": "booking.view.cancel", "translation": "Cancel" }, + { "id": "booking.view.line_items", "translation": "Line Items" }, + { "id": "booking.view.add_payment", "translation": "Add Payment" }, + { "id": "booking.view.item", "translation": "Item" }, + { "id": "booking.view.quantity", "translation": "Quantity" }, + { "id": "booking.view.price", "translation": "Price" }, + { "id": "booking.view.payment_method", "translation": "Payment Method" }, + { "id": "booking.view.subtotal", "translation": "Sub-total" }, + { "id": "booking.view.actions", "translation": "Actions" }, + { "id": "booking.view.total", "translation": "Total" }, + { "id": "booking.view.add_line_item_title", "translation": "Add New Line Item" }, + { "id": "booking.view.add_line_item", "translation": "Add Line Item" }, + { "id": "booking.lines.check_in", "translation": "Check-in" }, + { "id": "booking.lines.check_out", "translation": "Check-out" }, + { "id": "booking.lines.id_label", "translation": "ID" }, + { "id": "booking.lines.view_details", "translation": "View Details" }, + { "id": "payment.modal.title", "translation": "Add Payment" }, + { "id": "payment.modal.amount", "translation": "Amount" }, + { "id": "payment.modal.method", "translation": "Payment Method" }, + { + "id": "payment.modal.select_method", + "translation": "Select payment method" + }, + { "id": "payment.method.cash", "translation": "Cash" }, + { "id": "payment.method.card", "translation": "Card" }, + { "id": "payment.method.cheque", "translation": "Cheque" }, + { "id": "payment.method.transfer", "translation": "Bank Transfer" }, + { "id": "payment.modal.submit", "translation": "Add Payment" }, + { "id": "payment.view_in_stripe", "translation": "View in Stripe" }, + { + "id": "booking.payment_link_failed", + "translation": "Unable to create the Stripe payment link. Please try again." + }, + { + "id": "booking.payment_link_unavailable", + "translation": "Unable to create the Stripe payment link." + }, + { + "id": "booking.payment_link_unexpected", + "translation": "Unexpected error while creating payment link." + }, + { "id": "report.title", "translation": "Reports" }, + { + "id": "report.subtitle", + "translation": "Generate monthly and yearly statements" + }, + { "id": "report.period", "translation": "Period" }, + { "id": "report.period.monthly", "translation": "Monthly" }, + { "id": "report.period.yearly", "translation": "Yearly" }, + { "id": "report.year", "translation": "Year" }, + { "id": "report.month", "translation": "Month" }, + { "id": "report.generate", "translation": "Generate Report" }, + { "id": "report.section.title", "translation": "Your report" }, + { "id": "report.section.create_pdf", "translation": "Create PDF" }, + { "id": "report.table.id", "translation": "ID" }, + { "id": "report.table.name", "translation": "Name" }, + { "id": "report.table.from", "translation": "From" }, + { "id": "report.table.to", "translation": "To" }, + { "id": "report.table.revenue", "translation": "Revenue" }, + { "id": "report.table.platform", "translation": "Platform" }, + { "id": "report.table.platform_fees", "translation": "Platform Fees" }, + { "id": "report.table.fees", "translation": "Fees" }, + { "id": "report.table.profit", "translation": "Profit" }, + { "id": "report.table.totals", "translation": "Totals" }, + { "id": "report.table.card_only", "translation": "Card-only" }, + { "id": "report.table.booking_only", "translation": "Booking-only" }, + { "id": "success.done", "translation": "Done" } +] diff --git a/internal/i18n/locales/fr.json b/internal/i18n/locales/fr.json new file mode 100644 index 0000000..a983de7 --- /dev/null +++ b/internal/i18n/locales/fr.json @@ -0,0 +1,120 @@ +[ + { + "id": "app.title", + "translation": "RentEase | Votre système de gestion immobilière" + }, + { "id": "nav.bookings", "translation": "Réservations" }, + { "id": "nav.reports", "translation": "Rapports" }, + { "id": "nav.new_booking", "translation": "Nouvelle réservation" }, + { "id": "bookings.heading", "translation": "Réservations" }, + { "id": "bookings.subheading", "translation": "Aperçu de l’activité" }, + { + "id": "search.bookings.placeholder", + "translation": "Rechercher des réservations par nom…" + }, + { "id": "login.welcome", "translation": "Bienvenue" }, + { "id": "login.subtitle", "translation": "Gérez votre location" }, + { "id": "login.title", "translation": "Connexion" }, + { "id": "login.auth_error", "translation": "Erreur d’authentification" }, + { "id": "login.password_short", "translation": "Mot de passe trop court" }, + { "id": "login.submit", "translation": "Se connecter" }, + { + "id": "login.registration_disabled", + "translation": "L’inscription est désactivée. Demandez à un administrateur de l’activer." + }, + { "id": "booking.new.title", "translation": "Nouvelle réservation" }, + { "id": "booking.new.subtitle", "translation": "Créer une nouvelle réservation" }, + { "id": "booking.new.customer_name", "translation": "Nom du client" }, + { "id": "booking.new.phone_number", "translation": "Numéro de téléphone" }, + { "id": "booking.new.customer_number", "translation": "Nombre de clients" }, + { "id": "booking.new.email", "translation": "Email" }, + { "id": "booking.new.from", "translation": "Du" }, + { "id": "booking.new.to", "translation": "Au" }, + { "id": "booking.new.platform", "translation": "Plateforme" }, + { "id": "booking.new.fees", "translation": "Frais" }, + { "id": "booking.new.platform_id", "translation": "Identifiant plateforme" }, + { "id": "booking.new.submit", "translation": "Valider" }, + { "id": "booking.form.customer_info", "translation": "Informations client" }, + { "id": "booking.form.name", "translation": "Nom" }, + { "id": "booking.form.phone_number", "translation": "Numéro de téléphone" }, + { "id": "booking.form.email", "translation": "Email" }, + { "id": "booking.form.guests", "translation": "Nombre de voyageurs" }, + { "id": "booking.form.details", "translation": "Détails de la réservation" }, + { "id": "booking.form.from", "translation": "Du" }, + { "id": "booking.form.to", "translation": "Au" }, + { "id": "booking.form.platform", "translation": "Plateforme" }, + { "id": "booking.form.platform_id", "translation": "Identifiant plateforme" }, + { "id": "booking.form.platform_fees", "translation": "Frais de plateforme" }, + { "id": "action.update", "translation": "Mettre à jour" }, + { "id": "action.edit", "translation": "Modifier" }, + { "id": "action.save", "translation": "Enregistrer" }, + { "id": "booking.view.create_pdf", "translation": "Créer PDF" }, + { "id": "booking.view.canceled", "translation": "Annulée" }, + { "id": "booking.view.cancel", "translation": "Annuler" }, + { "id": "booking.view.line_items", "translation": "Lignes" }, + { "id": "booking.view.add_payment", "translation": "Ajouter un paiement" }, + { "id": "booking.view.item", "translation": "Article" }, + { "id": "booking.view.quantity", "translation": "Quantité" }, + { "id": "booking.view.price", "translation": "Prix" }, + { "id": "booking.view.payment_method", "translation": "Moyen de paiement" }, + { "id": "booking.view.subtotal", "translation": "Sous-total" }, + { "id": "booking.view.actions", "translation": "Actions" }, + { "id": "booking.view.total", "translation": "Total" }, + { "id": "booking.view.add_line_item_title", "translation": "Ajouter une nouvelle ligne" }, + { "id": "booking.view.add_line_item", "translation": "Ajouter une ligne" }, + { "id": "booking.lines.check_in", "translation": "Arrivée" }, + { "id": "booking.lines.check_out", "translation": "Départ" }, + { "id": "booking.lines.id_label", "translation": "ID" }, + { "id": "booking.lines.view_details", "translation": "Voir détails" }, + { "id": "payment.modal.title", "translation": "Ajouter un paiement" }, + { "id": "payment.modal.amount", "translation": "Montant" }, + { "id": "payment.modal.method", "translation": "Moyen de paiement" }, + { + "id": "payment.modal.select_method", + "translation": "Sélectionner un moyen de paiement" + }, + { "id": "payment.method.cash", "translation": "Espèces" }, + { "id": "payment.method.card", "translation": "Carte" }, + { "id": "payment.method.cheque", "translation": "Chèque" }, + { "id": "payment.method.transfer", "translation": "Virement" }, + { "id": "payment.modal.submit", "translation": "Ajouter le paiement" }, + { "id": "payment.view_in_stripe", "translation": "Voir dans Stripe" }, + { + "id": "booking.payment_link_failed", + "translation": "Impossible de créer le lien de paiement Stripe. Veuillez réessayer." + }, + { + "id": "booking.payment_link_unavailable", + "translation": "Impossible de créer le lien de paiement Stripe." + }, + { + "id": "booking.payment_link_unexpected", + "translation": "Erreur inattendue lors de la création du lien de paiement." + }, + { "id": "report.title", "translation": "Rapports" }, + { + "id": "report.subtitle", + "translation": "Générez des bilans mensuels et annuels" + }, + { "id": "report.period", "translation": "Période" }, + { "id": "report.period.monthly", "translation": "Mensuel" }, + { "id": "report.period.yearly", "translation": "Annuel" }, + { "id": "report.year", "translation": "Année" }, + { "id": "report.month", "translation": "Mois" }, + { "id": "report.generate", "translation": "Générer le rapport" }, + { "id": "report.section.title", "translation": "Votre rapport" }, + { "id": "report.section.create_pdf", "translation": "Créer PDF" }, + { "id": "report.table.id", "translation": "ID" }, + { "id": "report.table.name", "translation": "Nom" }, + { "id": "report.table.from", "translation": "Du" }, + { "id": "report.table.to", "translation": "Au" }, + { "id": "report.table.revenue", "translation": "Revenus" }, + { "id": "report.table.platform", "translation": "Plateforme" }, + { "id": "report.table.platform_fees", "translation": "Frais plateforme" }, + { "id": "report.table.fees", "translation": "Frais" }, + { "id": "report.table.profit", "translation": "Profit" }, + { "id": "report.table.totals", "translation": "Totaux" }, + { "id": "report.table.card_only", "translation": "Carte uniquement" }, + { "id": "report.table.booking_only", "translation": "Booking uniquement" }, + { "id": "success.done", "translation": "Terminé" } +] diff --git a/internal/server/handle_auth.go b/internal/server/handle_auth.go index 78a9316..e40e777 100644 --- a/internal/server/handle_auth.go +++ b/internal/server/handle_auth.go @@ -10,7 +10,7 @@ import ( func handleLoginPage() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - if err := renderTempl(w, http.StatusOK, view.Login(view.LoginFormViewModel{})); err != nil { + if err := renderTempl(w, r, http.StatusOK, view.Login(view.LoginFormViewModel{})); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } } @@ -33,7 +33,7 @@ func handleLogin(as *auth.Service) http.HandlerFunc { Errors: make(map[string]string), } lfvm.Errors["credentials"] = "invalid credentials" - if err := renderTempl(w, http.StatusUnauthorized, view.LoginForm(lfvm)); err != nil { + if err := renderTempl(w, r, http.StatusUnauthorized, view.LoginForm(lfvm)); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } return diff --git a/internal/server/handle_bookings.go b/internal/server/handle_bookings.go index ffd63de..6245dbd 100644 --- a/internal/server/handle_bookings.go +++ b/internal/server/handle_bookings.go @@ -54,9 +54,9 @@ func handleBookingListPage(bs *booking.Service, hc *config.Host) http.HandlerFun var err error switch { case hxRequest(r) && !hxBoosted(r): - err = renderTempl(w, http.StatusOK, view.BookingLines(bvm)) + err = renderTempl(w, r, http.StatusOK, view.BookingLines(bvm)) default: - err = renderTempl(w, http.StatusOK, view.ListBookings(bvm)) + err = renderTempl(w, r, http.StatusOK, view.ListBookings(bvm)) } if err != nil { @@ -105,7 +105,7 @@ func handleBookingList(bs *booking.Service) http.HandlerFunc { func handleBookingCreatePage(hc *config.Host) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - if err := renderTempl(w, http.StatusOK, view.NewBooking(u.Map(hc.Platforms, func(p config.Platform) string { + if err := renderTempl(w, r, http.StatusOK, view.NewBooking(u.Map(hc.Platforms, func(p config.Platform) string { return string(p) }))); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) @@ -229,7 +229,7 @@ func handleBookingPage(bs *booking.Service, hc *config.Host) http.HandlerFunc { PaymentMethods: hc.PaymentMethods, } - if err := renderTempl(w, http.StatusOK, view.BookingById(bvm)); err != nil { + if err := renderTempl(w, r, http.StatusOK, view.BookingById(bvm)); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } } @@ -340,7 +340,7 @@ func handleBookingUpdate(bs *booking.Service, hc *config.Host) http.HandlerFunc PdfUrl: templ.SafeURL(fmt.Sprintf("%s/pdf/%d", constant.RouteBooking, b.ID)), }) - if err := renderTempl(w, http.StatusOK, form); err != nil { + if err := renderTempl(w, r, http.StatusOK, form); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } } @@ -366,7 +366,7 @@ func handleLineItemForm(bs *booking.Service) http.HandlerFunc { ItemUrl: fmt.Sprintf("%s/%d", constant.RouteItem, i.ID), }) - if err := renderTempl(w, http.StatusOK, form); err != nil { + if err := renderTempl(w, r, http.StatusOK, form); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } } @@ -450,7 +450,7 @@ func handleItemPay(bs *booking.Service) http.HandlerFunc { } i := bs.PayItem(itemId) - if err := renderTempl(w, http.StatusOK, view.LineItem(&view.ItemViewModel{ + if err := renderTempl(w, r, http.StatusOK, view.LineItem(&view.ItemViewModel{ Id: itemIdStr, Item: i.Item, Quantity: strconv.Itoa(i.Quantity), @@ -494,7 +494,7 @@ func handleItemUpdate(bs *booking.Service) http.HandlerFunc { i := bs.UpdateItem(id, r.FormValue("item"), quantity, price, r.FormValue("paymentMethod"), r.FormValue("paymentStatus")) - if err := renderTempl(w, http.StatusCreated, view.LineItem(&view.ItemViewModel{ + if err := renderTempl(w, r, http.StatusCreated, view.LineItem(&view.ItemViewModel{ Id: strconv.Itoa(id), Item: i.Item, Quantity: strconv.Itoa(i.Quantity), @@ -524,7 +524,7 @@ func handleBookingCancel(bs *booking.Service) http.HandlerFunc { return err }) - if err := renderTempl(w, http.StatusOK, component); err != nil { + if err := renderTempl(w, r, http.StatusOK, component); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } } diff --git a/internal/server/handle_language.go b/internal/server/handle_language.go new file mode 100644 index 0000000..27778ae --- /dev/null +++ b/internal/server/handle_language.go @@ -0,0 +1,41 @@ +package server + +import ( + "net/http" + + "github.com/go-chi/chi/v5" + + ri18n "github.com/rjNemo/rentease/internal/i18n" +) + +func handleLanguage() http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + locale := chi.URLParam(r, "locale") + if locale != "fr" { + locale = "en" + } + + // Set preference cookie (1 year) + http.SetCookie(w, &http.Cookie{ + Name: ri18n.CookieName, + Value: locale, + Path: "/", + MaxAge: 31536000, + HttpOnly: false, + SameSite: http.SameSiteLaxMode, + }) + + // Redirect back to referer or home + referer := r.Header.Get("Referer") + if referer == "" { + referer = "/" + } + + if hxRequest(r) { + _ = hxRedirect(w, http.StatusSeeOther, referer) + return + } + + http.Redirect(w, r, referer, http.StatusSeeOther) + } +} diff --git a/internal/server/handle_payments.go b/internal/server/handle_payments.go index ff371e4..93de4b7 100644 --- a/internal/server/handle_payments.go +++ b/internal/server/handle_payments.go @@ -56,7 +56,7 @@ func handleCreatePayment(bs *booking.Service, ps *payment.Service, hc *config.Ho }), ) - if err := renderTempl(w, http.StatusOK, component); err != nil { + if err := renderTempl(w, r, http.StatusOK, component); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } } @@ -77,7 +77,7 @@ func handlePaymentForm(ps *payment.Service, hc *config.Host) http.HandlerFunc { } form := view.PaymentForm(paymentViewModelFromBookingPayment(*p, hc.StripeAccountID)) - if err := renderTempl(w, http.StatusOK, form); err != nil { + if err := renderTempl(w, r, http.StatusOK, form); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } } @@ -111,7 +111,7 @@ func handlePaymentUpdate(ps *payment.Service, hc *config.Host) http.HandlerFunc return } - if err := renderTempl(w, http.StatusOK, view.PaymentLine(paymentViewModelFromBookingPayment(*p, hc.StripeAccountID))); err != nil { + if err := renderTempl(w, r, http.StatusOK, view.PaymentLine(paymentViewModelFromBookingPayment(*p, hc.StripeAccountID))); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } } diff --git a/internal/server/handle_reports.go b/internal/server/handle_reports.go index 51409dd..c60722b 100644 --- a/internal/server/handle_reports.go +++ b/internal/server/handle_reports.go @@ -32,7 +32,7 @@ func handleReportsPage() http.HandlerFunc { return string(m) }), month, yearStr) - if err := renderTempl(w, http.StatusOK, component); err != nil { + if err := renderTempl(w, r, http.StatusOK, component); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } } @@ -91,7 +91,7 @@ func handleReportCompute(bs *booking.Service, hc *config.Host) http.HandlerFunc }), } - if err := renderTempl(w, http.StatusOK, view.ReportSection(reportVm)); err != nil { + if err := renderTempl(w, r, http.StatusOK, view.ReportSection(reportVm)); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } } diff --git a/internal/server/helper.go b/internal/server/helper.go index 6e4fe70..feb1772 100644 --- a/internal/server/helper.go +++ b/internal/server/helper.go @@ -1,18 +1,17 @@ package server import ( - "context" "log" "net/http" "github.com/a-h/templ" ) -func renderTempl(w http.ResponseWriter, status int, t templ.Component) error { +func renderTempl(w http.ResponseWriter, r *http.Request, status int, t templ.Component) error { w.Header().Set("Content-Type", "text/html; charset=utf-8") w.WriteHeader(status) - if err := t.Render(context.Background(), w); err != nil { + if err := t.Render(r.Context(), w); err != nil { log.Printf("failed to render response template %s", err) return err } diff --git a/internal/server/routes.go b/internal/server/routes.go index d31784c..2899964 100644 --- a/internal/server/routes.go +++ b/internal/server/routes.go @@ -13,6 +13,7 @@ func (s *Server) MountHandlers() { s.Router.Get("/", handleLoginPage()) s.Router.Post("/", handleLogin(s.as)) s.Router.Post("/webhooks/stripe", handleStripeWebhook(s.ps, s.stripeWebhookSecret)) + s.Router.Get("/lang/{locale}", handleLanguage()) s.Router.Route("/api", func(r chi.Router) { r.Use(apiKeyMiddleware(s.as)) diff --git a/internal/server/server.go b/internal/server/server.go index ee8c5f5..dbe5113 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -18,6 +18,7 @@ import ( "github.com/go-chi/cors" "github.com/rjNemo/rentease/internal/config" + ri18n "github.com/rjNemo/rentease/internal/i18n" "github.com/rjNemo/rentease/internal/service/auth" "github.com/rjNemo/rentease/internal/service/booking" "github.com/rjNemo/rentease/internal/service/payment" @@ -106,6 +107,12 @@ func NewRouter(filesystem embed.FS, debug bool, origins []string) (*chi.Mux, err r.Use(middleware.Recoverer) r.Use(middleware.Compress(5)) r.Use(CachingMiddleware(0, "js", "css", "png", "ico")) + // Initialize i18n and attach language middleware + bundle, err := ri18n.Bundle() + if err != nil { + return nil, fmt.Errorf("failed to initialize i18n: %w", err) + } + r.Use(ri18n.LanguageMiddleware(bundle)) if len(origins) == 0 { origins = []string{"*"} diff --git a/internal/view/booking_by_id.templ b/internal/view/booking_by_id.templ index 1a918c7..63637bd 100644 --- a/internal/view/booking_by_id.templ +++ b/internal/view/booking_by_id.templ @@ -2,6 +2,8 @@ package view import ( "fmt" + + "github.com/rjNemo/rentease/internal/i18n" "github.com/rjNemo/rentease/internal/view/layout" ) @@ -13,7 +15,7 @@ templ BookingById(booking *BookingViewModel) {

{ booking.Id }

- Create PDF + { i18n.Localize(ctx, "booking.view.create_pdf") } if booking.Canceled { - Canceled + { i18n.Localize(ctx, "booking.view.canceled") } } else { }
@@ -39,10 +41,10 @@ templ BookingById(booking *BookingViewModel) {

- Line Items + { i18n.Localize(ctx, "booking.view.line_items") }

- +
-

Add New Line Item

+

{ i18n.Localize(ctx, "booking.view.add_line_item_title") }

- +
@PaymentModal(booking.PaymentUrl) @@ -182,7 +189,7 @@ templ BookingById(booking *BookingViewModel) { templ PaymentModal(paymentUrl string) { diff --git a/internal/view/booking_by_id_templ.go b/internal/view/booking_by_id_templ.go index 2d3e7a7..093bf89 100644 --- a/internal/view/booking_by_id_templ.go +++ b/internal/view/booking_by_id_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.3.960 +// templ: version: v0.3.977 package view //lint:file-ignore SA4006 This context is only used if a nested component is present. @@ -10,6 +10,8 @@ import templruntime "github.com/a-h/templ/runtime" import ( "fmt" + + "github.com/rjNemo/rentease/internal/i18n" "github.com/rjNemo/rentease/internal/view/layout" ) @@ -53,7 +55,7 @@ func BookingById(booking *BookingViewModel) templ.Component { var templ_7745c5c3_Var3 string templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(booking.Name) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/booking_by_id.templ`, Line: 12, Col: 54} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/booking_by_id.templ`, Line: 14, Col: 54} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) if templ_7745c5c3_Err != nil { @@ -66,7 +68,7 @@ func BookingById(booking *BookingViewModel) templ.Component { var templ_7745c5c3_Var4 string templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(booking.Id) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/booking_by_id.templ`, Line: 13, Col: 56} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/booking_by_id.templ`, Line: 15, Col: 56} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) if templ_7745c5c3_Err != nil { @@ -79,41 +81,80 @@ func BookingById(booking *BookingViewModel) templ.Component { var templ_7745c5c3_Var5 templ.SafeURL templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinURLErrs(booking.PdfUrl) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/booking_by_id.templ`, Line: 16, Col: 66} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/booking_by_id.templ`, Line: 18, Col: 66} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "\" target=\"_blank\">Create PDF ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "\" target=\"_blank\">") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var6 string + templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(i18n.Localize(ctx, "booking.view.create_pdf")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/booking_by_id.templ`, Line: 18, Col: 132} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if booking.Canceled { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "Canceled") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var7 string + templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(i18n.Localize(ctx, "booking.view.canceled")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/booking_by_id.templ`, Line: 28, Col: 82} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "\" hx-swap=\"outerHTML\">") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var9 string + templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(i18n.Localize(ctx, "booking.view.cancel")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/booking_by_id.templ`, Line: 31, Col: 49} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -121,20 +162,124 @@ func BookingById(booking *BookingViewModel) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "

Line Items

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "
ItemQuantityPrice (€)Payment MethodSub-total (€)Actions
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -142,69 +287,147 @@ func BookingById(booking *BookingViewModel) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var13 string + templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(i18n.Localize(ctx, "booking.view.item")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/booking_by_id.templ`, Line: 63, Col: 52} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var14 string + templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(i18n.Localize(ctx, "booking.view.quantity")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/booking_by_id.templ`, Line: 64, Col: 56} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var15 string + templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(i18n.Localize(ctx, "booking.view.price")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/booking_by_id.templ`, Line: 65, Col: 53} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, " (€)") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var16 string + templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(i18n.Localize(ctx, "booking.view.payment_method")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/booking_by_id.templ`, Line: 66, Col: 62} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var17 string + templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(i18n.Localize(ctx, "booking.view.subtotal")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/booking_by_id.templ`, Line: 67, Col: 56} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, " (€)") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var18 string + templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(i18n.Localize(ctx, "booking.view.actions")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/booking_by_id.templ`, Line: 68, Col: 74} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "
Total:") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var8 string - templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(booking.Total) + var templ_7745c5c3_Var19 string + templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(i18n.Localize(ctx, "booking.view.total")) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/booking_by_id.templ`, Line: 73, Col: 56} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/booking_by_id.templ`, Line: 74, Col: 94} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "

Add New Line Item

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var9 string - templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%s/items", booking.Url)) + var templ_7745c5c3_Var20 string + templ_7745c5c3_Var20, templ_7745c5c3_Err = templ.JoinStringErrs(booking.Total) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/booking_by_id.templ`, Line: 82, Col: 50} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/booking_by_id.templ`, Line: 75, Col: 56} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var20)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "\" hx-target=\"#line-items\" hx-swap=\"afterend\" hx-on::after-request=\"if(event.detail.successful) this.reset()\" class=\"grid grid-cols-1 sm:grid-cols-2 md:grid-cols-4 gap-4 items-end\">
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } for _, item := range booking.ItemList { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 31, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -238,25 +461,142 @@ func PaymentModal(paymentUrl string) templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var12 := templ.GetChildren(ctx) - if templ_7745c5c3_Var12 == nil { - templ_7745c5c3_Var12 = templ.NopComponent + templ_7745c5c3_Var29 := templ.GetChildren(ctx) + if templ_7745c5c3_Var29 == nil { + templ_7745c5c3_Var29 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "

Add Payment

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var13 string - templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(paymentUrl) + var templ_7745c5c3_Var30 string + templ_7745c5c3_Var30, templ_7745c5c3_Err = templ.JoinStringErrs(i18n.Localize(ctx, "payment.modal.title")) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/booking_by_id.templ`, Line: 188, Col: 24} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/booking_by_id.templ`, Line: 192, Col: 76} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var30)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "\" hx-target=\"#payment-lines\" hx-swap=\"outerHTML\" hx-on::after-request=\"if(event.detail.successful) payment_modal.close()\">

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/internal/view/booking_form.templ b/internal/view/booking_form.templ index 55b9569..aa1433c 100644 --- a/internal/view/booking_form.templ +++ b/internal/view/booking_form.templ @@ -1,17 +1,19 @@ package view +import "github.com/rjNemo/rentease/internal/i18n" + templ BookingForm(booking BookingViewModel) {

- Customer Information + { i18n.Localize(ctx, "booking.form.customer_info") }

- ID: { b.Id } + { i18n.Localize(ctx, "booking.lines.id_label") }: { b.Id }
diff --git a/internal/view/booking_lines_templ.go b/internal/view/booking_lines_templ.go index 569769b..af4cdb6 100644 --- a/internal/view/booking_lines_templ.go +++ b/internal/view/booking_lines_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.3.960 +// templ: version: v0.3.977 package view //lint:file-ignore SA4006 This context is only used if a nested component is present. @@ -8,7 +8,7 @@ package view import "github.com/a-h/templ" import templruntime "github.com/a-h/templ/runtime" -import () +import "github.com/rjNemo/rentease/internal/i18n" func BookingLines(bookings []*ListBookingsViewModel) templ.Component { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { @@ -90,77 +90,129 @@ func BookingLines(bookings []*ListBookingsViewModel) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "
Check-in
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var5 string - templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(b.From) + templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(i18n.Localize(ctx, "booking.lines.check_in")) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/booking_lines.templ`, Line: 23, Col: 40} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/booking_lines.templ`, Line: 22, Col: 80} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "
Check-out
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var6 string - templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(b.To) + templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(b.From) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/booking_lines.templ`, Line: 27, Col: 38} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/booking_lines.templ`, Line: 23, Col: 40} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var7 string - templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(b.Total) + templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(i18n.Localize(ctx, "booking.lines.check_out")) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/booking_lines.templ`, Line: 32, Col: 16} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/booking_lines.templ`, Line: 26, Col: 81} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, " €
ID: ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var8 string - templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(b.Id) + templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(b.To) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/booking_lines.templ`, Line: 35, Col: 17} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/booking_lines.templ`, Line: 27, Col: 38} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var10 string + templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(i18n.Localize(ctx, "booking.lines.id_label")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/booking_lines.templ`, Line: 35, Col: 53} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, ": ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var11 string + templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(b.Id) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/booking_lines.templ`, Line: 35, Col: 63} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/internal/view/bookings_list.templ b/internal/view/bookings_list.templ index 557468a..d197b05 100644 --- a/internal/view/bookings_list.templ +++ b/internal/view/bookings_list.templ @@ -1,18 +1,21 @@ package view -import "github.com/rjNemo/rentease/internal/view/layout" +import ( + "github.com/rjNemo/rentease/internal/i18n" + "github.com/rjNemo/rentease/internal/view/layout" +) templ ListBookings(bookings []*ListBookingsViewModel) { @layout.BaseLayout() {
-

Bookings

-

Overview of the activity

+

{ i18n.Localize(ctx, "bookings.heading") }

+

{ i18n.Localize(ctx, "bookings.subheading") }

Bookings

Overview of the activity

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var3 string + templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(i18n.Localize(ctx, "bookings.heading")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/bookings_list.templ`, Line: 12, Col: 103} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var4 string + templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(i18n.Localize(ctx, "bookings.subheading")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/bookings_list.templ`, Line: 13, Col: 90} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/internal/view/bookings_new.templ b/internal/view/bookings_new.templ index 9fd53b8..88db829 100644 --- a/internal/view/bookings_new.templ +++ b/internal/view/bookings_new.templ @@ -1,13 +1,16 @@ package view -import "github.com/rjNemo/rentease/internal/view/layout" +import ( + "github.com/rjNemo/rentease/internal/i18n" + "github.com/rjNemo/rentease/internal/view/layout" +) templ NewBooking(platforms []string) { @layout.BaseLayout() {
-

New Booking

-

Create a new booking

+

{ i18n.Localize(ctx, "booking.new.title") }

+

{ i18n.Localize(ctx, "booking.new.subtitle") }

@@ -15,19 +18,19 @@ templ NewBooking(platforms []string) {
@@ -35,19 +38,19 @@ templ NewBooking(platforms []string) {
@@ -55,7 +58,7 @@ templ NewBooking(platforms []string) {
- +
diff --git a/internal/view/bookings_new_templ.go b/internal/view/bookings_new_templ.go index c18e998..02da52f 100644 --- a/internal/view/bookings_new_templ.go +++ b/internal/view/bookings_new_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.3.960 +// templ: version: v0.3.977 package view //lint:file-ignore SA4006 This context is only used if a nested component is present. @@ -8,7 +8,10 @@ package view import "github.com/a-h/templ" import templruntime "github.com/a-h/templ/runtime" -import "github.com/rjNemo/rentease/internal/view/layout" +import ( + "github.com/rjNemo/rentease/internal/i18n" + "github.com/rjNemo/rentease/internal/view/layout" +) func NewBooking(platforms []string) templ.Component { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { @@ -43,43 +46,199 @@ func NewBooking(platforms []string) templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "

New Booking

Create a new booking

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/internal/view/item_list.templ b/internal/view/item_list.templ index 5d08fb0..d244400 100644 --- a/internal/view/item_list.templ +++ b/internal/view/item_list.templ @@ -1,5 +1,7 @@ package view +import "github.com/rjNemo/rentease/internal/i18n" + templ ItemList(itemList ItemListViewModel) { for _, item := range itemList.Items { @@ -10,9 +12,9 @@ templ ItemList(itemList ItemListViewModel) { - Price (€) - Payment Method - Sub-total (€) + { i18n.Localize(ctx, "booking.view.price") } (€) + { i18n.Localize(ctx, "booking.view.payment_method") } + { i18n.Localize(ctx, "booking.view.subtotal") } (€) diff --git a/internal/view/item_list_templ.go b/internal/view/item_list_templ.go index 1cc18ea..90e610f 100644 --- a/internal/view/item_list_templ.go +++ b/internal/view/item_list_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.3.960 +// templ: version: v0.3.977 package view //lint:file-ignore SA4006 This context is only used if a nested component is present. @@ -8,6 +8,8 @@ package view import "github.com/a-h/templ" import templruntime "github.com/a-h/templ/runtime" +import "github.com/rjNemo/rentease/internal/i18n" + func ItemList(itemList ItemListViewModel) templ.Component { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context @@ -39,7 +41,46 @@ func ItemList(itemList ItemListViewModel) templ.Component { return templ_7745c5c3_Err } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, " Price (€)Payment MethodSub-total (€) ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, " ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var2 string + templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(i18n.Localize(ctx, "booking.view.price")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/item_list.templ`, Line: 15, Col: 49} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, " (€)") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var3 string + templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(i18n.Localize(ctx, "booking.view.payment_method")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/item_list.templ`, Line: 16, Col: 58} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var4 string + templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(i18n.Localize(ctx, "booking.view.subtotal")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/item_list.templ`, Line: 17, Col: 52} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, " (€) ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -51,7 +92,7 @@ func ItemList(itemList ItemListViewModel) templ.Component { } } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/internal/view/layout/base.templ b/internal/view/layout/base.templ index b3f6761..951d57d 100644 --- a/internal/view/layout/base.templ +++ b/internal/view/layout/base.templ @@ -1,13 +1,15 @@ package layout +import "github.com/rjNemo/rentease/internal/i18n" + const appName = "🏨 RentEase" templ BaseLayout() { - + @head() - @navbar() + @navbar(i18n.LangFromContext(ctx))
{ children... }
@@ -18,7 +20,7 @@ templ BaseLayout() { templ head() { - RentEase | Your Property Management System + { i18n.Localize(ctx, "app.title") } @@ -42,7 +44,7 @@ templ head() { } -templ navbar() { +templ navbar(lang string) { } diff --git a/internal/view/layout/base_templ.go b/internal/view/layout/base_templ.go index b74b789..8c12397 100644 --- a/internal/view/layout/base_templ.go +++ b/internal/view/layout/base_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.3.960 +// templ: version: v0.3.977 package layout //lint:file-ignore SA4006 This context is only used if a nested component is present. @@ -8,6 +8,8 @@ package layout import "github.com/a-h/templ" import templruntime "github.com/a-h/templ/runtime" +import "github.com/rjNemo/rentease/internal/i18n" + const appName = "🏨 RentEase" func BaseLayout() templ.Component { @@ -31,7 +33,20 @@ func BaseLayout() templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -39,15 +54,15 @@ func BaseLayout() templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = navbar().Render(ctx, templ_7745c5c3_Buffer) + templ_7745c5c3_Err = navbar(i18n.LangFromContext(ctx)).Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -55,7 +70,7 @@ func BaseLayout() templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -63,7 +78,7 @@ func BaseLayout() templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -87,12 +102,25 @@ func head() templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var2 := templ.GetChildren(ctx) - if templ_7745c5c3_Var2 == nil { - templ_7745c5c3_Var2 = templ.NopComponent + templ_7745c5c3_Var3 := templ.GetChildren(ctx) + if templ_7745c5c3_Var3 == nil { + templ_7745c5c3_Var3 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "RentEase | Your Property Management System") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var4 string + templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(i18n.Localize(ctx, "app.title")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/layout/base.templ`, Line: 23, Col: 42} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -100,7 +128,7 @@ func head() templ.Component { }) } -func navbar() templ.Component { +func navbar(lang string) templ.Component { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { @@ -116,25 +144,134 @@ func navbar() templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var3 := templ.GetChildren(ctx) - if templ_7745c5c3_Var3 == nil { - templ_7745c5c3_Var3 = templ.NopComponent + templ_7745c5c3_Var5 := templ.GetChildren(ctx) + if templ_7745c5c3_Var5 == nil { + templ_7745c5c3_Var5 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -158,25 +295,25 @@ func footer() templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var5 := templ.GetChildren(ctx) - if templ_7745c5c3_Var5 == nil { - templ_7745c5c3_Var5 = templ.NopComponent + templ_7745c5c3_Var16 := templ.GetChildren(ctx) + if templ_7745c5c3_Var16 == nil { + templ_7745c5c3_Var16 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/internal/view/layout/lang.go b/internal/view/layout/lang.go new file mode 100644 index 0000000..a284f69 --- /dev/null +++ b/internal/view/layout/lang.go @@ -0,0 +1,9 @@ +package layout + +func langToggleClass(current string, target string) string { + base := "btn btn-sm join-item" + if current == target { + return base + " btn-active" + } + return base +} diff --git a/internal/view/line_item.templ b/internal/view/line_item.templ index ed49542..f871d3c 100644 --- a/internal/view/line_item.templ +++ b/internal/view/line_item.templ @@ -1,5 +1,7 @@ package view +import "github.com/rjNemo/rentease/internal/i18n" + templ LineItem(item *ItemViewModel) { { item.Item } @@ -14,7 +16,7 @@ templ LineItem(item *ItemViewModel) { hx-target="closest tr" hx-swap="outerHTML" > - Edit + { i18n.Localize(ctx, "action.edit") } @@ -38,7 +40,7 @@ templ LineItemForm(item *ItemViewModel) { – { item.SubTotal } - + diff --git a/internal/view/line_item_templ.go b/internal/view/line_item_templ.go index 8721164..1d29907 100644 --- a/internal/view/line_item_templ.go +++ b/internal/view/line_item_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.3.960 +// templ: version: v0.3.977 package view //lint:file-ignore SA4006 This context is only used if a nested component is present. @@ -8,6 +8,8 @@ package view import "github.com/a-h/templ" import templruntime "github.com/a-h/templ/runtime" +import "github.com/rjNemo/rentease/internal/i18n" + func LineItem(item *ItemViewModel) templ.Component { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context @@ -36,7 +38,7 @@ func LineItem(item *ItemViewModel) templ.Component { var templ_7745c5c3_Var2 string templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(item.Item) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/line_item.templ`, Line: 5, Col: 17} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/line_item.templ`, Line: 7, Col: 17} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) if templ_7745c5c3_Err != nil { @@ -49,7 +51,7 @@ func LineItem(item *ItemViewModel) templ.Component { var templ_7745c5c3_Var3 string templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(item.Quantity) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/line_item.templ`, Line: 6, Col: 21} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/line_item.templ`, Line: 8, Col: 21} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) if templ_7745c5c3_Err != nil { @@ -62,7 +64,7 @@ func LineItem(item *ItemViewModel) templ.Component { var templ_7745c5c3_Var4 string templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(item.Price) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/line_item.templ`, Line: 7, Col: 18} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/line_item.templ`, Line: 9, Col: 18} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) if templ_7745c5c3_Err != nil { @@ -75,7 +77,7 @@ func LineItem(item *ItemViewModel) templ.Component { var templ_7745c5c3_Var5 string templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(item.SubTotal) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/line_item.templ`, Line: 9, Col: 21} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/line_item.templ`, Line: 11, Col: 21} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5)) if templ_7745c5c3_Err != nil { @@ -88,13 +90,26 @@ func LineItem(item *ItemViewModel) templ.Component { var templ_7745c5c3_Var6 string templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(item.ItemUrl) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/line_item.templ`, Line: 13, Col: 25} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/line_item.templ`, Line: 15, Col: 25} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "\" hx-target=\"closest tr\" hx-swap=\"outerHTML\">Edit") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "\" hx-target=\"closest tr\" hx-swap=\"outerHTML\">") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var7 string + templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(i18n.Localize(ctx, "action.edit")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/line_item.templ`, Line: 19, Col: 39} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -118,77 +133,90 @@ func LineItemForm(item *ItemViewModel) templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var7 := templ.GetChildren(ctx) - if templ_7745c5c3_Var7 == nil { - templ_7745c5c3_Var7 = templ.NopComponent + templ_7745c5c3_Var8 := templ.GetChildren(ctx) + if templ_7745c5c3_Var8 == nil { + templ_7745c5c3_Var8 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "
–") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "\" name=\"quantity\" form=\"edit-item\">
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "\" name=\"price\" form=\"edit-item\">–") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var13 string + templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(item.SubTotal) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/line_item.templ`, Line: 41, Col: 22} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/internal/view/login.templ b/internal/view/login.templ index e2775ee..67daa47 100644 --- a/internal/view/login.templ +++ b/internal/view/login.templ @@ -1,14 +1,17 @@ package view -import "github.com/rjNemo/rentease/internal/view/layout" +import ( + "github.com/rjNemo/rentease/internal/i18n" + "github.com/rjNemo/rentease/internal/view/layout" +) templ Login(lfvm LoginFormViewModel) { @layout.BaseLayout() {
-

Welcome

-

Manage your rental property

+

{ i18n.Localize(ctx, "login.welcome") }

+

{ i18n.Localize(ctx, "login.subtitle") }

@LoginForm(lfvm)
diff --git a/internal/view/login_form.templ b/internal/view/login_form.templ index f1be720..acf3ad9 100644 --- a/internal/view/login_form.templ +++ b/internal/view/login_form.templ @@ -1,5 +1,7 @@ package view +import "github.com/rjNemo/rentease/internal/i18n" + func isFormError(data map[string]string, key string) bool { _, ok := data[key] return ok @@ -9,7 +11,7 @@ templ LoginForm(lfvm LoginFormViewModel) {
-

Login

+

{ i18n.Localize(ctx, "login.title") }

if msg, ok := lfvm.Errors["credentials"]; ok { - Authentication error: { msg } + { i18n.Localize(ctx, "login.auth_error") }: { msg } }
@@ -46,11 +48,11 @@ templ LoginForm(lfvm LoginFormViewModel) { @input.debounce="passwordTooShort = $event.target.value.length < 4" :class="{'input-error': passwordTooShort}" /> - Password is too short + { i18n.Localize(ctx, "login.password_short") }
- +
- Registration is disabled. Please ask an admin to activate it. + { i18n.Localize(ctx, "login.registration_disabled") }
diff --git a/internal/view/login_form_templ.go b/internal/view/login_form_templ.go index 70f1c38..2fa3313 100644 --- a/internal/view/login_form_templ.go +++ b/internal/view/login_form_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.3.960 +// templ: version: v0.3.977 package view //lint:file-ignore SA4006 This context is only used if a nested component is present. @@ -8,6 +8,8 @@ package view import "github.com/a-h/templ" import templruntime "github.com/a-h/templ/runtime" +import "github.com/rjNemo/rentease/internal/i18n" + func isFormError(data map[string]string, key string) bool { _, ok := data[key] return ok @@ -34,76 +36,141 @@ func LoginForm(lfvm LoginFormViewModel) templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "

Login

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var2 string - templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(lfvm.Email) + templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(i18n.Localize(ctx, "login.title")) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/login_form.templ`, Line: 18, Col: 25} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/login_form.templ`, Line: 14, Col: 82} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "\" placeholder=\"john@email.com\" aria-label=\"email\" class=\"input input-bordered w-full\"") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, " autocomplete=\"email\" autofocus required> ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if msg, ok := lfvm.Errors["credentials"]; ok { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "Authentication error: ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var3 string - templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(msg) + var templ_7745c5c3_Var4 string + templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(i18n.Localize(ctx, "login.auth_error")) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/login_form.templ`, Line: 30, Col: 65} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/login_form.templ`, Line: 32, Col: 78} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, ": ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var5 string + templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(msg) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/login_form.templ`, Line: 32, Col: 87} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "
Password is too short
Registration is disabled. Please ask an admin to activate it.
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, " autocomplete=\"password\" required @input.debounce=\"passwordTooShort = $event.target.value.length < 4\" :class=\"{'input-error': passwordTooShort}\"> ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var7 string + templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(i18n.Localize(ctx, "login.password_short")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/login_form.templ`, Line: 51, Col: 107} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var9 string + templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(i18n.Localize(ctx, "login.registration_disabled")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/login_form.templ`, Line: 55, Col: 93} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/internal/view/login_templ.go b/internal/view/login_templ.go index 2971937..b1122fd 100644 --- a/internal/view/login_templ.go +++ b/internal/view/login_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.3.960 +// templ: version: v0.3.977 package view //lint:file-ignore SA4006 This context is only used if a nested component is present. @@ -8,7 +8,10 @@ package view import "github.com/a-h/templ" import templruntime "github.com/a-h/templ/runtime" -import "github.com/rjNemo/rentease/internal/view/layout" +import ( + "github.com/rjNemo/rentease/internal/i18n" + "github.com/rjNemo/rentease/internal/view/layout" +) func Login(lfvm LoginFormViewModel) templ.Component { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { @@ -43,7 +46,33 @@ func Login(lfvm LoginFormViewModel) templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "

Welcome

Manage your rental property

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var3 string + templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(i18n.Localize(ctx, "login.welcome")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/login.templ`, Line: 13, Col: 86} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var4 string + templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(i18n.Localize(ctx, "login.subtitle")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/login.templ`, Line: 14, Col: 84} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -51,7 +80,7 @@ func Login(lfvm LoginFormViewModel) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/internal/view/payment.templ b/internal/view/payment.templ index e4266a5..bff39f0 100644 --- a/internal/view/payment.templ +++ b/internal/view/payment.templ @@ -1,5 +1,7 @@ package view +import "github.com/rjNemo/rentease/internal/i18n" + templ PaymentLine(payment *PaymentViewModel) { @@ -14,7 +16,7 @@ templ PaymentLine(payment *PaymentViewModel) { rel="noreferrer noopener" class="badge badge-outline badge-sm ml-2" > - View in Stripe + { i18n.Localize(ctx, "payment.view_in_stripe") } } @@ -26,7 +28,7 @@ templ PaymentLine(payment *PaymentViewModel) { hx-target="closest tr" hx-swap="outerHTML" > - Edit + { i18n.Localize(ctx, "action.edit") } @@ -58,7 +60,7 @@ templ PaymentForm(payment *PaymentViewModel) { - + diff --git a/internal/view/payment_templ.go b/internal/view/payment_templ.go index bff03bc..27304d3 100644 --- a/internal/view/payment_templ.go +++ b/internal/view/payment_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.3.960 +// templ: version: v0.3.977 package view //lint:file-ignore SA4006 This context is only used if a nested component is present. @@ -8,6 +8,8 @@ package view import "github.com/a-h/templ" import templruntime "github.com/a-h/templ/runtime" +import "github.com/rjNemo/rentease/internal/i18n" + func PaymentLine(payment *PaymentViewModel) templ.Component { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context @@ -36,7 +38,7 @@ func PaymentLine(payment *PaymentViewModel) templ.Component { var templ_7745c5c3_Var2 string templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(payment.Amount) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/payment.templ`, Line: 7, Col: 24} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/payment.templ`, Line: 9, Col: 24} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) if templ_7745c5c3_Err != nil { @@ -49,7 +51,7 @@ func PaymentLine(payment *PaymentViewModel) templ.Component { var templ_7745c5c3_Var3 string templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(payment.PaymentMethod) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/payment.templ`, Line: 9, Col: 26} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/payment.templ`, Line: 11, Col: 26} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) if templ_7745c5c3_Err != nil { @@ -67,31 +69,57 @@ func PaymentLine(payment *PaymentViewModel) templ.Component { var templ_7745c5c3_Var4 templ.SafeURL templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinURLErrs(payment.StripeDashboardURL) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/payment.templ`, Line: 12, Col: 38} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/payment.templ`, Line: 14, Col: 38} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "\" target=\"_blank\" rel=\"noreferrer noopener\" class=\"badge badge-outline badge-sm ml-2\">View in Stripe") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "\" target=\"_blank\" rel=\"noreferrer noopener\" class=\"badge badge-outline badge-sm ml-2\">") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var5 string + templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(i18n.Localize(ctx, "payment.view_in_stripe")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/payment.templ`, Line: 19, Col: 51} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "\" hx-target=\"closest tr\" hx-swap=\"outerHTML\">") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var7 string + templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(i18n.Localize(ctx, "action.edit")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/payment.templ`, Line: 31, Col: 39} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -115,51 +143,64 @@ func PaymentForm(payment *PaymentViewModel) templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var6 := templ.GetChildren(ctx) - if templ_7745c5c3_Var6 == nil { - templ_7745c5c3_Var6 = templ.NopComponent + templ_7745c5c3_Var8 := templ.GetChildren(ctx) + if templ_7745c5c3_Var8 == nil { + templ_7745c5c3_Var8 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "\" id=\"edit-payment\" hx-target=\"closest tr\" hx-swap=\"outerHTML\">") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -183,12 +224,12 @@ func PaymentList(payments []*PaymentViewModel) templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var10 := templ.GetChildren(ctx) - if templ_7745c5c3_Var10 == nil { - templ_7745c5c3_Var10 = templ.NopComponent + templ_7745c5c3_Var13 := templ.GetChildren(ctx) + if templ_7745c5c3_Var13 == nil { + templ_7745c5c3_Var13 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -200,7 +241,7 @@ func PaymentList(payments []*PaymentViewModel) templ.Component { } } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/internal/view/report_section.templ b/internal/view/report_section.templ index fc4091e..b71d6e3 100644 --- a/internal/view/report_section.templ +++ b/internal/view/report_section.templ @@ -1,10 +1,12 @@ package view +import "github.com/rjNemo/rentease/internal/i18n" + templ ReportSection(report *ReportViewModel) {
-

Your report

+

{ i18n.Localize(ctx, "report.section.title") }

- Create PDF + { i18n.Localize(ctx, "report.section.create_pdf") } Share on WhatsApp @@ -14,15 +16,15 @@ templ ReportSection(report *ReportViewModel) { - - - - - - - - - + + + + + + + + + @@ -46,7 +48,7 @@ templ ReportSection(report *ReportViewModel) { - + @@ -60,9 +62,9 @@ templ ReportSection(report *ReportViewModel) { - + - + diff --git a/internal/view/report_section_templ.go b/internal/view/report_section_templ.go index 94dd450..21b625b 100644 --- a/internal/view/report_section_templ.go +++ b/internal/view/report_section_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.3.960 +// templ: version: v0.3.977 package view //lint:file-ignore SA4006 This context is only used if a nested component is present. @@ -8,6 +8,8 @@ package view import "github.com/a-h/templ" import templruntime "github.com/a-h/templ/runtime" +import "github.com/rjNemo/rentease/internal/i18n" + func ReportSection(report *ReportViewModel) templ.Component { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context @@ -29,238 +31,420 @@ func ReportSection(report *ReportViewModel) templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
IDNameFromToRevenue (€)PlatformPlatform Fees (€)Fees (€)Profit (€){ i18n.Localize(ctx, "report.table.id") }{ i18n.Localize(ctx, "report.table.name") }{ i18n.Localize(ctx, "report.table.from") }{ i18n.Localize(ctx, "report.table.to") }{ i18n.Localize(ctx, "report.table.revenue") } (€){ i18n.Localize(ctx, "report.table.platform") }{ i18n.Localize(ctx, "report.table.platform_fees") } (€){ i18n.Localize(ctx, "report.table.fees") } (€){ i18n.Localize(ctx, "report.table.profit") } (€)
Totals{ i18n.Localize(ctx, "report.table.totals") } Card-only: { i18n.Localize(ctx, "report.table.card_only") }: { report.CardTotal }Booking-only:{ i18n.Localize(ctx, "report.table.booking_only") }: { report.BookingFees }
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } + var templ_7745c5c3_Var3 templ.SafeURL + templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinURLErrs(report.PdfUrl) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/report_section.templ`, Line: 9, Col: 50} } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "
IDNameFromToRevenue (€)PlatformPlatform Fees (€)Fees (€)Profit (€)
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var4 string - templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(row.Id) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/report_section.templ`, Line: 33, Col: 16} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var5 string - templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(row.CustomerName) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/report_section.templ`, Line: 36, Col: 28} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var6 string - templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(row.From) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/report_section.templ`, Line: 37, Col: 20} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var7 string - templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(row.To) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/report_section.templ`, Line: 38, Col: 18} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var8 string - templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(row.Total) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/report_section.templ`, Line: 39, Col: 21} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var9 string - templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(row.Platform) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/report_section.templ`, Line: 40, Col: 24} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var10 string - templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(row.PlatformFees) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/report_section.templ`, Line: 41, Col: 28} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var11 string - templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(row.Fee) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/report_section.templ`, Line: 42, Col: 19} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var12 string - templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(row.Profit) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/report_section.templ`, Line: 43, Col: 22} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "
Totals") + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "\" target=\"_blank\">") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var4 string + templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(i18n.Localize(ctx, "report.section.create_pdf")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/report_section.templ`, Line: 9, Col: 118} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, " \"Share
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var14 string - templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(report.PlatformFees) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/report_section.templ`, Line: 55, Col: 30} + for _, row := range report.Lines { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14)) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var5 string + templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(i18n.Localize(ctx, "report.table.id")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/report_section.templ`, Line: 19, Col: 60} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var6 string + templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(i18n.Localize(ctx, "report.table.name")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/report_section.templ`, Line: 20, Col: 62} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var7 string + templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(i18n.Localize(ctx, "report.table.from")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/report_section.templ`, Line: 21, Col: 62} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var8 string + templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(i18n.Localize(ctx, "report.table.to")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/report_section.templ`, Line: 22, Col: 60} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var9 string + templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(i18n.Localize(ctx, "report.table.revenue")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/report_section.templ`, Line: 23, Col: 65} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, " (€)") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var10 string + templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(i18n.Localize(ctx, "report.table.platform")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/report_section.templ`, Line: 24, Col: 66} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var11 string + templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(i18n.Localize(ctx, "report.table.platform_fees")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/report_section.templ`, Line: 25, Col: 71} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, " (€)") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var12 string + templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(i18n.Localize(ctx, "report.table.fees")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/report_section.templ`, Line: 26, Col: 62} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, " (€)") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var13 string - templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(report.Total) + templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(i18n.Localize(ctx, "report.table.profit")) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/report_section.templ`, Line: 53, Col: 23} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/report_section.templ`, Line: 27, Col: 64} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, " (€)
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var15 string + templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(row.Id) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/report_section.templ`, Line: 35, Col: 16} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var16 string + templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(row.CustomerName) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/report_section.templ`, Line: 38, Col: 28} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var17 string + templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(row.From) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/report_section.templ`, Line: 39, Col: 20} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var18 string + templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(row.To) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/report_section.templ`, Line: 40, Col: 18} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var19 string + templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(row.Total) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/report_section.templ`, Line: 41, Col: 21} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var20 string + templ_7745c5c3_Var20, templ_7745c5c3_Err = templ.JoinStringErrs(row.Platform) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/report_section.templ`, Line: 42, Col: 24} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var20)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var21 string + templ_7745c5c3_Var21, templ_7745c5c3_Err = templ.JoinStringErrs(row.PlatformFees) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/report_section.templ`, Line: 43, Col: 28} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var21)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var22 string + templ_7745c5c3_Var22, templ_7745c5c3_Err = templ.JoinStringErrs(row.Fee) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/report_section.templ`, Line: 44, Col: 19} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var22)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var23 string + templ_7745c5c3_Var23, templ_7745c5c3_Err = templ.JoinStringErrs(row.Profit) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/report_section.templ`, Line: 45, Col: 22} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var23)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "") + var templ_7745c5c3_Var24 string + templ_7745c5c3_Var24, templ_7745c5c3_Err = templ.JoinStringErrs(i18n.Localize(ctx, "report.table.totals")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/report_section.templ`, Line: 51, Col: 64} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var24)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var15 string - templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(report.Fee) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/report_section.templ`, Line: 56, Col: 21} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15)) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "") + var templ_7745c5c3_Var25 string + templ_7745c5c3_Var25, templ_7745c5c3_Err = templ.JoinStringErrs(report.Total) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/report_section.templ`, Line: 55, Col: 23} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var25)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var16 string - templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(report.Profit) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/report_section.templ`, Line: 57, Col: 24} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16)) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "
Card-only: ") + var templ_7745c5c3_Var26 string + templ_7745c5c3_Var26, templ_7745c5c3_Err = templ.JoinStringErrs(report.PlatformFees) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/report_section.templ`, Line: 57, Col: 30} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var26)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var17 string - templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(report.CardTotal) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/report_section.templ`, Line: 64, Col: 27} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17)) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "Booking-only:") + var templ_7745c5c3_Var27 string + templ_7745c5c3_Var27, templ_7745c5c3_Err = templ.JoinStringErrs(report.Fee) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/report_section.templ`, Line: 58, Col: 21} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var27)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var18 string - templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(report.BookingFees) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/report_section.templ`, Line: 66, Col: 29} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18)) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "
") + var templ_7745c5c3_Var28 string + templ_7745c5c3_Var28, templ_7745c5c3_Err = templ.JoinStringErrs(report.Profit) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/report_section.templ`, Line: 59, Col: 24} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var28)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var29 string + templ_7745c5c3_Var29, templ_7745c5c3_Err = templ.JoinStringErrs(i18n.Localize(ctx, "report.table.card_only")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/report_section.templ`, Line: 65, Col: 55} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var29)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 31, ": ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var30 string + templ_7745c5c3_Var30, templ_7745c5c3_Err = templ.JoinStringErrs(report.CardTotal) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/report_section.templ`, Line: 66, Col: 27} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var30)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var31 string + templ_7745c5c3_Var31, templ_7745c5c3_Err = templ.JoinStringErrs(i18n.Localize(ctx, "report.table.booking_only")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/report_section.templ`, Line: 67, Col: 58} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var31)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, ":") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var32 string + templ_7745c5c3_Var32, templ_7745c5c3_Err = templ.JoinStringErrs(report.BookingFees) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/report_section.templ`, Line: 68, Col: 29} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var32)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/internal/view/reports.templ b/internal/view/reports.templ index e9c4770..08f24b2 100644 --- a/internal/view/reports.templ +++ b/internal/view/reports.templ @@ -1,39 +1,41 @@ package view import ( - "github.com/rjNemo/rentease/internal/view/layout" "strconv" + + "github.com/rjNemo/rentease/internal/i18n" + "github.com/rjNemo/rentease/internal/view/layout" ) templ Reports(months []string, m int, year string) { @layout.BaseLayout() {
-

Reports

-

Generate monthly and yearly statements

+

{ i18n.Localize(ctx, "report.title") }

+

{ i18n.Localize(ctx, "report.subtitle") }

- Period + { i18n.Localize(ctx, "report.period") }
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/internal/view/success.templ b/internal/view/success.templ index 7625cd8..b483bd8 100644 --- a/internal/view/success.templ +++ b/internal/view/success.templ @@ -1,5 +1,7 @@ package view +import "github.com/rjNemo/rentease/internal/i18n" + templ Success() { - Done + { i18n.Localize(ctx, "success.done") } } diff --git a/internal/view/success_templ.go b/internal/view/success_templ.go index c4ec344..4dc26b7 100644 --- a/internal/view/success_templ.go +++ b/internal/view/success_templ.go @@ -1,6 +1,6 @@ // Code generated by templ - DO NOT EDIT. -// templ: version: v0.3.960 +// templ: version: v0.3.977 package view //lint:file-ignore SA4006 This context is only used if a nested component is present. @@ -8,6 +8,8 @@ package view import "github.com/a-h/templ" import templruntime "github.com/a-h/templ/runtime" +import "github.com/rjNemo/rentease/internal/i18n" + func Success() templ.Component { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context @@ -29,7 +31,20 @@ func Success() templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "Done") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var2 string + templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(i18n.Localize(ctx, "success.done")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/success.templ`, Line: 6, Col: 45} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err }