Merge branch 'front-styles' of ssh://git.ma-al.com:8822/goc_daniel/b2b into translate

This commit is contained in:
2026-04-07 08:02:32 +02:00
9 changed files with 154 additions and 142 deletions

View File

@@ -5,6 +5,10 @@ body {
font-family: "Inter", sans-serif; font-family: "Inter", sans-serif;
} }
li {
margin-left: 20px
}
.inter { .inter {
font-family: "Inter", sans-serif; font-family: "Inter", sans-serif;
} }

View File

@@ -4,7 +4,8 @@
<CategoryMenu /> <CategoryMenu />
<div class="w-full flex flex-col items-center gap-4"> <div class="w-full flex flex-col items-center gap-4">
<UTable :data="productsList" :columns="columns" class="flex-1 w-full" :ui="{ <UTable :data="productsList" :columns="columns" class="flex-1 w-full" :ui="{
root: 'max-w-100wv overflow-auto!' }" /> root: 'max-w-100wv overflow-auto!'
}" />
<UPagination v-model:page="page" :total="total" :items-per-page="perPage" /> <UPagination v-model:page="page" :total="total" :items-per-page="perPage" />
</div> </div>
</div> </div>
@@ -152,7 +153,7 @@ async function fetchProductList() {
} }
} }
function goToProduct(productId: number) { function goToProduct(productId: number, linkRewrite: string) {
let path = { let path = {
name: route.name, name: route.name,
params: route.params, params: route.params,
@@ -161,7 +162,7 @@ function goToProduct(productId: number) {
localStorage.setItem('back_from_product', JSON.stringify(path)) localStorage.setItem('back_from_product', JSON.stringify(path))
router.push({ router.push({
name: 'customer-product-details', name: 'customer-product-details',
params: { product_id: productId } params: { product_id: productId, link_rewrite: linkRewrite }
}) })
} }
@@ -280,7 +281,7 @@ const columns: TableColumn<Product>[] = [
cell: ({ row }) => { cell: ({ row }) => {
return h(UButton, { return h(UButton, {
onClick: () => { onClick: () => {
goToProduct(row.original.product_id) goToProduct(row.original.product_id, row.original.link_rewrite)
}, },
class: 'cursor-pointer', class: 'cursor-pointer',
color: 'info', color: 'info',

View File

@@ -69,8 +69,9 @@
<div v-else-if="productStore.productDescription" class="space-y-7.5"> <div v-else-if="productStore.productDescription" class="space-y-7.5">
<div class="grid grid-cols-1 md:grid-cols-6 h-full w-full gap-6"> <div class="grid grid-cols-1 md:grid-cols-6 h-full w-full gap-6">
<img class="md:col-span-2 rounded-md" :src="productStore.productDescription.image_link" <img
:alt="productStore.productDescription.name" @onError="(e: Event) => { class="md:col-span-2 rounded-md bg-white rounded-md border border-(--border-light) dark:border-(--border-dark)"
:src="productStore.productDescription.image_link" :alt="productStore.productDescription.name" @error="(e: Event) => {
const target = e.target as HTMLImageElement const target = e.target as HTMLImageElement
target.src = errorImg target.src = errorImg
}"> }">
@@ -78,13 +79,13 @@
<div class="space-y-7.5"> <div class="space-y-7.5">
<div> <div>
<p v-if="!isTranslations" class="text-[25px] font-bold text-black dark:text-white"> <p v-if="!isTranslations" class="text-[25px] font-bold text-black dark:text-white">
{{ productStore.productDescription.name }} {{ productStore.productDescription.name || 'Product name not provided' }}
</p> </p>
<div class="" v-if="isTranslations"> <div class="" v-if="isTranslations">
<p>Title:</p> <p>Title:</p>
<UTextarea :rows="1" v-model="productStore.productDescription.name" autoresize :ui="{ <UTextarea :rows="1" v-model="productStore.productDescription.name" autoresize :ui="{
root: 'w-full bg-inherit!', root: 'w-full bg-white!',
base: 'text-2xl! bg-inherit!', base: 'text-2xl!',
}" /> }" />
</div> </div>
</div> </div>
@@ -97,9 +98,17 @@
}" /> }" />
</div> </div>
<div class="" v-if="isTranslations">
<p>Link rewrite:</p>
<UTextarea :rows="1" v-model="productStore.productDescription.link_rewrite" autoresize :ui="{
root: 'w-full bg-white!'
}" />
</div>
<div> <div>
<p v-if="!isTranslations" v-html="productStore.productDescription.description_short" <p v-if="!isTranslations"
class="text-black dark:text-white"></p> v-html="productStore.productDescription.description_short || 'No short description available'"
class="text-black dark:text-white" />
<div class="" v-if="isTranslations"> <div class="" v-if="isTranslations">
<p>Short description:</p> <p>Short description:</p>
<ProductEditor v-model="productStore.productDescription.description_short" /> <ProductEditor v-model="productStore.productDescription.description_short" />
@@ -107,19 +116,19 @@
</div> </div>
</div> </div>
<div class="space-y-[10px]"> <div class="space-y-2.5">
<div class="flex items-center gap-1"> <div v-if="productStore.productDescription.available_now" class="flex items-center gap-1">
<UIcon name="lets-icons:done-ring-round-fill" <UIcon name="lets-icons:done-ring-round-fill"
class="text-[20px] light:text-(--accent-green-light) dark:text-(--accent-green-dark)" /> class="text-[20px] light:text-(--accent-green-light) dark:text-(--accent-green-dark)" />
<p> <p>
{{ productStore.productDescription.available_now || 'Available now' }} {{ productStore.productDescription.available_now }}
</p> </p>
</div> </div>
<div class="flex items-center gap-1"> <div v-if="productStore.productDescription.delivery_in_stock" class="flex items-center gap-1">
<UIcon name="marketeq:car-shipping" <UIcon name="marketeq:car-shipping"
class="text-[25px] light:text-(--accent-green-light) dark:text-(--accent-green-dark)" /> class="text-[25px] light:text-(--accent-green-light) dark:text-(--accent-green-dark)" />
<p> <p>
{{ productStore.productDescription.delivery_in_stock || 'Delivery information' }} {{ productStore.productDescription.delivery_in_stock }}
</p> </p>
</div> </div>
</div> </div>
@@ -132,15 +141,18 @@
}"> }">
<template #description> <template #description>
<ProductEditor v-if="isTranslations" v-model="productStore.productDescription.description" /> <ProductEditor v-if="isTranslations" v-model="productStore.productDescription.description" />
<p v-else v-html="productStore.productDescription.description" class="text-black dark:text-white"></p> <p v-else v-html="productStore.productDescription.description || 'No description available'"
class="text-black dark:text-white" />
</template> </template>
<template #usage> <template #usage>
<ProductEditor v-if="isTranslations" v-model="productStore.productDescription.usage" /> <ProductEditor v-if="isTranslations" v-model="productStore.productDescription.usage" />
<p v-else v-html="productStore.productDescription.usage" class="text-black dark:text-white"></p> <p v-else v-html="productStore.productDescription.usage || 'No usage information available'"
class="text-black dark:text-white" />
</template> </template>
</UTabs> </UTabs>
</div> </div>
<div class=""></div>
</div> </div>
</component> </component>
</template> </template>

View File

@@ -7,7 +7,7 @@
Country/Currency Country/Currency
</span> </span>
<span v-if="country" class="font-medium dark:text-white text-black"> <span v-if="country" class="font-medium dark:text-white text-black">
{{ country?.name }} / {{ country?.ps_currency }} {{ country?.name || 'Country' }} / {{ country?.ps_currency || 'Currency' }}
</span> </span>
</div> </div>
</template> </template>

View File

@@ -1,7 +1,7 @@
<template> <template>
<UEditor v-slot="{ editor }" v-model="localValue" content-type="html" <UEditor v-slot="{ editor }" v-model="localValue" content-type="html"
:ui="{ base: 'p-8 sm:px-16', root: 'p-2' }" :ui="{ base: 'p-8 sm:px-16', root: 'p-2' }"
class="min-w-full border rounded-md border-(--border-light)" placeholder="Write there ..."> class="min-w-full border rounded-md bg-white! border-(--border-light)" placeholder="Write there ...">
<UEditorToolbar :editor="editor" :items="toolbarItems" class="sm:px-8 flex-wrap!"> <UEditorToolbar :editor="editor" :items="toolbarItems" class="sm:px-8 flex-wrap!">
<template #link> <template #link>
<EditorLinkPopover :editor="editor" auto-open /> <EditorLinkPopover :editor="editor" auto-open />

View File

@@ -175,6 +175,7 @@ const menu = ref<TopMenuItem[] | null>(null)
async function getTopMenu() { async function getTopMenu() {
try { try {
const { items } = await useFetchJson<TopMenuItem[]>('/api/v1/restricted/menu/get-top-menu') const { items } = await useFetchJson<TopMenuItem[]>('/api/v1/restricted/menu/get-top-menu')
menu.value = items menu.value = items
} catch (err) { } catch (err) {
console.log(err) console.log(err)

View File

@@ -47,6 +47,9 @@ export async function initCountryCurrency() {
} }
defCountry.value = items.find((x) => x.id === defLang.value?.id) defCountry.value = items.find((x) => x.id === defLang.value?.id)
currentCountry.value = idfromcookie ?? defCountry.value currentCountry.value = idfromcookie ?? defCountry.value
console.log(defCountry.value);
console.log(currentCountry.value);
} catch (error) { } catch (error) {
console.error('Failed to fetch languages:', error) console.error('Failed to fetch languages:', error)
} }

View File

@@ -10,35 +10,35 @@ CREATE TABLE IF NOT EXISTS b2b_routes (
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT IGNORE INTO b2b_routes -- INSERT IGNORE INTO b2b_routes
(name, path, component, meta, active) -- (name, path, component, meta, active)
VALUES -- VALUES
('root', '', '', '{"trans": "route.root"}', 0), -- ('root', '', '', '{"trans": "route.root"}', 0),
('home', '', '/views/HomeView.vue', '{"trans": "route.home"}', 1), -- ('home', '', '/views/HomeView.vue', '{"trans": "route.home"}', 1),
('login', 'login', '/views/LoginView.vue', '{"guest":true}', 1), -- ('login', 'login', '/views/LoginView.vue', '{"guest":true}', 1),
('register', 'register', '/views/RegisterView.vue', '{"guest":true}', 1), -- ('register', 'register', '/views/RegisterView.vue', '{"guest":true}', 1),
('password-recovery', 'password-recovery', '/views/PasswordRecoveryView.vue', '{"guest":true}', 1), -- ('password-recovery', 'password-recovery', '/views/PasswordRecoveryView.vue', '{"guest":true}', 1),
('reset-password', 'reset-password', '/views/ResetPasswordView.vue', '{"guest":true}', 1), -- ('reset-password', 'reset-password', '/views/ResetPasswordView.vue', '{"guest":true}', 1),
('verify-email', 'verify-email', '/views/VerifyEmailView.vue', '{"guest":true}', 1); -- ('verify-email', 'verify-email', '/views/VerifyEmailView.vue', '{"guest":true}', 1);
-- INSERT INTO `b2b_routes` (`id`, `name`, `path`, `component`, `meta`, `active`) VALUES (1, 'root', '', '', '{"trans": "route.root"}', 0);
-- INSERT INTO `b2b_routes` (`id`, `name`, `path`, `component`, `meta`, `active`) VALUES (2, 'home', '', '/views/HomeView.vue', '{"trans": "route.home"}', 1);
-- INSERT INTO `b2b_routes` (`id`, `name`, `path`, `component`, `meta`, `active`) VALUES (3, 'login', 'login', '/views/LoginView.vue', '{"guest":true}', 1);
-- INSERT INTO `b2b_routes` (`id`, `name`, `path`, `component`, `meta`, `active`) VALUES (4, 'register', 'register', '/views/RegisterView.vue', '{"guest":true}', 1);
-- INSERT INTO `b2b_routes` (`id`, `name`, `path`, `component`, `meta`, `active`) VALUES (5, 'password-recovery', 'password-recovery', '/views/PasswordRecoveryView.vue', '{"guest":true}', 1);
-- INSERT INTO `b2b_routes` (`id`, `name`, `path`, `component`, `meta`, `active`) VALUES (6, 'reset-password', 'reset-password', '/views/ResetPasswordForm.vue', '{"guest":true}', 1);
-- INSERT INTO `b2b_routes` (`id`, `name`, `path`, `component`, `meta`, `active`) VALUES (7, 'verify-email', 'verify-email', '/views/VerifyEmailView.vue', '{"guest":true}', 1);
-- INSERT INTO `b2b_routes` (`id`, `name`, `path`, `component`, `meta`, `active`) VALUES (8, 'category', 'category/:category_id-:link_rewrite', '/views/CategoryView.vue', '{"guest":true}', 1);
-- INSERT INTO `b2b_routes` (`id`, `name`, `path`, `component`, `meta`, `active`) VALUES (9, 'admin-products-category', 'products/:category_id-:link_rewrite', '/components/admin/PageProducts.vue', '{
-- "guest": true
-- }', 1);
-- INSERT INTO `b2b_routes` (`id`, `name`, `path`, `component`, `meta`, `active`) VALUES (10, 'customer-addresses', 'addresses', '/components/customer/PageAddresses.vue', '{"guest":true}', 1);
-- INSERT INTO `b2b_routes` (`id`, `name`, `path`, `component`, `meta`, `active`) VALUES (11, 'customer-carts', 'carts', '/components/customer/PageCarts.vue', '{"guest":true}', 1);
-- INSERT INTO `b2b_routes` (`id`, `name`, `path`, `component`, `meta`, `active`) VALUES (12, 'customer-orders', 'orders', '/components/customer/PageOrders.vue', '{"guest":true}', 1);
-- INSERT INTO `b2b_routes` (`id`, `name`, `path`, `component`, `meta`, `active`) VALUES (13, 'customer-statistic', 'statistic', '/components/customer/PageStatistic.vue', '{"guest":true}', 1);
-- INSERT INTO `b2b_routes` (`id`, `name`, `path`, `component`, `meta`, `active`) VALUES (14, 'customer-product-details', 'products/:product_id', '/components/admin/ProductDetailView.vue', '{"guest":true}', 1);
-- INSERT INTO `b2b_routes` (`id`, `name`, `path`, `component`, `meta`, `active`) VALUES (15, 'admin-products', 'products', '/components/admin/PageProducts.vue', '{"guest":true}', 1);
INSERT IGNORE INTO `b2b_routes` (`id`, `name`, `path`, `component`, `meta`, `active`) VALUES
(1, 'root', '', '', '{"trans": "route.root"}', 0),
(2, 'home', '', '/views/HomeView.vue', '{"trans": "route.home"}', 1),
(3, 'login', 'login', '/views/LoginView.vue', '{"guest":true}', 1),
(4, 'register', 'register', '/views/RegisterView.vue', '{"guest":true}', 1),
(5, 'password-recovery', 'password-recovery', '/views/PasswordRecoveryView.vue', '{"guest":true}', 1),
(6, 'reset-password', 'reset-password', '/views/ResetPasswordForm.vue', '{"guest":true}', 1),
(7, 'verify-email', 'verify-email', '/views/VerifyEmailView.vue', '{"guest":true}', 1),
(8, 'category', 'category/:category_id-:link_rewrite', '/views/CategoryView.vue', '{"guest":true}', 1),
(9, 'admin-products-category', 'products/:category_id-:link_rewrite', '/components/admin/PageProducts.vue', '{
"guest": true
}', 1),
(10, 'customer-addresses', 'addresses', '/components/customer/PageAddresses.vue', '{"guest":true}', 1),
(11, 'customer-carts', 'carts', '/components/customer/PageCarts.vue', '{"guest":true}', 1),
(12, 'customer-orders', 'orders', '/components/customer/PageOrders.vue', '{"guest":true}', 1),
(13, 'customer-statistic', 'statistic', '/components/customer/PageStatistic.vue', '{"guest":true}', 1),
(14, 'customer-product-details', 'products/:product_id/:link_rewrite', '/components/admin/ProductDetailView.vue', '{"guest":true}', 1),
(15, 'admin-products', 'products', '/components/admin/PageProducts.vue', '{"guest":true}', 1);
CREATE TABLE IF NOT EXISTS b2b_top_menu ( CREATE TABLE IF NOT EXISTS b2b_top_menu (
menu_id INT AUTO_INCREMENT NOT NULL, menu_id INT AUTO_INCREMENT NOT NULL,
@@ -54,97 +54,91 @@ CREATE TABLE IF NOT EXISTS b2b_top_menu (
INDEX FK_b2b_top_menu_parent_id_idx (parent_id ASC) INDEX FK_b2b_top_menu_parent_id_idx (parent_id ASC)
) ENGINE = InnoDB; ) ENGINE = InnoDB;
INSERT IGNORE INTO `b2b_top_menu` (`menu_id`, `label`, `parent_id`, `params`, `active`, `position`) VALUES
INSERT IGNORE INTO `b2b_top_menu` (`menu_id`, `label`, `parent_id`, `params`, `active`, `position`) VALUES (1, '{"name":"root","trans":{"pl":{"label":"Menu główne"},"en":{"label":"Main Menu"},"de":{"label":"Hauptmenü"}}}', NULL, '{}', 1, 1),
(1, JSON_COMPACT('{"name":"root","trans":{"pl":{"label":"Menu główne"},"en":{"label":"Main Menu"},"de":{"label":"Hauptmenü"}}}'),NULL,JSON_COMPACT('{}'),1,1), (2, '{
(3, JSON_COMPACT('{"name":"admin-products","trans":{"pl":{"label":"admin-products"},"en":{"label":"admin-products"},"de":{"label":"admin-products"}}}'),1,JSON_COMPACT('{}'),1,1), "name": "admin-products",
(9, JSON_COMPACT('{"name":"carts","trans":{"pl":{"label":"Koszyki"},"en":{"label":"Carts"},"de":{"label":"Warenkörbe"}}}'),3,JSON_COMPACT('{"route": {"name": "home", "params":{"locale": ""}}}'),1,1); "trans": {
"pl": {
"label": "Products"
-- INSERT INTO `b2b_top_menu` (`menu_id`, `label`, `parent_id`, `params`, `active`, `position`) VALUES (1, '{"name":"root","trans":{"pl":{"label":"Menu główne"},"en":{"label":"Main Menu"},"de":{"label":"Hauptmenü"}}}', NULL, '{}', 1, 1); },
-- INSERT INTO `b2b_top_menu` (`menu_id`, `label`, `parent_id`, `params`, `active`, `position`) VALUES (2, '{ "en": {
-- "name": "admin-products", "label": "Products"
-- "trans": { },
-- "pl": { "de": {
-- "label": "Products" "label": "Products"
-- }, }
-- "en": { },
-- "label": "Products" "icon" : "quill:list"
-- }, }', 1, '{"route":{"name":"admin-products","params":{"locale":""}}}', 1, 1),
-- "de": { (3, '{
-- "label": "Products" "name": "customer-carts",
-- } "trans": {
-- }, "pl": {
-- "icon" : "quill:list" "label": "Carts"
-- }', 1, '{"route":{"name":"admin-products","params":{"locale":""}}}', 1, 1); },
-- INSERT INTO `b2b_top_menu` (`menu_id`, `label`, `parent_id`, `params`, `active`, `position`) VALUES (3, '{ "en": {
-- "name": "customer-carts", "label": "Carts"
-- "trans": { },
-- "pl": { "de": {
-- "label": "Carts" "label": "Carts"
-- }, }
-- "en": { },
-- "label": "Carts" "icon" : "proicons:cart"
-- }, }', 1, '{"route":{"name":"customer-carts","params":{"locale":""}}}', 1, 1),
-- "de": { (4, '{
-- "label": "Carts" "name": "customer-addresses",
-- } "trans": {
-- }, "pl": {
-- "icon" : "proicons:cart" "label": "Addresses"
-- }', 1, '{"route":{"name":"customer-carts","params":{"locale":""}}}', 1, 1); },
-- INSERT INTO `b2b_top_menu` (`menu_id`, `label`, `parent_id`, `params`, `active`, `position`) VALUES (4, '{ "en": {
-- "name": "customer-addresses", "label": "Addresses"
-- "trans": { },
-- "pl": { "de": {
-- "label": "Addresses" "label": "Addresses"
-- }, }
-- "en": { },
-- "label": "Addresses" "icon" : "ph:address-book"
-- }, }', 1, '{"route":{"name":"customer-addresses","params":{"locale":""}}}', 1, 1),
-- "de": { (5, '{
-- "label": "Addresses" "name": "customer-orders",
-- } "trans": {
-- }, "pl": {
-- "icon" : "ph:address-book" "label": "Orders"
-- }', 1, '{"route":{"name":"customer-addresses","params":{"locale":""}}}', 1, 1); },
-- INSERT INTO `b2b_top_menu` (`menu_id`, `label`, `parent_id`, `params`, `active`, `position`) VALUES (5, '{ "en": {
-- "name": "customer-orders", "label": "Orders"
-- "trans": { },
-- "pl": { "de": {
-- "label": "Orders" "label": "Orders"
-- }, }
-- "en": { },
-- "label": "Orders" "icon" : "lsicon:order-integral-outline"
-- }, }', 1, '{"route":{"name":"customer-orders","params":{"locale":""}}}', 1, 1),
-- "de": { (6, '{
-- "label": "Orders" "name": "customer-statistic",
-- } "trans": {
-- }, "pl": {
-- "icon" : "lsicon:order-integral-outline" "label": "Statistic"
-- }', 1, '{"route":{"name":"customer-orders","params":{"locale":""}}}', 1, 1); },
-- INSERT INTO `b2b_top_menu` (`menu_id`, `label`, `parent_id`, `params`, `active`, `position`) VALUES (6, '{ "en": {
-- "name": "customer-statistic", "label": "Statistic"
-- "trans": { },
-- "pl": { "de": {
-- "label": "Statistic" "label": "Statistic"
-- }, }
-- "en": { },
-- "label": "Statistic" "icon" : "akar-icons:statistic-up"
-- }, }', 1, '{
-- "de": { "route": {
-- "label": "Statistic" "name": "customer-statistic",
-- } "params": {
-- }, "locale": ""
-- "icon" : "akar-icons:statistic-up" }
-- }', 1, '{ }
-- "route": { }', 1, 1),
-- "name": "customer-statistic", (9, '{"name":"carts","trans":{"pl":{"label":"Koszyki"},"en":{"label":"Carts"},"de":{"label":"Warenkörbe"}}}', 3, '{"route":{"name":"home","params":{"locale":""}}}', 1, 1);
-- "params": {
-- "locale": ""
-- }
-- }
-- }', 1, 1);
-- INSERT INTO `b2b_top_menu` (`menu_id`, `label`, `parent_id`, `params`, `active`, `position`) VALUES (9, '{"name":"carts","trans":{"pl":{"label":"Koszyki"},"en":{"label":"Carts"},"de":{"label":"Warenkörbe"}}}', 3, '{"route":{"name":"home","params":{"locale":""}}}', 1, 1);

View File

@@ -11,7 +11,6 @@ INSERT INTO `b2b_roles` (`name`, `id`) VALUES ('user','1');
INSERT INTO `b2b_roles` (`name`, `id`) VALUES ('admin','2'); INSERT INTO `b2b_roles` (`name`, `id`) VALUES ('admin','2');
INSERT INTO `b2b_roles` (`name`, `id`) VALUES ('super_admin','3'); INSERT INTO `b2b_roles` (`name`, `id`) VALUES ('super_admin','3');
-- insert sample admin user admin@ma-al.com/Maal12345678 -- insert sample admin user admin@ma-al.com/Maal12345678
INSERT IGNORE INTO b2b_customers (id, email, password, first_name, last_name, role_id, provider, provider_id, avatar_url, is_active, email_verified, email_verification_token, email_verification_expires, password_reset_token, password_reset_expires, last_password_reset_request, last_login_at, lang_id, country_id, created_at, updated_at, deleted_at) INSERT IGNORE INTO b2b_customers (id, email, password, first_name, last_name, role_id, provider, provider_id, avatar_url, is_active, email_verified, email_verification_token, email_verification_expires, password_reset_token, password_reset_expires, last_password_reset_request, last_login_at, lang_id, country_id, created_at, updated_at, deleted_at)
VALUES VALUES
@@ -30,6 +29,4 @@ VALUES
(3, '🇨🇿', 16, 2), (3, '🇨🇿', 16, 2),
(4, '🇩🇪', 1, 2); (4, '🇩🇪', 1, 2);
-- +goose Down -- +goose Down