Compare commits
5 Commits
fe8ec468fe
...
8bab93274b
Author | SHA1 | Date | |
---|---|---|---|
8bab93274b | |||
10b9610918 | |||
edf3036e6a | |||
9d7fd3d52a | |||
4fc12ff9bf |
@ -1,7 +0,0 @@
|
||||
@font-face {
|
||||
font-family: "Bounded";
|
||||
src: url("/fonts/Bounded/Bounded-Variable.ttf") format("truetype");
|
||||
font-weight: 100 900;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
}
|
35
assets/toastify-custom.css
Normal file
35
assets/toastify-custom.css
Normal file
@ -0,0 +1,35 @@
|
||||
.Toastify__toast {
|
||||
font-family: var(--font-inter);
|
||||
background-color: var(--color-bg-light);
|
||||
border: 2px solid var(--color-block);
|
||||
color: var(--color-bg-dark);
|
||||
border-radius: 8px;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.dark .Toastify__toast {
|
||||
background-color: var(--color-bg-dark);
|
||||
border: 1px solid var(--color-block);
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.Toastify__toast--error {
|
||||
background-color: #dc3545;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.dark .Toastify__toast--error {
|
||||
background-color: #c82333;
|
||||
}
|
||||
|
||||
.Toastify__progress-bar {
|
||||
background-color: var(--color-accent-green-dark);
|
||||
}
|
||||
|
||||
.Toastify__toast--success .Toastify__toast-icon svg {
|
||||
fill: var(--color-accent-green-dark);
|
||||
}
|
||||
|
||||
.dark .Toastify__close-button {
|
||||
color: #fff;
|
||||
}
|
3
bun.lock
3
bun.lock
@ -12,7 +12,6 @@
|
||||
"@tailwindcss/vite": "^4.1.8",
|
||||
"@vueuse/core": "^13.3.0",
|
||||
"nuxt": "^3.17.4",
|
||||
"pocketbase": "^0.26.0",
|
||||
"tailwindcss": "^4.1.7",
|
||||
"vue": "^3.5.14",
|
||||
"vue-router": "^4.5.1",
|
||||
@ -1827,8 +1826,6 @@
|
||||
|
||||
"pluralize": ["pluralize@8.0.0", "", {}, "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA=="],
|
||||
|
||||
"pocketbase": ["pocketbase@0.26.1", "", {}, "sha512-fjcPDpxyqTZCwqGUTPUV7vssIsNMqHxk9GxbhxYHPEf18RqX2d9cpSqbbHk7aas30jqkgptuKfG7aY/Mytjj3g=="],
|
||||
|
||||
"portfinder": ["portfinder@1.0.37", "", { "dependencies": { "async": "^3.2.6", "debug": "^4.3.6" } }, "sha512-yuGIEjDAYnnOex9ddMnKZEMFE0CcGo6zbfzDklkmT1m5z734ss6JMzN9rNB3+RR7iS+F10D4/BVIaXOyh8PQKw=="],
|
||||
|
||||
"possible-typed-array-names": ["possible-typed-array-names@1.1.0", "", {}, "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg=="],
|
||||
|
@ -1,45 +1,81 @@
|
||||
<template>
|
||||
<div ref="dropdownRef">
|
||||
<i @click="openCart = !openCart" class="uil uil-shopping-cart text-[31px] cursor-pointer"></i>
|
||||
<div v-if="openCart" class="max-w-[1067px] w-full absolute top-[130px] z-50 right-20">
|
||||
<div
|
||||
class="w-full p-[50px] bg-bg-light dark:bg-bg-dark border border-button rounded-2xl h-full space-y-[55px]">
|
||||
<div class="pb-[25px] border-b border-block" v-if="productStore.productList">
|
||||
<div class="flex items-center h-[205px]">
|
||||
<div class="w-[205px] h-full flex items-center justify-center">
|
||||
<img :src="`https://www.yourgold.cz/api/public/file/${productStore.productList[0]?.cover_picture_uuid}.webp`"
|
||||
alt="pics" class="w-auto h-full" />
|
||||
</div>
|
||||
<div class="flex flex-col justify-between h-full w-full gap-[7px] sm:gap-[15px]"
|
||||
@click="productStore.addToCart(productStore.productList[0])">
|
||||
<h3
|
||||
class="text-[10px] sm:text-base md:text-lg text-xl font-bold leading-[130%] sm:leading-[150%] text-bg-dark max-w-[250px]">
|
||||
{{ productStore.productList[0]?.name }}
|
||||
</h3>
|
||||
<div class="flex flex-col gap-[10px]">
|
||||
<p
|
||||
class="text-accent-green-light font-inter text-[12px] sm:text-[21px] md:text-2xl leading-[150%] font-bold">
|
||||
{{ productStore.productList[0]?.formatted_price }}
|
||||
</p>
|
||||
<div class="flex items-center gap-4 text-xl">
|
||||
<p class="cursor-pointer">-</p>
|
||||
<div class="w-11 min-h-11 border border-button flex items-center justify-center">{{
|
||||
count }}
|
||||
<div @click="openCart = !openCart" class="relative cursor-pointer">
|
||||
<i class="uil uil-shopping-cart text-[31px]"></i>
|
||||
<div v-if="productStore.cart.cart_items && productStore.cart.cart_items.length > 0"
|
||||
class="w-[15px] h-[15px] rounded-full bg-accent-green-light dark:bg-accent-green-light text-white flex items-center justify-center text-[9px] absolute top-1 right-0">
|
||||
{{ productStore.cart.cart_items.length }}</div>
|
||||
</div>
|
||||
<div v-if="openCart" @click.self="openCart = !openCart"
|
||||
class="absolute left-1/2 transform -translate-x-1/2 w-full px-4 sm:max-w-[768px] sm:px-[17px] md:max-w-[1000px] md:px-6 xl:max-w-[1920px] xl:px-20 right-0 z-50 flex items-center justify-end top-[90px] sm:top-[100px] md:top-[140px]">
|
||||
<div class="xl:w-[55%] md:w-[90%] w-full px-4 md:px-0">
|
||||
<div v-if="productStore.cart.cart_items && productStore.cart.cart_items.length > 0"
|
||||
class="w-full p-[25px] sm:p-[50px] bg-bg-light dark:bg-bg-dark border border-button rounded-xl sm:rounded-[32px] h-full space-25-55">
|
||||
<div>
|
||||
<!-- product -->
|
||||
<div v-for="item in productStore.cart.cart_items"
|
||||
class="py-[13px] sm:py-[25px] first:pt-0 border-b border-block">
|
||||
<div class="flex items-center h-[100px] sm:h-[205px]">
|
||||
<div
|
||||
class="min-w-[100px] sm:min-w-[205px] flex items-center justify-center h-[100px] sm:h-[205px]">
|
||||
<img :src="`https://www.yourgold.cz/api/public/file/${item.picture_uuid}.webp`"
|
||||
alt="" class="max-w-full max-h-full object-contain">
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col justify-between min-h-full w-full gap-[7px] sm:gap-[15px]">
|
||||
<div class="w-full flex items-center justify-between">
|
||||
<h3
|
||||
class="text-[10px] sm:text-base md:text-lg text-xl font-bold leading-[130%] sm:leading-[150%] max-w-[100px] sm:max-w-[200px] md:max-w-[250px]">
|
||||
{{ item.name }}
|
||||
</h3>
|
||||
<i @click="productStore.deleteCartItem(item.cart_item_id)"
|
||||
class="uil uil-trash-alt text-lg sm:text-2xl cursor-pointer"></i>
|
||||
</div>
|
||||
<div class="flex flex-col gap-[10px]">
|
||||
<p
|
||||
class="text-accent-green-light dark:text-accent-green-dark font-inter text-[12px] sm:text-[21px] md:text-2xl leading-[150%] font-bold">
|
||||
{{ item.total_price }}
|
||||
</p>
|
||||
<div class="flex items-center gap-[2px] sm:gap-4 text-xl">
|
||||
<div
|
||||
class="w-5 min-h-5 sm:w-11 sm:min-h-11 text-[10px] sm:text-lg flex items-center justify-center">
|
||||
<i class="uil uil-minus cursor-pointer text-gray dark:text-button-disabled hover:text-gray-200 transition-all"
|
||||
@click="productStore.decrementCartItem(item.cart_item_id)"></i>
|
||||
</div>
|
||||
<div
|
||||
class="w-5 min-h-5 sm:w-10 sm:min-h-11 text-[10px] sm:text-xl border border-button flex items-center justify-center rounded-[4px]">
|
||||
{{ item.quantity }}
|
||||
</div>
|
||||
<div
|
||||
class="w-5 min-h-5 sm:w-11 sm:min-h-11 text-[10px] sm:text-lg flex items-center justify-center">
|
||||
<i class="uil uil-plus cursor-pointer hover:text-gray-200 transition-all"
|
||||
@click="productStore.incrementCartItem(item.product_id)"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p>+</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center justify-between">
|
||||
<h4 class="font-inter text-[12px] leading-[150%] font-bold uppercase sm:text-[24px]">{{
|
||||
$t('total_amount') }}</h4>
|
||||
<p
|
||||
class="text-accent-green-light dark:text-accent-green-dark font-inter text-[12px] sm:text-[21px] md:text-2xl leading-[150%] font-bold">
|
||||
{{ productStore.cart.total_value }}
|
||||
</p>
|
||||
</div>
|
||||
<UiButtonArrow class="w-full" type="fill" :arrow="true" :full="true">{{ $t('to_checkout') }}
|
||||
</UiButtonArrow>
|
||||
</div>
|
||||
<div class="flex items-center justify-between">
|
||||
<h4 class="h4-uppercase-bold-inter">Celková částka</h4>
|
||||
<p
|
||||
class="text-accent-green-light font-inter text-[12px] sm:text-[21px] md:text-2xl leading-[150%] font-bold">
|
||||
{{ productStore.productList[0]?.formatted_price }}
|
||||
</p>
|
||||
<div v-else
|
||||
class="w-full p-[50px] bg-bg-light dark:bg-bg-dark border border-button rounded-[32px] h-[400px] flex items-center justify-center">
|
||||
<div
|
||||
class="border border-block inline-flex items-center justify-center w-[30%] h-[200px] rounded-[8px]">
|
||||
<h4 class="font-inter text-base leading-[150%] font-bold uppercase sm:text-[20px] md:text-xl">
|
||||
košík je prázdný</h4>
|
||||
</div>
|
||||
</div>
|
||||
<UiButtonArrow class="w-full" type="fill" :arrow="true" :full="true">Přejít k pokladně</UiButtonArrow>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -3,10 +3,10 @@
|
||||
<UButton color="neutral" variant="subtle" trailing-icon="i-lucide-chevron-down"
|
||||
class="bg-bg-light dark:bg-bg-dark m-0 ring-0 text-xl font-medium uppercase cursor-pointer hover:bg-inherit text-text-light dark:text-text-dark"
|
||||
block @click="isOpen = !isOpen">
|
||||
{{ menuStore.selectedCountry }}/{{ menuStore.selectedCurrency?.iso_code }}
|
||||
{{ $session.cookieData.value.country.iso_code }}/{{ $session.cookieData.value.currency.iso_code }}
|
||||
</UButton>
|
||||
|
||||
<div class="absolute ring-0 top-12 p-0 m-0 border-none w-48" v-if="isOpen">
|
||||
<div class="absolute ring-0 top-12 p-0 m-0 border-none w-48 z-50" v-if="isOpen">
|
||||
<div class="border border-button px-4 py-[10px] rounded-[5px] bg-bg-light dark:bg-bg-dark">
|
||||
<div class="p-0 flex flex-col gap-4 bg-bg-light dark:bg-bg-dark">
|
||||
<div class="flex flex-col items-start gap-1">
|
||||
@ -15,7 +15,7 @@
|
||||
class="bg-inherit w-full ring-0 cursor-pointer focus:ring-0 outline-none focus-visible:ring-0 space-y-1">
|
||||
<div class="p-0" @click="openDrop('country')">
|
||||
<div class="flex items-center gap-2 text-xl font-medium uppercase text-text-light dark:text-text-dark">
|
||||
{{ menuStore.selectedCountry }} <span> <i
|
||||
{{ $session.currentCountryIso }} <span> <i
|
||||
class="uil uil-angle-down text-2xl font-light cursor-pointer"></i></span>
|
||||
</div>
|
||||
</div>
|
||||
@ -23,12 +23,9 @@
|
||||
<div v-if="dropCountry"
|
||||
class="rounded-[5px] data-highlighted:not-data-disabled:before:bg-button/50 bg-inherit ring-0 cursor-pointer w-full focus:ring-0 outline-none focus-visible:ring-0 border border-button py-[10px] px-[5px]">
|
||||
<div class="overflow-auto h-[200px] w-full">
|
||||
<p @click="() => {
|
||||
menuStore.selectedCountry = item.iso_code
|
||||
dropCountry = false
|
||||
}"
|
||||
<p @click="() => { $session.setCountry(item.iso_code); $session.loadSession(); dropCountry = false }"
|
||||
class="w-full hover:bg-block dark:hover:bg-button pl-2 py-2 text-base text-text-light dark:text-text-dark rounded-[5px]"
|
||||
v-for="item in menuStore.countryList">
|
||||
v-for="item in menuStore.countries" :key="item.iso_code">
|
||||
{{ item?.name }}
|
||||
</p>
|
||||
</div>
|
||||
@ -41,7 +38,7 @@
|
||||
class="bg-inherit w-full ring-0 cursor-pointer focus:ring-0 outline-none focus-visible:ring-0 space-y-1">
|
||||
<div class="p-0" @click="openDrop()">
|
||||
<div class="flex items-center gap-2 text-xl font-medium uppercase text-text-light dark:text-text-dark">
|
||||
{{ menuStore.selectedCurrency?.iso_code }}<span> <i
|
||||
{{ $session.currentCurrencyIso }}<span> <i
|
||||
class="uil uil-angle-down text-2xl font-light cursor-pointer"></i></span>
|
||||
</div>
|
||||
</div>
|
||||
@ -49,12 +46,9 @@
|
||||
<div v-if="dropCurrency"
|
||||
class="rounded-[5px] data-highlighted:not-data-disabled:before:bg-button/50 bg-inherit ring-0 cursor-pointer w-full focus:ring-0 outline-none focus-visible:ring-0 border border-button py-[10px] px-[5px]">
|
||||
<div class="overflow-auto w-full">
|
||||
<p @click="() => {
|
||||
menuStore.selectedCurrency = item
|
||||
dropCurrency = false
|
||||
}"
|
||||
<p @click="() => { $session.setCurrency(item.iso_code); $session.loadSession(); dropCurrency = false }"
|
||||
class="w-full hover:bg-block dark:hover:bg-button pl-1 py-2 text-base text-text-light dark:text-text-dark rounded-[5px]"
|
||||
v-for="item in menuStore.currencies">
|
||||
v-for="item in menuStore.currencies" :key="item.iso_code">
|
||||
{{ item?.name }}
|
||||
</p>
|
||||
</div>
|
||||
@ -69,6 +63,8 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onClickOutside } from "@vueuse/core";
|
||||
const {$session} = useNuxtApp();
|
||||
|
||||
const isOpen = ref(false);
|
||||
const menuStore = useMenuStore();
|
||||
|
||||
@ -87,22 +83,6 @@ function openDrop(type?: string) {
|
||||
}
|
||||
}
|
||||
|
||||
watchEffect(() => {
|
||||
if (
|
||||
!menuStore.selectedCountry &&
|
||||
menuStore.countryList &&
|
||||
menuStore.countryList.length > 0
|
||||
) {
|
||||
menuStore.selectedCountry = menuStore.countryList[0].iso_code;
|
||||
}
|
||||
if (
|
||||
!menuStore.selectedCurrency &&
|
||||
menuStore.currencies &&
|
||||
menuStore.currencies.length > 0
|
||||
) {
|
||||
menuStore.selectedCurrency = menuStore.currencies[0];
|
||||
}
|
||||
});
|
||||
|
||||
onClickOutside(dropdownRef, () => {
|
||||
isOpen.value = false
|
||||
|
@ -5,8 +5,9 @@
|
||||
<UiContainer class="relative">
|
||||
<div class="hidden h-[120px] w-full items-center gap-[145px] xl:flex">
|
||||
<ul class="flex items-center justify-between whitespace-nowrap w-full">
|
||||
<li v-for="(item, index) in menuStore.menu" @click="menuStore.navigateToItem(item)" :key="index"
|
||||
:class="['hover:text-accent-green-light dark:hover:text-accent-green-dark cursor-pointer text-lg transition-all text-inter', route.params.slug === item.front_menu_lang[0].link_rewrite && 'text-accent-green-light dark:text-accent-green-dark font-bold underline']">
|
||||
<li v-for="(item, index) in menuStore.menu" @click="menuStore.navigateToItem(item)" :key="item.id"
|
||||
:class="['hover:text-accent-green-light dark:hover:text-accent-green-dark cursor-pointer text-lg transition-all text-inter',
|
||||
route.params.id == item.id.toString() ? 'text-accent-green-light dark:text-accent-green-dark font-bold underline' : false]">
|
||||
0{{ index + 1 }} <br />
|
||||
{{ item.front_menu_lang[0].name }}
|
||||
</li>
|
||||
@ -25,8 +26,12 @@
|
||||
<CountryCurrencySelector />
|
||||
</div>
|
||||
<ThemeSwitcher />
|
||||
<button @click="menuStore.navigateToShop"
|
||||
class="hover:bg-button-hover bg-button cursor-pointer rounded-xl px-6 py-3 font-medium text-white transition-all text-inter">
|
||||
<button @click="menuStore.navigateToShop" :class="[
|
||||
'cursor-pointer transition-all text-inter',
|
||||
route.params.id == '5'
|
||||
? 'text-accent-green-light dark:text-accent-green-dark font-bold pb-1 border-b-2'
|
||||
: 'hover:bg-button-hover bg-button text-white font-medium rounded-xl px-6 py-3'
|
||||
]">
|
||||
{{ $t('eshop') }}
|
||||
</button>
|
||||
</div>
|
||||
@ -45,7 +50,7 @@
|
||||
<div class="flex items-center gap-6">
|
||||
<div class="flex items-center gap-[30px]">
|
||||
<i class="uil uil-user text-[31px] cursor-pointer"></i>
|
||||
<i class="uil uil-shopping-cart text-[31px] cursor-pointer"></i>
|
||||
<CartPopup />
|
||||
</div>
|
||||
<div class="flex">
|
||||
<LangSwitcher />
|
||||
@ -91,7 +96,7 @@
|
||||
<div class="flex items-center gap-6">
|
||||
<div class="flex items-center gap-[30px]">
|
||||
<i class="uil uil-user text-[31px] cursor-pointer"></i>
|
||||
<i class="uil uil-shopping-cart text-[31px] cursor-pointer"></i>
|
||||
<CartPopup />
|
||||
</div>
|
||||
<i variant="subtle" block class="uil uil-apps text-[30px] cursor-pointer" @click="open = !open"></i>
|
||||
</div>
|
||||
@ -107,10 +112,10 @@
|
||||
open = false;
|
||||
}
|
||||
" :key="index"
|
||||
:class="['flex items-center justify-between transition-all hover:text-accent-green-light dark:hover:text-accent-green-dark cursor-pointer', route.params.slug === item.link_rewrite && 'text-accent-green-light dark:text-accent-green-dark font-bold underline']">
|
||||
:class="['flex items-center justify-between transition-all hover:text-accent-green-light dark:hover:text-accent-green-dark cursor-pointer', route.params.slug === item.front_menu_lang[0].link_rewrite && 'text-accent-green-light dark:text-accent-green-dark font-bold underline']">
|
||||
<div class="leading-[70%] text-inter">
|
||||
<span class="mr-4">0{{ index + 1 }}</span>
|
||||
{{ item.name }}
|
||||
{{ item.front_menu_lang[0].name }}
|
||||
</div>
|
||||
<!-- <i class="uil uil-arrow-up-right text-[35px]"></i> -->
|
||||
<svg class="" width="20" height="20" viewBox="0 0 26 26" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
@ -127,7 +132,7 @@
|
||||
</div>
|
||||
<div class="flex items-center justify-between">
|
||||
<p class="leading-[70%] text-inter">
|
||||
{{ $t("change_currency_country") }}
|
||||
{{ $t("change_currency_and_country") }}
|
||||
</p>
|
||||
<CountryCurrencySelector />
|
||||
</div>
|
||||
@ -152,7 +157,7 @@
|
||||
@click="menuStore.navigateToItem()" />
|
||||
</ClientOnly>
|
||||
<div class="flex items-center gap-6">
|
||||
<i class="uil uil-shopping-cart text-[31px] cursor-pointer"></i>
|
||||
<CartPopup />
|
||||
<i variant="subtle" block class="uil uil-apps text-[30px] cursor-pointer" @click="open = !open"></i>
|
||||
</div>
|
||||
</UiContainer>
|
||||
@ -167,10 +172,10 @@
|
||||
open = false;
|
||||
}
|
||||
" :key="index"
|
||||
:class="['flex items-center justify-between transition-all hover:text-accent-green-light dark:hover:text-accent-green-dark cursor-pointer', route.params.slug === item.link_rewrite && 'text-accent-green-light dark:text-accent-green-dark font-bold underline']">
|
||||
:class="['flex items-center justify-between transition-all hover:text-accent-green-light dark:hover:text-accent-green-dark cursor-pointer', route.params.slug === item.front_menu_lang[0].link_rewrite && 'text-accent-green-light dark:text-accent-green-dark font-bold underline']">
|
||||
<div class="leading-[70%] text-inter">
|
||||
<span class="mr-4">0{{ index + 1 }}</span>
|
||||
{{ item.name }}
|
||||
{{ item.front_menu_lang[0].name }}
|
||||
</div>
|
||||
<!-- <i class="uil uil-arrow-up-right text-[35px]"></i> -->
|
||||
<svg class="" width="20" height="20" viewBox="0 0 26 26" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
@ -187,7 +192,7 @@
|
||||
</div>
|
||||
<div class="flex items-center justify-between">
|
||||
<p class="leading-[70%] text-lg text-inter">
|
||||
{{ $t("change_currency_country") }}
|
||||
{{ $t("change_currency_and_country") }}
|
||||
</p>
|
||||
<CountryCurrencySelector />
|
||||
</div>
|
||||
@ -214,7 +219,7 @@ const productStore = useProductStore();
|
||||
const open = ref(false);
|
||||
const colorMode = useColorMode();
|
||||
|
||||
// productStore.getCart()
|
||||
productStore.getCart()
|
||||
|
||||
const route = useRoute()
|
||||
const isDark = computed({
|
||||
|
@ -14,11 +14,11 @@
|
||||
group: 'px-[5px] py-[10px]',
|
||||
item: 'hover:bg-block dark:hover:bg-button rounded-[5px] data-highlighted:not-data-disabled:before:bg-button/50',
|
||||
}"
|
||||
@update:model-value="setLocale"
|
||||
@update:model-value="setLocale($event); $session.setLanguage($event); $session.loadSession()"
|
||||
>
|
||||
<template #leading="{ modelValue }">
|
||||
<div class="flex items-center gap-2 text-xl font-medium uppercase">
|
||||
{{ locales.find((item) => item.code === modelValue)?.code }}
|
||||
{{ locales.find((item: any) => item.code === modelValue)?.code }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -39,20 +39,10 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useI18n } from "#imports";
|
||||
|
||||
const { locale, locales, setLocale } = useI18n();
|
||||
const {$session} = useNuxtApp();
|
||||
|
||||
const isOpen = ref(false);
|
||||
|
||||
const selectedLocaleCode = ref(locale.value);
|
||||
const selectedIcon = ref(
|
||||
locales.value.find((item) => item.code === locale.value)?.icon
|
||||
);
|
||||
|
||||
watch(selectedLocaleCode, async (newCode) => {
|
||||
if (newCode !== locale.value) {
|
||||
await setLocale(newCode);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
File diff suppressed because one or more lines are too long
@ -7,8 +7,8 @@
|
||||
</h2>
|
||||
</div>
|
||||
<div class="space-y-[40px] sm:space-55-75">
|
||||
<div v-for="(item, index) in component.front_section_lang[0].data.section_1.text_blocks"
|
||||
:key="index" class="grid grid-cols-7 md:grid-cols-4 xl:grid-cols-2">
|
||||
<div v-for="(item, index) in component.front_section_lang[0].data.section_1.text_blocks" :key="index"
|
||||
class="grid grid-cols-7 md:grid-cols-4 xl:grid-cols-2">
|
||||
<div class="flex gap-[200px]">
|
||||
<h4 class="h4-uppercase-bold-inter">0{{ index + 1 }}</h4>
|
||||
<h4 class="hidden xl:block h4-uppercase-bold-inter w-full whitespace-nowrap">
|
||||
@ -29,8 +29,8 @@
|
||||
{{ component.front_section_lang[0].data.section_2.title }}
|
||||
</h2>
|
||||
<div class="grid sm:grid-cols-2 xl:grid-cols-4 gap-[30px] auto-cols-fr auto-rows-fr">
|
||||
<div class="border border-border rounded-2xl p-8 flex flex-col justify-between gap-[55px]" v-for="(item, index) in component.front_section_lang[0].data.section_2
|
||||
.text_blocks" :key="index">
|
||||
<div class="border border-border rounded-2xl p-8 flex flex-col justify-between gap-[55px]"
|
||||
v-for="(item, index) in component.front_section_lang[0].data.section_2.text_blocks" :key="index">
|
||||
<div>
|
||||
<h4 class="h4-uppercase-bold-inter">0{{ index + 1 }}</h4>
|
||||
<h4 class="h4-uppercase-bold-inter">{{ item.block_title }}</h4>
|
||||
@ -57,8 +57,7 @@
|
||||
{{ component.front_section_lang[0].data.section_3.title }}
|
||||
</h2>
|
||||
<div class="flex flex-col space-25-55">
|
||||
<p v-for="(item, index) in component.front_section_lang[0].data.section_3
|
||||
.text_blocks" :key="index">
|
||||
<p v-for="(item, index) in component.front_section_lang[0].data.section_3.text_blocks" :key="index">
|
||||
{{ item }}
|
||||
</p>
|
||||
</div>
|
||||
@ -75,7 +74,8 @@
|
||||
backgroundSize: 'cover',
|
||||
backgroundPosition: 'center',
|
||||
}" />
|
||||
<p class="xl:col-start-2 xl:col-end-3">{{ component.front_section_lang[0].data.section_4.description_second }}</p>
|
||||
<p class="xl:col-start-2 xl:col-end-3">{{ component.front_section_lang[0].data.section_4.description_second
|
||||
}}</p>
|
||||
</div>
|
||||
</UiContainer>
|
||||
</template>
|
||||
|
@ -11,7 +11,9 @@
|
||||
<p class="text-text-light sm:text-xl md:text-2xl font-medium">{{
|
||||
component.front_section_lang[0].data.description }}</p>
|
||||
</div>
|
||||
<UiButtonArrow type="fill" :arrow="true">{{ $t('buy_gold') }}</UiButtonArrow>
|
||||
<UiButtonArrow type="fill" :arrow="true">
|
||||
{{ $t('buy_gold') }}
|
||||
</UiButtonArrow>
|
||||
</div>
|
||||
<div class="flex gap-[10px] sm:gap-[30px]">
|
||||
<div class="rounded-2xl h-[155px] sm:h-[225px] md:h-[280px] w-full" :style="{
|
||||
@ -43,8 +45,9 @@
|
||||
<div class="space-25-55-75">
|
||||
<h2 class="h2-bold-bounded">{{ component.front_section_lang[0].data.section_2.title }}</h2>
|
||||
<div class="space-y-[40px] sm:space-y-[50px]">
|
||||
<p v-for="(item, index) in component.front_section_lang[0].data.section_2.text_blocks" :key="index">{{ item
|
||||
}}</p>
|
||||
<p v-for="(item, index) in component.front_section_lang[0].data.section_2.text_blocks" :key="index">
|
||||
{{ item }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full md:h-full rounded-2xl h-[327px] sm:h-[550px]" :style="{
|
||||
@ -55,7 +58,8 @@
|
||||
</div>
|
||||
<div
|
||||
class="grid grid-cols-1 sm:grid-cols-2 xl:grid-cols-4 gap-y-[25px] sm:gap-y-[55px] xl:gap-y-0 gap-x-[30px]">
|
||||
<h2 class="h2-bold-bounded sm:col-start-1 sm:col-end-3">{{ component.front_section_lang[0].data.section_3.title }}
|
||||
<h2 class="h2-bold-bounded sm:col-start-1 sm:col-end-3">{{
|
||||
component.front_section_lang[0].data.section_3.title }}
|
||||
</h2>
|
||||
<div v-for="(item, index) in component.front_section_lang[0].data.section_3.text_blocks" :key="index"
|
||||
class="flex flex-col justify-between space-25-55">
|
||||
|
7
components/section/CheckoutMain.vue
Normal file
7
components/section/CheckoutMain.vue
Normal file
@ -0,0 +1,7 @@
|
||||
<template>
|
||||
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Veritatis dignissimos impedit eligendi quaerat. Doloribus
|
||||
eius nisi facere suscipit pariatur reprehenderit reiciendis tempora est accusamus adipisci hic voluptate asperiores,
|
||||
voluptas enim.
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup></script>
|
@ -8,12 +8,12 @@
|
||||
<div class="p-[25px] md:p-[50px] bg-block rounded-2xl space-y-[30px] xl:ml-40 xl:w-[65%]">
|
||||
<div class="flex gap-[30px]">
|
||||
<input :placeholder="$t('first_name')" type="text"
|
||||
class="border border-text-dark placeholder:text-button rounded-lg px-3 py-1.5 w-full focus:outline-none focus:ring-0 focus:border-2 text-button" />
|
||||
class="border border-button placeholder:text-button rounded-lg px-3 py-1.5 w-full focus:outline-none focus:ring-0 focus:border-2 text-button" />
|
||||
<input :placeholder="$t('email')" type="text"
|
||||
class="border border-text-dark placeholder:text-button rounded-lg px-3 py-1.5 w-full focus:outline-none focus:ring-0 focus:border-2 text-button" />
|
||||
class="border border-button placeholder:text-button rounded-lg px-3 py-1.5 w-full focus:outline-none focus:ring-0 focus:border-2 text-button" />
|
||||
</div>
|
||||
<textarea :placeholder="$t('form_question')"
|
||||
class="border h-[276px] border-text-dark placeholder:text-button rounded-lg px-3 py-1.5 w-full focus:outline-none focus:ring-0 focus:border-2 text-button" />
|
||||
class="border h-[276px] border-button placeholder:text-button rounded-lg px-3 py-1.5 w-full focus:outline-none focus:ring-0 focus:border-2 text-button" />
|
||||
|
||||
<div class="w-full flex justify-center sm:justify-start">
|
||||
<UiButtonArrow type="border">{{
|
||||
|
@ -23,7 +23,7 @@
|
||||
}" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center justify-center">
|
||||
<div class="flex items-center justify-center w-[60%] mx-auto">
|
||||
<div class="flex flex-col items-center p-3 sm:p-6 md:p-8 xl:p-11 border border-block rounded-2xl gap-5">
|
||||
<h4 class="h4-uppercase-bold-inter text-accent-green-light dark:text-accent-green-dark">
|
||||
20 {{ $t("years") }}
|
||||
|
@ -43,7 +43,7 @@
|
||||
<p class="text-accent-green-light text-bold-24">
|
||||
{{ item.formatted_price }}
|
||||
</p>
|
||||
<button
|
||||
<button @click="productStore.incrementCartItem(item.id)"
|
||||
class="w-9 h-9 md:w-12 md:h-12 rounded-xl bg-button cursor-pointer hover:bg-button-hover transition-all flex items-center justify-center">
|
||||
<i class="uil uil-shopping-cart text-[25px] md:text-[24px] text-bg-light"></i>
|
||||
</button>
|
||||
@ -52,7 +52,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<UiButtonArrow :arrow="true" class="mx-auto" type="fill">{{ $t('eshop') }}</UiButtonArrow>
|
||||
<UiButtonArrow @click="menuStore.navigateToShop" :arrow="true" class="mx-auto" type="fill">{{ $t('eshop') }}</UiButtonArrow>
|
||||
</div>
|
||||
|
||||
<!-- calculator-block -->
|
||||
@ -107,7 +107,7 @@
|
||||
</div>
|
||||
<UiButtonArrow :arrow="true" type="fill" class="mx-auto sm:m-0">{{
|
||||
component.front_section_lang[0].data.button
|
||||
}}</UiButtonArrow>
|
||||
}}</UiButtonArrow>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,12 +1,7 @@
|
||||
<template>
|
||||
<UiContainer
|
||||
class="flex flex-wrap items-center justify-between gap-[30px] sm:gap-y-[55px] xl:gap-y-[100px]"
|
||||
>
|
||||
<div
|
||||
class="w-full flex flex-col gap-[25px] xl:max-w-[48%] md:mx-10 xl:m-0"
|
||||
v-for="(item, index) in component.front_section_lang[0].data"
|
||||
:key="index"
|
||||
>
|
||||
<UiContainer class="flex flex-wrap items-center justify-between gap-[30px] sm:gap-y-[55px] xl:gap-y-[100px]">
|
||||
<div class="w-full flex flex-col gap-[25px] xl:max-w-[48%] md:mx-10 xl:m-0"
|
||||
v-for="(item, index) in component.front_section_lang[0].data" :key="index">
|
||||
<!-- xl -->
|
||||
<div class="hidden xl:flex xl:h-[330px] flex-col justify-between">
|
||||
<div class="space-y-[55px]">
|
||||
@ -29,23 +24,19 @@
|
||||
backgroundImage: `url('/api/public/file/${component.img[index]}_l.webp')`,
|
||||
backgroundSize: 'cover',
|
||||
backgroundPosition: 'center',
|
||||
}"
|
||||
>
|
||||
}">
|
||||
<div
|
||||
class="hidden sm:block absolute bottom-0 right-0 pt-2 pl-2 bg-bg-light dark:bg-bg-dark rounded-tl-2xl"
|
||||
>
|
||||
class="hidden sm:block absolute bottom-0 right-0 pt-2 pl-2 bg-bg-light dark:bg-bg-dark rounded-tl-2xl">
|
||||
<UiButtonArrow :arrow="true">{{ item.title }}</UiButtonArrow>
|
||||
</div>
|
||||
</div>
|
||||
<UiButtonArrow :arrow="true" class="sm:hidden mx-auto">{{
|
||||
item.title
|
||||
}}</UiButtonArrow>
|
||||
}}</UiButtonArrow>
|
||||
</div>
|
||||
|
||||
<!-- Map block with same layout rules -->
|
||||
<div
|
||||
class="w-full xl:max-w-[48%] md:mx-10 xl:m-0 flex flex-col gap-4 items-center"
|
||||
>
|
||||
<div class="w-full xl:max-w-[48%] md:mx-10 xl:m-0 flex flex-col gap-4 items-center">
|
||||
<h1 class="text-sm sm:text-xl uppercase">
|
||||
Jsme tu pro vás napříč Evropou
|
||||
</h1>
|
||||
|
@ -29,8 +29,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
defineProps<{ component: Component }>();
|
||||
type Component = {
|
||||
defineProps<{ component: {
|
||||
id: number
|
||||
name: string
|
||||
img: string[]
|
||||
@ -46,5 +45,6 @@ type Component = {
|
||||
id_front_section: number
|
||||
id_lang: number
|
||||
}[]
|
||||
};
|
||||
} }>();
|
||||
|
||||
</script>
|
||||
|
@ -22,7 +22,7 @@
|
||||
<p class="text-accent-green-light text-bold-24">
|
||||
{{ item.formatted_price }}
|
||||
</p>
|
||||
<button
|
||||
<button @click="productStore.incrementCartItem(item.id)"
|
||||
class="w-9 h-9 md:w-12 md:h-12 rounded-xl bg-button cursor-pointer hover:bg-button-hover transition-all flex items-center justify-center">
|
||||
<i class="uil uil-shopping-cart text-[25px] md:text-[24px] text-bg-light"></i>
|
||||
</button>
|
||||
|
@ -1,10 +1,11 @@
|
||||
<template>
|
||||
<div
|
||||
class="w-[150px] sm:w-[260px] md:w-[330px] px-2 py-3 sm:py-5 sm:px-[15px] bg-block rounded-2xl flex flex-col items-center gap-[15px] sm:gap-[50px]">
|
||||
<img :src="`https://www.yourgold.cz/api/public/file/${props.product?.cover_picture_uuid}.webp`" alt="pics"
|
||||
class="max-h-[95px] sm:max-h-[180px] md:max-h-[205px] rounded-[5px]" />
|
||||
<div class="flex flex-col justify-between h-full w-full gap-[7px] sSm:gap-[15px]"
|
||||
@click="productStore.addToCart(props.product)">
|
||||
<img :src="`https://www.yourgold.cz/api/public/file/${props.product?.cover_picture_uuid}.webp`" alt="Product Image"
|
||||
class="max-h-[95px] sm:max-h-[180px] md:max-h-[205px] rounded-[5px]"
|
||||
onerror="this.onerror=null; this.src='/photo.svg';" />
|
||||
|
||||
<div class="flex flex-col justify-between h-full w-full gap-[7px] sSm:gap-[15px]">
|
||||
<div class="flex flex-col gap-[7px] sm:gap-[15px] w-full">
|
||||
<h3 class="text-[10px] sm:text-base md:text-lg text-xl font-bold leading-[130%] sm:leading-[150%] text-bg-dark">
|
||||
{{ props.product?.name }}
|
||||
@ -17,9 +18,9 @@
|
||||
<p class="text-accent-green-light font-inter text-[12px] sm:text-[21px] md:text-2xl leading-[150%] font-bold">
|
||||
{{ props.product?.formatted_price }}
|
||||
</p>
|
||||
<button
|
||||
class="w-[22px] h-[22px] sm:w-9 sm:h-9 md:w-12 md:h-12 rounded-[5px] sm:rounded-xl bg-button cursor-pointer hover:bg-button-hover transition-all flex items-center justify-center p-1">
|
||||
<i class="uil uil-shopping-cart text-[10px] sm:text-[25px] md:text-2xl cursor-pointer"></i>
|
||||
<button @click="productStore.incrementCartItem(props.product?.id)"
|
||||
class="w-[22px] h-[22px] sm:w-9 sm:h-9 md:w-12 md:h-12 rounded-[5px] text-bg-light sm:rounded-xl bg-button cursor-pointer hover:bg-button-hover transition-all flex items-center justify-center p-1">
|
||||
<i class="uil uil-shopping-cart text-lg sm:text-2xl md:text-[31px] cursor-pointer"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@ -27,15 +28,9 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
// import imgUrl from "~/utils/imgUrl";
|
||||
const props = defineProps({
|
||||
product: Object,
|
||||
});
|
||||
|
||||
const productStore = useProductStore()
|
||||
|
||||
// const addToCartAndPreventNavigation = (event: any) => {
|
||||
// event.preventDefault();
|
||||
// useCartStore().addToCart(props.product);
|
||||
// };
|
||||
</script>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<UiContainer class="flex py-[15px] xl:py-20 sm:py-0">
|
||||
<div class="hidden xl:block rounded-2xl min-w-[40%] h-[830px]" :style="{
|
||||
backgroundImage: `url('/api/files/${component.image_collection}/${component.section_id}/${component.section_img[0]}?thumb=1200x0')`,
|
||||
backgroundImage: `url('/api/public/file/${component.img[0]}_l.webp')`,
|
||||
backgroundSize: 'cover',
|
||||
backgroundPosition: 'center',
|
||||
}" />
|
||||
@ -50,10 +50,9 @@
|
||||
<div v-if="dropCountry"
|
||||
class="mt-2 absolute bg-bg-light dark:bg-bg-dark rounded-[5px] ring-0 cursor-pointer w-full border border-button py-[10px] px-[5px] overflow-hidden">
|
||||
<div class="overflow-y-auto h-[200px] w-full">
|
||||
<p v-for="item in menuStore.countryList" @click="() => {
|
||||
menuStore.selectedPhoneCountry = item
|
||||
dropCountry = false
|
||||
}" class="w-full truncate whitespace-nowrap overflow-hidden hover:bg-block dark:hover:bg-button pl-2 py-2 text-base text-text-light dark:text-text-dark rounded-[5px]"
|
||||
<p v-for="item in menuStore.countries" :key="item.iso_code"
|
||||
@click="() => { menuStore.selectedPhoneCountry = item; dropCountry = false }"
|
||||
class="w-full truncate whitespace-nowrap overflow-hidden hover:bg-block dark:hover:bg-button pl-2 py-2 text-base text-text-light dark:text-text-dark rounded-[5px]"
|
||||
:title="item.name">
|
||||
{{ item.name }}
|
||||
</p>
|
||||
@ -62,14 +61,14 @@
|
||||
|
||||
</div>
|
||||
<p class="text-sm sm:text-xl font-normal">{{ menuStore.selectedPhoneCountry.call_prefix
|
||||
}}</p>
|
||||
}}</p>
|
||||
<input :placeholder="$t('phone')" type="text"
|
||||
class="text-sm sm:text-xl placeholder:text-gray dark:placeholder:text-button-disabled text-bg-dark dark:text-bg-light px-6 h-[50px] sm:h-[67px] w-full focus:outline-none focus:ring-0" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="space-y-[15px]">
|
||||
<p class="pl-6">{{ $t('account_type') }}</p>
|
||||
<USelect v-model="selectedType" :items="component.section_lang_data.account_types"
|
||||
<USelect v-model="selectedType" :items="component.front_section_lang[0].data.account_types"
|
||||
value-key="name" :searchable="false" :ui="{
|
||||
base: 'bg-inherit ring-0 cursor-pointer w-auto focus:ring-0 outline-none focus-visible:ring-0 h-[50px] sm:h-[67px] w-full p-0',
|
||||
trailing: 'hidden w-full',
|
||||
@ -84,8 +83,8 @@
|
||||
<div
|
||||
class="flex items-center justify-between gap-2 uppercase text-sm sm:text-xl border-2 border-block placeholder:text-gray dark:placeholder:text-button-disabled text-bg-dark dark:text-bg-light rounded-lg px-6 w-full h-[50px] sm:h-[67px]">
|
||||
<p class="truncate whitespace-nowrap">
|
||||
{{component.section_lang_data.account_types.find((item) => item.name ===
|
||||
modelValue)?.name}}</p>
|
||||
{{ component.front_section_lang[0].data.account_types.find((item) => item.name === modelValue)?.name }}
|
||||
</p>
|
||||
<span> <i
|
||||
class="uil uil-angle-down text-2xl font-light cursor-pointer"></i></span>
|
||||
</div>
|
||||
@ -115,10 +114,10 @@
|
||||
<div class="mt-[25px] sm:mt-[30px] w-full flex justify-center gap-3">
|
||||
<p class="cursor-pointer hover:underline transition-all">{{
|
||||
$t('is_account')
|
||||
}}</p>
|
||||
}}</p>
|
||||
<p class="text-button cursor-pointer hover:text-button-hover">{{
|
||||
$t('login')
|
||||
}}</p>
|
||||
}}</p>
|
||||
</div>
|
||||
</div>
|
||||
</UiContainer>
|
||||
@ -126,23 +125,32 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onClickOutside } from "@vueuse/core";
|
||||
const props = defineProps<{ component: Component }>();
|
||||
type Component = {
|
||||
image_collection: string;
|
||||
section_id: string;
|
||||
section_img: string;
|
||||
section_lang_data: {
|
||||
account_types: [{
|
||||
id: number,
|
||||
name: string
|
||||
}]
|
||||
};
|
||||
};
|
||||
const props = defineProps<{
|
||||
component: {
|
||||
id: number
|
||||
name: string
|
||||
img: string[]
|
||||
component_name: string
|
||||
is_no_lang: boolean
|
||||
page_name: string
|
||||
front_section_lang: {
|
||||
data: {
|
||||
account_types: {
|
||||
id: number,
|
||||
name: string
|
||||
}[]
|
||||
}
|
||||
id_front_section: number
|
||||
id_lang: number
|
||||
}[]
|
||||
}
|
||||
}>();
|
||||
|
||||
const menuStore = useMenuStore()
|
||||
const dropdownRef = ref(null);
|
||||
const dropCountry = ref()
|
||||
|
||||
const selectedType = ref(props.component.section_lang_data.account_types[0].name)
|
||||
const selectedType = ref(props.component.front_section_lang[0].data.account_types[0].name)
|
||||
|
||||
onClickOutside(dropdownRef, () => {
|
||||
dropCountry.value = false
|
||||
|
@ -137,13 +137,11 @@
|
||||
<div class="flex flex-col sm:flex-row gap-[25px]">
|
||||
<div class="flex flex-col justify-between gap-[25px]">
|
||||
<h4 class="font-inter text-lg sm:text-[24px] leading-[150%] md:leading-[120%] font-bold">
|
||||
{{ component.section_lang_data.title }}
|
||||
{{ component.front_section_lang[0].data.title }}
|
||||
</h4>
|
||||
<p>{{ component.section_lang_data.description }}</p>
|
||||
<p>{{ component.front_section_lang[0].data.description }}</p>
|
||||
</div>
|
||||
<img class="max-w-[150px] mx-auto"
|
||||
:src="`/api/files/${component.image_collection}/${component.section_id}/${component.section_img[0]}?thumb=640x0')`"
|
||||
alt="" />
|
||||
<img class="max-w-[150px] mx-auto" :src="`/api/public/file/${component.img[0]}_m.webp')`" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -170,17 +168,29 @@ import { ref } from "vue";
|
||||
import Product from "./Product.vue";
|
||||
import type { Feature, GenericResponse, GenericResponseChildren, GenericResponseItems, ProductType } from "~/types";
|
||||
import CategoryTree from "./CategoryTree.vue";
|
||||
const { $session } = useNuxtApp();
|
||||
|
||||
defineProps<{ component: Component }>();
|
||||
type Component = {
|
||||
image_collection: string;
|
||||
section_id: string;
|
||||
section_img: string;
|
||||
section_lang_data: {
|
||||
title: string;
|
||||
description: string
|
||||
};
|
||||
};
|
||||
|
||||
watch(() => $session.cookieData, async () => await getProducts(), { deep: true });
|
||||
|
||||
const props = defineProps<{
|
||||
component: {
|
||||
id: number
|
||||
name: string
|
||||
img: string[]
|
||||
component_name: string
|
||||
is_no_lang: boolean
|
||||
page_name: string
|
||||
front_section_lang: {
|
||||
data: {
|
||||
title: string;
|
||||
description: string
|
||||
}
|
||||
id_front_section: number
|
||||
id_lang: number
|
||||
}[]
|
||||
}
|
||||
}>();
|
||||
|
||||
const openCategories = ref(false);
|
||||
const isInfo = ref<boolean>(true);
|
||||
|
@ -1,15 +0,0 @@
|
||||
// import { ref } from 'vue';
|
||||
import pocketbase from "pocketbase";
|
||||
|
||||
export const usePB = () => {
|
||||
const nuxtApp = useNuxtApp();
|
||||
|
||||
const isServer = !!nuxtApp.ssrContext;
|
||||
if (isServer) {
|
||||
const pb = new pocketbase(process.env.POCKETBASE_URL || "http://127.0.0.1:8090");
|
||||
return pb;
|
||||
}
|
||||
|
||||
const pb = new pocketbase(window.location.origin);
|
||||
return pb;
|
||||
};
|
@ -6,23 +6,29 @@ export default defineNuxtConfig({
|
||||
// app: {
|
||||
// pageTransition: { name: "page", mode: "out-in" },
|
||||
// },
|
||||
nitro: {
|
||||
routeRules: {
|
||||
"/api/**": {
|
||||
proxy: {
|
||||
to: `${process.env.POCKETBASE_URL || "http://127.0.0.1:8090"}/api/**`,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
// nitro: {
|
||||
// routeRules: {
|
||||
// "/api/**": {
|
||||
// proxy: {
|
||||
// to: `${process.env.POCKETBASE_URL || "http://127.0.0.1:8090"}/api/**`,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
|
||||
modules: ["@pinia/nuxt", "@nuxt/eslint", "@nuxt/ui", "@nuxtjs/i18n", "@pinia/nuxt"],
|
||||
modules: [
|
||||
"@pinia/nuxt",
|
||||
"@nuxt/eslint",
|
||||
"@nuxt/ui",
|
||||
"@nuxtjs/i18n",
|
||||
"@pinia/nuxt",
|
||||
],
|
||||
|
||||
i18n: {
|
||||
locales: [
|
||||
{ code: "pl", name: "Polski", icon: "circle-flags:pl" },
|
||||
{ code: "en", name: "English", icon: "circle-flags:gb" },
|
||||
{ code: "cs", name: "Čeština", icon: "circle-flags:cz" }
|
||||
{ code: "cs", name: "Čeština", icon: "circle-flags:cz" },
|
||||
],
|
||||
lazy: true,
|
||||
defaultLocale: "en",
|
||||
@ -31,7 +37,11 @@ export default defineNuxtConfig({
|
||||
optimizeTranslationDirective: false,
|
||||
},
|
||||
},
|
||||
css: ["@/assets/fonts.css", "@/assets/main.css"],
|
||||
css: [
|
||||
"@/assets/main.css",
|
||||
"vue3-toastify/dist/index.css",
|
||||
"@/assets/toastify-custom.css",
|
||||
],
|
||||
vite: {
|
||||
plugins: [tailwindcss()],
|
||||
build: {
|
||||
@ -44,7 +54,7 @@ export default defineNuxtConfig({
|
||||
},
|
||||
hmr: {
|
||||
clientPort: 3000, // useful if proxying
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
typescript: {
|
||||
|
@ -18,10 +18,10 @@
|
||||
"@tailwindcss/vite": "^4.1.8",
|
||||
"@vueuse/core": "^13.3.0",
|
||||
"nuxt": "^3.17.4",
|
||||
"pocketbase": "^0.26.0",
|
||||
"tailwindcss": "^4.1.7",
|
||||
"vue": "^3.5.14",
|
||||
"vue-router": "^4.5.1"
|
||||
"vue-router": "^4.5.1",
|
||||
"vue3-toastify": "^0.2.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nuxtjs/tailwindcss": "^6.14.0"
|
||||
|
@ -1,16 +1,11 @@
|
||||
<template>
|
||||
<KeepAlive>
|
||||
<component
|
||||
:is="component.componentInstance"
|
||||
v-for="component in componentsList"
|
||||
:key="component.name"
|
||||
:component="component.component"
|
||||
/>
|
||||
<component :is="component.componentInstance" v-for="component in componentsList" :key="component.name"
|
||||
:component="component.component" />
|
||||
</KeepAlive>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
// import { useStore } from "@/stores/store";
|
||||
const route = useRoute();
|
||||
const store = useStore();
|
||||
const menuStore = useMenuStore();
|
||||
@ -20,7 +15,7 @@ onMounted(() => {
|
||||
menuStore.openMenu = false;
|
||||
});
|
||||
|
||||
// useHead(menuStore.headMeta);
|
||||
useHead(menuStore.headMeta);
|
||||
|
||||
const componentsList = await store.getComponents(route.params.id)
|
||||
|
||||
|
@ -1,17 +1,12 @@
|
||||
<template>
|
||||
<KeepAlive>
|
||||
<component
|
||||
:is="component.componentInstance"
|
||||
v-for="component in componentsList"
|
||||
:key="component.name"
|
||||
:component="component.component"
|
||||
/>
|
||||
<component :is="component.componentInstance" v-for="component in componentsList" :key="component.name"
|
||||
:component="component.component" />
|
||||
|
||||
</KeepAlive>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useStore } from "@/stores/store";
|
||||
const menuStore = useMenuStore();
|
||||
|
||||
const route = useRoute();
|
||||
@ -26,6 +21,6 @@ onMounted(() => {
|
||||
menuStore.openMenu = false;
|
||||
});
|
||||
|
||||
// useHead(menuStore.headMeta);
|
||||
useHead(menuStore.headMeta);
|
||||
const componentsList = await store.getComponents(route.params.id);
|
||||
</script>
|
||||
|
132
plugins/01_i18n.ts
Normal file
132
plugins/01_i18n.ts
Normal file
@ -0,0 +1,132 @@
|
||||
import type { VueI18n } from "vue-i18n";
|
||||
import type { RouteLocation, Router } from "vue-router";
|
||||
import type { CookieData, GenericResponse } from "~/types";
|
||||
|
||||
|
||||
// Extend the NuxtApp type
|
||||
declare module '#app' {
|
||||
interface NuxtApp {
|
||||
$session: Session;
|
||||
}
|
||||
}
|
||||
|
||||
declare module 'vue' {
|
||||
interface ComponentCustomProperties {
|
||||
$session: Session;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
export class Session {
|
||||
|
||||
cookieData = ref({} as CookieData);
|
||||
urlParams = new URLSearchParams()
|
||||
currentLanguageIso = ref("" as string)
|
||||
currentCountryIso = ref("" as string)
|
||||
currentCurrencyIso = ref("" as string)
|
||||
|
||||
route = {} as RouteLocation
|
||||
router = {} as Router
|
||||
|
||||
i18n = {} as VueI18n
|
||||
sessionOngoing: boolean = false
|
||||
|
||||
constructor(i18n: VueI18n, router: Router) {
|
||||
this.route = router.currentRoute.value
|
||||
this.router = router
|
||||
this.i18n = i18n
|
||||
|
||||
|
||||
this.setLanguage(this.route.query?.lang_iso ? this.route.query?.lang_iso as string : unref(i18n.locale))
|
||||
this.setCountry(this.route.query?.country_iso ? this.route.query?.country_iso as string : "")
|
||||
this.setCurrency(this.route.query?.currency_iso ? this.route.query?.currency_iso as string : "")
|
||||
}
|
||||
|
||||
|
||||
async loadSession() {
|
||||
if (this.sessionOngoing) return
|
||||
this.sessionOngoing = true
|
||||
this.setQueryParams()
|
||||
const { data } = await useMyFetch<GenericResponse<CookieData>>(`/api/public/cookie?${this.urlParams.toString()}`, {
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
onErrorOccured: (_, status) => {
|
||||
throw new Error(`HTTP error: ${status}`);
|
||||
},
|
||||
});
|
||||
this.cookieData.value = data;
|
||||
this.currentCountryIso.value = this.cookieData.value.country.iso_code
|
||||
this.currentLanguageIso.value = this.cookieData.value.language.iso_code
|
||||
this.currentCurrencyIso.value = this.cookieData.value.currency.iso_code
|
||||
setTimeout(() => this.sessionOngoing = false, 2000)
|
||||
}
|
||||
|
||||
setLanguage(iso: string) {
|
||||
this.currentLanguageIso.value = iso
|
||||
}
|
||||
|
||||
setCurrency(iso: string) {
|
||||
this.currentCurrencyIso.value = iso
|
||||
}
|
||||
|
||||
setCountry(iso: string) {
|
||||
this.currentCountryIso.value = iso
|
||||
}
|
||||
|
||||
setQueryParams() {
|
||||
if (this.currentLanguageIso.value.length > 0) {
|
||||
this.urlParams.set("lang_iso", this.currentLanguageIso.value)
|
||||
} else {
|
||||
this.urlParams.delete("lang_iso")
|
||||
}
|
||||
|
||||
if (this.currentCountryIso.value.length > 0) {
|
||||
this.urlParams.set("country_iso", this.currentCountryIso.value)
|
||||
} else {
|
||||
this.urlParams.delete("country_iso")
|
||||
}
|
||||
|
||||
if (this.currentCurrencyIso.value.length > 0) {
|
||||
this.urlParams.set("currency_iso", this.currentCurrencyIso.value)
|
||||
} else {
|
||||
this.urlParams.delete("currency_iso")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export default defineNuxtPlugin(async (nuxtApp) => {
|
||||
const loaded = [] as Array<string>;
|
||||
|
||||
const { $i18n: i18n } = nuxtApp as unknown as { $i18n: VueI18n };
|
||||
const { $router: router } = nuxtApp as unknown as { $router: Router };
|
||||
|
||||
i18n.onBeforeLanguageSwitch = async (_, newLocale) => {
|
||||
if (loaded.includes(newLocale)) return;
|
||||
|
||||
try {
|
||||
loaded.push(newLocale);
|
||||
const { data } = await useMyFetch<GenericResponse<object>>(
|
||||
"/api/public/front/translation"
|
||||
);
|
||||
|
||||
i18n.setLocaleMessage(newLocale, data);
|
||||
|
||||
} catch (err) {
|
||||
console.error("❌ Failed to load translation for locale:", newLocale);
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
const session = new Session(i18n, router)
|
||||
|
||||
await session.loadSession();
|
||||
nuxtApp.provide("session", session);
|
||||
|
||||
});
|
@ -3,7 +3,8 @@ import { defineNuxtPlugin } from "#app";
|
||||
export default defineNuxtPlugin(async () => {
|
||||
const menuStore = useMenuStore();
|
||||
await menuStore.loadMenu();
|
||||
await menuStore.loadFooter();
|
||||
await menuStore.getCountryList();
|
||||
await menuStore.getCurrencies();
|
||||
await menuStore.getLocales();
|
||||
const store = useStore();
|
||||
await store.getMinValue();
|
||||
await store.getCalculator();
|
||||
});
|
@ -1,31 +0,0 @@
|
||||
import type { VueI18n } from "vue-i18n";
|
||||
import { usePB } from "~/composables/usePB";
|
||||
|
||||
export default defineNuxtPlugin(async (nuxtApp) => {
|
||||
const loaded = [] as Array<string>;
|
||||
|
||||
const i18n = nuxtApp.$i18n as VueI18n;
|
||||
const pb = usePB();
|
||||
|
||||
i18n.onBeforeLanguageSwitch = async (oldLocale, newLocale) => {
|
||||
if (loaded.includes(newLocale)) return;
|
||||
|
||||
try {
|
||||
const translation = await pb.collection("translation").getList(1, 1, {
|
||||
expand: "id_lang",
|
||||
filter: `id_lang.iso='${newLocale}'`,
|
||||
});
|
||||
|
||||
if (translation.totalItems === 1) {
|
||||
i18n.setLocaleMessage(newLocale, translation.items[0].data);
|
||||
} else {
|
||||
i18n.setLocaleMessage(newLocale, {});
|
||||
}
|
||||
|
||||
loaded.push(newLocale);
|
||||
} catch (err) {
|
||||
console.error("❌ Failed to load translation for locale:", newLocale);
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
});
|
10
plugins/vue3-toastify.client.ts
Normal file
10
plugins/vue3-toastify.client.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import * as Vue3Toastify from "vue3-toastify";
|
||||
import "vue3-toastify/dist/index.css";
|
||||
|
||||
export default defineNuxtPlugin((nuxtApp) => {
|
||||
nuxtApp.vueApp.use(Vue3Toastify.default, { autoClose: 2000 });
|
||||
|
||||
return {
|
||||
provide: { toast: Vue3Toastify.toast },
|
||||
};
|
||||
});
|
13388
pnpm-lock.yaml
generated
Normal file
13388
pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,3 +0,0 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M1.29289 17.4628L0.585786 18.1699L2 19.5841L2.70711 18.877L1.29289 17.4628ZM19.9706 1.19936C19.9706 0.647074 19.5228 0.199359 18.9706 0.199359L9.97056 0.19936C9.41828 0.199359 8.97056 0.647075 8.97056 1.19936C8.97056 1.75164 9.41828 2.19936 9.97056 2.19936L17.9706 2.19936L17.9706 10.1994C17.9706 10.7516 18.4183 11.1994 18.9706 11.1994C19.5228 11.1994 19.9706 10.7516 19.9706 10.1994L19.9706 1.19936ZM2 18.1699L2.70711 18.877L19.6777 1.90647L18.9706 1.19936L18.2635 0.492253L1.29289 17.4628L2 18.1699Z" fill="#1A1A1A"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 633 B |
@ -1,3 +0,0 @@
|
||||
<svg width="20" height="21" viewBox="0 0 20 21" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M2.7364 1.49211L2.0293 0.785005L0.615083 2.19922L1.32219 2.90633L2.7364 1.49211ZM18.9999 20.1698C19.5521 20.1698 19.9999 19.7221 19.9999 19.1698L19.9999 10.1698C19.9999 9.6175 19.5521 9.16978 18.9999 9.16978C18.4476 9.16978 17.9999 9.6175 17.9999 10.1698L17.9999 18.1698L9.99986 18.1698C9.44758 18.1698 8.99986 18.6175 8.99986 19.1698C8.99986 19.7221 9.44757 20.1698 9.99986 20.1698L18.9999 20.1698ZM2.0293 2.19922L1.32219 2.90633L18.2928 19.8769L18.9999 19.1698L19.707 18.4627L2.7364 1.49211L2.0293 2.19922Z" fill="#1A1A1A"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 639 B |
3
public/photo.svg
Normal file
3
public/photo.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="76" height="53" viewBox="0 0 76 53" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M76 49.8V2C76 0.9 75.1 0 74 0H2C0.9 0 0 0.9 0 2V50C0 52.5 3.3 52 2 52H74C77 52 75.6 47.4 76 49.8ZM6 48L28 19.3L46.4 43.4L49.9 48H6ZM55 48L50.5 42.2L58 32.4L69.9 48H55ZM72 44L59.6 27.8C58.8 26.7 57.2 26.7 56.4 27.8L48 38.8L29.6 14.8C28.8 13.7 27.2 13.7 26.4 14.8L4 44.1V4H72V44ZM49 10C45.1 10 42 13.1 42 17C42 20.9 45.1 24 49 24C52.9 24 56 20.9 56 17C56 13.1 52.8 10 49 10ZM49 20C47.4 20 46 18.7 46 17C46 15.3 47.3 14 49 14C50.7 14 52 15.3 52 17C52 18.7 50.6 20 49 20Z" fill="#004F3D"/>
|
||||
</svg>
|
After Width: | Height: | Size: 598 B |
BIN
public/pics.png
BIN
public/pics.png
Binary file not shown.
Before Width: | Height: | Size: 49 KiB |
BIN
public/pics1.png
BIN
public/pics1.png
Binary file not shown.
Before Width: | Height: | Size: 101 KiB |
@ -1,101 +0,0 @@
|
||||
import type { CountryList, PartnersList } from "~/types";
|
||||
|
||||
export const useMapStore = defineStore("mapStore", () => {
|
||||
const partnersList = ref<PartnersList[]>([
|
||||
{
|
||||
country_iso: "cz",
|
||||
total: 9,
|
||||
country_name: "Czech Republic",
|
||||
},
|
||||
{
|
||||
country_iso: "de",
|
||||
total: 1,
|
||||
country_name: "Germany",
|
||||
},
|
||||
{
|
||||
country_iso: "ie",
|
||||
total: 1,
|
||||
country_name: "Ireland",
|
||||
},
|
||||
{
|
||||
country_iso: "nl",
|
||||
total: 1,
|
||||
country_name: "Netherlands",
|
||||
},
|
||||
{
|
||||
country_iso: "pl",
|
||||
total: 61,
|
||||
country_name: "Poland",
|
||||
},
|
||||
]);
|
||||
|
||||
const customersList = ref([
|
||||
"be",
|
||||
"cz",
|
||||
"de",
|
||||
"dk",
|
||||
"gb",
|
||||
"ie",
|
||||
"it",
|
||||
"nl",
|
||||
"no",
|
||||
"pl",
|
||||
"sk",
|
||||
"at",
|
||||
"lt",
|
||||
"is",
|
||||
"se"
|
||||
]);
|
||||
|
||||
// async function getPartnersList() {
|
||||
// try {
|
||||
// const res = await fetch(
|
||||
// `http://127.0.0.1:4000/api/public/partners/count`,
|
||||
// {
|
||||
// headers: {
|
||||
// "Content-Type": "application/json",
|
||||
// },
|
||||
// }
|
||||
// );
|
||||
|
||||
// if (!res.ok) {
|
||||
// throw new Error(`HTTP error: ${res.status}`);
|
||||
// }
|
||||
|
||||
// const data = await res.json();
|
||||
// partnersList.value = data.data
|
||||
// } catch (error) {
|
||||
// console.error("getList error:", error);
|
||||
// }
|
||||
// }
|
||||
|
||||
// async function getCustomerList() {
|
||||
// try {
|
||||
// const res = await fetch(
|
||||
// `http://127.0.0.1:4000/api/public/customer/countries`,
|
||||
// {
|
||||
// headers: {
|
||||
// "Content-Type": "application/json",
|
||||
// },
|
||||
// }
|
||||
// );
|
||||
|
||||
// if (!res.ok) {
|
||||
// throw new Error(`HTTP error: ${res.status}`);
|
||||
// }
|
||||
|
||||
// const data = await res.json();
|
||||
// customersList.value = data.data
|
||||
// } catch (error) {
|
||||
// console.error("getList error:", error);
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
return {
|
||||
partnersList,
|
||||
customersList,
|
||||
// getPartnersList,
|
||||
// getCustomerList,
|
||||
};
|
||||
});
|
@ -1,46 +1,37 @@
|
||||
import { usePB } from "~/composables/usePB";
|
||||
import type {
|
||||
Country,
|
||||
Currencies,
|
||||
Currency,
|
||||
FooterListResponse,
|
||||
FrontMenu,
|
||||
GenericResponse,
|
||||
GenericResponseItems,
|
||||
PBFooterItem,
|
||||
Language,
|
||||
UIFrontMenu,
|
||||
UIMenuItem,
|
||||
} from "~/types";
|
||||
import { useStore } from "./store";
|
||||
import { ref, watch } from "vue";
|
||||
import { useMyFetch } from "#imports";
|
||||
// import { useSession } from "~/plugins/01_i18n";
|
||||
|
||||
// function buildTreeRecursive(
|
||||
// data: (PBMenuItem | UIMenuItem)[],
|
||||
// parentId: string
|
||||
// ): UIMenuItem[] {
|
||||
// const children = data.filter(
|
||||
// (item): item is UIMenuItem =>
|
||||
// item.id_parent === parentId && !item.is_default
|
||||
// );
|
||||
|
||||
// return children.map((item) => ({
|
||||
// ...item,
|
||||
// children: buildTreeRecursive(data, item.id),
|
||||
// }));
|
||||
// }
|
||||
function buildTreeRecursive(
|
||||
data: (FrontMenu | UIFrontMenu)[],
|
||||
parentId: number
|
||||
): UIFrontMenu[] {
|
||||
const children = data.filter(
|
||||
(item): item is UIFrontMenu =>
|
||||
item.id_parent === parentId && !item.is_default
|
||||
);
|
||||
|
||||
function buildTreeRecursive(data: (FrontMenu | UIFrontMenu)[], parentId: number): UIFrontMenu[] {
|
||||
const children = data.filter((item): item is UIFrontMenu => item.id_parent === parentId && !item.is_default);
|
||||
|
||||
return children.map((item) => ({ ...item, children: buildTreeRecursive(data, item.id) }));
|
||||
return children.map((item) => ({
|
||||
...item,
|
||||
children: buildTreeRecursive(data, item.id),
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
export const useMenuStore = defineStore("menuStore", () => {
|
||||
const pb = usePB();
|
||||
const store = useStore();
|
||||
const { $i18n } = useNuxtApp();
|
||||
// const session = useSession();
|
||||
const { $session } = useNuxtApp();
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
|
||||
@ -48,43 +39,57 @@ export const useMenuStore = defineStore("menuStore", () => {
|
||||
const openDropDown = ref(false);
|
||||
|
||||
const defaultMenu = ref();
|
||||
// const menu = ref<UIMenuItem[]>([]);
|
||||
// const menuItems = ref<MenuListResponse>();
|
||||
|
||||
const menu = ref<UIFrontMenu[]>([]);
|
||||
const menuItems = ref<FrontMenu[]>();
|
||||
|
||||
const footerItems = ref<FooterListResponse>();
|
||||
const countryList = ref<Country[]>();
|
||||
const currencies = ref<Currency[]>();
|
||||
const menu = ref([] as UIFrontMenu[]);
|
||||
const menuItems = ref([] as FrontMenu[]);
|
||||
|
||||
|
||||
// curr/country
|
||||
const selectedCountry = ref();
|
||||
const selectedPhoneCountry = ref();
|
||||
const selectedCurrency = ref<Currencies>();
|
||||
const selectedCountry = ref({} as Country);
|
||||
const selectedPhoneCountry = ref({} as Country);
|
||||
const selectedCurrency = ref({} as Currency);
|
||||
const selectedLanguage = ref({} as Language);
|
||||
|
||||
|
||||
const countries = ref([] as Country[]);
|
||||
const currencies = ref([] as Currency[]);
|
||||
const languages = ref([] as Language[]);
|
||||
|
||||
|
||||
const getLocales = async () => {
|
||||
const { data: countriesList } = await useMyFetch<GenericResponse<Country[]>>(`/api/public/country/list`);
|
||||
countries.value = countriesList;
|
||||
selectedCountry.value = countriesList.find((country) => country.iso_code === $session.currentCountryIso.value) as Country;
|
||||
selectedPhoneCountry.value = countriesList.find((country) => country.iso_code === $session.currentCountryIso.value) as Country;
|
||||
|
||||
|
||||
const { data: currenciesList } = await useMyFetch<GenericResponseItems<Currency[]>>(`/api/public/currencies`)
|
||||
currencies.value = currenciesList.items;
|
||||
selectedCurrency.value = currenciesList.items.find((currency) => currency.iso_code === $session.currentCurrencyIso.value) as Currency;
|
||||
|
||||
const { data: languagesList } = await useMyFetch<GenericResponseItems<Language[]>>(`/api/public/languages`)
|
||||
languages.value = languagesList.items;
|
||||
selectedLanguage.value = languagesList.items.find((language) => language.iso_code === $session.currentLanguageIso.value) as Language;
|
||||
};
|
||||
|
||||
|
||||
const loadMenu = async () => {
|
||||
try {
|
||||
// menuItems.value = (await pb
|
||||
// .collection("menu_view")
|
||||
// .getList<PBMenuItem>(1, 50, {
|
||||
// filter: `id_lang="${$i18n.locale.value}"&&active=true`,
|
||||
// sort: "position_id",
|
||||
// })) as MenuListResponse;
|
||||
|
||||
const { data } = await useMyFetch<GenericResponse<FrontMenu[]>>(`/api/public/front/menu`, {
|
||||
onErrorOccured: (err, status) => {
|
||||
console.log(err, status);
|
||||
},
|
||||
// onSuccess(data) {
|
||||
// console.log(data.data, "data");
|
||||
const { data } = await useMyFetch<GenericResponse<FrontMenu[]>>(
|
||||
`/api/public/front/menu`,
|
||||
{
|
||||
onErrorOccured: (err, status) => {
|
||||
console.log(err, status);
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
// },
|
||||
})
|
||||
menuItems.value = data;
|
||||
|
||||
const root = data.find((item) => item.is_root) as UIFrontMenu;
|
||||
defaultMenu.value = data.find((item) => item.is_default);
|
||||
// console.log(menuNew, "data");
|
||||
if (root) {
|
||||
menu.value = buildTreeRecursive(data, root.id);
|
||||
} else {
|
||||
@ -92,84 +97,11 @@ export const useMenuStore = defineStore("menuStore", () => {
|
||||
menu.value = [];
|
||||
}
|
||||
|
||||
|
||||
// const root = menuItems.value.items.find((item) => item.is_root);
|
||||
// defaultMenu.value = menuItems.value.items.find((item) => item.is_default);
|
||||
|
||||
// if (root) {
|
||||
// menu.value = buildTreeRecursive(menuItems.value.items, root.id);
|
||||
// store.currentPageID = menu.value[0]?.id_page || "";
|
||||
// } else {
|
||||
// console.warn("Root menu item not found");
|
||||
// menu.value = [];
|
||||
// }
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
};
|
||||
|
||||
const loadFooter = async () => {
|
||||
try {
|
||||
footerItems.value = (await pb
|
||||
.collection("footer_view")
|
||||
.getList<PBFooterItem>(1, 50, {
|
||||
filter: `id_lang="${$i18n.locale.value}"`,
|
||||
})) as FooterListResponse;
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
};
|
||||
|
||||
const getCountryList = async () => {
|
||||
try {
|
||||
const { data } = await useMyFetch<GenericResponse<Country[]>>(
|
||||
`/api/public/country/list`,
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
// if (!res.ok) {
|
||||
// throw new Error(`HTTP error: ${res.status}`);
|
||||
// }
|
||||
|
||||
// const data = await res.json();
|
||||
countryList.value = data
|
||||
if (countryList.value)
|
||||
selectedPhoneCountry.value = countryList.value[0]
|
||||
|
||||
} catch (error) {
|
||||
console.error("getList error:", error);
|
||||
}
|
||||
}
|
||||
|
||||
const getCurrencies = async () => {
|
||||
try {
|
||||
const { data } = await useMyFetch<GenericResponseItems<Currency[]>>(
|
||||
`/api/public/currencies`,
|
||||
{
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
onErrorOccured: (_, status) => { throw new Error(`HTTP error: ${status}`) },
|
||||
}
|
||||
);
|
||||
|
||||
// if (!res.ok) {
|
||||
// throw new Error(`HTTP error: ${res.status}`);
|
||||
// }
|
||||
|
||||
// const data = await res.json();
|
||||
currencies.value = data.items
|
||||
|
||||
// console.log(data.items, "data");
|
||||
|
||||
} catch (error) {
|
||||
console.error("getList error:", error);
|
||||
}
|
||||
}
|
||||
|
||||
const navigateToItem = (item?: UIFrontMenu) => {
|
||||
if (item) {
|
||||
@ -178,12 +110,11 @@ export const useMenuStore = defineStore("menuStore", () => {
|
||||
name: `id-slug___${$i18n.locale.value}`,
|
||||
});
|
||||
openDropDown.value = false;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
router.push({
|
||||
params: {
|
||||
slug: defaultMenu.value.link_rewrite,
|
||||
id: defaultMenu.value.id_page,
|
||||
slug: defaultMenu.value.front_menu_lang[0].link_rewrite,
|
||||
id: defaultMenu.value.id,
|
||||
},
|
||||
name: `id-slug___${$i18n.locale.value}`,
|
||||
});
|
||||
@ -191,113 +122,108 @@ export const useMenuStore = defineStore("menuStore", () => {
|
||||
};
|
||||
|
||||
function navigateToShop() {
|
||||
navigateToItem(menuItems.value?.items.find(item => item.page_name === 'shop'))
|
||||
navigateToItem(menuItems.value?.find((item) => item.id === 5));
|
||||
}
|
||||
|
||||
// function redirectToPage(link_rewrite: string) {
|
||||
// const page = menuItems.value?.items.find(
|
||||
// (item) => item.link_rewrite === link_rewrite
|
||||
// );
|
||||
|
||||
// if (!page?.id_page || !page?.link_rewrite) {
|
||||
// console.warn(`Page not found or missing data for name: ${link_rewrite}`);
|
||||
// return;
|
||||
// }
|
||||
|
||||
// router.push({
|
||||
// params: {
|
||||
// id: page?.id_page,
|
||||
// slug: page?.link_rewrite,
|
||||
// },
|
||||
// });
|
||||
// }
|
||||
|
||||
const getFirstImage = () => {
|
||||
const getFirstImage = (size: "l" | "m" | "s" = "m", needbaseurl: boolean) => {
|
||||
const req = useRequestEvent();
|
||||
const url = useRequestURL();
|
||||
let img = "";
|
||||
// let img = "";
|
||||
const img: string[] = []
|
||||
for (const s in store.components) {
|
||||
store.components[s].section_img.map((item) => {
|
||||
img = `${req?.headers.get("x-forwarded-proto") || url.protocol}://${req?.headers.get("x-forwarded-host") || req?.headers.get("host")
|
||||
}/api/files/${store.components[s].image_collection}/${store.components[s].section_id
|
||||
}/${item}?thumb=400x0`;
|
||||
});
|
||||
if (img.length > 0) return img;
|
||||
if (store.components[s].front_section.img.length === 0) continue;
|
||||
img.push(`/api/public/file/${store.components[s].front_section.img[0]}_${size}.webp`)
|
||||
if (img.length > 0) break;;
|
||||
}
|
||||
if (img.length > 0) {
|
||||
if (needbaseurl) {
|
||||
return `${req?.headers.get("x-forwarded-proto") || url.protocol}://${req?.headers.get("x-forwarded-host") || url.host || req?.headers.get("host")}${img[0]}`;
|
||||
}
|
||||
return img[0];
|
||||
}
|
||||
return "";
|
||||
};
|
||||
|
||||
const headMeta = computed(() => {
|
||||
const item = menuItems.value?.items.find(
|
||||
(item) => item.id_page === route.params.id
|
||||
const item = menuItems.value?.find(
|
||||
(item) => item.id.toString() === route.params.id
|
||||
);
|
||||
return {
|
||||
title: item?.meta_title,
|
||||
|
||||
const meta = {
|
||||
title: item?.front_menu_lang[0].meta_title,
|
||||
htmlAttrs: {
|
||||
lang: $i18n.locale.value,
|
||||
},
|
||||
link: [{ rel: "manifest", href: "/api/manifest.json" }],
|
||||
link: [
|
||||
// { rel: "manifest", href: "/api/manifest.json" }
|
||||
],
|
||||
meta: [
|
||||
{
|
||||
hid: "description",
|
||||
name: "description",
|
||||
content: item?.meta_description,
|
||||
content: item?.front_menu_lang[0].meta_description,
|
||||
},
|
||||
{
|
||||
property: "og:title",
|
||||
content: item?.meta_title,
|
||||
content: item?.front_menu_lang[0].meta_title,
|
||||
},
|
||||
{
|
||||
property: "og:description",
|
||||
content: item?.meta_description,
|
||||
content: item?.front_menu_lang[0].meta_description,
|
||||
},
|
||||
{
|
||||
property: "og:image",
|
||||
content: getFirstImage(),
|
||||
content: getFirstImage("m", true),
|
||||
},
|
||||
{
|
||||
property: "twitter:title",
|
||||
content: item?.meta_title,
|
||||
content: item?.front_menu_lang[0].meta_title,
|
||||
},
|
||||
{
|
||||
property: "twitter:description",
|
||||
content: item?.meta_description,
|
||||
content: item?.front_menu_lang[0].meta_description,
|
||||
},
|
||||
{
|
||||
property: "twitter:image",
|
||||
content: getFirstImage(),
|
||||
content: getFirstImage("m", true),
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const preload = getFirstImage("l", false);
|
||||
if (preload) {
|
||||
meta.link.push({ rel: "preload", as: "image", href: preload } as never);
|
||||
}
|
||||
|
||||
return meta;
|
||||
|
||||
});
|
||||
|
||||
watch($i18n.locale, async () => {
|
||||
// watches
|
||||
watch(() => $session.cookieData, async () => {
|
||||
await getLocales();
|
||||
await loadMenu();
|
||||
await loadFooter();
|
||||
});
|
||||
await store.getMinValue();
|
||||
await store.getCalculator();
|
||||
}, { deep: true });
|
||||
|
||||
watch(selectedCurrency, () => {
|
||||
store.getCalculator()
|
||||
})
|
||||
return {
|
||||
menu,
|
||||
menuItems,
|
||||
footerItems,
|
||||
openMenu,
|
||||
openDropDown,
|
||||
countryList,
|
||||
currencies,
|
||||
languages,
|
||||
countries,
|
||||
selectedCountry,
|
||||
selectedCurrency,
|
||||
selectedPhoneCountry,
|
||||
selectedLanguage,
|
||||
defaultMenu,
|
||||
headMeta,
|
||||
navigateToShop,
|
||||
loadMenu,
|
||||
loadFooter,
|
||||
getCountryList,
|
||||
navigateToItem,
|
||||
// redirectToPage,
|
||||
getCurrencies
|
||||
getLocales,
|
||||
};
|
||||
});
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { NuxtErrorBoundary } from "#components";
|
||||
import { useMyFetch } from "#imports";
|
||||
import type {
|
||||
CartItem,
|
||||
GenericResponse,
|
||||
GenericResponseChildren,
|
||||
GenericResponseItems,
|
||||
@ -9,6 +9,7 @@ import type {
|
||||
import type { Product } from "~/types/product";
|
||||
|
||||
export const useProductStore = defineStore("productStore", () => {
|
||||
const { $toast } = useNuxtApp();
|
||||
const productList = ref<Product[]>();
|
||||
const modules = ref();
|
||||
|
||||
@ -59,10 +60,10 @@ export const useProductStore = defineStore("productStore", () => {
|
||||
}
|
||||
}
|
||||
|
||||
async function addToCart(product: Product) {
|
||||
async function incrementCartItem(id: number) {
|
||||
try {
|
||||
const { data } = await useMyFetch<GenericResponse<UserCart>>(
|
||||
`/api/public/user/cart/item/add/${product.id}/1`,
|
||||
const res = await useMyFetch<GenericResponse<object>>(
|
||||
`/api/public/user/cart/item/add/${id}/1`,
|
||||
{
|
||||
method: "PUT",
|
||||
headers: {
|
||||
@ -73,8 +74,97 @@ export const useProductStore = defineStore("productStore", () => {
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
if (res.status === 200) {
|
||||
$toast.success("Item successfully added to your cart.", {
|
||||
autoClose: 5000,
|
||||
dangerouslyHTMLString: true,
|
||||
});
|
||||
getCart();
|
||||
} else {
|
||||
$toast.error("Failed to add item to cart. Please try again.", {
|
||||
autoClose: 5000,
|
||||
dangerouslyHTMLString: true,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("getList error:", error);
|
||||
$toast.error("An unexpected error occurred while updating your cart.", {
|
||||
autoClose: 5000,
|
||||
dangerouslyHTMLString: true,
|
||||
});
|
||||
console.error("incrementCartItem error:", error);
|
||||
}
|
||||
}
|
||||
|
||||
async function decrementCartItem(id: number) {
|
||||
try {
|
||||
const res = await useMyFetch<GenericResponse<object>>(
|
||||
`/api/public/user/cart/item/subtract/${id}/1`,
|
||||
{
|
||||
method: "PUT",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
onErrorOccured: (_, status) => {
|
||||
throw new Error(`HTTP error: ${status}`);
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
if (res.status === 200) {
|
||||
$toast.success("Item successfully removed from your cart.", {
|
||||
autoClose: 5000,
|
||||
dangerouslyHTMLString: true,
|
||||
});
|
||||
getCart();
|
||||
} else {
|
||||
$toast.error("Failed to removed item from cart. Please try again.", {
|
||||
autoClose: 5000,
|
||||
dangerouslyHTMLString: true,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
$toast.error("An unexpected error occurred while updating your cart.", {
|
||||
autoClose: 5000,
|
||||
dangerouslyHTMLString: true,
|
||||
});
|
||||
console.error("decrementCartItem error:", error);
|
||||
}
|
||||
}
|
||||
|
||||
async function deleteCartItem(id: number) {
|
||||
try {
|
||||
const res = await useMyFetch<GenericResponse<object>>(
|
||||
`/api/public/user/cart/item/${id}`,
|
||||
{
|
||||
method: "DELETE",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
onErrorOccured: (_, status) => {
|
||||
throw new Error(`HTTP error: ${status}`);
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
if (res.status === 200) {
|
||||
$toast.success("Item successfully removed from your cart.", {
|
||||
autoClose: 5000,
|
||||
dangerouslyHTMLString: true,
|
||||
});
|
||||
getCart();
|
||||
} else {
|
||||
$toast.error("Failed to removed item from cart. Please try again.", {
|
||||
autoClose: 5000,
|
||||
dangerouslyHTMLString: true,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
$toast.error("An unexpected error occurred while updating your cart.", {
|
||||
autoClose: 5000,
|
||||
dangerouslyHTMLString: true,
|
||||
});
|
||||
console.error("deleteCartItem error:", error);
|
||||
}
|
||||
}
|
||||
|
||||
@ -93,10 +183,6 @@ export const useProductStore = defineStore("productStore", () => {
|
||||
}
|
||||
);
|
||||
|
||||
// if (!res.ok) {
|
||||
// throw new Error(`HTTP error: ${res.status}`);
|
||||
// }
|
||||
|
||||
cart.value = data;
|
||||
} catch (error) {
|
||||
console.error("getList error:", error);
|
||||
@ -106,9 +192,12 @@ export const useProductStore = defineStore("productStore", () => {
|
||||
return {
|
||||
productList,
|
||||
modules,
|
||||
cart,
|
||||
getList,
|
||||
getModules,
|
||||
addToCart,
|
||||
// getCart,
|
||||
incrementCartItem,
|
||||
decrementCartItem,
|
||||
deleteCartItem,
|
||||
getCart,
|
||||
};
|
||||
});
|
||||
|
@ -1,16 +1,14 @@
|
||||
import { useMyFetch } from "#imports";
|
||||
// import { usePB } from "~/composables/usePB";
|
||||
import type {
|
||||
componentsListType,
|
||||
GenericResponse,
|
||||
PlanPrediction,
|
||||
} from "~/types";
|
||||
// import { useI18n } from "vue-i18n";
|
||||
import type { FrontPageSection } from "~/types/frontSection";
|
||||
|
||||
export const useStore = defineStore("store", () => {
|
||||
const currentPageID = ref("");
|
||||
// const pb = usePB();
|
||||
// const { $i18n } = useNuxtApp();
|
||||
|
||||
|
||||
// calculator
|
||||
const monthlySavings = ref(137);
|
||||
@ -23,40 +21,14 @@ export const useStore = defineStore("store", () => {
|
||||
const password = ref();
|
||||
|
||||
const components = ref({} as FrontPageSection[]);
|
||||
// const getSections = async (id: string) => {
|
||||
// pb.cancelRequest("menu_view");
|
||||
// components.value = (
|
||||
// await pb.collection<PBPageItem>("page_view").getList(1, 50, {
|
||||
// filter: `id="${id}"&&(section_lang_id_lang="${
|
||||
// $i18n.locale.value
|
||||
// }"||section_is_no_lang=${true})`,
|
||||
// sort: "page_section_id_position",
|
||||
// })
|
||||
// ).items as PBPageItem[];
|
||||
// };
|
||||
|
||||
|
||||
const getSections = async (id: string) => {
|
||||
// if(!id){
|
||||
// id = useMenuStore().defaultMenu.id
|
||||
// }
|
||||
// console.log(useMenuStore().defaultMenu);
|
||||
|
||||
const {data} = await useMyFetch<GenericResponse<FrontPageSection[]>>(
|
||||
const { data } = await useMyFetch<GenericResponse<FrontPageSection[]>>(
|
||||
`/api/public/front/sections/${id}`
|
||||
)
|
||||
// console.log(data, id, "data");
|
||||
components.value = data
|
||||
// return data
|
||||
|
||||
// pb.cancelRequest("menu_view");
|
||||
// components.value = (
|
||||
// await pb.collection<PBPageItem>("page_view").getList(1, 50, {
|
||||
// filter: `id="${id}"&&(section_lang_id_lang="${
|
||||
// $i18n.locale.value
|
||||
// }"||section_is_no_lang=${true})`,
|
||||
// sort: "page_section_id_position",
|
||||
// })
|
||||
// ).items as PBPageItem[];
|
||||
};
|
||||
|
||||
async function getComponents(): Promise<componentsListType[]> {
|
||||
@ -72,7 +44,6 @@ export const useStore = defineStore("store", () => {
|
||||
|
||||
for (const child of children) {
|
||||
const componentName = child.front_section.component_name;
|
||||
// const pageName = child.front_section.page_name;
|
||||
if (!componentName) continue;
|
||||
|
||||
try {
|
||||
@ -85,8 +56,7 @@ export const useStore = defineStore("store", () => {
|
||||
name: componentName,
|
||||
component: child.front_section,
|
||||
componentInstance: nonReactiveComponent,
|
||||
// data: child.front_section.front_section_lang[0].data || {} as unknown,
|
||||
// data: {}
|
||||
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(`Failed to load component ${componentName}`, error);
|
||||
@ -133,11 +103,7 @@ export const useStore = defineStore("store", () => {
|
||||
}
|
||||
);
|
||||
|
||||
// if (!res.ok) {
|
||||
// throw new Error(`HTTP error: ${res.status}`);
|
||||
// }
|
||||
|
||||
// const data = await res.json();
|
||||
minValue.value = data;
|
||||
} catch (error) {
|
||||
console.error("getList error:", error);
|
||||
@ -169,8 +135,6 @@ export const useStore = defineStore("store", () => {
|
||||
}
|
||||
}
|
||||
|
||||
getCalculator();
|
||||
getMinValue();
|
||||
|
||||
return {
|
||||
currentPageID,
|
||||
@ -185,5 +149,6 @@ export const useStore = defineStore("store", () => {
|
||||
getCalculator,
|
||||
getComponents,
|
||||
getSections,
|
||||
getMinValue,
|
||||
};
|
||||
});
|
||||
|
115
taskfile.yml
115
taskfile.yml
@ -1,115 +0,0 @@
|
||||
version: "3"
|
||||
vars:
|
||||
REGISTRY: registry.ma-al.com
|
||||
Version: "0.0.6"
|
||||
BuildDate: $(date +"%Y-%m-%d %H:%M")
|
||||
Company: Maal sp. z o.o.
|
||||
CompanyUrl: "https://www.ma-al.com"
|
||||
CompileStr: go build -ldflags "-s -w -X 'pocketbase/custom/version.Version={{.Version}}' -X 'pocketbase/custom/version.BuildDate={{.BuildDate}}' -X 'pocketbase/custom/version.Company={{.Company}}' -X 'pocketbase/custom/version.CompanyUrl={{.CompanyUrl}}'" -o ../.pocketbase/pocketbase .
|
||||
|
||||
tasks:
|
||||
default:
|
||||
cmds:
|
||||
- task --list
|
||||
silent: true
|
||||
|
||||
compile_musl:
|
||||
aliases: [cm]
|
||||
desc: "compiles pocketbase for musl"
|
||||
env:
|
||||
CGO_ENABLED: "0"
|
||||
GOOS: "linux"
|
||||
GOARCH: "amd64"
|
||||
CC: "x86_64-linux-musl-gcc"
|
||||
cmds:
|
||||
- |
|
||||
mkdir -p ./.output
|
||||
cd ./backend
|
||||
{{.CompileStr}}
|
||||
|
||||
compile_gnu:
|
||||
aliases: [cg]
|
||||
desc: "compiles pocketbase for gnu"
|
||||
env:
|
||||
CGO_ENABLED: "0"
|
||||
GOOS: "linux"
|
||||
GOARCH: "amd64"
|
||||
cmds:
|
||||
- |
|
||||
mkdir -p ./.output
|
||||
cd ./backend
|
||||
{{.CompileStr}}
|
||||
|
||||
build_run_gnu:
|
||||
aliases: [br]
|
||||
desc: "compiles pocketbase for gnu"
|
||||
env:
|
||||
CGO_ENABLED: "0"
|
||||
GOOS: "linux"
|
||||
GOARCH: "amd64"
|
||||
cmds:
|
||||
- |
|
||||
mkdir -p ./.output
|
||||
cd ./backend
|
||||
go build -ldflags "-s -w" -o ../.pocketbase/pocketbase .
|
||||
cd ..
|
||||
./.pocketbase/pocketbase serve --dir=./backend/pb_data
|
||||
|
||||
watch_backend:
|
||||
aliases: [wb]
|
||||
desc: "watch backend and compile"
|
||||
cmds:
|
||||
- |
|
||||
cd ./backend
|
||||
pwd
|
||||
air -build.args_bin='serve --dir=./pb_data' -build.exclude_dir=pb_data,backups -build.include_ext=go
|
||||
|
||||
watch_front:
|
||||
aliases: [wf]
|
||||
desc: "build and watch frontend in dev mode"
|
||||
cmds:
|
||||
- |
|
||||
bun run dev
|
||||
|
||||
preview_front:
|
||||
aliases: [pf]
|
||||
desc: "build and preview frontend"
|
||||
cmds:
|
||||
- |
|
||||
bun run build && bun run preview
|
||||
|
||||
rebuild_front:
|
||||
aliases: [rf]
|
||||
desc: "remove all and install all packages"
|
||||
cmds:
|
||||
- |
|
||||
rm -rf ./node_modules ./bun-lock ./.nuxt ./.output
|
||||
bun install
|
||||
|
||||
# build_docker_image:
|
||||
# aliases: [bdi]
|
||||
# desc: "build docker image"
|
||||
# cmds:
|
||||
# - |
|
||||
# bun run build
|
||||
# task compile_gnu
|
||||
# cat <<EOF > temp.Dockerfile
|
||||
# FROM node:slim
|
||||
|
||||
# COPY ./.output /nuxt
|
||||
# COPY ./.pocketbase/pocketbase /bin/
|
||||
# RUN mkdir /data
|
||||
|
||||
# # ENTRYPOINT ["ash"]
|
||||
# CMD ["pocketbase", "serve", "--dir=/data", "--proxy=http://localhost:3000", "--subcommand=node /nuxt/server/index.mjs", "--http=0.0.0.0:8090"]
|
||||
# EOF
|
||||
# docker build -t {{.REGISTRY}}/abrasive/abrasive:{{.Version}} -t {{.REGISTRY}}/abrasive/abrasive:latest -f temp.Dockerfile .
|
||||
# rm temp.Dockerfile
|
||||
|
||||
# push_docker_image:
|
||||
# aliases: [pdi]
|
||||
# desc: "push docker image to registry server"
|
||||
# cmds:
|
||||
# - |
|
||||
# docker push {{.REGISTRY}}/abrasive/abrasive:{{.Version}}
|
||||
# docker push {{.REGISTRY}}/abrasive/abrasive:latest
|
145
types/index.ts
145
types/index.ts
@ -1,115 +1,12 @@
|
||||
import type { DefineComponent } from "vue";
|
||||
import type { FrontSection } from "~/types/frontSection";
|
||||
|
||||
export interface ListResponse {
|
||||
page: number;
|
||||
perPage: number;
|
||||
totalItems: number;
|
||||
totalPages: number;
|
||||
}
|
||||
|
||||
export interface PBMenuItem {
|
||||
page: number;
|
||||
page_name: string;
|
||||
perPage: number;
|
||||
totalItems: number;
|
||||
totalPages: number;
|
||||
is_root: boolean;
|
||||
is_default: boolean;
|
||||
id_page: string;
|
||||
id: string;
|
||||
id_parent: string;
|
||||
url: string;
|
||||
name: string;
|
||||
link_rewrite: string;
|
||||
active: boolean;
|
||||
collectionId: string;
|
||||
collectionName: string;
|
||||
created: string;
|
||||
link_title: string;
|
||||
meta_description: string;
|
||||
meta_title: string;
|
||||
position_id: number;
|
||||
updated: string;
|
||||
}
|
||||
|
||||
export interface PBFooterItem {
|
||||
id: string;
|
||||
id_lang: string;
|
||||
address: string;
|
||||
phone: string;
|
||||
email: string;
|
||||
contact_info: Array<{
|
||||
field: keyof PBFooterItem;
|
||||
title: string;
|
||||
}>;
|
||||
data: Array<{
|
||||
title: string;
|
||||
items: Array<string>;
|
||||
}>;
|
||||
company_info: Array<{
|
||||
data: string;
|
||||
title: string;
|
||||
}>;
|
||||
}
|
||||
|
||||
// export interface PBPageItem {
|
||||
// collectionId: string;
|
||||
// collectionName: string;
|
||||
// component_name: string;
|
||||
// id: string;
|
||||
// image_collection: string;
|
||||
// page_created: string;
|
||||
// page_id: string;
|
||||
// page_name: string;
|
||||
// page_section_id_position: number;
|
||||
// page_updated: string;
|
||||
// section_id: string;
|
||||
// section_img: string[];
|
||||
// section_lang_created: string;
|
||||
// section_lang_data: SectionLangData;
|
||||
// section_lang_id_lang: string;
|
||||
// section_name: string;
|
||||
// }
|
||||
|
||||
// export interface SectionLangData {
|
||||
// title: string;
|
||||
// description: string;
|
||||
// button: string;
|
||||
// button_call: string;
|
||||
// }
|
||||
|
||||
export interface UIMenuItem extends PBMenuItem {
|
||||
children?: UIMenuItem[];
|
||||
}
|
||||
|
||||
export interface MenuListResponse extends ListResponse {
|
||||
items: PBMenuItem[];
|
||||
}
|
||||
|
||||
export interface FooterListResponse extends ListResponse {
|
||||
items: PBFooterItem[];
|
||||
}
|
||||
|
||||
export type componentsListType = {
|
||||
name: string;
|
||||
component: FrontSection;
|
||||
componentInstance: DefineComponent;
|
||||
// data: unknown;
|
||||
};
|
||||
|
||||
// menuStore
|
||||
// export type CountryList = {
|
||||
// call_prefix: string;
|
||||
// currency_iso_code: string;
|
||||
// iso_code: string;
|
||||
// name: string;
|
||||
// }
|
||||
|
||||
export type Countries = {
|
||||
call_prefix: string;
|
||||
currency_iso_code: string;
|
||||
iso_code: string;
|
||||
name: string;
|
||||
};
|
||||
|
||||
export type PartnersList = {
|
||||
@ -118,17 +15,6 @@ export type PartnersList = {
|
||||
total: number;
|
||||
};
|
||||
|
||||
export type Currencies = {
|
||||
iso_code: string;
|
||||
name: string;
|
||||
UpdatedAt: string;
|
||||
iso_code_num: number;
|
||||
precision: number;
|
||||
sign: string;
|
||||
active: boolean;
|
||||
suffix: boolean;
|
||||
};
|
||||
|
||||
export type FeatureValue = {
|
||||
parent: number;
|
||||
products_with_value: number;
|
||||
@ -170,6 +56,7 @@ export interface Country {
|
||||
name: string;
|
||||
}
|
||||
|
||||
|
||||
export interface Currency {
|
||||
iso_code: string;
|
||||
name: string;
|
||||
@ -181,11 +68,37 @@ export interface Currency {
|
||||
suffix: boolean;
|
||||
}
|
||||
|
||||
export interface Language {
|
||||
id: number
|
||||
name: string
|
||||
iso_code: string
|
||||
lang_code: string
|
||||
date_format: string
|
||||
date_format_short: string
|
||||
rtl: boolean
|
||||
is_default: boolean
|
||||
active: boolean
|
||||
}
|
||||
|
||||
export interface CookieData { country: Country, currency: Currency, language: Language }
|
||||
|
||||
|
||||
export interface CartItem {
|
||||
cart_item_id: number;
|
||||
link_rewrite: string;
|
||||
name: string;
|
||||
picture_uuid: string;
|
||||
product_id: number;
|
||||
quantity: number;
|
||||
single_item_price: number;
|
||||
total_price: number;
|
||||
}
|
||||
export interface UserCart {
|
||||
cart_items: CartItem[];
|
||||
id: number;
|
||||
checkout_in_progress: boolean;
|
||||
total_value: number;
|
||||
currency_iso: string;
|
||||
total_value: number;
|
||||
}
|
||||
|
||||
export interface GenericResponse<Data> {
|
||||
|
Reference in New Issue
Block a user