Merge branch 'main' of ssh://git.ma-al.com:8822/goc_daniel/b2b into product-procedures

This commit is contained in:
2026-03-26 15:57:21 +01:00
10 changed files with 247 additions and 190 deletions

View File

@@ -1236,6 +1236,51 @@
}
}
},
"/api/v1/restricted/menu/get-top-menu": {
"get": {
"tags": ["Menu"],
"summary": "Get top menu",
"description": "Returns the top-level menu items for the current language. Requires authentication.",
"operationId": "getTopMenu",
"security": [
{
"CookieAuth": []
}
],
"responses": {
"200": {
"description": "Top menu retrieved successfully",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ApiResponse"
}
}
}
},
"400": {
"description": "Invalid request",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Not authenticated",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}
},
"/api/v1/restricted/meili-search/search": {
"get": {
"tags": ["Search"],

View File

@@ -25,6 +25,7 @@ func MenuHandlerRoutes(r fiber.Router) fiber.Router {
r.Get("/get-menu", handler.GetMenu)
r.Get("/get-routes", handler.GetRouting)
r.Get("/get-top-menu", handler.GetTopMenu)
return r
}
@@ -58,3 +59,18 @@ func (h *MenuHandler) GetRouting(c fiber.Ctx) error {
return c.JSON(response.Make(&menu, 0, i18n.T_(c, response.Message_OK)))
}
func (h *MenuHandler) GetTopMenu(c fiber.Ctx) error {
lang_id, ok := c.Locals("langID").(uint)
if !ok {
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute)))
}
menu, err := h.menuService.GetTopMenu(lang_id)
if err != nil {
return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
}
return c.JSON(response.Make(&menu, len(menu), i18n.T_(c, response.Message_OK)))
}

17
app/model/topMenu.go Normal file
View File

@@ -0,0 +1,17 @@
package model
type B2BTopMenu struct {
MenuID int `gorm:"column:menu_id;primaryKey;autoIncrement" json:"menu_id"`
Label string `gorm:"column:label;type:longtext;not null;default:'{}'" json:"label"`
ParentID *int `gorm:"column:parent_id;index:FK_b2b_top_menu_parent_id" json:"parent_id,omitempty"`
Params string `gorm:"column:params;type:longtext;not null;default:'{}'" json:"params"`
Active int8 `gorm:"column:active;type:tinyint;not null;default:1" json:"active"`
Position int `gorm:"column:position;not null;default:1" json:"position"`
Parent *B2BTopMenu `gorm:"foreignKey:ParentID;references:MenuID;constraint:OnDelete:RESTRICT,OnUpdate:RESTRICT" json:"parent,omitempty"`
Children []B2BTopMenu `gorm:"foreignKey:ParentID" json:"children,omitempty"`
}
func (B2BTopMenu) TableName() string {
return "b2b_top_menu"
}

View File

@@ -7,6 +7,7 @@ import (
type UIRoutesRepo interface {
GetRoutes(langId uint) ([]model.Route, error)
GetTopMenu(id uint) ([]model.B2BTopMenu, error)
}
type RoutesRepo struct{}
@@ -23,3 +24,14 @@ func (p *RoutesRepo) GetRoutes(langId uint) ([]model.Route, error) {
}
return routes, nil
}
func (p *RoutesRepo) GetTopMenu(id uint) ([]model.B2BTopMenu, error) {
var menus []model.B2BTopMenu
err := db.Get().
Where("active = ?", 1).
Order("parent_id ASC, position ASC").
Find(&menus).Error
return menus, err
}

View File

