Compare commits
No commits in common. "b1c653e7de82477cbae233710a858392ed8d3e76" and "586db8d553a732df731a6cb58ed248c22d727e76" have entirely different histories.
b1c653e7de
...
586db8d553
@ -83,6 +83,7 @@ type Tax struct {
|
||||
}
|
||||
|
||||
type TaxDetailsPage struct {
|
||||
Title string
|
||||
BusinessName string
|
||||
VATIN string
|
||||
TradeName string
|
||||
@ -103,7 +104,9 @@ type TaxDetailsPage struct {
|
||||
func CompanyTaxDetailsHandler() http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
locale := getLocale(r)
|
||||
page := &TaxDetailsPage{}
|
||||
page := &TaxDetailsPage{
|
||||
Title: pgettext("title", "Tax Details", locale),
|
||||
}
|
||||
company := mustGetCompany(r)
|
||||
conn := getConn(r)
|
||||
if r.Method == "POST" {
|
||||
|
@ -12,6 +12,7 @@ type ContactEntry struct {
|
||||
}
|
||||
|
||||
type ContactsIndexPage struct {
|
||||
Title string
|
||||
Contacts []*ContactEntry
|
||||
}
|
||||
|
||||
@ -37,7 +38,9 @@ func ContactsHandler() http.Handler {
|
||||
conn.MustExec(r.Context(), "insert into contact (company_id, business_name, vatin, trade_name, phone, email, web, address, province, city, postal_code, country_code) values ($1, $2, ($12 || $3)::vatin, $4, parse_packed_phone_number($5, $12), $6, $7, $8, $9, $10, $11, $12)", company.Id, page.BusinessName, page.VATIN, page.TradeName, page.Phone, page.Email, page.Web, page.Address, page.City, page.Province, page.PostalCode, page.CountryCode)
|
||||
http.Redirect(w, r, "/company/"+company.Slug+"/contacts", http.StatusSeeOther)
|
||||
} else {
|
||||
locale := getLocale(r)
|
||||
page := &ContactsIndexPage{
|
||||
Title: pgettext("title", "Customers", locale),
|
||||
Contacts: mustGetContactEntries(r.Context(), conn, company),
|
||||
}
|
||||
mustRenderAppTemplate(w, r, "contacts-index.gohtml", page)
|
||||
@ -69,6 +72,7 @@ func mustGetContactEntries(ctx context.Context, conn *Conn, company *Company) []
|
||||
}
|
||||
|
||||
type NewContactPage struct {
|
||||
Title string
|
||||
BusinessName string
|
||||
VATIN string
|
||||
TradeName string
|
||||
@ -88,6 +92,7 @@ func NewContactHandler() http.Handler {
|
||||
locale := getLocale(r)
|
||||
conn := getConn(r)
|
||||
page := &NewContactPage{
|
||||
Title: pgettext("title", "New Contact", locale),
|
||||
CountryCode: "ES",
|
||||
Countries: mustGetCountryOptions(r.Context(), conn, locale),
|
||||
}
|
||||
|
73
pkg/form.go
73
pkg/form.go
@ -1,73 +0,0 @@
|
||||
package pkg
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/mail"
|
||||
)
|
||||
|
||||
type InputField struct {
|
||||
Name string
|
||||
Label string
|
||||
Type string
|
||||
Value string
|
||||
Required bool
|
||||
Errors []error
|
||||
}
|
||||
|
||||
func (field *InputField) Equals(other *InputField) bool {
|
||||
return field.Value == other.Value
|
||||
}
|
||||
|
||||
func (field *InputField) IsEmpty() bool {
|
||||
return field.Value == ""
|
||||
}
|
||||
|
||||
func (field *InputField) HasValidEmail() bool {
|
||||
_, err := mail.ParseAddress(field.Value)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
type SelectOption struct {
|
||||
Value string
|
||||
Label string
|
||||
}
|
||||
|
||||
type SelectField struct {
|
||||
Name string
|
||||
Label string
|
||||
Selected string
|
||||
Options []*SelectOption
|
||||
Errors []error
|
||||
}
|
||||
|
||||
func (field *SelectField) HasValidOption() bool {
|
||||
for _, option := range field.Options {
|
||||
if option.Value == field.Selected {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func MustGetOptions(ctx context.Context, conn *Conn, sql string, args ...interface{}) []*SelectOption {
|
||||
rows, err := conn.Query(ctx, sql, args...)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var options []*SelectOption
|
||||
for rows.Next() {
|
||||
option := &SelectOption{}
|
||||
err = rows.Scan(&option.Value, &option.Label)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
options = append(options, option)
|
||||
}
|
||||
if rows.Err() != nil {
|
||||
panic(rows.Err())
|
||||
}
|
||||
|
||||
return options
|
||||
}
|
@ -66,10 +66,6 @@ func pgettext(context string, str string, locale *Locale) string {
|
||||
return locale.GetC(str, context)
|
||||
}
|
||||
|
||||
func gettext(str string, locale *Locale) string {
|
||||
return locale.Get(str)
|
||||
}
|
||||
|
||||
func mustGetAvailableLanguages(db *Db) []language.Tag {
|
||||
rows, err := db.Query(context.Background(), "select lang_tag from language where selectable")
|
||||
if err != nil {
|
||||
|
@ -64,7 +64,6 @@ func LogoutHandler() http.Handler {
|
||||
conn := getConn(r)
|
||||
conn.MustExec(r.Context(), "select logout()")
|
||||
http.SetCookie(w, createSessionCookie("", -24*time.Hour))
|
||||
http.Redirect(w, r, "/login", http.StatusSeeOther)
|
||||
})
|
||||
}
|
||||
|
||||
|
163
pkg/profile.go
163
pkg/profile.go
@ -2,9 +2,7 @@ package pkg
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type LanguageOption struct {
|
||||
@ -12,88 +10,14 @@ type LanguageOption struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
type profileForm struct {
|
||||
Name *InputField
|
||||
Email *InputField
|
||||
Password *InputField
|
||||
PasswordConfirm *InputField
|
||||
Language *SelectField
|
||||
Valid bool
|
||||
}
|
||||
|
||||
func newProfileForm(ctx context.Context, conn *Conn, locale *Locale) *profileForm {
|
||||
automaticOption := pgettext("language option", "Automatic", locale)
|
||||
languages := MustGetOptions(ctx, conn, "select 'und', $1 union all select lang_tag, endonym from language where selectable", automaticOption)
|
||||
return &profileForm{
|
||||
Name: &InputField{
|
||||
Name: "name",
|
||||
Label: pgettext("input", "User name", locale),
|
||||
Type: "text",
|
||||
Required: true,
|
||||
},
|
||||
Email: &InputField{
|
||||
Name: "email",
|
||||
Label: pgettext("input", "Email", locale),
|
||||
Type: "email",
|
||||
Required: true,
|
||||
},
|
||||
Password: &InputField{
|
||||
Name: "password",
|
||||
Label: pgettext("input", "Password", locale),
|
||||
Type: "password",
|
||||
},
|
||||
PasswordConfirm: &InputField{
|
||||
Name: "password_confirm",
|
||||
Label: pgettext("input", "Password Confirmation", locale),
|
||||
Type: "password",
|
||||
},
|
||||
Language: &SelectField{
|
||||
Name: "language",
|
||||
Label: pgettext("input", "Language", locale),
|
||||
Options: languages,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (form *profileForm) Parse(r *http.Request) error {
|
||||
if err := r.ParseForm(); err != nil {
|
||||
return err
|
||||
}
|
||||
form.Email.Value = strings.TrimSpace(r.FormValue("email"))
|
||||
form.Name.Value = strings.TrimSpace(r.FormValue("name"))
|
||||
form.Password.Value = strings.TrimSpace(r.FormValue("password"))
|
||||
form.PasswordConfirm.Value = strings.TrimSpace(r.FormValue("password_confirm"))
|
||||
form.Language.Selected = r.FormValue("language")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (form *profileForm) Validate(locale *Locale) bool {
|
||||
form.Valid = true
|
||||
if form.Email.IsEmpty() {
|
||||
form.AppendInputError(form.Email, errors.New(gettext("Email can not be empty.", locale)))
|
||||
} else if !form.Email.HasValidEmail() {
|
||||
form.AppendInputError(form.Email, errors.New(gettext("This value is not a valid email. It should be like name@domain.com.", locale)))
|
||||
}
|
||||
if form.Name.IsEmpty() {
|
||||
form.AppendInputError(form.Name, errors.New(gettext("Name can not be empty.", locale)))
|
||||
}
|
||||
if !form.PasswordConfirm.Equals(form.Password) {
|
||||
form.AppendInputError(form.PasswordConfirm, errors.New(gettext("Confirmation does not match password.", locale)))
|
||||
}
|
||||
if !form.Language.HasValidOption() {
|
||||
form.AppendSelectError(form.Language, errors.New(gettext("Selected language is not valid.", locale)))
|
||||
}
|
||||
return form.Valid
|
||||
}
|
||||
|
||||
func (form *profileForm) AppendInputError(field *InputField, err error) {
|
||||
field.Errors = append(field.Errors, err)
|
||||
form.Valid = false
|
||||
}
|
||||
|
||||
func (form *profileForm) AppendSelectError(field *SelectField, err error) {
|
||||
field.Errors = append(field.Errors, err)
|
||||
form.Valid = false
|
||||
type ProfilePage struct {
|
||||
Title string
|
||||
Name string
|
||||
Email string
|
||||
Password string
|
||||
PasswordConfirm string
|
||||
Language string
|
||||
Languages []LanguageOption
|
||||
}
|
||||
|
||||
func ProfileHandler() http.Handler {
|
||||
@ -101,29 +25,54 @@ func ProfileHandler() http.Handler {
|
||||
user := getUser(r)
|
||||
conn := getConn(r)
|
||||
locale := getLocale(r)
|
||||
form := newProfileForm(r.Context(), conn, locale)
|
||||
if r.Method == "POST" {
|
||||
if err := form.Parse(r); err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
if ok := form.Validate(locale); ok {
|
||||
//goland:noinspection SqlWithoutWhere
|
||||
cookie := conn.MustGetText(r.Context(), "", "update user_profile set name = $1, email = $2, lang_tag = $3 returning build_cookie()", form.Name.Value, form.Email.Value, form.Language.Selected)
|
||||
setSessionCookie(w, cookie)
|
||||
if form.Password.Value != "" {
|
||||
conn.MustExec(r.Context(), "select change_password($1)", form.Password.Value)
|
||||
}
|
||||
company := getCompany(r)
|
||||
http.Redirect(w, r, "/company/"+company.Slug+"/profile", http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
w.WriteHeader(http.StatusUnprocessableEntity)
|
||||
} else {
|
||||
form.Name.Value = conn.MustGetText(r.Context(), "", "select name from user_profile")
|
||||
form.Email.Value = user.Email
|
||||
form.Language.Selected = user.Language.String()
|
||||
page := ProfilePage{
|
||||
Title: pgettext("title", "User Settings", locale),
|
||||
Email: user.Email,
|
||||
Language: user.Language.String(),
|
||||
}
|
||||
mustRenderAppTemplate(w, r, "profile.gohtml", form)
|
||||
if r.Method == "POST" {
|
||||
r.ParseForm()
|
||||
page.Email = r.FormValue("email")
|
||||
page.Name = r.FormValue("name")
|
||||
page.Password = r.FormValue("password")
|
||||
page.PasswordConfirm = r.FormValue("password_confirm")
|
||||
page.Language = r.FormValue("language")
|
||||
cookie := conn.MustGetText(r.Context(), "", "update user_profile set name = $1, email = $2, lang_tag = $3 returning build_cookie()", page.Name, page.Email, page.Language)
|
||||
setSessionCookie(w, cookie)
|
||||
if page.Password != "" && page.Password == page.PasswordConfirm {
|
||||
conn.MustExec(r.Context(), "select change_password($1)", page.Password)
|
||||
}
|
||||
http.Redirect(w, r, "/profile", http.StatusSeeOther)
|
||||
return
|
||||
} else {
|
||||
page.Languages = mustGetLanguageOptions(r.Context(), conn)
|
||||
if err := conn.QueryRow(r.Context(), "select name from user_profile").Scan(&page.Name); err != nil {
|
||||
panic(nil)
|
||||
}
|
||||
}
|
||||
mustRenderAppTemplate(w, r, "profile.gohtml", page)
|
||||
})
|
||||
}
|
||||
|
||||
func mustGetLanguageOptions(ctx context.Context, conn *Conn) []LanguageOption {
|
||||
rows, err := conn.Query(ctx, "select lang_tag, endonym from language where selectable")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var langs []LanguageOption
|
||||
for rows.Next() {
|
||||
var lang LanguageOption
|
||||
err = rows.Scan(&lang.Tag, &lang.Name)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
langs = append(langs, lang)
|
||||
}
|
||||
if rows.Err() != nil {
|
||||
panic(rows.Err())
|
||||
}
|
||||
|
||||
return langs
|
||||
}
|
||||
|
@ -17,9 +17,6 @@ func mustRenderTemplate(wr io.Writer, r *http.Request, layout string, filename s
|
||||
t.Funcs(template.FuncMap{
|
||||
"gettext": locale.Get,
|
||||
"pgettext": locale.GetC,
|
||||
"currentLocale": func() string {
|
||||
return locale.Language.String()
|
||||
},
|
||||
"companyURI": func(uri string) string {
|
||||
if company == nil {
|
||||
return uri
|
||||
@ -27,7 +24,7 @@ func mustRenderTemplate(wr io.Writer, r *http.Request, layout string, filename s
|
||||
return "/company/" + company.Slug + uri
|
||||
},
|
||||
})
|
||||
if _, err := t.ParseFiles(templateFile(filename), templateFile(layout), templateFile("form.gohtml")); err != nil {
|
||||
if _, err := t.ParseFiles(templateFile(filename), templateFile(layout)); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := t.ExecuteTemplate(wr, layout, data); err != nil {
|
||||
|
349
po/ca.po
349
po/ca.po
@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: numerus\n"
|
||||
"Report-Msgid-Bugs-To: jordi@tandem.blog\n"
|
||||
"POT-Creation-Date: 2023-01-31 15:17+0100\n"
|
||||
"POT-Creation-Date: 2023-01-30 16:46+0100\n"
|
||||
"PO-Revision-Date: 2023-01-18 17:08+0100\n"
|
||||
"Last-Translator: jordi fita mas <jordi@tandem.blog>\n"
|
||||
"Language-Team: Catalan <ca@dodds.net>\n"
|
||||
@ -17,10 +17,10 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: web/template/dashboard.gohtml:2
|
||||
#: web/template/web.gohtml:6 web/template/login.gohtml:9
|
||||
msgctxt "title"
|
||||
msgid "Dashboard"
|
||||
msgstr "Tauler"
|
||||
msgid "Login"
|
||||
msgstr "Entrada"
|
||||
|
||||
#: web/template/app.gohtml:20
|
||||
msgctxt "menu"
|
||||
@ -39,233 +39,198 @@ msgstr "Surt"
|
||||
|
||||
#: web/template/app.gohtml:42
|
||||
msgctxt "nav"
|
||||
msgid "Dashboard"
|
||||
msgstr "Tauler"
|
||||
|
||||
#: web/template/app.gohtml:43
|
||||
msgctxt "nav"
|
||||
msgid "Customers"
|
||||
msgstr "Clients"
|
||||
|
||||
#: web/template/login.gohtml:2 web/template/login.gohtml:13
|
||||
msgctxt "title"
|
||||
msgid "Login"
|
||||
msgstr "Entrada"
|
||||
|
||||
#: web/template/login.gohtml:9
|
||||
#: web/template/login.gohtml:5
|
||||
msgid "Invalid user or password"
|
||||
msgstr "Nom d’usuari o contrasenya incorrectes"
|
||||
|
||||
#: web/template/login.gohtml:17 web/template/tax-details.gohtml:27
|
||||
#: web/template/contacts-new.gohtml:27 pkg/profile.go:37
|
||||
#: web/template/login.gohtml:13 web/template/profile.gohtml:15
|
||||
#: web/template/tax-details.gohtml:23 web/template/contacts-new.gohtml:23
|
||||
msgctxt "input"
|
||||
msgid "Email"
|
||||
msgstr "Correu-e"
|
||||
|
||||
#: web/template/login.gohtml:22 pkg/profile.go:43
|
||||
#: web/template/login.gohtml:18 web/template/profile.gohtml:23
|
||||
msgctxt "input"
|
||||
msgid "Password"
|
||||
msgstr "Contrasenya"
|
||||
|
||||
#: web/template/login.gohtml:25
|
||||
#: web/template/login.gohtml:21
|
||||
msgctxt "action"
|
||||
msgid "Login"
|
||||
msgstr "Entra"
|
||||
|
||||
#: web/template/profile.gohtml:2 web/template/profile.gohtml:7
|
||||
#: web/template/profile.gohtml:3 pkg/profile.go:29
|
||||
msgctxt "title"
|
||||
msgid "User Settings"
|
||||
msgstr "Configuració usuari"
|
||||
|
||||
#: web/template/profile.gohtml:10
|
||||
#: web/template/profile.gohtml:6
|
||||
msgctxt "title"
|
||||
msgid "User Access Data"
|
||||
msgstr "Dades accés usuari"
|
||||
|
||||
#: web/template/profile.gohtml:16
|
||||
msgctxt "title"
|
||||
msgid "Password Change"
|
||||
msgstr "Canvi contrasenya"
|
||||
|
||||
#: web/template/profile.gohtml:23
|
||||
msgctxt "title"
|
||||
msgid "Language"
|
||||
msgstr "Idioma"
|
||||
|
||||
#: web/template/profile.gohtml:27 web/template/tax-details.gohtml:133
|
||||
msgctxt "action"
|
||||
msgid "Save changes"
|
||||
msgstr "Desa canvis"
|
||||
|
||||
#: web/template/contacts-index.gohtml:2
|
||||
msgctxt "title"
|
||||
msgid "Customers"
|
||||
msgstr "Clients"
|
||||
|
||||
#: web/template/contacts-index.gohtml:6 web/template/contacts-new.gohtml:60
|
||||
msgctxt "action"
|
||||
msgid "New contact"
|
||||
msgstr "Nou contacte"
|
||||
|
||||
#: web/template/contacts-index.gohtml:11
|
||||
msgctxt "contact"
|
||||
msgid "All"
|
||||
msgstr "Tots"
|
||||
|
||||
#: web/template/contacts-index.gohtml:12
|
||||
msgctxt "title"
|
||||
msgid "Customer"
|
||||
msgstr "Client"
|
||||
|
||||
#: web/template/contacts-index.gohtml:13
|
||||
msgctxt "title"
|
||||
msgid "Email"
|
||||
msgstr "Correu-e"
|
||||
|
||||
#: web/template/contacts-index.gohtml:14
|
||||
msgctxt "title"
|
||||
msgid "Phone"
|
||||
msgstr "Telèfon"
|
||||
|
||||
#: web/template/contacts-index.gohtml:29
|
||||
msgid "No customers added yet."
|
||||
msgstr "No hi ha cap client."
|
||||
|
||||
#: web/template/tax-details.gohtml:2 web/template/tax-details.gohtml:7
|
||||
msgctxt "title"
|
||||
msgid "Tax Details"
|
||||
msgstr "Configuració fiscal"
|
||||
|
||||
#: web/template/tax-details.gohtml:11 web/template/contacts-new.gohtml:11
|
||||
msgctxt "input"
|
||||
msgid "Business name"
|
||||
msgstr "Nom i cognom"
|
||||
|
||||
#: web/template/tax-details.gohtml:15 web/template/contacts-new.gohtml:15
|
||||
msgctxt "input"
|
||||
msgid "VAT number"
|
||||
msgstr "DNI / NIF"
|
||||
|
||||
#: web/template/tax-details.gohtml:19 web/template/contacts-new.gohtml:19
|
||||
msgctxt "input"
|
||||
msgid "Trade name"
|
||||
msgstr "Nom comercial"
|
||||
|
||||
#: web/template/tax-details.gohtml:23 web/template/contacts-new.gohtml:23
|
||||
msgctxt "input"
|
||||
msgid "Phone"
|
||||
msgstr "Telèfon"
|
||||
|
||||
#: web/template/tax-details.gohtml:31 web/template/contacts-new.gohtml:31
|
||||
msgctxt "input"
|
||||
msgid "Web"
|
||||
msgstr "Web"
|
||||
|
||||
#: web/template/tax-details.gohtml:35 web/template/contacts-new.gohtml:35
|
||||
msgctxt "input"
|
||||
msgid "Address"
|
||||
msgstr "Adreça"
|
||||
|
||||
#: web/template/tax-details.gohtml:39 web/template/contacts-new.gohtml:39
|
||||
msgctxt "input"
|
||||
msgid "City"
|
||||
msgstr "Població"
|
||||
|
||||
#: web/template/tax-details.gohtml:43 web/template/contacts-new.gohtml:43
|
||||
msgctxt "input"
|
||||
msgid "Province"
|
||||
msgstr "Província"
|
||||
|
||||
#: web/template/tax-details.gohtml:47 web/template/contacts-new.gohtml:47
|
||||
msgctxt "input"
|
||||
msgid "Postal code"
|
||||
msgstr "Codi postal"
|
||||
|
||||
#: web/template/tax-details.gohtml:56 web/template/contacts-new.gohtml:56
|
||||
msgctxt "input"
|
||||
msgid "Country"
|
||||
msgstr "País"
|
||||
|
||||
#: web/template/tax-details.gohtml:60
|
||||
msgctxt "input"
|
||||
msgid "Currency"
|
||||
msgstr "Moneda"
|
||||
|
||||
#: web/template/tax-details.gohtml:78
|
||||
msgctxt "title"
|
||||
msgid "Tax Name"
|
||||
msgstr "Nom import"
|
||||
|
||||
#: web/template/tax-details.gohtml:79
|
||||
msgctxt "title"
|
||||
msgid "Rate (%)"
|
||||
msgstr "Percentatge"
|
||||
|
||||
#: web/template/tax-details.gohtml:100
|
||||
msgid "No taxes added yet."
|
||||
msgstr "No hi ha cap impost."
|
||||
|
||||
#: web/template/tax-details.gohtml:106
|
||||
msgctxt "title"
|
||||
msgid "New Line"
|
||||
msgstr "Nova línia"
|
||||
|
||||
#: web/template/tax-details.gohtml:111
|
||||
msgctxt "input"
|
||||
msgid "Tax name"
|
||||
msgstr "Nom impost"
|
||||
|
||||
#: web/template/tax-details.gohtml:118
|
||||
msgctxt "input"
|
||||
msgid "Rate (%)"
|
||||
msgstr "Percentatge"
|
||||
|
||||
#: web/template/tax-details.gohtml:125
|
||||
msgctxt "action"
|
||||
msgid "Add new tax"
|
||||
msgstr "Afegeix nou impost"
|
||||
|
||||
#: web/template/contacts-new.gohtml:2 web/template/contacts-new.gohtml:7
|
||||
msgctxt "title"
|
||||
msgid "New Contact"
|
||||
msgstr "Nou contacte"
|
||||
|
||||
#: pkg/profile.go:26
|
||||
msgctxt "language option"
|
||||
msgid "Automatic"
|
||||
msgstr "Automàtic"
|
||||
|
||||
#: pkg/profile.go:31
|
||||
#: web/template/profile.gohtml:10
|
||||
msgctxt "input"
|
||||
msgid "User name"
|
||||
msgstr "Nom d’usuari"
|
||||
|
||||
#: pkg/profile.go:48
|
||||
#: web/template/profile.gohtml:19
|
||||
msgctxt "title"
|
||||
msgid "Password Change"
|
||||
msgstr "Canvi contrasenya"
|
||||
|
||||
#: web/template/profile.gohtml:28
|
||||
msgctxt "input"
|
||||
msgid "Password Confirmation"
|
||||
msgstr "Confirmació contrasenya"
|
||||
|
||||
#: pkg/profile.go:53
|
||||
#: web/template/profile.gohtml:33
|
||||
msgctxt "input"
|
||||
msgid "Language"
|
||||
msgstr "Idioma"
|
||||
|
||||
#: pkg/profile.go:74
|
||||
msgid "Email can not be empty."
|
||||
msgstr "No podeu deixar el correu-e en blanc."
|
||||
#: web/template/profile.gohtml:36
|
||||
msgctxt "language option"
|
||||
msgid "Automatic"
|
||||
msgstr "Automàtic"
|
||||
|
||||
#: pkg/profile.go:76
|
||||
msgid "This value is not a valid email. It should be like name@domain.com."
|
||||
msgstr "Aquest valor no és un correu-e vàlid. Hauria de ser similar a nom@domini.cat."
|
||||
#: web/template/profile.gohtml:42 web/template/tax-details.gohtml:127
|
||||
msgctxt "action"
|
||||
msgid "Save changes"
|
||||
msgstr "Desa canvis"
|
||||
|
||||
#: pkg/profile.go:79
|
||||
msgid "Name can not be empty."
|
||||
msgstr "No podeu deixar el nom en blanc."
|
||||
#: web/template/contacts-index.gohtml:2 web/template/contacts-new.gohtml:56
|
||||
msgctxt "action"
|
||||
msgid "New contact"
|
||||
msgstr "Nou contacte"
|
||||
|
||||
#: pkg/profile.go:82
|
||||
msgid "Confirmation does not match password."
|
||||
msgstr "La confirmació no és igual a la contrasenya."
|
||||
#: web/template/contacts-index.gohtml:7
|
||||
msgctxt "contact"
|
||||
msgid "All"
|
||||
msgstr "Tots"
|
||||
|
||||
#: pkg/profile.go:85
|
||||
msgid "Selected language is not valid."
|
||||
msgstr "Heu seleccionat un idioma que no és vàlid."
|
||||
#: web/template/contacts-index.gohtml:8
|
||||
msgctxt "title"
|
||||
msgid "Customer"
|
||||
msgstr "Client"
|
||||
|
||||
#: web/template/contacts-index.gohtml:9
|
||||
msgctxt "title"
|
||||
msgid "Email"
|
||||
msgstr "Correu-e"
|
||||
|
||||
#: web/template/contacts-index.gohtml:10
|
||||
msgctxt "title"
|
||||
msgid "Phone"
|
||||
msgstr "Telèfon"
|
||||
|
||||
#: web/template/contacts-index.gohtml:25
|
||||
msgid "No customers added yet."
|
||||
msgstr "No hi ha cap client."
|
||||
|
||||
#: web/template/tax-details.gohtml:3 pkg/company.go:108
|
||||
msgctxt "title"
|
||||
msgid "Tax Details"
|
||||
msgstr "Configuració fiscal"
|
||||
|
||||
#: web/template/tax-details.gohtml:7 web/template/contacts-new.gohtml:7
|
||||
msgctxt "input"
|
||||
msgid "Business name"
|
||||
msgstr "Nom i cognom"
|
||||
|
||||
#: web/template/tax-details.gohtml:11 web/template/contacts-new.gohtml:11
|
||||
msgctxt "input"
|
||||
msgid "VAT number"
|
||||
msgstr "DNI / NIF"
|
||||
|
||||
#: web/template/tax-details.gohtml:15 web/template/contacts-new.gohtml:15
|
||||
msgctxt "input"
|
||||
msgid "Trade name"
|
||||
msgstr "Nom comercial"
|
||||
|
||||
#: web/template/tax-details.gohtml:19 web/template/contacts-new.gohtml:19
|
||||
msgctxt "input"
|
||||
msgid "Phone"
|
||||
msgstr "Telèfon"
|
||||
|
||||
#: web/template/tax-details.gohtml:27 web/template/contacts-new.gohtml:27
|
||||
msgctxt "input"
|
||||
msgid "Web"
|
||||
msgstr "Web"
|
||||
|
||||
#: web/template/tax-details.gohtml:31 web/template/contacts-new.gohtml:31
|
||||
msgctxt "input"
|
||||
msgid "Address"
|
||||
msgstr "Adreça"
|
||||
|
||||
#: web/template/tax-details.gohtml:35 web/template/contacts-new.gohtml:35
|
||||
msgctxt "input"
|
||||
msgid "City"
|
||||
msgstr "Població"
|
||||
|
||||
#: web/template/tax-details.gohtml:39 web/template/contacts-new.gohtml:39
|
||||
msgctxt "input"
|
||||
msgid "Province"
|
||||
msgstr "Província"
|
||||
|
||||
#: web/template/tax-details.gohtml:43 web/template/contacts-new.gohtml:43
|
||||
msgctxt "input"
|
||||
msgid "Postal code"
|
||||
msgstr "Codi postal"
|
||||
|
||||
#: web/template/tax-details.gohtml:52 web/template/contacts-new.gohtml:52
|
||||
msgctxt "input"
|
||||
msgid "Country"
|
||||
msgstr "País"
|
||||
|
||||
#: web/template/tax-details.gohtml:56
|
||||
msgctxt "input"
|
||||
msgid "Currency"
|
||||
msgstr "Moneda"
|
||||
|
||||
#: web/template/tax-details.gohtml:74
|
||||
msgctxt "title"
|
||||
msgid "Tax Name"
|
||||
msgstr "Nom import"
|
||||
|
||||
#: web/template/tax-details.gohtml:75
|
||||
msgctxt "title"
|
||||
msgid "Rate (%)"
|
||||
msgstr "Percentatge"
|
||||
|
||||
#: web/template/tax-details.gohtml:96
|
||||
msgid "No taxes added yet."
|
||||
msgstr "No hi ha cap impost."
|
||||
|
||||
#: web/template/tax-details.gohtml:102
|
||||
msgctxt "title"
|
||||
msgid "New Line"
|
||||
msgstr "Nova línia"
|
||||
|
||||
#: web/template/tax-details.gohtml:106
|
||||
msgctxt "input"
|
||||
msgid "Tax name"
|
||||
msgstr "Nom impost"
|
||||
|
||||
#: web/template/tax-details.gohtml:112
|
||||
msgctxt "input"
|
||||
msgid "Rate (%)"
|
||||
msgstr "Percentatge"
|
||||
|
||||
#: web/template/tax-details.gohtml:119
|
||||
msgctxt "action"
|
||||
msgid "Add new tax"
|
||||
msgstr "Afegeix nou impost"
|
||||
|
||||
#: web/template/contacts-new.gohtml:3 pkg/contacts.go:95
|
||||
msgctxt "title"
|
||||
msgid "New Contact"
|
||||
msgstr "Nou contacte"
|
||||
|
||||
#: pkg/contacts.go:43
|
||||
msgctxt "title"
|
||||
msgid "Customers"
|
||||
msgstr "Clients"
|
||||
|
349
po/es.po
349
po/es.po
@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: numerus\n"
|
||||
"Report-Msgid-Bugs-To: jordi@tandem.blog\n"
|
||||
"POT-Creation-Date: 2023-01-31 15:17+0100\n"
|
||||
"POT-Creation-Date: 2023-01-30 16:46+0100\n"
|
||||
"PO-Revision-Date: 2023-01-18 17:45+0100\n"
|
||||
"Last-Translator: jordi fita mas <jordi@tandem.blog>\n"
|
||||
"Language-Team: Spanish <es@tp.org.es>\n"
|
||||
@ -17,10 +17,10 @@ msgstr ""
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: web/template/dashboard.gohtml:2
|
||||
#: web/template/web.gohtml:6 web/template/login.gohtml:9
|
||||
msgctxt "title"
|
||||
msgid "Dashboard"
|
||||
msgstr "Panel"
|
||||
msgid "Login"
|
||||
msgstr "Entrada"
|
||||
|
||||
#: web/template/app.gohtml:20
|
||||
msgctxt "menu"
|
||||
@ -39,233 +39,198 @@ msgstr "Salir"
|
||||
|
||||
#: web/template/app.gohtml:42
|
||||
msgctxt "nav"
|
||||
msgid "Dashboard"
|
||||
msgstr "Panel"
|
||||
|
||||
#: web/template/app.gohtml:43
|
||||
msgctxt "nav"
|
||||
msgid "Customers"
|
||||
msgstr "Clientes"
|
||||
|
||||
#: web/template/login.gohtml:2 web/template/login.gohtml:13
|
||||
msgctxt "title"
|
||||
msgid "Login"
|
||||
msgstr "Entrada"
|
||||
|
||||
#: web/template/login.gohtml:9
|
||||
#: web/template/login.gohtml:5
|
||||
msgid "Invalid user or password"
|
||||
msgstr "Nombre de usuario o contraseña inválido"
|
||||
|
||||
#: web/template/login.gohtml:17 web/template/tax-details.gohtml:27
|
||||
#: web/template/contacts-new.gohtml:27 pkg/profile.go:37
|
||||
#: web/template/login.gohtml:13 web/template/profile.gohtml:15
|
||||
#: web/template/tax-details.gohtml:23 web/template/contacts-new.gohtml:23
|
||||
msgctxt "input"
|
||||
msgid "Email"
|
||||
msgstr "Correo-e"
|
||||
|
||||
#: web/template/login.gohtml:22 pkg/profile.go:43
|
||||
#: web/template/login.gohtml:18 web/template/profile.gohtml:23
|
||||
msgctxt "input"
|
||||
msgid "Password"
|
||||
msgstr "Contraseña"
|
||||
|
||||
#: web/template/login.gohtml:25
|
||||
#: web/template/login.gohtml:21
|
||||
msgctxt "action"
|
||||
msgid "Login"
|
||||
msgstr "Entrar"
|
||||
|
||||
#: web/template/profile.gohtml:2 web/template/profile.gohtml:7
|
||||
#: web/template/profile.gohtml:3 pkg/profile.go:29
|
||||
msgctxt "title"
|
||||
msgid "User Settings"
|
||||
msgstr "Configuración usuario"
|
||||
|
||||
#: web/template/profile.gohtml:10
|
||||
#: web/template/profile.gohtml:6
|
||||
msgctxt "title"
|
||||
msgid "User Access Data"
|
||||
msgstr "Datos acceso usuario"
|
||||
|
||||
#: web/template/profile.gohtml:16
|
||||
msgctxt "title"
|
||||
msgid "Password Change"
|
||||
msgstr "Cambio de contraseña"
|
||||
|
||||
#: web/template/profile.gohtml:23
|
||||
msgctxt "title"
|
||||
msgid "Language"
|
||||
msgstr "Idioma"
|
||||
|
||||
#: web/template/profile.gohtml:27 web/template/tax-details.gohtml:133
|
||||
msgctxt "action"
|
||||
msgid "Save changes"
|
||||
msgstr "Guardar cambios"
|
||||
|
||||
#: web/template/contacts-index.gohtml:2
|
||||
msgctxt "title"
|
||||
msgid "Customers"
|
||||
msgstr "Clientes"
|
||||
|
||||
#: web/template/contacts-index.gohtml:6 web/template/contacts-new.gohtml:60
|
||||
msgctxt "action"
|
||||
msgid "New contact"
|
||||
msgstr "Nuevo contacto"
|
||||
|
||||
#: web/template/contacts-index.gohtml:11
|
||||
msgctxt "contact"
|
||||
msgid "All"
|
||||
msgstr "Todos"
|
||||
|
||||
#: web/template/contacts-index.gohtml:12
|
||||
msgctxt "title"
|
||||
msgid "Customer"
|
||||
msgstr "Cliente"
|
||||
|
||||
#: web/template/contacts-index.gohtml:13
|
||||
msgctxt "title"
|
||||
msgid "Email"
|
||||
msgstr "Correo-e"
|
||||
|
||||
#: web/template/contacts-index.gohtml:14
|
||||
msgctxt "title"
|
||||
msgid "Phone"
|
||||
msgstr "Teléfono"
|
||||
|
||||
#: web/template/contacts-index.gohtml:29
|
||||
msgid "No customers added yet."
|
||||
msgstr "No hay clientes."
|
||||
|
||||
#: web/template/tax-details.gohtml:2 web/template/tax-details.gohtml:7
|
||||
msgctxt "title"
|
||||
msgid "Tax Details"
|
||||
msgstr "Configuración fiscal"
|
||||
|
||||
#: web/template/tax-details.gohtml:11 web/template/contacts-new.gohtml:11
|
||||
msgctxt "input"
|
||||
msgid "Business name"
|
||||
msgstr "Nombre y apellidos"
|
||||
|
||||
#: web/template/tax-details.gohtml:15 web/template/contacts-new.gohtml:15
|
||||
msgctxt "input"
|
||||
msgid "VAT number"
|
||||
msgstr "DNI / NIF"
|
||||
|
||||
#: web/template/tax-details.gohtml:19 web/template/contacts-new.gohtml:19
|
||||
msgctxt "input"
|
||||
msgid "Trade name"
|
||||
msgstr "Nombre comercial"
|
||||
|
||||
#: web/template/tax-details.gohtml:23 web/template/contacts-new.gohtml:23
|
||||
msgctxt "input"
|
||||
msgid "Phone"
|
||||
msgstr "Teléfono"
|
||||
|
||||
#: web/template/tax-details.gohtml:31 web/template/contacts-new.gohtml:31
|
||||
msgctxt "input"
|
||||
msgid "Web"
|
||||
msgstr "Web"
|
||||
|
||||
#: web/template/tax-details.gohtml:35 web/template/contacts-new.gohtml:35
|
||||
msgctxt "input"
|
||||
msgid "Address"
|
||||
msgstr "Dirección"
|
||||
|
||||
#: web/template/tax-details.gohtml:39 web/template/contacts-new.gohtml:39
|
||||
msgctxt "input"
|
||||
msgid "City"
|
||||
msgstr "Población"
|
||||
|
||||
#: web/template/tax-details.gohtml:43 web/template/contacts-new.gohtml:43
|
||||
msgctxt "input"
|
||||
msgid "Province"
|
||||
msgstr "Provincia"
|
||||
|
||||
#: web/template/tax-details.gohtml:47 web/template/contacts-new.gohtml:47
|
||||
msgctxt "input"
|
||||
msgid "Postal code"
|
||||
msgstr "Código postal"
|
||||
|
||||
#: web/template/tax-details.gohtml:56 web/template/contacts-new.gohtml:56
|
||||
msgctxt "input"
|
||||
msgid "Country"
|
||||
msgstr "País"
|
||||
|
||||
#: web/template/tax-details.gohtml:60
|
||||
msgctxt "input"
|
||||
msgid "Currency"
|
||||
msgstr "Moneda"
|
||||
|
||||
#: web/template/tax-details.gohtml:78
|
||||
msgctxt "title"
|
||||
msgid "Tax Name"
|
||||
msgstr "Nombre impuesto"
|
||||
|
||||
#: web/template/tax-details.gohtml:79
|
||||
msgctxt "title"
|
||||
msgid "Rate (%)"
|
||||
msgstr "Porcentage"
|
||||
|
||||
#: web/template/tax-details.gohtml:100
|
||||
msgid "No taxes added yet."
|
||||
msgstr "No hay impuestos."
|
||||
|
||||
#: web/template/tax-details.gohtml:106
|
||||
msgctxt "title"
|
||||
msgid "New Line"
|
||||
msgstr "Nueva línea"
|
||||
|
||||
#: web/template/tax-details.gohtml:111
|
||||
msgctxt "input"
|
||||
msgid "Tax name"
|
||||
msgstr "Nombre impuesto"
|
||||
|
||||
#: web/template/tax-details.gohtml:118
|
||||
msgctxt "input"
|
||||
msgid "Rate (%)"
|
||||
msgstr "Porcentage"
|
||||
|
||||
#: web/template/tax-details.gohtml:125
|
||||
msgctxt "action"
|
||||
msgid "Add new tax"
|
||||
msgstr "Añadir nuevo impuesto"
|
||||
|
||||
#: web/template/contacts-new.gohtml:2 web/template/contacts-new.gohtml:7
|
||||
msgctxt "title"
|
||||
msgid "New Contact"
|
||||
msgstr "Nuevo contacto"
|
||||
|
||||
#: pkg/profile.go:26
|
||||
msgctxt "language option"
|
||||
msgid "Automatic"
|
||||
msgstr "Automático"
|
||||
|
||||
#: pkg/profile.go:31
|
||||
#: web/template/profile.gohtml:10
|
||||
msgctxt "input"
|
||||
msgid "User name"
|
||||
msgstr "Nombre de usuario"
|
||||
|
||||
#: pkg/profile.go:48
|
||||
#: web/template/profile.gohtml:19
|
||||
msgctxt "title"
|
||||
msgid "Password Change"
|
||||
msgstr "Cambio de contraseña"
|
||||
|
||||
#: web/template/profile.gohtml:28
|
||||
msgctxt "input"
|
||||
msgid "Password Confirmation"
|
||||
msgstr "Confirmación contrasenya"
|
||||
|
||||
#: pkg/profile.go:53
|
||||
#: web/template/profile.gohtml:33
|
||||
msgctxt "input"
|
||||
msgid "Language"
|
||||
msgstr "Idioma"
|
||||
|
||||
#: pkg/profile.go:74
|
||||
msgid "Email can not be empty."
|
||||
msgstr "No podéis dejar el correo-e en blanco."
|
||||
#: web/template/profile.gohtml:36
|
||||
msgctxt "language option"
|
||||
msgid "Automatic"
|
||||
msgstr "Automático"
|
||||
|
||||
#: pkg/profile.go:76
|
||||
msgid "This value is not a valid email. It should be like name@domain.com."
|
||||
msgstr "Este valor no es un correo-e válido. Tiene que ser parecido a nombre@dominio.es."
|
||||
#: web/template/profile.gohtml:42 web/template/tax-details.gohtml:127
|
||||
msgctxt "action"
|
||||
msgid "Save changes"
|
||||
msgstr "Guardar cambios"
|
||||
|
||||
#: pkg/profile.go:79
|
||||
msgid "Name can not be empty."
|
||||
msgstr "No podéis dejar el nombre en blanco."
|
||||
#: web/template/contacts-index.gohtml:2 web/template/contacts-new.gohtml:56
|
||||
msgctxt "action"
|
||||
msgid "New contact"
|
||||
msgstr "Nuevo contacto"
|
||||
|
||||
#: pkg/profile.go:82
|
||||
msgid "Confirmation does not match password."
|
||||
msgstr "La confirmación no corresponde con la contraseña."
|
||||
#: web/template/contacts-index.gohtml:7
|
||||
msgctxt "contact"
|
||||
msgid "All"
|
||||
msgstr "Todos"
|
||||
|
||||
#: pkg/profile.go:85
|
||||
msgid "Selected language is not valid."
|
||||
msgstr "Habéis escogido un idioma que no es válido."
|
||||
#: web/template/contacts-index.gohtml:8
|
||||
msgctxt "title"
|
||||
msgid "Customer"
|
||||
msgstr "Cliente"
|
||||
|
||||
#: web/template/contacts-index.gohtml:9
|
||||
msgctxt "title"
|
||||
msgid "Email"
|
||||
msgstr "Correo-e"
|
||||
|
||||
#: web/template/contacts-index.gohtml:10
|
||||
msgctxt "title"
|
||||
msgid "Phone"
|
||||
msgstr "Teléfono"
|
||||
|
||||
#: web/template/contacts-index.gohtml:25
|
||||
msgid "No customers added yet."
|
||||
msgstr "No hay clientes."
|
||||
|
||||
#: web/template/tax-details.gohtml:3 pkg/company.go:108
|
||||
msgctxt "title"
|
||||
msgid "Tax Details"
|
||||
msgstr "Configuración fiscal"
|
||||
|
||||
#: web/template/tax-details.gohtml:7 web/template/contacts-new.gohtml:7
|
||||
msgctxt "input"
|
||||
msgid "Business name"
|
||||
msgstr "Nombre y apellidos"
|
||||
|
||||
#: web/template/tax-details.gohtml:11 web/template/contacts-new.gohtml:11
|
||||
msgctxt "input"
|
||||
msgid "VAT number"
|
||||
msgstr "DNI / NIF"
|
||||
|
||||
#: web/template/tax-details.gohtml:15 web/template/contacts-new.gohtml:15
|
||||
msgctxt "input"
|
||||
msgid "Trade name"
|
||||
msgstr "Nombre comercial"
|
||||
|
||||
#: web/template/tax-details.gohtml:19 web/template/contacts-new.gohtml:19
|
||||
msgctxt "input"
|
||||
msgid "Phone"
|
||||
msgstr "Teléfono"
|
||||
|
||||
#: web/template/tax-details.gohtml:27 web/template/contacts-new.gohtml:27
|
||||
msgctxt "input"
|
||||
msgid "Web"
|
||||
msgstr "Web"
|
||||
|
||||
#: web/template/tax-details.gohtml:31 web/template/contacts-new.gohtml:31
|
||||
msgctxt "input"
|
||||
msgid "Address"
|
||||
msgstr "Dirección"
|
||||
|
||||
#: web/template/tax-details.gohtml:35 web/template/contacts-new.gohtml:35
|
||||
msgctxt "input"
|
||||
msgid "City"
|
||||
msgstr "Población"
|
||||
|
||||
#: web/template/tax-details.gohtml:39 web/template/contacts-new.gohtml:39
|
||||
msgctxt "input"
|
||||
msgid "Province"
|
||||
msgstr "Provincia"
|
||||
|
||||
#: web/template/tax-details.gohtml:43 web/template/contacts-new.gohtml:43
|
||||
msgctxt "input"
|
||||
msgid "Postal code"
|
||||
msgstr "Código postal"
|
||||
|
||||
#: web/template/tax-details.gohtml:52 web/template/contacts-new.gohtml:52
|
||||
msgctxt "input"
|
||||
msgid "Country"
|
||||
msgstr "País"
|
||||
|
||||
#: web/template/tax-details.gohtml:56
|
||||
msgctxt "input"
|
||||
msgid "Currency"
|
||||
msgstr "Moneda"
|
||||
|
||||
#: web/template/tax-details.gohtml:74
|
||||
msgctxt "title"
|
||||
msgid "Tax Name"
|
||||
msgstr "Nombre impuesto"
|
||||
|
||||
#: web/template/tax-details.gohtml:75
|
||||
msgctxt "title"
|
||||
msgid "Rate (%)"
|
||||
msgstr "Porcentage"
|
||||
|
||||
#: web/template/tax-details.gohtml:96
|
||||
msgid "No taxes added yet."
|
||||
msgstr "No hay impuestos."
|
||||
|
||||
#: web/template/tax-details.gohtml:102
|
||||
msgctxt "title"
|
||||
msgid "New Line"
|
||||
msgstr "Nueva línea"
|
||||
|
||||
#: web/template/tax-details.gohtml:106
|
||||
msgctxt "input"
|
||||
msgid "Tax name"
|
||||
msgstr "Nombre impuesto"
|
||||
|
||||
#: web/template/tax-details.gohtml:112
|
||||
msgctxt "input"
|
||||
msgid "Rate (%)"
|
||||
msgstr "Porcentage"
|
||||
|
||||
#: web/template/tax-details.gohtml:119
|
||||
msgctxt "action"
|
||||
msgid "Add new tax"
|
||||
msgstr "Añadir nuevo impuesto"
|
||||
|
||||
#: web/template/contacts-new.gohtml:3 pkg/contacts.go:95
|
||||
msgctxt "title"
|
||||
msgid "New Contact"
|
||||
msgstr "Nuevo contacto"
|
||||
|
||||
#: pkg/contacts.go:43
|
||||
msgctxt "title"
|
||||
msgid "Customers"
|
||||
msgstr "Clientes"
|
||||
|
2317
web/static/fonts/remixicon.css
Normal file
2317
web/static/fonts/remixicon.css
Normal file
File diff suppressed because it is too large
Load Diff
1
web/static/fonts/remixicon.glyph.json
Normal file
1
web/static/fonts/remixicon.glyph.json
Normal file
File diff suppressed because one or more lines are too long
2319
web/static/fonts/remixicon.less
Normal file
2319
web/static/fonts/remixicon.less
Normal file
File diff suppressed because it is too large
Load Diff
11356
web/static/fonts/remixicon.symbol.svg
Normal file
11356
web/static/fonts/remixicon.symbol.svg
Normal file
File diff suppressed because it is too large
Load Diff
After Width: | Height: | Size: 877 KiB |
@ -246,7 +246,7 @@ header {
|
||||
background-color: var(--numerus--header--background-color);
|
||||
}
|
||||
|
||||
header, nav a {
|
||||
header, nav {
|
||||
padding: 0 3rem;
|
||||
}
|
||||
|
||||
@ -320,19 +320,13 @@ input.width-2x {
|
||||
top: 1rem;
|
||||
}
|
||||
|
||||
.input ul {
|
||||
font-size: .8em;
|
||||
padding-left: 1em;
|
||||
color: var(--numerus--color--red);
|
||||
}
|
||||
|
||||
[lang="en"] input:not([required]) + label::after {
|
||||
content: " (optional)"
|
||||
}
|
||||
|
||||
[lang="ca"] input:not([required]) + label::after
|
||||
, [lang="es"] input:not([required]) + label::after {
|
||||
content: " (opcional)"
|
||||
content: " (optional)"
|
||||
}
|
||||
|
||||
.input label, .input input:focus ~ label {
|
||||
@ -392,11 +386,11 @@ fieldset {
|
||||
|
||||
/* Profile Menu */
|
||||
|
||||
#profile-menu {
|
||||
#profilemenu {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#profile-menu summary {
|
||||
#profilemenu summary {
|
||||
width: 7rem;
|
||||
height: 7rem;
|
||||
margin: 1rem 0;
|
||||
@ -407,19 +401,19 @@ fieldset {
|
||||
border: none;
|
||||
}
|
||||
|
||||
#profile-menu summary::-webkit-details-marker {
|
||||
#profilemenu summary::-webkit-details-marker {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#profile-menu summary, #profile-menu button {
|
||||
#profilemenu summary, #profilemenu button {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#profile-menu summary, #profile-menu ul {
|
||||
#profilemenu summary, #profilemenu ul {
|
||||
background-color: var(--numerus--background-color);
|
||||
}
|
||||
|
||||
#profile-menu[open] summary::before {
|
||||
#profilemenu[open] summary::before {
|
||||
background-color: var(--numerus--header--background-color);
|
||||
position: fixed;
|
||||
top: 0;
|
||||
@ -432,7 +426,7 @@ fieldset {
|
||||
mix-blend-mode: multiply;
|
||||
}
|
||||
|
||||
#profile-menu ul {
|
||||
#profilemenu ul {
|
||||
list-style: none;
|
||||
position: absolute;
|
||||
right: -1.875em;
|
||||
@ -441,11 +435,11 @@ fieldset {
|
||||
z-index: 20;
|
||||
}
|
||||
|
||||
#profile-menu li + li {
|
||||
#profilemenu li + li {
|
||||
border-top: 1px solid var(--numerus--color--black);
|
||||
}
|
||||
|
||||
#profile-menu button, #profile-menu a {
|
||||
#profilemenu button, #profilemenu a {
|
||||
font-size: 2rem;
|
||||
font-style: italic;
|
||||
height: 8rem;
|
||||
@ -459,15 +453,15 @@ fieldset {
|
||||
text-transform: initial;
|
||||
}
|
||||
|
||||
#profile-menu li i[class^='ri-'] {
|
||||
#profilemenu li i[class^='ri-'] {
|
||||
margin-right: 2rem;
|
||||
color: var(--numerus--color--dark-gray);
|
||||
}
|
||||
|
||||
#profile-menu summary:hover
|
||||
, #profile-menu summary:focus
|
||||
, #profile-menu button:hover
|
||||
, #profile-menu a:hover
|
||||
#profilemenu summary:hover
|
||||
, #profilemenu summary:focus
|
||||
, #profilemenu button:hover
|
||||
, #profilemenu a:hover
|
||||
, nav a:hover
|
||||
{
|
||||
background-color: var(--numerus--color--light-gray);
|
||||
@ -488,7 +482,6 @@ fieldset {
|
||||
}
|
||||
|
||||
[class^='ri-'], [class*=' ri-'] {
|
||||
/*noinspection CssNoGenericFontName*/
|
||||
font-family: 'remixicon' !important;
|
||||
font-style: normal;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
|
@ -1,15 +1,15 @@
|
||||
<!doctype html>
|
||||
<html lang="{{ currentLocale }}">
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>{{ template "title" . }} — Numerus</title>
|
||||
<title>{{ .Title }} — Numerus</title>
|
||||
<link rel="stylesheet" type="text/css" media="screen" href="/static/numerus.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<h1><img src="/static/numerus.svg" alt="Numerus" width="261" height="33"></h1>
|
||||
<details id="profile-menu">
|
||||
<details id="profilemenu">
|
||||
<summary>
|
||||
<i class="ri-eye-close-line ri-3x"></i>
|
||||
</summary>
|
||||
@ -39,7 +39,6 @@
|
||||
</header>
|
||||
<nav aria-label="{{( pgettext "Main" "title" )}}">
|
||||
<ul>
|
||||
<li><a href="{{ companyURI "/" }}">{{( pgettext "Dashboard" "nav" )}}</a></li>
|
||||
<li><a href="{{ companyURI "/contacts" }}">{{( pgettext "Customers" "nav" )}}</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
@ -1,7 +1,3 @@
|
||||
{{ define "title" -}}
|
||||
{{( pgettext "Customers" "title" )}}
|
||||
{{- end }}
|
||||
|
||||
{{ define "content" }}
|
||||
<a class="primary button" href="{{ companyURI "/contacts/new" }}">{{( pgettext "New contact" "action" )}}</a>
|
||||
|
||||
|
@ -1,7 +1,3 @@
|
||||
{{ define "title" -}}
|
||||
{{( pgettext "New Contact" "title" )}}
|
||||
{{- end }}
|
||||
|
||||
{{ define "content" }}
|
||||
<section class="dialog-content">
|
||||
<h2>{{(pgettext "New Contact" "title")}}</h2>
|
||||
|
@ -1,6 +1,2 @@
|
||||
{{ define "title" -}}
|
||||
{{( pgettext "Dashboard" "title" )}}
|
||||
{{- end }}
|
||||
|
||||
{{ define "content" }}
|
||||
{{- end }}
|
||||
|
@ -1,33 +0,0 @@
|
||||
{{ define "input-field" -}}
|
||||
<div class="input {{ if .Errors }}has-errors{{ end }}">
|
||||
<input type="{{ .Type }}" name="{{ .Name }}" id="{{ .Name }}-field"
|
||||
{{ if .Required }}required="required"{{ end }} value="{{ .Value }}" placeholder="{{ .Label }}">
|
||||
<label for="{{ .Name }}-field">{{ .Label }}</label>
|
||||
{{ if .Errors }}
|
||||
<ul>
|
||||
{{- range $error := .Errors }}
|
||||
<li>{{ . }}</li>
|
||||
{{- end }}
|
||||
</ul>
|
||||
{{ end }}
|
||||
</div>
|
||||
{{- end }}
|
||||
|
||||
{{ define "select-field" -}}
|
||||
<div class="input {{ if .Errors }}has-errors{{ end }}">
|
||||
<select id="{{ .Name }}-field" name="{{ .Name }}">
|
||||
{{- range $option := .Options }}
|
||||
<option value="{{ .Value }}"
|
||||
{{ if eq .Value $.Selected }}selected="selected"{{ end }}>{{ .Label }}</option>
|
||||
{{- end }}
|
||||
</select>
|
||||
<label for="{{ .Name }}-field">{{ .Label }}</label>
|
||||
{{ if .Errors }}
|
||||
<ul>
|
||||
{{- range $error := .Errors }}
|
||||
<li>{{ . }}</li>
|
||||
{{- end }}
|
||||
</ul>
|
||||
{{ end }}
|
||||
</div>
|
||||
{{- end }}
|
@ -1,7 +1,3 @@
|
||||
{{ define "title" -}}
|
||||
{{( pgettext "Login" "title" )}}
|
||||
{{- end }}
|
||||
|
||||
{{ define "content" }}
|
||||
<h1><img src="/static/numerus.svg" alt="Numerus" width="620" height="77"></h1>
|
||||
{{ if .LoginError -}}
|
||||
|
@ -1,31 +1,46 @@
|
||||
{{ define "title" -}}
|
||||
{{( pgettext "User Settings" "title" )}}
|
||||
{{- end }}
|
||||
|
||||
{{ define "content" }}
|
||||
<section class="dialog-content">
|
||||
<h2>{{(pgettext "User Settings" "title")}}</h2>
|
||||
<form method="POST">
|
||||
<fieldset class="full-width">
|
||||
<legend>{{( pgettext "User Access Data" "title" )}}</legend>
|
||||
<section class="dialog-content">
|
||||
<h2>{{(pgettext "User Settings" "title")}}</h2>
|
||||
<form method="POST" action="/profile">
|
||||
<fieldset class="full-width">
|
||||
<legend>{{( pgettext "User Access Data" "title" )}}</legend>
|
||||
|
||||
{{ template "input-field" .Name }}
|
||||
{{ template "input-field" .Email }}
|
||||
</fieldset>
|
||||
<fieldset class="full-width">
|
||||
<legend>{{( pgettext "Password Change" "title" )}}</legend>
|
||||
<div class="input">
|
||||
<input type="text" name="name" id="name" required="required" value="{{ .Name }}" placeholder="{{( pgettext "User name" "input" )}}">
|
||||
<label for="name">{{( pgettext "User name" "input" )}}</label>
|
||||
</div>
|
||||
|
||||
{{ template "input-field" .Password }}
|
||||
{{ template "input-field" .PasswordConfirm }}
|
||||
</fieldset>
|
||||
<div class="input">
|
||||
<input type="email" name="email" id="email" required="required" value="{{ .Email }}" placeholder="{{( pgettext "Email" "input" )}}">
|
||||
<label for="email">{{( pgettext "Email" "input" )}}</label>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset class="full-width">
|
||||
<legend>{{( pgettext "Password Change" "title" )}}</legend>
|
||||
|
||||
<fieldset>
|
||||
<legend id="language-legend">{{( pgettext "Language" "title" )}}</legend>
|
||||
<div class="input">
|
||||
<input type="password" name="password" id="password" value="{{ .Password }}" placeholder="{{( pgettext "Password" "input" )}}">
|
||||
<label for="password">{{( pgettext "Password" "input" )}}</label>
|
||||
</div>
|
||||
|
||||
{{ template "select-field" .Language }}
|
||||
<div class="input">
|
||||
<input type="password" name="password_confirm" id="password_confirm" value="{{ .PasswordConfirm }}" placeholder="{{( pgettext "Password Confirmation" "input" )}}">
|
||||
<label for="password_confirm">{{( pgettext "Password Confirmation" "input" )}}</label>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<button type="submit">{{( pgettext "Save changes" "action" )}}</button>
|
||||
</fieldset>
|
||||
</form>
|
||||
</section>
|
||||
<fieldset>
|
||||
<legend id="language-legend">{{( pgettext "Language" "input" )}}</legend>
|
||||
|
||||
<select id="language" name="language" aria-labelledby="language-legend">
|
||||
<option value="und">{{( pgettext "Automatic" "language option" )}}</option>
|
||||
{{- range $language := .Languages }}
|
||||
<option value="{{ .Tag }}" {{ if eq .Tag $.Language }}selected="selected"{{ end }}>{{ .Name }}</option>
|
||||
{{- end }}
|
||||
</select>
|
||||
|
||||
<button type="submit">{{( pgettext "Save changes" "action" )}}</button>
|
||||
</fieldset>
|
||||
</form>
|
||||
</section>
|
||||
{{- end }}
|
||||
|
@ -1,7 +1,3 @@
|
||||
{{ define "title" -}}
|
||||
{{( pgettext "Tax Details" "title" )}}
|
||||
{{- end }}
|
||||
|
||||
{{ define "content" }}
|
||||
<section class="dialog-content">
|
||||
<h2>{{(pgettext "Tax Details" "title")}}</h2>
|
||||
@ -89,7 +85,7 @@
|
||||
<td>{{ .Rate }}</td>
|
||||
<td>
|
||||
<form method="POST" action="{{ companyURI "/tax"}}/{{ .Id }}">
|
||||
<input type="hidden" name="_method" value="DELETE"/>
|
||||
<input type="hidden" name="_method" name="DELETE"/>
|
||||
<button class="icon" aria-label="{{( gettext "Delete tax" )}}" type="submit"><i class="ri-delete-back-2-line"></i></button>
|
||||
</form>
|
||||
</td>
|
||||
|
@ -1,9 +1,9 @@
|
||||
<!doctype html>
|
||||
<html lang="{{ currentLocale }}">
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>{{ template "title" . }} — Numerus</title>
|
||||
<title>{{( pgettext "Login" "title" )}} — Numerus</title>
|
||||
<link rel="stylesheet" type="text/css" media="screen" href="/static/numerus.css">
|
||||
</head>
|
||||
<body class="web">
|
||||
|
Loading…
x
Reference in New Issue
Block a user