@@ -3,12 +3,9 @@ package menuService
import (
"sort"
"git.ma-al.com/goc_daniel/b2b/app/db"
"git.ma-al.com/goc_daniel/b2b/app/model"
"git.ma-al.com/goc_daniel/b2b/app/model/prestadb"
"git.ma-al.com/goc_daniel/b2b/app/repos/categoriesRepo"
routesRepo "git.ma-al.com/goc_daniel/b2b/app/repos/routesRepo"
"git.ma-al.com/goc_daniel/b2b/app/utils/jsonprint"
"git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors"
)
@@ -77,17 +74,6 @@ func (s *MenuService) createTree(index int, all_categories *([]model.ScannedCate
}
func (s *MenuService) GetRoutes(id_lang uint) ([]model.Route, error) {
type XX struct {
prestadb.PsProduct
// PsProductLang prestadb.PsProductLang `gorm:"foreignKey:IDProduct;references:IDProduct"`
// PSProductAttribute prestadb.PsProductAttribute `gorm:"foreignKey:IDProduct;references:IDProduct"`
}
product := XX{}
db.Get().Debug().Find(&product, prestadb.PsCategoryProduct{IDProduct: 53})
// fmt.Printf("%v\n nnnnnnnn", product)
jsonprint.Print(product)
return s.routesRepo.GetRoutes(id_lang)
}
@@ -111,3 +97,42 @@ type ByPosition []ChildWithPosition
func (a ByPosition) Len() int { return len(a) }
func (a ByPosition) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a ByPosition) Less(i, j int) bool { return a[i].Position < a[j].Position }
func (s *MenuService) GetTopMenu(id uint) ([]model.B2BTopMenu, error) {
items, err := s.routesRepo.GetTopMenu(id)
if err != nil {
return nil, err
}
if len(items) == 0 {
return []model.B2BTopMenu{}, nil
}
// Build a map with empty children slices
itemMap := make(map[int]model.B2BTopMenu, len(items))
for i := range items {
items[i].Children = []model.B2BTopMenu{}
itemMap[items[i].MenuID] = items[i]
}
// Build the tree
var roots []model.B2BTopMenu
for _, item := range itemMap {
if item.ParentID == nil || *item.ParentID == 0 {
roots = append(roots, itemMap[item.MenuID])
} else {
parentID := *item.ParentID
if parent, exists := itemMap[parentID]; exists {
parent.Children = append(parent.Children, item)
itemMap[parentID] = parent
}
}
}
// Update roots with children
for i := range roots {
roots[i] = itemMap[roots[i].MenuID]
}
return roots, nil
}

View File

@@ -2,10 +2,10 @@
database:
type: mysql # "mysql" (default),sqlite or "postgres"
host: localhost
port: 5432
user: gitea
password: gitea
database: gitea
port: 3306
user: root
password: Maal12345678
database: nalu
max_open_conns: 10
max_idle_conns: 5

View File

@@ -28,6 +28,46 @@ VALUES
('reset-password', 'reset-password', '@/views/ResetPasswordView.vue', 'empty', '{"guest":true}', 1, 5, NULL),
('verify-email', 'verify-email', '@/views/VerifyEmailView.vue', 'empty', '{"guest":true}', 1, 6, NULL);
CREATE TABLE IF NOT EXISTS b2b_top_menu (
menu_id INT AUTO_INCREMENT NOT NULL,
label LONGTEXT NOT NULL DEFAULT '{}',
parent_id INT NULL DEFAULT NULL,
params LONGTEXT NOT NULL DEFAULT '{}',
active TINYINT NOT NULL DEFAULT 1,
position INT NOT NULL DEFAULT 1,
PRIMARY KEY (menu_id),
CONSTRAINT FK_b2b_top_menu_parent_id FOREIGN KEY (parent_id)
REFERENCES b2b_top_menu (menu_id)
ON DELETE RESTRICT ON UPDATE RESTRICT,
INDEX FK_b2b_top_menu_parent_id_idx (parent_id ASC)
) ENGINE = InnoDB;
INSERT IGNORE INTO `b2b_top_menu` (`menu_id`, `label`, `parent_id`, `params`)
VALUES
-- ROOT
(1, JSON_COMPACT('{"name":"root","trans":{"pl":"Menu główne","en":"Main Menu","de":"Hauptmenü"}}'), NULL, '{}'),
-- LEVEL 1
(2, JSON_COMPACT('{"name":"dashboard","trans":{"pl":"Panel","en":"Dashboard","de":"Dashboard"}}'), 1, '{}'),
(3, JSON_COMPACT('{"name":"orders","trans":{"pl":"Zamówienia","en":"Orders","de":"Bestellungen"}}'), 1, '{}'),
(4, JSON_COMPACT('{"name":"customers","trans":{"pl":"Klienci","en":"Customers","de":"Kunden"}}'), 1, '{}'),
(5, JSON_COMPACT('{"name":"products","trans":{"pl":"Produkty","en":"Products","de":"Produkte"}}'), 1, '{}'),
(6, JSON_COMPACT('{"name":"reports","trans":{"pl":"Raporty","en":"Reports","de":"Berichte"}}'), 1, '{}'),
-- LEVEL 2 (Orders)
(7, JSON_COMPACT('{"name":"order_list","trans":{"pl":"Lista zamówień","en":"Order List","de":"Bestellliste"}}'), 3, '{}'),
(8, JSON_COMPACT('{"name":"pending_orders","trans":{"pl":"Oczekujące zamówienia","en":"Pending Orders","de":"Ausstehende Bestellungen"}}'), 3, '{}'),
(9, JSON_COMPACT('{"name":"carts","trans":{"pl":"Koszyki","en":"Carts","de":"Warenkörbe"}}'), 3, '{}'),
-- LEVEL 2 (Products)
(10, JSON_COMPACT('{"name":"product_list","trans":{"pl":"Lista produktów","en":"Product List","de":"Produktliste"}}'), 5, '{}'),
(11, JSON_COMPACT('{"name":"categories","trans":{"pl":"Kategorie","en":"Categories","de":"Kategorien"}}'), 5, '{}'),
(12, JSON_COMPACT('{"name":"inventory","trans":{"pl":"Magazyn","en":"Inventory","de":"Lagerbestand"}}'), 5, '{}'),
-- LEVEL 2 (Customers)
(13, JSON_COMPACT('{"name":"customer_list","trans":{"pl":"Lista klientów","en":"Customer List","de":"Kundenliste"}}'), 4, '{}'),
(14, JSON_COMPACT('{"name":"customer_groups","trans":{"pl":"Grupy klientów","en":"Customer Groups","de":"Kundengruppen"}}'), 4, '{}');
-- +goose Down
DROP TABLE IF EXISTS b2b_routes;

View File

@@ -1,34 +0,0 @@
-- +goose Up
-- -- create routes table
-- CREATE TABLE IF NOT EXISTS b2b_routes (
-- id INT AUTO_INCREMENT PRIMARY KEY,
-- name VARCHAR(255) NOT NULL UNIQUE,
-- path VARCHAR(255) NULL,
-- component VARCHAR(255) NOT NULL COMMENT 'path to component file',
-- layout VARCHAR(50) DEFAULT 'default' COMMENT "'default' | 'empty'",
-- meta JSON DEFAULT '{}',
-- is_active BOOLEAN DEFAULT TRUE,
-- sort_order INT DEFAULT 0,
-- parent_id INT NULL,
-- CONSTRAINT fk_parent
-- FOREIGN KEY (parent_id)
-- REFERENCES b2b_routes(id)
-- ON DELETE SET NULL
-- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- INSERT IGNORE INTO b2b_routes
-- (name, path, component, layout, meta, is_active, sort_order, parent_id)
-- VALUES
-- ('root', '', '', 'default', '{"trans": "route.root"}', 0, 0, 0),
-- ('home', '', '@/views/HomeView.vue', 'default', '{"trans": "route.home"}', 1, 0, 0),
-- ('login', 'login', '@/views/LoginView.vue', 'empty', '{"guest":true}', 1, 2, NULL),
-- ('register', 'register', '@/views/RegisterView.vue', 'empty', '{"guest":true}', 1, 3, NULL),
-- ('password-recovery', 'password-recovery', '@/views/PasswordRecoveryView.vue', 'empty', '{"guest":true}', 1, 4, NULL),
-- ('reset-password', 'reset-password', '@/views/ResetPasswordView.vue', 'empty', '{"guest":true}', 1, 5, NULL),
-- ('verify-email', 'verify-email', '@/views/VerifyEmailView.vue', 'empty', '{"guest":true}', 1, 6, NULL);
-- +goose Down
-- DROP TABLE IF EXISTS b2b_routes;

View File

@@ -24,8 +24,7 @@ INSERT IGNORE INTO b2b_language
VALUES
(1, '2022-09-16 17:10:02.837', '2026-03-02 21:24:36.779730', NULL, 'Polski', 'pl', 'pl', '__-__-____', '__-__', 0, 0, 1, '🇵🇱'),
(2, '2022-09-16 17:10:02.852', '2026-03-02 21:24:36.779730', NULL, 'English', 'en', 'en', '__-__-____', '__-__', 0, 1, 1, '🇬🇧'),
(3, '2022-09-16 17:10:02.865', '2026-03-02 21:24:36.779730', NULL, 'Čeština', 'cs', 'cs', '__-__-____', '__-__', 0, 0, 0, '🇨🇿'),
(4, '2022-09-16 17:10:02.852', '2026-03-02 21:24:36.779730', NULL, 'Deutsch', 'de', 'de', '__-__-____', '__-__', 0, 0, 1, '🇩🇪');
(3, '2022-09-16 17:10:02.852', '2026-03-02 21:24:36.779730', NULL, 'Deutsch', 'de', 'de', '__-__-____', '__-__', 0, 0, 1, '🇩🇪');
CREATE TABLE IF NOT EXISTS b2b_components (
id INT AUTO_INCREMENT PRIMARY KEY,

View File

@@ -20,49 +20,53 @@ INSERT IGNORE b2b_scopes (id, name) VALUES (1, 'Backend');
-- Translations
-- Component: be
INSERT IGNORE b2b_translations (lang_id, scope_id, component_id, `key`, data) VALUES
(1, 1, 1, 'langs_loaded', NULL),
(1, 1, 1, 'langs_not_loaded', NULL),
(1, 1, 1, 'message_nok', NULL),
(1, 1, 1, 'message_ok', NULL),
(1, 1, 1, 'translations_loaded', NULL),
(1, 1, 1, 'translations_not_loaded', NULL),
(2, 1, 1, 'langs_loaded', NULL),
(2, 1, 1, 'langs_not_loaded', NULL),
(2, 1, 1, 'message_nok', NULL),
(2, 1, 1, 'message_ok', NULL),
(2, 1, 1, 'translations_loaded', NULL),
(2, 1, 1, 'translations_not_loaded', NULL),
(3, 1, 1, 'langs_loaded', NULL),
(3, 1, 1, 'langs_not_loaded', NULL),
(3, 1, 1, 'message_nok', NULL),
(3, 1, 1, 'message_ok', NULL),
(3, 1, 1, 'translations_loaded', NULL),
(3, 1, 1, 'translations_not_loaded', NULL);
-- -- Component: be
-- INSERT IGNORE b2b_translations (lang_id, scope_id, component_id, `key`, data) VALUES
-- (1, 1, 1, 'langs_loaded', 'Języki załadowane'),
-- (1, 1, 1, 'langs_not_loaded', 'Nie udało się załadować języków'),
-- (1, 1, 1, 'message_nok', 'Błąd'),
-- (1, 1, 1, 'message_ok', 'Sukces'),
-- (1, 1, 1, 'translations_loaded', 'Tłumaczenia załadowane'),
-- (1, 1, 1, 'translations_not_loaded', 'Nie udało się załadować tłumaczeń'),
-- Component: email
INSERT IGNORE b2b_translations (lang_id, scope_id, component_id, `key`, data) VALUES
(1, 1, 100, 'langs_loaded', NULL),
(1, 1, 100, 'langs_not_loaded', NULL),
(1, 1, 100, 'message_nok', NULL),
(1, 1, 100, 'message_ok', NULL),
(1, 1, 100, 'translations_loaded', NULL),
(1, 1, 100, 'translations_not_loaded', NULL),
(2, 1, 100, 'langs_loaded', NULL),
(2, 1, 100, 'langs_not_loaded', NULL),
(2, 1, 100, 'message_nok', NULL),
(2, 1, 100, 'message_ok', NULL),
(2, 1, 100, 'translations_loaded', NULL),
(2, 1, 100, 'translations_not_loaded', NULL),
(3, 1, 100, 'langs_loaded', NULL),
(3, 1, 100, 'langs_not_loaded', NULL),
(3, 1, 100, 'message_nok', NULL),
(3, 1, 100, 'message_ok', NULL),
(3, 1, 100, 'translations_loaded', NULL),
(3, 1, 100, 'translations_not_loaded', NULL);
-- (2, 1, 1, 'langs_loaded', 'Languages loaded'),
-- (2, 1, 1, 'langs_not_loaded', 'Failed to load languages'),
-- (2, 1, 1, 'message_nok', 'Error'),
-- (2, 1, 1, 'message_ok', 'Success'),
-- (2, 1, 1, 'translations_loaded', 'Translations loaded'),
-- (2, 1, 1, 'translations_not_loaded', 'Failed to load translations'),
-- Component: error
-- (3, 1, 1, 'langs_loaded', 'Sprachen geladen'),
-- (3, 1, 1, 'langs_not_loaded', 'Sprachen konnten nicht geladen werden'),
-- (3, 1, 1, 'message_nok', 'Fehler'),
-- (3, 1, 1, 'message_ok', 'Erfolg'),
-- (3, 1, 1, 'translations_loaded', 'Übersetzungen geladen'),
-- (3, 1, 1, 'translations_not_loaded', 'Übersetzungen konnten nicht geladen werden');
-- Component: email (component_id = 100)
INSERT IGNORE b2b_translations (lang_id, scope_id, component_id, `key`, data) VALUES
(1, 1, 100, 'langs_loaded', 'Języki załadowane'),
(1, 1, 100, 'langs_not_loaded', 'Nie udało się załadować języków'),
(1, 1, 100, 'message_nok', 'Błąd'),
(1, 1, 100, 'message_ok', 'Sukces'),
(1, 1, 100, 'translations_loaded', 'Tłumaczenia załadowane'),
(1, 1, 100, 'translations_not_loaded', 'Nie udało się załadować tłumaczeń'),
(2, 1, 100, 'langs_loaded', 'Languages loaded'),
(2, 1, 100, 'langs_not_loaded', 'Failed to load languages'),
(2, 1, 100, 'message_nok', 'Error'),
(2, 1, 100, 'message_ok', 'Success'),
(2, 1, 100, 'translations_loaded', 'Translations loaded'),
(2, 1, 100, 'translations_not_loaded', 'Failed to load translations'),
(3, 1, 100, 'langs_loaded', 'Sprachen geladen'),
(3, 1, 100, 'langs_not_loaded', 'Sprachen konnten nicht geladen werden'),
(3, 1, 100, 'message_nok', 'Fehler'),
(3, 1, 100, 'message_ok', 'Erfolg'),
(3, 1, 100, 'translations_loaded', 'Übersetzungen geladen'),
(3, 1, 100, 'translations_not_loaded', 'Übersetzungen konnten nicht geladen werden');
-- Component: error (component_id = 101)
INSERT IGNORE b2b_translations (lang_id, scope_id, component_id, `key`, data) VALUES
(1, 1, 101, 'err_bad_paging', 'zła paginacja'),
(1, 1, 101, 'err_bad_quarter_attribute', 'nieprawidłowy atrybut quarter'),
@@ -91,6 +95,7 @@ INSERT IGNORE b2b_translations (lang_id, scope_id, component_id, `key`, data) VA
(1, 1, 101, 'err_user_inactive', 'konto użytkownika jest nieaktywne'),
(1, 1, 101, 'err_user_not_found', 'użytkownik nie został znaleziony'),
(1, 1, 101, 'err_verification_token_expired', 'token weryfikacyjny wygasł'),
(2, 1, 101, 'err_bad_paging', 'bad paging'),
(2, 1, 101, 'err_bad_quarter_attribute', 'bad quarter attribute'),
(2, 1, 101, 'err_bad_repo_id_attribute', 'bad repoID attribute'),
@@ -118,102 +123,34 @@ INSERT IGNORE b2b_translations (lang_id, scope_id, component_id, `key`, data) VA
(2, 1, 101, 'err_user_inactive', 'user account is inactive'),
(2, 1, 101, 'err_user_not_found', 'user not found'),
(2, 1, 101, 'err_verification_token_expired', 'verification token has expired'),
(3, 1, 101, 'err_bad_paging', 'špatné stránkování'),
(3, 1, 101, 'err_bad_quarter_attribute', 'atribut špatné čtvrtiny'),
(3, 1, 101, 'err_bad_repo_id_attribute', 'špatný atribut repoID'),
(3, 1, 101, 'err_bad_year_attribute', 'atribut špatného roku'),
(3, 1, 101, 'err_email_exists', 'e-mail již existuje'),
(3, 1, 101, 'err_email_not_verified', 'e-mail nebyl ověřen'),
(3, 1, 101, 'err_email_password_required', 'je vyžadován e-mail a heslo'),
(3, 1, 101, 'err_email_required', 'e-mail je povinný'),
(3, 1, 101, 'err_first_last_name_required', 'křestní jméno a příjmení je povinné'),
(3, 1, 101, 'err_internal_server_error', 'interní chyba serveru'),
(3, 1, 101, 'err_invalid_body', 'neplatné tělo požadavku'),
(3, 1, 101, 'err_invalid_credentials', 'neplatný e-mail nebo heslo'),
(3, 1, 101, 'err_invalid_password', 'heslo musí mít alespoň 10 znaků a musí obsahovat alespoň jedno malé písmeno, jedno velké písmeno a jednu číslici'),
(3, 1, 101, 'err_invalid_repo_id', 'nepřístupné ID úložiště'),
(3, 1, 101, 'err_invalid_reset_token', 'neplatný resetovací token'),
(3, 1, 101, 'err_invalid_token', 'neplatný token'),
(3, 1, 101, 'err_invalid_verification_token', 'neplatný ověřovací token'),
(3, 1, 101, 'err_not_authenticated', 'neověřeno'),
(3, 1, 101, 'err_passwords_do_not_match', 'hesla se neshodují'),
(3, 1, 101, 'err_refresh_token_required', 'Je vyžadován token pro obnovení'),
(3, 1, 101, 'err_reset_token_expired', 'Platnost resetovacího tokenu vypršela'),
(3, 1, 101, 'err_token_expired', 'platnost tokenu vypršela'),
(3, 1, 101, 'err_token_password_required', 'je vyžadován token a heslo'),
(3, 1, 101, 'err_token_required', 'je vyžadován token'),
(3, 1, 101, 'err_user_inactive', 'uživatelský účet je neaktivní'),
(3, 1, 101, 'err_user_not_found', 'uživatel nenalezen'),
(3, 1, 101, 'err_verification_token_expired', 'platnost ověřovacího tokenu vypršela');
-- Component: auth
INSERT IGNORE b2b_translations (lang_id, scope_id, component_id, `key`, data) VALUES
(1, 1, 102, 'auth_if_account_exists', 'jeśli konto o tym adresie e-mail istnieje, został wysłany link do resetowania hasła'),
(1, 1, 102, 'auth_logged_out_successfully', 'wylogowano pomyślnie'),
(1, 1, 102, 'auth_password_reset_successfully', 'pomyślnie zresetowano hasło'),
(1, 1, 102, 'auth_registration_successful', 'rejestracja pomyślna, proszę zweryfikować swój adres e-mail'),
(2, 1, 102, 'auth_if_account_exists', 'if an account with that email exists, a password reset link has been sent'),
(2, 1, 102, 'auth_logged_out_successfully', 'logged out successfully'),
(2, 1, 102, 'auth_password_reset_successfully', 'password reset successfully'),
(2, 1, 102, 'auth_registration_successful', 'registration successful, please verify your email'),
(3, 1, 102, 'auth_if_account_exists', 'Pokud účet s danou e-mailovou adresou existuje, byl odeslán odkaz pro resetování hesla.'),
(3, 1, 102, 'auth_logged_out_successfully', 'úspěšně odhlášen/a'),
(3, 1, 102, 'auth_password_reset_successfully', 'úspěšné obnovení hesla'),
(3, 1, 102, 'auth_registration_successful', 'Registrace úspěšná, prosím ověřte svůj e-mail');
-- Component: email
INSERT IGNORE b2b_translations (lang_id, scope_id, component_id, `key`, data) VALUES
(1, 1, 103, 'email_admin_notification_title', 'Admin notification title'),
(1, 1, 103, 'email_footer', 'Wszelkie prawa zastrzeżone.'),
(1, 1, 103, 'email_greeting', 'Witaj,'),
(1, 1, 103, 'email_ignore', 'Jeśli nie jesteś właścicielem tego konta, prosimy o zignorowanie maila.'),
(1, 1, 103, 'email_ignore_reset', 'Jeśli nie chcesz zmieniać hasła, prosimy o zignorowanie maila. Twoje hasło pozostanie niezmienione.'),
(1, 1, 103, 'email_or_copy', 'Bądź przekopiuj poniższy link do przeglądarki:'),
(1, 1, 103, 'email_password_reset_message1', 'Otrzymaliśmy prośbę o zresetowanie Twojego hasła. Aby utworzyć nowe hasło, kliknij w poniższy przycisk:'),
(1, 1, 103, 'email_password_reset_subject', 'Zresetuj hasło'),
(1, 1, 103, 'email_password_reset_title', 'Zresetuj swoje hasło'),
(1, 1, 103, 'email_password_reset_warning', 'Link na zresesetowanie hasła przedawni się po 1 godzinie.'),
(1, 1, 103, 'email_reset_button', 'Zresetuj hasło'),
(1, 1, 103, 'email_verification_message1', 'Dziękujemy za rejestrację. Aby dokończyć proces rejestracji, zweryfikuj swojego maila klikając w poniższy link:'),
(1, 1, 103, 'email_verification_note', 'Uwaga: link weryfikacyjny przedawni się za 24 godziny.'),
(1, 1, 103, 'email_verification_subject', 'Zweryfikuj swój adres email'),
(1, 1, 103, 'email_verification_title', 'Weryfikacja Adresu email'),
(1, 1, 103, 'email_verify_button', 'Zweryfikuj adres email'),
(1, 1, 103, 'email_warning_title', 'Ważne:'),
(2, 1, 103, 'email_admin_notification_title', 'Admin notification title'),
(2, 1, 103, 'email_footer', 'All rights reserved.'),
(2, 1, 103, 'email_greeting', 'Hello,'),
(2, 1, 103, 'email_ignore', 'If you did not create an account with us, please ignore this email.'),
(2, 1, 103, 'email_ignore_reset', 'If you did not request a password reset, please ignore this email. Your password will remain unchanged.'),
(2, 1, 103, 'email_or_copy', 'Or copy and paste this link into your browser:'),
(2, 1, 103, 'email_password_reset_message1', 'We received a request to reset your password. Click the button below to create a new password:'),
(2, 1, 103, 'email_password_reset_subject', 'Reset Your Password'),
(2, 1, 103, 'email_password_reset_title', 'Reset Your Password'),
(2, 1, 103, 'email_password_reset_warning', 'This password reset link will expire in 1 hour for security reasons.'),
(2, 1, 103, 'email_reset_button', 'Reset Password'),
(2, 1, 103, 'email_verification_message1', 'Thank you for registering with us. To complete your registration and activate your account, please verify your email address by clicking the button below:'),
(2, 1, 103, 'email_verification_note', 'Note: This verification link will expire in 24 hours.'),
(2, 1, 103, 'email_verification_subject', 'Verify Your Email Address'),
(2, 1, 103, 'email_verification_title', 'Verify Your Email Address'),
(2, 1, 103, 'email_verify_button', 'Verify Email Address'),
(2, 1, 103, 'email_warning_title', 'Important:'),
(3, 1, 103, 'email_admin_notification_title', 'Admin notification title'),
(3, 1, 103, 'email_footer', 'Všechna práva vyhrazena.'),
(3, 1, 103, 'email_greeting', 'Ahoj,'),
(3, 1, 103, 'email_ignore', 'Pokud jste si u nás nevytvořili účet, prosím, ignorujte tento e-mail.'),
(3, 1, 103, 'email_ignore_reset', 'Pokud jste nepožádali o obnovení hesla, ignorujte prosím tento e-mail. Vaše heslo zůstane nezměněno.'),
(3, 1, 103, 'email_or_copy', 'Nebo zkopírujte a vložte tento odkaz do prohlížeče:'),
(3, 1, 103, 'email_password_reset_message1', 'Obdrželi jsme žádost o obnovení hesla. Klikněte na tlačítko níže a vytvořte si nové heslo:'),
(3, 1, 103, 'email_password_reset_subject', 'Obnovte si heslo'),
(3, 1, 103, 'email_password_reset_title', 'Obnovte si heslo'),
(3, 1, 103, 'email_password_reset_warning', 'Z bezpečnostních důvodů platnost tohoto odkazu pro obnovení hesla vyprší za 1 hodinu.'),
(3, 1, 103, 'email_reset_button', 'Obnovit heslo'),
(3, 1, 103, 'email_verification_message1', 'Děkujeme za registraci u nás. Chcete-li dokončit registraci a aktivovat svůj účet, ověřte prosím svou e-mailovou adresu kliknutím na tlačítko níže:'),
(3, 1, 103, 'email_verification_note', 'Poznámka: Platnost tohoto ověřovacího odkazu vyprší za 24 hodin.'),
(3, 1, 103, 'email_verification_subject', 'Ověřte svou e-mailovou adresu'),
(3, 1, 103, 'email_verification_title', 'Ověřte svou e-mailovou adresu'),
(3, 1, 103, 'email_verify_button', 'Ověření e-mailové adresy'),
(3, 1, 103, 'email_warning_title', 'Důležité:');
(3, 1, 101, 'err_bad_paging', 'Ungültige Paginierung'),
(3, 1, 101, 'err_bad_quarter_attribute', 'Ungültiges Quarter-Attribut'),
(3, 1, 101, 'err_bad_repo_id_attribute', 'Ungültiges RepoID-Attribut'),
(3, 1, 101, 'err_bad_year_attribute', 'Ungültiges Year-Attribut'),
(3, 1, 101, 'err_email_exists', 'E-Mail existiert bereits'),
(3, 1, 101, 'err_email_not_verified', 'E-Mail nicht verifiziert'),
(3, 1, 101, 'err_email_password_required', 'E-Mail und Passwort erforderlich'),
(3, 1, 101, 'err_email_required', 'E-Mail ist erforderlich'),
(3, 1, 101, 'err_first_last_name_required', 'Vor- und Nachname erforderlich'),
(3, 1, 101, 'err_internal_server_error', 'Interner Serverfehler'),
(3, 1, 101, 'err_invalid_body', 'Ungültiger Request-Body'),
(3, 1, 101, 'err_invalid_credentials', 'Ungültige E-Mail oder Passwort'),
(3, 1, 101, 'err_invalid_password', 'Passwort muss mindestens 10 Zeichen enthalten und mindestens einen Kleinbuchstaben, einen Großbuchstaben und eine Zahl beinhalten'),
(3, 1, 101, 'err_invalid_repo_id', 'Nicht zugängliche Repo-ID'),
(3, 1, 101, 'err_invalid_reset_token', 'Ungültiger Reset-Token'),
(3, 1, 101, 'err_invalid_token', 'Ungültiger Token'),
(3, 1, 101, 'err_invalid_verification_token', 'Ungültiger Verifizierungstoken'),
(3, 1, 101, 'err_not_authenticated', 'Nicht authentifiziert'),
(3, 1, 101, 'err_passwords_do_not_match', 'Passwörter stimmen nicht überein'),
(3, 1, 101, 'err_refresh_token_required', 'Refresh-Token erforderlich'),
(3, 1, 101, 'err_reset_token_expired', 'Reset-Token ist abgelaufen'),
(3, 1, 101, 'err_token_expired', 'Token abgelaufen'),
(3, 1, 101, 'err_token_password_required', 'Token und Passwort erforderlich'),
(3, 1, 101, 'err_token_required', 'Token erforderlich'),
(3, 1, 101, 'err_user_inactive', 'Benutzerkonto ist inaktiv'),
(3, 1, 101, 'err_user_not_found', 'Benutzer nicht gefunden'),
(3, 1, 101, 'err_verification_token_expired', 'Verifizierungstoken abgelaufen');
-- +goose Down
-- Remove b2b_translations for this scope