3 Commits

Author SHA1 Message Date
e0a1e35771 Merge pull request 'calculator and other cleaning' (#4) from linter into main
Reviewed-on: #4
2025-07-04 20:45:56 +00:00
0bab1d83a1 calculator and other cleaning 2025-07-04 22:40:27 +02:00
a2db817133 pre registration 2025-07-04 16:01:44 +02:00
23 changed files with 916 additions and 490 deletions

View File

@ -2,9 +2,9 @@
<div ref="dropdownRef"> <div ref="dropdownRef">
<div class="relative cursor-pointer" @click="openCart = !openCart"> <div class="relative cursor-pointer" @click="openCart = !openCart">
<i class="uil uil-shopping-cart text-[31px]"></i> <i class="uil uil-shopping-cart text-[31px]"></i>
<div v-if="checkoutStore.products && checkoutStore.products.length > 0" <div v-if="checkoutStore.totalNumberOfProducts"
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"> 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">
{{ checkoutStore.products.length }} {{ checkoutStore.totalNumberOfProducts }}
</div> </div>
</div> </div>
<div v-if="openCart" <div v-if="openCart"
@ -69,10 +69,10 @@
</div> </div>
<UiButtonArrow class="w-full" type="fill" :arrow="true" :full="true" @click="() => { <UiButtonArrow class="w-full" type="fill" :arrow="true" :full="true" @click="() => {
if (userStore.isLogged) { if (userStore.isLogged) {
menuStore.navigateToItem(menuStore.menuItems?.find((item) => item.id === 12)) menuStore.navigateToItem(menuStore.menuItems?.find((item: any) => item.id === 12))
} }
else { else {
menuStore.navigateToItem(menuStore.menuItems?.find((item) => item.id === 11)) menuStore.navigateToItem(menuStore.menuItems?.find((item: any) => item.id === 11))
} }
openCart = false openCart = false
}"> }">

View File

@ -4,38 +4,26 @@
<div class="w-full border-b border-border"> <div class="w-full border-b border-border">
<UiContainer class="relative"> <UiContainer class="relative">
<div class="hidden h-[120px] w-full items-center gap-[145px] xl:flex"> <div class="hidden h-[120px] w-full items-center gap-[145px] xl:flex">
<ul <ul class="flex items-center justify-between gap-5 whitespace-nowrap w-full">
class="flex items-center justify-between gap-5 whitespace-nowrap w-full" <li v-for="(item, index) in menuStore.menu" :key="item.id" :class="[
>
<li
v-for="(item, index) in menuStore.menu"
:key="item.id"
:class="[
'hover:text-accent-green-light dark:hover:text-accent-green-dark cursor-pointer text-lg transition-all text-inter', '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() route.params.id == item.id.toString()
? 'text-accent-green-light dark:text-accent-green-dark font-bold underline' ? 'text-accent-green-light dark:text-accent-green-dark font-bold underline'
: false, : false,
]" ]" @click="menuStore.navigateToItem(item)">
@click="menuStore.navigateToItem(item)"
>
0{{ index + 1 }} <br> 0{{ index + 1 }} <br>
{{ item.front_menu_lang[0].name }} {{ item.front_menu_lang[0].name }}
</li> </li>
</ul> </ul>
<ClientOnly v-if="!colorMode?.forced"> <ClientOnly v-if="!colorMode?.forced">
<img <img class="cursor-pointer" :src="isDark ? '/logo-dark.svg' : '/logo.svg'" alt="logo"
class="cursor-pointer" @click="menuStore.navigateToItem()">
:src="isDark ? '/logo-dark.svg' : '/logo.svg'"
alt="logo"
@click="menuStore.navigateToItem()"
>
</ClientOnly> </ClientOnly>
<div class="w-full flex items-center justify-between"> <div class="w-full flex items-center justify-between">
<div class="flex items-center gap-[30px]"> <div class="flex items-center gap-[30px]">
<div> <div>
<i v-if="!userStore.isLogged" <i v-if="!userStore.isLogged" class="uil uil-user text-[31px] cursor-pointer"
class="uil uil-user text-[31px] cursor-pointer" @click="menuStore.navigateToItem(menuStore.menuItems?.find((item:any) => item.id === 11))"></i>
@click="menuStore.navigateToItem(menuStore.menuItems?.find((item) => item.id === 11))"></i>
<div v-else class="py-[6px] px-3 border border-block rounded-sm"> <div v-else class="py-[6px] px-3 border border-block rounded-sm">
{{ userStore.user }} {{ userStore.user }}
</div> </div>
@ -47,15 +35,12 @@
<CountryCurrencySelector /> <CountryCurrencySelector />
</div> </div>
<ThemeSwitcher /> <ThemeSwitcher />
<button <button :class="[
:class="[
'cursor-pointer transition-all text-inter whitespace-nowrap', 'cursor-pointer transition-all text-inter whitespace-nowrap',
route.params.id == '5' route.params.id == '5'
? 'text-accent-green-light dark:text-accent-green-dark font-bold pb-1 border-b-2' ? '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', : 'hover:bg-button-hover bg-button text-white font-medium rounded-xl px-6 py-3',
]" ]" @click="menuStore.navigateToShop">
@click="menuStore.navigateToShop"
>
{{ $t("eshop") }} {{ $t("eshop") }}
</button> </button>
</div> </div>
@ -64,35 +49,19 @@
</div> </div>
<!-- md --> <!-- md -->
<div <div class="hidden w-full md:flex md:flex-col xl:hidden items-center justify-center">
class="hidden w-full md:flex md:flex-col xl:hidden items-center justify-center"
>
<div class="w-full border-border border-b"> <div class="w-full border-border border-b">
<UiContainer class="h-[116px] flex items-center justify-between"> <UiContainer class="h-[116px] flex items-center justify-between">
<ClientOnly v-if="!colorMode?.forced"> <ClientOnly v-if="!colorMode?.forced">
<img <img class="cursor-pointer" :src="isDark ? '/logo-dark.svg' : '/logo.svg'" alt="logo"
class="cursor-pointer" @click="menuStore.navigateToItem()">
:src="isDark ? '/logo-dark.svg' : '/logo.svg'"
alt="logo"
@click="menuStore.navigateToItem()"
>
</ClientOnly> </ClientOnly>
<div class="flex items-center gap-6"> <div class="flex items-center gap-6">
<div class="flex items-center gap-[30px]"> <div class="flex items-center gap-[30px]">
<div> <div>
<i <i v-if="!userStore.isLogged" class="uil uil-user text-[31px] cursor-pointer" @click="
v-if="!userStore.isLogged" menuStore.navigateToItem(menuStore.menuItems?.find((item:any) => item.id === 11)) " />
class="uil uil-user text-[31px] cursor-pointer" <div v-else class="py-[6px] px-3 border border-block rounded-sm">
@click="
menuStore.navigateToItem(
menuStore.menuItems?.find((item) => item.id === 11),
)
"
/>
<div
v-else
class="py-[6px] px-3 border border-block rounded-sm"
>
{{ userStore.user }} {{ userStore.user }}
</div> </div>
</div> </div>
@ -103,54 +72,33 @@
<CountryCurrencySelector /> <CountryCurrencySelector />
</div> </div>
<ThemeSwitcher /> <ThemeSwitcher />
<i <i variant="subtle" block class="uil uil-apps text-[33px] cursor-pointer" @click="open = !open" />
variant="subtle"
block
class="uil uil-apps text-[33px] cursor-pointer"
@click="open = !open"
/>
</div> </div>
</UiContainer> </UiContainer>
</div> </div>
<UCollapsible <UCollapsible v-model:open="open" :ui="{ content: 'w-full' }" class="w-full">
v-model:open="open"
:ui="{ content: 'w-full' }"
class="w-full"
>
<template #content> <template #content>
<div class="w-full border-border border-b pt-6 pb-8"> <div class="w-full border-border border-b pt-6 pb-8">
<UiContainer class="flex flex-col gap-[30px]"> <UiContainer class="flex flex-col gap-[30px]">
<div <div v-for="(item, index) in menuStore.menu" :key="index" :class="[
v-for="(item, index) in menuStore.menu"
:key="index"
:class="[
'flex items-center justify-between transition-all hover:text-accent-green-light dark:hover:text-accent-green-dark cursor-pointer', '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 route.params.slug === item.front_menu_lang[0].link_rewrite
&& 'text-accent-green-light dark:text-accent-green-dark font-bold underline', && 'text-accent-green-light dark:text-accent-green-dark font-bold underline',
]" ]" @click="
@click="
() => { () => {
menuStore.navigateToItem(item); menuStore.navigateToItem(item);
open = false; open = false;
} }
" ">
>
<div class="leading-[70%] text-inter"> <div class="leading-[70%] text-inter">
<span class="mr-4">0{{ index + 1 }}</span> <span class="mr-4">0{{ index + 1 }}</span>
{{ item.front_menu_lang[0].name }} {{ item.front_menu_lang[0].name }}
</div> </div>
<!-- <i class="uil uil-arrow-up-right text-[35px]"></i> --> <!-- <i class="uil uil-arrow-up-right text-[35px]"></i> -->
<svg <svg width="20" height="20" viewBox="0 0 26 26" fill="none" xmlns="http://www.w3.org/2000/svg">
width="20"
height="20"
viewBox="0 0 26 26"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path <path
d="M25.1274 1.87258C25.1274 1.3203 24.6797 0.872582 24.1274 0.872584L15.1274 0.872583C14.5751 0.872583 14.1274 1.3203 14.1274 1.87258C14.1274 2.42487 14.5751 2.87258 15.1274 2.87258L23.1274 2.87258L23.1274 10.8726C23.1274 11.4249 23.5751 11.8726 24.1274 11.8726C24.6797 11.8726 25.1274 11.4249 25.1274 10.8726L25.1274 1.87258ZM1.5 24.5L2.20711 25.2071L24.8345 2.57969L24.1274 1.87258L23.4203 1.16548L0.792893 23.7929L1.5 24.5Z" d="M25.1274 1.87258C25.1274 1.3203 24.6797 0.872582 24.1274 0.872584L15.1274 0.872583C14.5751 0.872583 14.1274 1.3203 14.1274 1.87258C14.1274 2.42487 14.5751 2.87258 15.1274 2.87258L23.1274 2.87258L23.1274 10.8726C23.1274 11.4249 23.5751 11.8726 24.1274 11.8726C24.6797 11.8726 25.1274 11.4249 25.1274 10.8726L25.1274 1.87258ZM1.5 24.5L2.20711 25.2071L24.8345 2.57969L24.1274 1.87258L23.4203 1.16548L0.792893 23.7929L1.5 24.5Z"
fill="currentColor" fill="currentColor" />
/>
</svg> </svg>
</div> </div>
</UiContainer> </UiContainer>
@ -160,88 +108,51 @@
</div> </div>
<!-- sm --> <!-- sm -->
<div <div class="hidden w-full items-center justify-between sm:flex sm:flex-col md:hidden">
class="hidden w-full items-center justify-between sm:flex sm:flex-col md:hidden"
>
<div class="w-full border-border border-b"> <div class="w-full border-border border-b">
<UiContainer class="h-[84px] flex items-center justify-between"> <UiContainer class="h-[84px] flex items-center justify-between">
<ClientOnly v-if="!colorMode?.forced"> <ClientOnly v-if="!colorMode?.forced">
<img <img class="cursor-pointer" :src="isDark ? '/logo-dark.svg' : '/logo.svg'" alt="logo"
class="cursor-pointer" @click="menuStore.navigateToItem()">
:src="isDark ? '/logo-dark.svg' : '/logo.svg'"
alt="logo"
@click="menuStore.navigateToItem()"
>
</ClientOnly> </ClientOnly>
<div class="flex items-center gap-6"> <div class="flex items-center gap-6">
<div class="flex items-center gap-[30px]"> <div class="flex items-center gap-[30px]">
<div> <div>
<i <i v-if="!userStore.isLogged" class="uil uil-user text-[31px] cursor-pointer" @click="
v-if="!userStore.isLogged" menuStore.navigateToItem(menuStore.menuItems?.find((item:any) => item.id === 11)) " />
class="uil uil-user text-[31px] cursor-pointer" <div v-else class="py-[6px] px-3 border border-block rounded-sm">
@click="
menuStore.navigateToItem(
menuStore.menuItems?.find((item) => item.id === 11),
)
"
/>
<div
v-else
class="py-[6px] px-3 border border-block rounded-sm"
>
{{ userStore.user }} {{ userStore.user }}
</div> </div>
</div> </div>
<CartPopup /> <CartPopup />
</div> </div>
<i <i variant="subtle" block class="uil uil-apps text-[30px] cursor-pointer" @click="open = !open" />
variant="subtle"
block
class="uil uil-apps text-[30px] cursor-pointer"
@click="open = !open"
/>
</div> </div>
</UiContainer> </UiContainer>
</div> </div>
<UCollapsible <UCollapsible v-model:open="open" :ui="{ content: 'w-full' }" class="w-full">
v-model:open="open"
:ui="{ content: 'w-full' }"
class="w-full"
>
<template #content> <template #content>
<div class="w-full border-border border-b pt-6 pb-8"> <div class="w-full border-border border-b pt-6 pb-8">
<UiContainer class="flex flex-col gap-[30px]"> <UiContainer class="flex flex-col gap-[30px]">
<div <div v-for="(item, index) in menuStore.menu" :key="index" :class="[
v-for="(item, index) in menuStore.menu"
:key="index"
:class="[
'flex items-center justify-between transition-all hover:text-accent-green-light dark:hover:text-accent-green-dark cursor-pointer', '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 route.params.slug === item.front_menu_lang[0].link_rewrite
&& 'text-accent-green-light dark:text-accent-green-dark font-bold underline', && 'text-accent-green-light dark:text-accent-green-dark font-bold underline',
]" ]" @click="
@click="
() => { () => {
menuStore.navigateToItem(item); menuStore.navigateToItem(item);
open = false; open = false;
} }
" ">
>
<div class="leading-[70%] text-inter"> <div class="leading-[70%] text-inter">
<span class="mr-4">0{{ index + 1 }}</span> <span class="mr-4">0{{ index + 1 }}</span>
{{ item.front_menu_lang[0].name }} {{ item.front_menu_lang[0].name }}
</div> </div>
<!-- <i class="uil uil-arrow-up-right text-[35px]"></i> --> <!-- <i class="uil uil-arrow-up-right text-[35px]"></i> -->
<svg <svg width="20" height="20" viewBox="0 0 26 26" fill="none" xmlns="http://www.w3.org/2000/svg">
width="20"
height="20"
viewBox="0 0 26 26"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path <path
d="M25.1274 1.87258C25.1274 1.3203 24.6797 0.872582 24.1274 0.872584L15.1274 0.872583C14.5751 0.872583 14.1274 1.3203 14.1274 1.87258C14.1274 2.42487 14.5751 2.87258 15.1274 2.87258L23.1274 2.87258L23.1274 10.8726C23.1274 11.4249 23.5751 11.8726 24.1274 11.8726C24.6797 11.8726 25.1274 11.4249 25.1274 10.8726L25.1274 1.87258ZM1.5 24.5L2.20711 25.2071L24.8345 2.57969L24.1274 1.87258L23.4203 1.16548L0.792893 23.7929L1.5 24.5Z" d="M25.1274 1.87258C25.1274 1.3203 24.6797 0.872582 24.1274 0.872584L15.1274 0.872583C14.5751 0.872583 14.1274 1.3203 14.1274 1.87258C14.1274 2.42487 14.5751 2.87258 15.1274 2.87258L23.1274 2.87258L23.1274 10.8726C23.1274 11.4249 23.5751 11.8726 24.1274 11.8726C24.6797 11.8726 25.1274 11.4249 25.1274 10.8726L25.1274 1.87258ZM1.5 24.5L2.20711 25.2071L24.8345 2.57969L24.1274 1.87258L23.4203 1.16548L0.792893 23.7929L1.5 24.5Z"
fill="currentColor" fill="currentColor" />
/>
</svg> </svg>
</div> </div>
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
@ -273,74 +184,41 @@
<div class="w-full border-border border-b"> <div class="w-full border-border border-b">
<UiContainer class="h-[84px] flex items-center justify-between"> <UiContainer class="h-[84px] flex items-center justify-between">
<ClientOnly v-if="!colorMode?.forced"> <ClientOnly v-if="!colorMode?.forced">
<img <img class="cursor-pointer" :src="isDark ? '/logo-dark.svg' : '/logo.svg'" alt="logo"
class="cursor-pointer" @click="menuStore.navigateToItem()">
:src="isDark ? '/logo-dark.svg' : '/logo.svg'"
alt="logo"
@click="menuStore.navigateToItem()"
>
</ClientOnly> </ClientOnly>
<div class="flex items-center gap-6"> <div class="flex items-center gap-6">
<div> <div>
<i <i class="uil uil-user text-[30px] cursor-pointer" @click=" !userStore.isLogged && menuStore.navigateToItem(menuStore.menuItems?.find((item:any) => item.id === 11)) " />
class="uil uil-user text-[30px] cursor-pointer"
@click="
!userStore.isLogged
&& menuStore.navigateToItem(
menuStore.menuItems?.find((item) => item.id === 11),
)
"
/>
</div> </div>
<CartPopup /> <CartPopup />
<i <i variant="subtle" block class="uil uil-apps text-[30px] cursor-pointer" @click="open = !open" />
variant="subtle"
block
class="uil uil-apps text-[30px] cursor-pointer"
@click="open = !open"
/>
</div> </div>
</UiContainer> </UiContainer>
</div> </div>
<UCollapsible <UCollapsible v-model:open="open" :ui="{ content: 'w-full' }" class="w-full">
v-model:open="open"
:ui="{ content: 'w-full' }"
class="w-full"
>
<template #content> <template #content>
<div class="w-full border-border border-b pt-6 pb-8"> <div class="w-full border-border border-b pt-6 pb-8">
<UiContainer class="flex flex-col gap-[30px]"> <UiContainer class="flex flex-col gap-[30px]">
<div <div v-for="(item, index) in menuStore.menu" :key="index" :class="[
v-for="(item, index) in menuStore.menu"
:key="index"
:class="[
'flex items-center justify-between transition-all hover:text-accent-green-light dark:hover:text-accent-green-dark cursor-pointer', '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 route.params.slug === item.front_menu_lang[0].link_rewrite
&& 'text-accent-green-light dark:text-accent-green-dark font-bold underline', && 'text-accent-green-light dark:text-accent-green-dark font-bold underline',
]" ]" @click="
@click="
() => { () => {
menuStore.navigateToItem(item); menuStore.navigateToItem(item);
open = false; open = false;
} }
" ">
>
<div class="leading-[70%] text-inter"> <div class="leading-[70%] text-inter">
<span class="mr-4">0{{ index + 1 }}</span> <span class="mr-4">0{{ index + 1 }}</span>
{{ item.front_menu_lang[0].name }} {{ item.front_menu_lang[0].name }}
</div> </div>
<!-- <i class="uil uil-arrow-up-right text-[35px]"></i> --> <!-- <i class="uil uil-arrow-up-right text-[35px]"></i> -->
<svg <svg width="20" height="20" viewBox="0 0 26 26" fill="none" xmlns="http://www.w3.org/2000/svg">
width="20"
height="20"
viewBox="0 0 26 26"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path <path
d="M25.1274 1.87258C25.1274 1.3203 24.6797 0.872582 24.1274 0.872584L15.1274 0.872583C14.5751 0.872583 14.1274 1.3203 14.1274 1.87258C14.1274 2.42487 14.5751 2.87258 15.1274 2.87258L23.1274 2.87258L23.1274 10.8726C23.1274 11.4249 23.5751 11.8726 24.1274 11.8726C24.6797 11.8726 25.1274 11.4249 25.1274 10.8726L25.1274 1.87258ZM1.5 24.5L2.20711 25.2071L24.8345 2.57969L24.1274 1.87258L23.4203 1.16548L0.792893 23.7929L1.5 24.5Z" d="M25.1274 1.87258C25.1274 1.3203 24.6797 0.872582 24.1274 0.872584L15.1274 0.872583C14.5751 0.872583 14.1274 1.3203 14.1274 1.87258C14.1274 2.42487 14.5751 2.87258 15.1274 2.87258L23.1274 2.87258L23.1274 10.8726C23.1274 11.4249 23.5751 11.8726 24.1274 11.8726C24.6797 11.8726 25.1274 11.4249 25.1274 10.8726L25.1274 1.87258ZM1.5 24.5L2.20711 25.2071L24.8345 2.57969L24.1274 1.87258L23.4203 1.16548L0.792893 23.7929L1.5 24.5Z"
fill="currentColor" fill="currentColor" />
/>
</svg> </svg>
</div> </div>
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">

View File

@ -2,52 +2,26 @@
<div class="border-t border-border pt-[75px]"> <div class="border-t border-border pt-[75px]">
<UiContainer class="flex flex-col gap-24"> <UiContainer class="flex flex-col gap-24">
<div <div
class="grid grid-cols-1 md:grid-cols-2 gap-[75px] xl:gap-0 xl:grid-cols-none xl:grid-flow-col auto-cols-max justify-between" class="grid grid-cols-1 md:grid-cols-2 gap-[75px] xl:gap-0 xl:grid-cols-none xl:grid-flow-col auto-cols-max justify-between">
> <div class="flex flex-col gap-[25px] sm:gap-8 max-w-[280px]">
<div> <div v-for="(item, key) in contact" :key="key">
<div <h3 v-if="key == 'header'" class="h4-uppercase-bold-inter">
v-for="(item, key) in contact"
:key="key"
class="flex flex-col gap-[25px] sm:gap-8 max-w-[280px]"
>
<h3 v-if="key == 'header'"
class="h4-uppercase-bold-inter"
>
{{ item }} {{ item }}
</h3> </h3>
<div v-else <div v-else class="transition-all text-inter">
class="transition-all text-inter"
>
{{ item }} {{ item }}
</div> </div>
</div> </div>
<div class="text-red-500"> <a href="/lei_certificate_aurrie.pdf" target="_blank" rel="noopener noreferrer">{{ $t("footer_lei") }}</a>
arina - doadj tu icone i style
</div>
<a
href="/lei_certificate_aurrie.pdf"
target="_blank"
rel="noopener noreferrer"
>{{ $t("Footer.Lei") }}</a>
</div> </div>
<div <div v-for="(section, index) in docs" :key="index" class="flex flex-col gap-[25px] sm:gap-8 max-w-[280px]">
v-for="(section, index) in docs"
:key="index"
class="flex flex-col gap-[25px] sm:gap-8 max-w-[280px]"
>
<h3 class="h4-uppercase-bold-inter"> <h3 class="h4-uppercase-bold-inter">
{{ section.translation }} {{ section.translation }}
</h3> </h3>
<div v-for="(item, key) in section.data" <div v-for="(item, key) in section.data" :key="key">
:key="key" <div class="cursor-pointer hover:text-text-light/80 dark:hover:text-text-dark/70 transition-all text-inter">
> <a target="_blank" :href="`/api/public/document/${item.name}`">{{
<div
class="cursor-pointer hover:text-text-light/80 dark:hover:text-text-dark/70 transition-all text-inter"
>
<a target="_blank"
:href="`/api/public/document/${item.name}`"
>{{
item.translation item.translation
}}</a> }}</a>
</div> </div>
@ -56,12 +30,8 @@
</div> </div>
<ClientOnly v-if="!colorMode?.forced"> <ClientOnly v-if="!colorMode?.forced">
<img <img class="cursor-pointer w-[70%] sm:w-[50%] xl:w-[30%]"
class="cursor-pointer w-[70%] sm:w-[50%] xl:w-[30%]" :src="isDark ? '/logo-footer-dark.svg' : '/logo-footer.svg'" alt="logo" @click="menuStore.navigateToItem()">
:src="isDark ? '/logo-footer-dark.svg' : '/logo-footer.svg'"
alt="logo"
@click="menuStore.navigateToItem()"
>
</ClientOnly> </ClientOnly>
</UiContainer> </UiContainer>
</div> </div>

View File

@ -0,0 +1,248 @@
<template>
<UiContainer class="space-25-75">
<div>
<div class="flex flex-col w-full">
<div class="relative flex flex-col">
<h1 class="text-3xl font-bold">
{{ component.front_section_lang.at(0).data.drawing_up_a_proposal_for_asave_contract }}
</h1>
<div class="flex flex-wrap flex-1">
<!-- left -->
<div class="w-full md:w-1/2 p-4">
<h3 class="w-full border-b my-2">
{{ component.front_section_lang.at(0).data.simulation_of_the_contract_proposal }}
</h3>
<p>{{ component.front_section_lang.at(0).data.monthly_savings }}</p>
<div class="my-8">
<div class="text-2xl">
{{ formater.price(store.monthlySavings) }}
</div>
<input v-model="store.monthlySavings" type="range" :max="store.getMaxAmount" :min="store.getMinAmount" class="w-full accent-button cursor-pointer" @change="investmentStore.getCalculator()">
</div>
<div class="my-8">
<div class="text-2xl">
{{ store.storagePeriod }}
</div>
<input v-model="store.storagePeriod" type="range" :max="investmentStore.maxYear" :min="investmentStore.minYear" class="w-full accent-button cursor-pointer" @change="investmentStore.getCalculator()">
</div>
</div>
<!-- right -->
<div class="w-full md:w-1/2 p-4">
<h3 class="w-full border-b my-2">
{{ component.front_section_lang.at(0).data.details_of_the_contract_proposal }}
</h3>
<p class="flex justify-between my-4">
<span>{{ component.front_section_lang.at(0).data.current_price_per_bar }}</span>
<span>{{ formater.price(investmentStore.calculationResult.calculator_output.investment_piece.price) }}</span>
</p>
<p class="flex justify-between my-4">
<span>{{ component.front_section_lang.at(0).data.money_for_spend }}</span>
<span>{{ formater.price(investmentStore.calculationResult.calculator_output.money_spent) }}</span>
</p>
<p class="flex justify-between my-4">
<span>{{ component.front_section_lang.at(0).data.weight_per_bar }}</span>
<span>{{ getWeight }}</span>
</p>
<p class="flex justify-between my-4">
<span>{{ component.front_section_lang.at(0).data.count }}</span>
<span>{{ investmentStore.calculationResult.calculator_output.max_pieces_in_package }}</span>
</p>
<p class="flex justify-between my-4">
<span>{{ component.front_section_lang.at(0).data.contract_type }}</span>
<span>50/50</span>
</p>
<p class="flex justify-between my-4">
<span>{{ component.front_section_lang.at(0).data.special_fee }}</span>
<span>{{ formater.price(investmentStore.calculationResult.calculator_output.total_input_price_increase) }}</span>
</p>
</div>
</div>
</div>
<!-- next section -->
<div class="flex flex-wrap">
<!-- left -->
<div class="w-full md:w-1/2 p-4">
<h3 class="w-full border-b my-2">
{{ component.front_section_lang.at(0).data.graphic_simulation_of_future_profits }}
</h3>
<p class="my-4 md:my-12">
<img :src="`data:image/svg+xml;base64,${investmentStore.calculationResult.chart}`" alt="" class="bg-white rounded-2xl p-2">
</p>
</div>
<!-- right -->
<div class="w-full md:w-1/2 p-4">
<h3 class="w-full border-b my-2">
{{ component.front_section_lang.at(0).data.summary_of_the_contract_proposal }}
</h3>
<p class="flex justify-between my-4">
<span>{{ component.front_section_lang.at(0).data.save }}</span>
<span>{{ component.front_section_lang.at(0).data.expected_value_of_savings }}</span>
</p>
<p class="flex justify-between my-4">
<span></span>
<span class="font-bold text-2xl">{{ formater.price(investmentStore.calculationResult.calculator_output.total_investement_value)
}}</span>
</p>
<div class="flex flex-col items-center">
<img :src="`/api/public/file/${investmentStore.calculationResult.calculator_output.investment_piece.cover_picture_uuid}_m.webp`" :alt="investmentStore.calculationResult.calculator_output.investment_piece.name" class="object-contain object-center w-48 max-h-64">
<span class="my-2 text-sm">{{ investmentStore.calculationResult.calculator_output.investment_piece.name }}</span>
</div>
</div>
</div>
</div>
<hr class="my-4">
<div class="flex w-full flex-wrap justify-center md:justify-end mt-8">
<a :href="getPrintLink" target="_blank" class="my-2 mx-4">
<UiButtonArrow :arrow="true" type="fill" class="mx-auto sm:m-0">
{{ component.front_section_lang.at(0).data.print }}
</UiButtonArrow>
</a>
<nuxt-link :to="getInvestLink" class="my-2 mx-4">
<UiButtonArrow :arrow="true" type="fill" class="mx-auto sm:m-0">
{{ component.front_section_lang.at(0).data.invest }}
</UiButtonArrow>
</nuxt-link>
</div>
</div>
</UiContainer>
</template>
<script setup lang="ts">
defineProps<{
component: {
id: number
name: string
img: string[]
component_name: string
is_no_lang: boolean
page_name: string
front_section_lang: {
data: {
drawing_up_a_proposal_for_asave_contract: string
simulation_of_the_contract_proposal: string
monthly_savings: string
details_of_the_contract_proposal: string
current_price_per_bar: string
money_for_spend: string
weight_per_bar: string
count: string
contract_type: string
special_fee: string
graphic_simulation_of_future_profits: string
summary_of_the_contract_proposal: string
save: string
expected_value_of_savings: string
print: string
invest: string
}
id_front_section: number
id_lang: number
}[]
}
}>()
const investmentStore = useInvestmentStore()
const store = useStore()
const formater = useFormater(useNuxtApp())
const userStore = useUserStore()
const router = useRouter()
const menuStore = useMenuStore()
await investmentStore.getCalculator()
const getWeight = computed(() => {
return investmentStore.calculationResult.calculator_output.investment_piece.features.find(feature => feature.feature_id === 1)?.value
})
const getPrintLink = computed(() => {
const query = new URLSearchParams({
monthly_deposit: String(store.monthlySavings),
years: String(store.storagePeriod),
grid: 'false',
legend: 'false',
title: 'false',
ingots_bought_dots: 'true',
draw_linear: 'true',
annotations: 'false',
show_real_value: 'false',
series_stroke_width: '1',
})
return `/api/public/plan-prediction/easy/plan-proposal?${query.toString()}`
})
const getInvestLink = computed(() => {
if (userStore.isLogged) {
return { path: '/golden-panel/save-contract' }
}
return { name: router.currentRoute.value.name, params: { id: menuStore.getLoginMenu()?.id, slug: menuStore.getLoginMenu()?.front_menu_lang.at(0)?.link_rewrite }, query: { to: btoa('/golden-panel/save-contract') } }
})
/*
INSERT INTO `front_page` (`created_at`, `updated_at`, `name`, `is_default`, `id`) VALUES ('2025-06-25 11:07:28.000','2025-06-25 11:07:28.000','investment-calculator','0','16');
INSERT INTO `front_menu` (`created_at`, `updated_at`, `active`, `position_id`, `id_front_page`, `is_default`, `is_root`, `id`) VALUES ('2025-06-25 11:07:28.000','2025-06-25 11:07:28.000','1','1','16','0','0','16');
INSERT INTO `front_menu_lang` (`name`, `id_lang`, `id_front_menu`, `link_rewrite`) VALUES ('investment','2','16','Investment');
INSERT INTO `front_menu_lang` (`link_rewrite`, `id_front_menu`, `id_lang`, `name`) VALUES ('inwestycja','16','1','Inwestycja');
INSERT INTO `front_menu_lang` (`name`, `id_lang`, `id_front_menu`, `link_rewrite`) VALUES ('investice','3','16','Investice');
INSERT INTO `front_section` (`id`, `created_at`, `updated_at`, `name`, `img`, `component_name`, `is_no_lang`) VALUES ('35','2025-06-25 11:07:28.000','2025-06-25 11:07:28.000','investment-calculator','[]','InvestmentBlock','0');
INSERT INTO `front_page_section` (`id_front_page`, `id_position`, `id_front_section`) VALUES ('16','1','35');
INSERT INTO `front_page_section` (`id_front_page`, `id_position`, `id_front_section`) VALUES ('16','2','4');
INSERT INTO `front_section_lang` (`data`, `id_front_section`, `id_lang`) VALUES ('{
"drawing_up_a_proposal_for_asave_contract": "Przygotowanie propozycji umowy SAVE",
"simulation_of_the_contract_proposal": "Symulacja propozycji umowy",
"monthly_savings": "Miesięczne oszczędności",
"details_of_the_contract_proposal": "Szczegóły propozycji umowy",
"current_price_per_bar": "Aktualna cena za sztabkę",
"money_for_spend": "Kwota do wydania",
"weight_per_bar": "Waga jednej sztabki",
"count": "Liczba",
"contract_type": "Typ umowy",
"special_fee": "Opłata specjalna",
"graphic_simulation_of_future_profits": "Graficzna symulacja przyszłych zysków",
"summary_of_the_contract_proposal": "Podsumowanie propozycji umowy",
"save": "Zaoszczędzona kwota",
"expected_value_of_savings": "Oczekiwana wartość oszczędności",
"print": "Drukuj",
"invest": "Zainwestuj"
}', '35', '1');
INSERT INTO `front_section_lang` (`data`, `id_front_section`, `id_lang`) VALUES ('{
"drawing_up_a_proposal_for_asave_contract": "Drawing up a proposal for a SAVE contract",
"simulation_of_the_contract_proposal": "Simulation of the contract proposal",
"monthly_savings": "Monthly savings",
"details_of_the_contract_proposal": "Details of the contract proposal",
"current_price_per_bar": "Current price per bar",
"money_for_spend": "Money for spend",
"weight_per_bar": "Weight per bar",
"count": "Count",
"contract_type": "Contract type",
"special_fee": "Special fee",
"graphic_simulation_of_future_profits": "Graphic simulation of future profits",
"summary_of_the_contract_proposal": "Summary of the contract proposal",
"save": "Saved Amount",
"expected_value_of_savings": "Expected value of savings",
"print": "Print",
"invest": "Invest"
}', '35', '2');
INSERT INTO `front_section_lang` (`data`, `id_front_section`, `id_lang`) VALUES ('{
"drawing_up_a_proposal_for_asave_contract": "Vypracování návrhu smlouvy SAVE",
"simulation_of_the_contract_proposal": "Simulace návrhu smlouvy",
"monthly_savings": "Měsíční úspory",
"details_of_the_contract_proposal": "Podrobnosti návrhu smlouvy",
"current_price_per_bar": "Aktuální cena za slitku",
"money_for_spend": "Částka k utracení",
"weight_per_bar": "Hmotnost slitku",
"count": "Počet",
"contract_type": "Typ smlouvy",
"special_fee": "Speciální poplatek",
"graphic_simulation_of_future_profits": "Grafická simulace budoucích zisků",
"summary_of_the_contract_proposal": "Shrnutí návrhu smlouvy",
"save": "Ušetřená částka",
"expected_value_of_savings": "Očekávaná hodnota úspor",
"print": "Tisk",
"invest": "Investovat"
}', '35', '3');
*/
</script>

View File

@ -73,22 +73,11 @@
<div class="flex flex-col gap-4"> <div class="flex flex-col gap-4">
<div class="flex justify-between"> <div class="flex justify-between">
<p>{{ $t("monthly_savings") }}</p> <p>{{ $t("monthly_savings") }}</p>
<p <p class="text-accent-green-light dark:text-accent-green-dark font-bold">
class="text-accent-green-light dark:text-accent-green-dark font-bold" {{ formater.price(store.monthlySavings) }}
>
{{ store.monthlySavings }}
{{ menuStore.selectedCurrency?.sign }}
</p> </p>
</div> </div>
<input <input v-model="store.monthlySavings" type="range" :max="store.getMaxAmount" :min="store.getMinAmount" class="w-full accent-button cursor-pointer" @change="store.getCalculator()">
v-model="store.monthlySavings"
type="range"
max="600"
:min="store.minValue"
class="w-full accent-button cursor-pointer"
@mouseup="store.getCalculator()"
@touchend="store.getCalculator()"
>
</div> </div>
<div class="flex flex-col gap-4"> <div class="flex flex-col gap-4">
<div class="flex justify-between"> <div class="flex justify-between">
@ -99,14 +88,7 @@
{{ store.storagePeriod }} {{ store.storagePeriod }}
</p> </p>
</div> </div>
<input <input v-model="store.storagePeriod" type="range" max="20" class="w-full accent-button cursor-pointer" @change="store.getCalculator()">
v-model="store.storagePeriod"
type="range"
max="20"
class="w-full accent-button cursor-pointer"
@mouseup="store.getCalculator()"
@touchend="store.getCalculator()"
>
</div> </div>
</div> </div>
<div <div
@ -117,17 +99,14 @@
<h2 <h2
class="h2-bold-bounded text-accent-green-light dark:text-accent-green-dark" class="h2-bold-bounded text-accent-green-light dark:text-accent-green-dark"
> >
{{ menuStore.selectedCurrency?.sign }} {{ store.totalInvestment }} {{ formater.price(store.totalInvestment) }}
</h2> </h2>
</div> </div>
<UiButtonArrow :arrow="true" <nuxt-link :to="{ name: `id-slug___${$i18n.locale}`, params: { id: menuStore.getInvestmentCalculatorMenu()?.id, slug: menuStore.getInvestmentCalculatorMenu()?.front_menu_lang.at(0)?.link_rewrite } }">
type="fill" <UiButtonArrow :arrow="true" type="fill" class="mx-auto sm:m-0">
class="mx-auto sm:m-0" {{ component.front_section_lang[0].data.button }}
>
{{
component.front_section_lang[0].data.button
}}
</UiButtonArrow> </UiButtonArrow>
</nuxt-link>
</div> </div>
</div> </div>
</div> </div>
@ -168,9 +147,11 @@ defineProps<{
const store = useStore() const store = useStore()
const menuStore = useMenuStore() const menuStore = useMenuStore()
const { $session } = useNuxtApp()
const itemCount = ref(4) const itemCount = ref(4)
const productStore = useProductStore() const productStore = useProductStore()
const formater = useFormater(useNuxtApp())
async function updateItemCount() { async function updateItemCount() {
const width = window.innerWidth const width = window.innerWidth
@ -185,6 +166,10 @@ watch(itemCount, async () => {
await productStore.getList(itemCount.value) await productStore.getList(itemCount.value)
}) })
watch($session.cookieData, async () => {
await productStore.getList(itemCount.value)
})
onMounted(async () => { onMounted(async () => {
await updateItemCount() await updateItemCount()
window.addEventListener('resize', updateItemCount) window.addEventListener('resize', updateItemCount)

View File

@ -46,7 +46,8 @@
<p> <p>
{{ $t("no_account") }} {{ $t("no_account") }}
</p> </p>
<nuxt-link :to="{ name: `id-slug___${$i18n.locale}`, params: { id: menuStore.getRegistrationMenu()?.id, slug: menuStore.getRegistrationMenu()?.front_menu_lang.at(0)?.link_rewrite } }"> <nuxt-link
:to="{ name: `id-slug___${$i18n.locale}`, params: { id: menuStore.getPreRegistrationMenu()?.id, slug: menuStore.getPreRegistrationMenu()?.front_menu_lang.at(0)?.link_rewrite } }">
<p class="text-button cursor-pointer hover:text-button-hover"> <p class="text-button cursor-pointer hover:text-button-hover">
{{ $t("sign_up_now") }} {{ $t("sign_up_now") }}
</p> </p>

View File

@ -19,7 +19,7 @@
{{ component.front_section_lang[0].data.title_second }} {{ component.front_section_lang[0].data.title_second }}
</h3> </h3>
<div class="flex w-full items-start justify-center sm:justify-end"> <div class="flex w-full items-start justify-center sm:justify-end">
<nuxt-link :to="{ name: `id-slug___${$i18n.locale}`, params: { id: menuStore.getRegistrationMenu()?.id, slug: menuStore.getRegistrationMenu()?.front_menu_lang.at(0)?.link_rewrite } }"> <nuxt-link :to="{ name: `id-slug___${$i18n.locale}`, params: { id: menuStore.getPreRegistrationMenu()?.id, slug: menuStore.getPreRegistrationMenu()?.front_menu_lang.at(0)?.link_rewrite } }">
<UiButtonArrow :arrow="true" <UiButtonArrow :arrow="true"
type="fill" type="fill"
> >

View File

@ -43,6 +43,7 @@ defineProps<{
const menuStore = useMenuStore() const menuStore = useMenuStore()
const itemCount = ref(4) const itemCount = ref(4)
const productStore = useProductStore() const productStore = useProductStore()
const { $session } = useNuxtApp()
async function updateItemCount() { async function updateItemCount() {
const width = window.innerWidth const width = window.innerWidth
@ -57,6 +58,10 @@ watch(itemCount, async () => {
await productStore.getList(itemCount.value) await productStore.getList(itemCount.value)
}) })
watch($session.cookieData, async () => {
await productStore.getList(itemCount.value)
})
onMounted(async () => { onMounted(async () => {
await updateItemCount() await updateItemCount()
window.addEventListener('resize', updateItemCount) window.addEventListener('resize', updateItemCount)

View File

@ -0,0 +1,254 @@
<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/public/file/${component.img[0]}_l.webp')`,
backgroundSize: 'cover',
backgroundPosition: 'center',
}" />
<div class="w-full sm:w-[80%] mx-auto my-auto xl:w-full xl:px-12">
<div class="space-25-55">
<div class="flex flex-wrap-reverse gap-y-4 justify-between">
<h2 class="h2-bold-bounded">
{{ $t("sign_up") }}
</h2>
<button
class="h-[40px] sm:h-[43px] px-[10px] sm:px-[17px] border border-gray dark:border-button-disabled text-gray dark:text-button-disabled hover:bg-gray transition-all hover:text-white rounded-[8px] cursor-pointer"
@click="menuStore.navigateToItem()">
{{ $t("back_to_home") }}
</button>
</div>
<div class="space-y-[25px] sm:space-y-[30px]">
<p>{{ $t("current_information") }}</p>
<div class="grid grid-cols-1 md:grid-cols-2 gap-[30px]">
<CheckoutInput :id="1" v-model="user.data.name" :validation="nameValidation"
:validation-text="$t('enter_correct_data')" :placeholder="$t('first_name')">
{{ $t("first_name") }}
</CheckoutInput>
<CheckoutInput :id="1" v-model="user.data.surname" :validation="surnameValidation"
:validation-text="$t('enter_correct_data')" :placeholder="$t('last_name')">
{{ $t("last_name") }}
</CheckoutInput>
<CheckoutInput :id="1" v-model="user.data.email" :validation="emailValidation"
:validation-text="$t('enter_correct_data')" :placeholder="$t('email')">
{{ $t("email") }}
</CheckoutInput>
<div ref="dropdownRef" class="space-y-[15px]">
<p class="pl-6">
{{ $t("phone") }}
</p>
<div>
<div class="flex items-center border border-block rounded-lg">
<div
class="relative z-50 bg-inherit ring-0 cursor-pointer focus:ring-0 outline-none focus-visible:ring-0">
<div class="px-[25px]" @click="dropCountry = !dropCountry">
<div
class="flex items-center gap-2 text-sm sm:text-xl uppercase text-text-light dark:text-text-dark">
<span :class="[dropCountry && 'rotate-180', 'transition-all']">
<i class="uil uil-angle-down text-2xl font-light cursor-pointer" /></span>
<p class="text-sm sm:text-xl">
{{ menuStore.selectedPhoneCountry.iso_code }}
</p>
</div>
</div>
<div v-if="dropCountry"
class="mt-2 absolute bg-bg-light dark:bg-bg-dark rounded-[5px] ring-0 cursor-pointer w-[130px] sm: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.countries" :key="item.iso_code"
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" @click="
() => {
menuStore.selectedPhoneCountry = item;
dropCountry = false;
}
">
{{ item.name }}
</p>
</div>
</div>
</div>
<p class="text-sm sm:text-xl font-normal">
{{ menuStore.selectedPhoneCountry.call_prefix }}
</p>
<input id="phone" v-model="user.data.phone" :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>
<p v-if="!phoneValidation && phoneValidation != null" class="mt-2 text-xs text-red-600">
{{ $t('enter_correct_data') }}
</p>
</div>
</div>
<div class="space-y-[15px]">
<p class="pl-6">
{{ $t("account_type") }}
</p>
<USelect v-model="selectedType" :items="component.front_section_lang
&& 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',
viewport: 'ring-0 min-w-full',
content:
'bg-bg-light dark:bg-bg-dark ring-0 border border-button',
leading:
'left-1/2 top-1/2 transform -translate-x-1/2 -translate-y-1/2 p-0 w-full',
group: 'px-[5px] py-[10px]',
item: 'hover:bg-block dark:hover:bg-button rounded-[5px] data-highlighted:not-data-disabled:before:bg-button/50 min-w-full',
}">
<template #leading="{ modelValue }">
<div
class="flex items-center justify-between gap-2 uppercase text-sm sm:text-xl border 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.front_section_lang
&& 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" /></span>
</div>
</template>
<template #item="{ item }">
<div class="flex items-center gap-2 cursor-pointer min-w-full">
<p
class="truncate whitespace-nowrap text-sm sm:text-xl font-medium uppercase text-text-light dark:text-text-dark opacity-100">
{{ item.name }}
</p>
</div>
</template>
</USelect>
</div>
<div class="space-y-[15px]">
<p class="pl-6">
{{ $t("partner_code") }}
</p>
<input :placeholder="$t('placeholder_password')" type="text"
class="border border-block placeholder:text-gray dark:placeholder:text-button-disabled text-bg-dark dark:text-bg-light rounded-lg px-6 h-[50px] sm:h-[67px] w-full focus:outline-none focus:ring-0 focus:border-2">
</div>
</div>
</div>
</div>
<div class="py-[25px] sm:py-12 border-b border-gray flex justify-center w-full">
<UiButtonArrow type="fill" :arrow="true" @click="sendForm()">
{{
$t("sign_up")
}}
</UiButtonArrow>
</div>
<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>
<nuxt-link
:to="{ name: `id-slug___${$i18n.locale}`, params: { id: menuStore.getLoginMenu()?.id, slug: menuStore.getLoginMenu()?.front_menu_lang.at(0)?.link_rewrite } }">
<p class="text-button cursor-pointer hover:text-button-hover">
{{ $t("login") }}
</p>
</nuxt-link>
</div>
</div>
</UiContainer>
</template>
<script lang="ts" setup>
import { onClickOutside } from '@vueuse/core'
import CheckoutInput from '../ui/CheckoutInput.vue'
import type { GenericResponse } from '~/types'
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
value: string
}[]
}
id_front_section: number
id_lang: number
}[]
}
}>()
const menuStore = useMenuStore()
const dropdownRef = ref(null)
const dropCountry = ref()
const user = ref({
data: {
name: '',
surname: '',
email: '',
phone: '',
},
})
const nameValidation = ref<boolean | null>(null)
const surnameValidation = ref<boolean | null>(null)
const emailValidation = ref<boolean | null>(null)
const phoneValidation = ref<boolean | null>(null)
const codeValidation = ref<boolean | null>(null)
const selectedType = ref()
if (props.component.front_section_lang)
selectedType.value
= props.component.front_section_lang[0].data.account_types[0].name
const sendForm = async () => {
const phoneNum = `${menuStore.selectedPhoneCountry.call_prefix}${user.value.data.phone}`.replaceAll(' ', '').trim()
console.log(phoneNum)
nameValidation.value = validation(user.value.data.name, 1, 49)
surnameValidation.value = validation(user.value.data.surname, 1, 49)
emailValidation.value = validation(user.value.data.email, 1, 49, REGEX_EMAIL)
phoneValidation.value = validation(phoneNum, 1, 49, REGEX_PHONE)
// codeValidation.value = validation(vCode.value as string, 1, 49);
const selectedTypeValue = props.component.front_section_lang[0].data.account_types.find(item => item.name === selectedType.value)?.value
if (nameValidation.value && surnameValidation.value && emailValidation.value && phoneValidation.value && codeValidation) {
try {
await useMyFetch<GenericResponse<object>>(
`/api/public/register/new_link?customer_type=${selectedTypeValue}`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
email: user.value.data.email,
first_name: user.value.data.name,
last_name: user.value.data.surname,
phone_number: phoneNum,
// partner_code: vCode.value,
customer_type: selectedType.value,
}),
onErrorOccured: (_, status) => {
throw new Error(`HTTP error: ${status}`)
},
},
)
}
// successRegister.value = true;
// isLoader.value = false;
catch (error) {
console.error('getList error:', error)
}
}
}
onClickOutside(dropdownRef, () => {
dropCountry.value = false
})
</script>

View File

@ -29,7 +29,7 @@
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<p <p
class="text-accent-green-light font-inter text-[12px] sm:text-[21px] md:text-2xl leading-[150%] font-bold"> class="text-accent-green-light font-inter text-[12px] sm:text-[21px] md:text-2xl leading-[150%] font-bold">
{{ product.formatted_price }} {{ formater.price(product.price) }}
</p> </p>
<button <button
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" 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"
@ -57,7 +57,7 @@ defineProps<{ product: Product }>()
const productStore = useProductStore() const productStore = useProductStore()
const menuStore = useMenuStore() const menuStore = useMenuStore()
const formater = useFormater(useNuxtApp())
function handleImageError(event: Event) { function handleImageError(event: Event) {
const img = event.target as HTMLImageElement const img = event.target as HTMLImageElement
img.src = '/photo.svg' img.src = '/photo.svg'

View File

@ -13,7 +13,7 @@
</button> </button>
</div> </div>
</transition> </transition>
<div class="space-y-10 sm:space-y-[75px]"> <div ref="productBlockRef" class="space-y-10 sm:space-y-[75px]">
<div class="flex flex-col items-start xl:flex-row gap-[40px] sm:gap-[100px] border-b-2 border-block pb-[25px]"> <div class="flex flex-col items-start xl:flex-row gap-[40px] sm:gap-[100px] border-b-2 border-block pb-[25px]">
<!-- images block --> <!-- images block -->
<button <button
@ -70,14 +70,14 @@
}}</span> }}</span>
</p> </p>
</div> </div>
<div class="mx-auto sm:mx-0 group flex cursor-pointer items-center justify-start gap-2 whitespace-nowrap"> <div class="mx-auto sm:mx-0 group flex cursor-pointer items-center justify-start gap-2 whitespace-nowrap" @click="productStore.incrementCartItem(product.id)">
<button <button
class="h-[40px] cursor-pointer min-w-40 rounded-[10px] px-[22px] transition-all sm:h-[50px] md:h-[65px] md:rounded-[15px] md:px-[42px] bg-button text-text-dark group-hover:bg-button-hover"> class="h-[40px] cursor-pointer min-w-40 rounded-[10px] px-[22px] transition-all sm:h-[50px] md:h-[65px] md:rounded-[15px] md:px-[42px] bg-button text-text-dark group-hover:bg-button-hover">
Add to cart Add to cart
</button> </button>
<div :disabled="!product.sale_active" class=" <div :disabled="!product.sale_active" class="
flex h-[40px] w-[40px] items-center justify-center rounded-[10px] p-2.5 transition-all sm:h-[50px] sm:w-[50px] md:h-[65px] md:w-[65px] md:rounded-[15px] bg-button text-text-dark group-hover:bg-button-hover flex h-[40px] w-[40px] items-center justify-center rounded-[10px] p-2.5 transition-all sm:h-[50px] sm:w-[50px] md:h-[65px] md:w-[65px] md:rounded-[15px] bg-button text-text-dark group-hover:bg-button-hover
" @click="productStore.incrementCartItem(product.id)"> ">
<i class="uil uil-shopping-cart text-[23px] sm:text-[33px]"></i> <i class="uil uil-shopping-cart text-[23px] sm:text-[33px]"></i>
</div> </div>
</div> </div>
@ -115,7 +115,7 @@
.link_rewrite, .link_rewrite,
}, },
query: { prod_id: item?.id, name: item?.link_rewrite }, query: { prod_id: item?.id, name: item?.link_rewrite },
}"> }" @click.stop.prevent="scrollToTop">
<div <div
class="w-[200px] sm:w-[260px] md:w-[290px] sm:py-5 sm:px-[15px] py-[15px] px-[10px] bg-block rounded-2xl flex flex-col items-center gap-5 sm:gap-7 h-full"> class="w-[200px] sm:w-[260px] md:w-[290px] sm:py-5 sm:px-[15px] py-[15px] px-[10px] bg-block rounded-2xl flex flex-col items-center gap-5 sm:gap-7 h-full">
<img :src="`/api/public/file/${item.cover_picture_uuid}.webp`" alt="pics" <img :src="`/api/public/file/${item.cover_picture_uuid}.webp`" alt="pics"
@ -176,10 +176,11 @@ const menuStore = useMenuStore()
const { $session } = useNuxtApp() const { $session } = useNuxtApp()
const productStore = useProductStore() const productStore = useProductStore()
const dropdownRef = ref() const dropdownRef = ref()
const productBlockRef = ref()
// const addToCart = (p: ProductItem) => { function scrollToTop() {
// alert('add to cart product: ' + p.name) productBlockRef.value?.scrollIntoView({ behavior: 'smooth' })
// } }
const formatPrice = (p: number) => { const formatPrice = (p: number) => {
const formatdecimal = new Intl.NumberFormat( const formatdecimal = new Intl.NumberFormat(

View File

@ -1,13 +1,5 @@
<template> <template>
<UiContainer class="flex py-[15px] xl:py-20 sm:py-0"> <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/public/file/${component.img[0]}_l.webp')`,
backgroundSize: 'cover',
backgroundPosition: 'center',
}"
/>
<div class="w-full sm:w-[80%] mx-auto my-auto xl:w-full xl:px-12"> <div class="w-full sm:w-[80%] mx-auto my-auto xl:w-full xl:px-12">
<div class="space-25-55"> <div class="space-25-55">
<div class="flex flex-wrap-reverse gap-y-4 justify-between"> <div class="flex flex-wrap-reverse gap-y-4 justify-between">
@ -16,89 +8,55 @@
</h2> </h2>
<button <button
class="h-[40px] sm:h-[43px] px-[10px] sm:px-[17px] border border-gray dark:border-button-disabled text-gray dark:text-button-disabled hover:bg-gray transition-all hover:text-white rounded-[8px] cursor-pointer" class="h-[40px] sm:h-[43px] px-[10px] sm:px-[17px] border border-gray dark:border-button-disabled text-gray dark:text-button-disabled hover:bg-gray transition-all hover:text-white rounded-[8px] cursor-pointer"
@click="menuStore.navigateToItem()" @click="menuStore.navigateToItem()">
>
{{ $t("back_to_home") }} {{ $t("back_to_home") }}
</button> </button>
</div> </div>
<div class="space-y-[25px] sm:space-y-[30px]"> <div class="space-y-[25px] sm:space-y-[30px]">
<p>{{ $t("current_information") }}</p> <p>{{ $t("current_information") }}</p>
<div class="grid grid-cols-1 md:grid-cols-2 gap-[30px]"> <div class="grid grid-cols-1 md:grid-cols-2 gap-[30px]">
<div class="space-y-[15px]"> <CheckoutInput :id="1" v-model="user.data.name" :validation="nameValidation"
<p class="pl-6"> :validation-text="$t('enter_correct_data')" :placeholder="$t('first_name')">
{{ $t("first_name") }} {{ $t("first_name") }}
</p> </CheckoutInput>
<input <CheckoutInput :id="1" v-model="user.data.surname" :validation="surnameValidation"
:placeholder="$t('first_name')" :validation-text="$t('enter_correct_data')" :placeholder="$t('last_name')">
type="text"
class="text-sm sm:text-xl border border-block placeholder:text-gray dark:placeholder:text-button-disabled text-bg-dark dark:text-bg-light rounded-lg px-6 h-[50px] sm:h-[67px] w-full focus:outline-none focus:ring-0 focus:border-2"
>
</div>
<div class="space-y-[15px]">
<p class="pl-6">
{{ $t("last_name") }} {{ $t("last_name") }}
</p> </CheckoutInput>
<input <CheckoutInput :id="1" v-model="user.data.email" :validation="emailValidation"
:placeholder="$t('last_name')" :validation-text="$t('enter_correct_data')" :placeholder="$t('email')">
type="text"
class="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 h-[50px] sm:h-[67px] w-full focus:outline-none focus:ring-0 focus:border-2"
>
</div>
<div class="space-y-[15px]">
<p class="pl-6">
{{ $t("email") }} {{ $t("email") }}
</p> </CheckoutInput>
<input <div ref="dropdownRef" class="space-y-[15px]">
:placeholder="$t('email')"
type="text"
class="text-sm sm:text-xl border border-block placeholder:text-gray dark:placeholder:text-button-disabled text-bg-dark dark:text-bg-light rounded-lg px-6 h-[50px] sm:h-[67px] w-full focus:outline-none focus:ring-0 focus:border-2"
>
</div>
<div ref="dropdownRef"
class="space-y-[15px]"
>
<p class="pl-6"> <p class="pl-6">
{{ $t("phone") }} {{ $t("phone") }}
</p> </p>
<div class="flex items-center border-2 border-block rounded-lg"> <div>
<div class="flex items-center border border-block rounded-lg">
<div <div
class="relative z-50 bg-inherit ring-0 cursor-pointer focus:ring-0 outline-none focus-visible:ring-0" class="relative z-50 bg-inherit ring-0 cursor-pointer focus:ring-0 outline-none focus-visible:ring-0">
> <div class="px-[25px]" @click="dropCountry = !dropCountry">
<div class="px-[25px]"
@click="dropCountry = !dropCountry"
>
<div <div
class="flex items-center gap-2 text-sm sm:text-xl uppercase text-text-light dark:text-text-dark" class="flex items-center gap-2 text-sm sm:text-xl uppercase text-text-light dark:text-text-dark">
> <span :class="[dropCountry && 'rotate-180', 'transition-all']">
<span <i class="uil uil-angle-down text-2xl font-light cursor-pointer" /></span>
:class="[dropCountry && 'rotate-180', 'transition-all']"
>
<i
class="uil uil-angle-down text-2xl font-light cursor-pointer"
/></span>
<p class="text-sm sm:text-xl"> <p class="text-sm sm:text-xl">
{{ menuStore.selectedPhoneCountry.iso_code }} {{ menuStore.selectedPhoneCountry.iso_code }}
</p> </p>
</div> </div>
</div> </div>
<div <div v-if="dropCountry"
v-if="dropCountry" class="mt-2 absolute bg-bg-light dark:bg-bg-dark rounded-[5px] ring-0 cursor-pointer w-[130px] sm:w-full border border-button py-[10px] px-[5px] overflow-hidden">
class="mt-2 absolute bg-bg-light dark:bg-bg-dark rounded-[5px] ring-0 cursor-pointer w-[130px] sm:w-full border border-button py-[10px] px-[5px] overflow-hidden"
>
<div class="overflow-y-auto h-[200px] w-full"> <div class="overflow-y-auto h-[200px] w-full">
<p <p v-for="item in menuStore.countries" :key="item.iso_code"
v-for="item in menuStore.countries"
:key="item.iso_code"
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]" 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" :title="item.name" @click="
@click="
() => { () => {
menuStore.selectedPhoneCountry = item; menuStore.selectedPhoneCountry = item;
dropCountry = false; dropCountry = false;
} }
" ">
>
{{ item.name }} {{ item.name }}
</p> </p>
</div> </div>
@ -107,27 +65,21 @@
<p class="text-sm sm:text-xl font-normal"> <p class="text-sm sm:text-xl font-normal">
{{ menuStore.selectedPhoneCountry.call_prefix }} {{ menuStore.selectedPhoneCountry.call_prefix }}
</p> </p>
<input <input id="phone" v-model="user.data.phone" :placeholder="$t('phone')" type="text"
id="phone" 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">
:placeholder="$t('phone')" </div>
type="text" <p v-if="!phoneValidation && phoneValidation != null" class="mt-2 text-xs text-red-600">
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" {{ $t('enter_correct_data') }}
> </p>
</div> </div>
</div> </div>
<div class="space-y-[15px]"> <div class="space-y-[15px]">
<p class="pl-6"> <p class="pl-6">
{{ $t("account_type") }} {{ $t("account_type") }}
</p> </p>
<USelect <USelect v-model="selectedType" :items="component.front_section_lang
v-model="selectedType"
:items="
component.front_section_lang
&& component.front_section_lang[0].data.account_types && component.front_section_lang[0].data.account_types
" " value-key="name" :searchable="false" :ui="{
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', 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', trailing: 'hidden w-full',
viewport: 'ring-0 min-w-full', viewport: 'ring-0 min-w-full',
@ -137,34 +89,22 @@
'left-1/2 top-1/2 transform -translate-x-1/2 -translate-y-1/2 p-0 w-full', 'left-1/2 top-1/2 transform -translate-x-1/2 -translate-y-1/2 p-0 w-full',
group: 'px-[5px] py-[10px]', group: 'px-[5px] py-[10px]',
item: 'hover:bg-block dark:hover:bg-button rounded-[5px] data-highlighted:not-data-disabled:before:bg-button/50 min-w-full', item: 'hover:bg-block dark:hover:bg-button rounded-[5px] data-highlighted:not-data-disabled:before:bg-button/50 min-w-full',
}" }">
>
<template #leading="{ modelValue }"> <template #leading="{ modelValue }">
<div <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]" class="flex items-center justify-between gap-2 uppercase text-sm sm:text-xl border 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"> <p class="truncate whitespace-nowrap">
{{ {{ component.front_section_lang.at(0).data.account_types.find((item: any) => item.name === modelValue)?.name }}
component.front_section_lang
&& component.front_section_lang[0].data.account_types.find(
(item) => item.name === modelValue,
)?.name
}}
</p> </p>
<span> <span>
<i <i class="uil uil-angle-down text-2xl font-light cursor-pointer" /></span>
class="uil uil-angle-down text-2xl font-light cursor-pointer"
/></span>
</div> </div>
</template> </template>
<template #item="{ item }"> <template #item="{ item }">
<div <div class="flex items-center gap-2 cursor-pointer min-w-full">
class="flex items-center gap-2 cursor-pointer min-w-full"
>
<p <p
class="truncate whitespace-nowrap text-sm sm:text-xl font-medium uppercase text-text-light dark:text-text-dark opacity-100" class="truncate whitespace-nowrap text-sm sm:text-xl font-medium uppercase text-text-light dark:text-text-dark opacity-100">
>
{{ item.name }} {{ item.name }}
</p> </p>
</div> </div>
@ -175,21 +115,14 @@
<p class="pl-6"> <p class="pl-6">
{{ $t("partner_code") }} {{ $t("partner_code") }}
</p> </p>
<input <input :placeholder="$t('placeholder_password')" type="text"
:placeholder="$t('placeholder_password')" class="border border-block placeholder:text-gray dark:placeholder:text-button-disabled text-bg-dark dark:text-bg-light rounded-lg px-6 h-[50px] sm:h-[67px] w-full focus:outline-none focus:ring-0 focus:border-2">
type="text"
class="border-2 border-block placeholder:text-gray dark:placeholder:text-button-disabled text-bg-dark dark:text-bg-light rounded-lg px-6 h-[50px] sm:h-[67px] w-full focus:outline-none focus:ring-0 focus:border-2"
>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div <div class="py-[25px] sm:py-12 border-b border-gray flex justify-center w-full">
class="py-[25px] sm:py-12 border-b border-gray flex justify-center w-full" <UiButtonArrow type="fill" :arrow="true" @click="sendForm()">
>
<UiButtonArrow type="fill"
:arrow="true"
>
{{ {{
$t("sign_up") $t("sign_up")
}} }}
@ -199,7 +132,8 @@
<p class="cursor-pointer hover:underline transition-all"> <p class="cursor-pointer hover:underline transition-all">
{{ $t("is_account") }} {{ $t("is_account") }}
</p> </p>
<nuxt-link :to="{ name: `id-slug___${$i18n.locale}`, params: { id: menuStore.getLoginMenu()?.id, slug: menuStore.getLoginMenu()?.front_menu_lang.at(0)?.link_rewrite } }"> <nuxt-link
:to="{ name: `id-slug___${$i18n.locale}`, params: { id: menuStore.getLoginMenu()?.id, slug: menuStore.getLoginMenu()?.front_menu_lang.at(0)?.link_rewrite } }">
<p class="text-button cursor-pointer hover:text-button-hover"> <p class="text-button cursor-pointer hover:text-button-hover">
{{ $t("login") }} {{ $t("login") }}
</p> </p>
@ -211,6 +145,8 @@
<script lang="ts" setup> <script lang="ts" setup>
import { onClickOutside } from '@vueuse/core' import { onClickOutside } from '@vueuse/core'
import CheckoutInput from '../ui/CheckoutInput.vue'
import type { GenericResponse } from '~/types'
const props = defineProps<{ const props = defineProps<{
component: { component: {
@ -225,6 +161,7 @@ const props = defineProps<{
account_types: { account_types: {
id: number id: number
name: string name: string
value: string
}[] }[]
} }
id_front_section: number id_front_section: number
@ -237,11 +174,70 @@ const menuStore = useMenuStore()
const dropdownRef = ref(null) const dropdownRef = ref(null)
const dropCountry = ref() const dropCountry = ref()
const user = ref({
data: {
name: '',
surname: '',
email: '',
phone: '',
},
})
const nameValidation = ref<boolean | null>(null)
const surnameValidation = ref<boolean | null>(null)
const emailValidation = ref<boolean | null>(null)
const phoneValidation = ref<boolean | null>(null)
const codeValidation = ref<boolean | null>(null)
const selectedType = ref() const selectedType = ref()
if (props.component.front_section_lang) if (props.component.front_section_lang)
selectedType.value selectedType.value
= props.component.front_section_lang[0].data.account_types[0].name = props.component.front_section_lang[0].data.account_types[0].name
const sendForm = async () => {
const phoneNum = `${menuStore.selectedPhoneCountry.call_prefix}${user.value.data.phone}`.replaceAll(' ', '').trim()
console.log(phoneNum)
nameValidation.value = validation(user.value.data.name, 1, 49)
surnameValidation.value = validation(user.value.data.surname, 1, 49)
emailValidation.value = validation(user.value.data.email, 1, 49, REGEX_EMAIL)
phoneValidation.value = validation(phoneNum, 1, 49, REGEX_PHONE)
// codeValidation.value = validation(vCode.value as string, 1, 49);
const selectedTypeValue = props.component.front_section_lang[0].data.account_types.find(item => item.name === selectedType.value)?.value
if (nameValidation.value && surnameValidation.value && emailValidation.value && phoneValidation.value && codeValidation) {
try {
await useMyFetch<GenericResponse<object>>(
`/api/public/register/new_link?customer_type=${selectedTypeValue}`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
email: user.value.data.email,
first_name: user.value.data.name,
last_name: user.value.data.surname,
phone_number: phoneNum,
// partner_code: vCode.value,
customer_type: selectedType.value,
}),
onErrorOccured: (_, status) => {
throw new Error(`HTTP error: ${status}`)
},
},
)
}
// successRegister.value = true;
// isLoader.value = false;
catch (error) {
console.error('getList error:', error)
}
}
}
onClickOutside(dropdownRef, () => { onClickOutside(dropdownRef, () => {
dropCountry.value = false dropCountry.value = false
}) })

View File

@ -350,10 +350,7 @@ async function loadMoreProducts() {
qParams.append('p', `${page.value}`) qParams.append('p', `${page.value}`)
qParams.append('elems', `${elems.value}`) qParams.append('elems', `${elems.value}`)
qParams.append( qParams.append('features', selectedFilters.value.length > 0 ? `${selectedFilters.value}` : '')
'features',
selectedFilters.value.length > 0 ? selectedFilters.value : null,
)
try { try {
const { data } = await useMyFetch<GenericResponseItems<ProductType[]>>( const { data } = await useMyFetch<GenericResponseItems<ProductType[]>>(
@ -395,7 +392,7 @@ const changeCategory = (item: CategoryItem) => {
categoryId.value = item.id categoryId.value = item.id
} }
watch(selectedFilters, async (newQuestion: string) => { watch(selectedFilters, async (newQuestion) => {
if (newQuestion) { if (newQuestion) {
page.value = 1 page.value = 1
reachedEnd.value = false reachedEnd.value = false
@ -407,7 +404,7 @@ watch(selectedFilters, async (newQuestion: string) => {
qParams.append('elems', `${elems.value}`) qParams.append('elems', `${elems.value}`)
qParams.append( qParams.append(
'features', 'features',
selectedFilters.value.length > 0 ? selectedFilters.value : null, selectedFilters.value.length > 0 ? `${selectedFilters.value}` : '',
) )
try { try {
@ -443,7 +440,7 @@ watch(categoryId, async (newCategoryId) => {
qParams.append('elems', `${elems.value}`) qParams.append('elems', `${elems.value}`)
qParams.append( qParams.append(
'features', 'features',
selectedFilters.value.length > 0 ? selectedFilters.value : null, selectedFilters.value.length > 0 ? `${selectedFilters.value}` : '',
) )
try { try {

View File

@ -1,53 +1,32 @@
<template> <template>
<div class="space-y-[15px]"> <div class="space-y-[15px]">
<p :for="`base-input-${id}`" <p :for="`base-input-${id}`" class="pl-6">
class="pl-6"
>
<slot /> <slot />
</p> </p>
<div class="flex flex-col"> <div class="flex flex-col">
<div class="flex relative"> <div class="flex relative">
<input <input :id="`base-input-${id}`" :value="modelValue" :type="!isPasswordVisible ? type : 'text'"
:id="`base-input-${id}`" :placeholder="placeholder" :disabled="disabled"
:value="modelValue"
:type="!isPasswordVisible ? type : 'text'"
:placeholder="placeholder"
:disabled="disabled"
class="border border-block placeholder:text-gray dark:placeholder:text-button-disabled rounded-lg px-6 h-[50px] sm:h-[67px] w-full focus:outline-none focus:ring-0 focus:border-2" class="border border-block placeholder:text-gray dark:placeholder:text-button-disabled rounded-lg px-6 h-[50px] sm:h-[67px] w-full focus:outline-none focus:ring-0 focus:border-2"
@input=" @input="
$emit( $emit(
'update:modelValue', 'update:modelValue',
($event.target as HTMLInputElement).value, ($event.target as HTMLInputElement).value,
) )
" " @focus="$emit('focus')" @blur="$emit('blur')">
@focus="$emit('focus')" <i v-if="disabled" class="uil uil-lock-alt text-[22px] absolute right-6 top-1/2 -translate-y-1/2 text-gray" />
@blur="$emit('blur')"
>
<i
v-if="disabled"
class="uil uil-lock-alt text-[22px] absolute right-6 top-1/2 -translate-y-1/2 text-gray"
/>
<div <div v-if="type === 'password'" class="order-2 ml-1.5 cursor-pointer" :title="!isPasswordVisible ? $t('show_password') : $t('hide_password')
v-if="type === 'password'" " @click="isPasswordVisible = !isPasswordVisible">
class="order-2 ml-1.5 cursor-pointer" <FaceObserver class="ml-4 text-xl leading-6" :is-password-visible="isPasswordVisible" />
:title="
!isPasswordVisible ? $t('show_password') : $t('hide_password')
"
@click="isPasswordVisible = !isPasswordVisible"
>
<FaceObserver
class="ml-4 text-xl leading-6"
:is-password-visible="isPasswordVisible"
/>
</div> </div>
</div> </div>
<!-- <p class="mt-2 text-xs text-red-600">{{ validationText }}</p> --> <!-- <p class="mt-2 text-xs text-red-600">{{ validationText }}</p> -->
<!-- <p v-if="!validation && validation != null" class="mt-2 text-xs text-red-600"> <p v-if="!validation && validation != null" class="mt-2 text-xs text-red-600">
{{ validationText }} {{ validationText }}
</p> --> </p>
</div> </div>
</div> </div>
</template> </template>

View File

@ -0,0 +1,30 @@
import type { NuxtApp } from '#app'
export const useFormater = (nuxtApp: NuxtApp) => {
return new Formater(nuxtApp)
}
class Formater {
private session
constructor(nuxtApp: NuxtApp) {
const { $session } = nuxtApp
this.session = $session
}
price(p: number) {
const formatdecimal = new Intl.NumberFormat(
this.session.cookieData.value.country.iso_code,
{
style: 'decimal',
maximumFractionDigits: this.session.cookieData.value.currency.precision,
minimumFractionDigits: this.session.cookieData.value.currency.precision,
},
)
if (this.session.cookieData.value.currency.suffix) {
return this.session.cookieData.value.currency.sign + ' ' + formatdecimal.format(p)
}
else {
return formatdecimal.format(p) + ' ' + this.session.cookieData.value.currency.sign
}
}
}

View File

@ -15,10 +15,6 @@ import ScrollTrigger from 'gsap/ScrollTrigger'
gsap.registerPlugin(ScrollTrigger) gsap.registerPlugin(ScrollTrigger)
watch(useColorMode(), (color) => {
console.log(color)
})
onMounted(() => { onMounted(() => {
const anim = gsap.fromTo( const anim = gsap.fromTo(
'h1', 'h1',

View File

@ -5,6 +5,8 @@ export default defineNuxtPlugin(async () => {
await menuStore.loadMenu() await menuStore.loadMenu()
await menuStore.getLocales() await menuStore.getLocales()
const store = useStore() const store = useStore()
await store.getMinValue() await store.getMinMaxRange()
await store.getCalculator() await store.getCalculator()
const userStore = useUserStore()
await userStore.checkIsLogged()
}) })

View File

@ -21,6 +21,7 @@ export const useCheckoutStore = defineStore('checkoutStore', () => {
const vNote = ref('') const vNote = ref('')
const legalValidation = ref(false) const legalValidation = ref(false)
const termsValidation = ref(false) const termsValidation = ref(false)
const totalNumberOfProducts = ref(0)
// get address list // get address list
const addressesList = ref<AddressesList[]>() const addressesList = ref<AddressesList[]>()
@ -265,6 +266,13 @@ export const useCheckoutStore = defineStore('checkoutStore', () => {
}, },
) )
totalNumberOfProducts.value = 0
if (data.cart_items && Array.isArray(data.cart_items)) {
for (const item of data.cart_items) {
totalNumberOfProducts.value = totalNumberOfProducts.value + item.quantity
}
}
products.value = data.cart_items products.value = data.cart_items
fullPrice.value = data.total_value fullPrice.value = data.total_value
fullProductsPrice.value = data.total_value fullProductsPrice.value = data.total_value
@ -551,6 +559,7 @@ export const useCheckoutStore = defineStore('checkoutStore', () => {
paymentMethods, paymentMethods,
currentPayment, currentPayment,
fullAddress, fullAddress,
totalNumberOfProducts,
vLegal, vLegal,
vTerms, vTerms,

49
stores/investmentStore.ts Normal file
View File

@ -0,0 +1,49 @@
// import { useMyFetch } from '#imports'
import type { CalculatorOutput, GenericResponse } from '~/types'
export const useInvestmentStore = defineStore('investmentStore', () => {
const store = useStore()
// const monthlySavings = ref(store.monthlySavings || 100)
// const yearsNumber = ref(store.storagePeriod || 10)
const calculationResult = ref<CalculatorOutput>({} as CalculatorOutput)
const minYear = 1
const maxYear = 20
const { $session: session } = useNuxtApp()
watch(session.cookieData, async () => {
await getCalculator()
}, { deep: true })
const getCalculator = async () => {
const query = new URLSearchParams({
monthly_deposit: String(store.monthlySavings),
years: String(store.storagePeriod),
format: 'svg',
grid: 'false',
legend: 'false',
title: 'false',
ingots_bought_dots: 'true',
draw_linear: 'true',
annotations: 'false',
show_real_value: 'false',
series_stroke_width: '1',
// colors: '#004f3d,#004f3d,#004f3d,#004f3d,#000',
colors: '#9a7f62,#9a7f62,#9a7f62,#9a7f62,#000',
})
const { data } = await useMyFetch<GenericResponse<CalculatorOutput>>(`/api/public/plan-prediction/easy/chart?${query.toString()}`)
calculationResult.value = data
}
return {
// monthlySavings,
// yearsNumber,
minYear,
maxYear,
calculationResult,
getCalculator,
}
})

View File

@ -139,7 +139,7 @@ export const useMenuStore = defineStore('menuStore', () => {
return menuItems.value?.find(item => item.id === 14) return menuItems.value?.find(item => item.id === 14)
} }
function getRegistrationMenu() { function getPreRegistrationMenu() {
return menuItems.value?.find(item => item.id === 4) return menuItems.value?.find(item => item.id === 4)
} }
@ -167,6 +167,14 @@ export const useMenuStore = defineStore('menuStore', () => {
return menuItems.value?.find(item => item.id === 10) return menuItems.value?.find(item => item.id === 10)
} }
function getRegistrationMenu() {
return menuItems.value?.find(item => item.id === 15)
}
function getInvestmentCalculatorMenu() {
return menuItems.value?.find(item => item.id === 16)
}
const getFirstImage = (size: 'l' | 'm' | 's' = 'm', needbaseurl: boolean) => { const getFirstImage = (size: 'l' | 'm' | 's' = 'm', needbaseurl: boolean) => {
const req = useRequestEvent() const req = useRequestEvent()
const url = useRequestURL() const url = useRequestURL()
@ -269,7 +277,7 @@ export const useMenuStore = defineStore('menuStore', () => {
async () => { async () => {
await getLocales() await getLocales()
await loadMenu() await loadMenu()
await store.getMinValue() await store.getMinMaxRange()
await store.getCalculator() await store.getCalculator()
}, },
{ deep: true }, { deep: true },
@ -296,7 +304,7 @@ export const useMenuStore = defineStore('menuStore', () => {
getLocales, getLocales,
getProductMenu, getProductMenu,
formatPrice, formatPrice,
getRegistrationMenu, getPreRegistrationMenu,
getLoginMenu, getLoginMenu,
getInvestitionMenu, getInvestitionMenu,
getAboutUsMenu, getAboutUsMenu,
@ -304,5 +312,7 @@ export const useMenuStore = defineStore('menuStore', () => {
getAboutGoldMenu, getAboutGoldMenu,
getContactMenu, getContactMenu,
getShopMenu, getShopMenu,
getRegistrationMenu,
getInvestmentCalculatorMenu,
} }
}) })

View File

@ -5,6 +5,7 @@ import type {
PlanPrediction, PlanPrediction,
} from '~/types' } from '~/types'
import type { FrontPageSection } from '~/types/frontSection' import type { FrontPageSection } from '~/types/frontSection'
import type { MinMaxRange } from '~/types/planPrediction'
export const useStore = defineStore('store', () => { export const useStore = defineStore('store', () => {
const currentPageID = ref('') const currentPageID = ref('')
@ -13,7 +14,7 @@ export const useStore = defineStore('store', () => {
const monthlySavings = ref(137) const monthlySavings = ref(137)
const storagePeriod = ref(10) const storagePeriod = ref(10)
const totalInvestment: Ref<number> = ref(0) const totalInvestment: Ref<number> = ref(0)
const minValue = ref() const minMaxRange = ref({} as MinMaxRange)
const components = ref({} as FrontPageSection[]) const components = ref({} as FrontPageSection[])
@ -84,10 +85,10 @@ export const useStore = defineStore('store', () => {
} }
} }
async function getMinValue() { async function getMinMaxRange() {
try { try {
const { data } = await useMyFetch<GenericResponse<number>>( const { data } = await useMyFetch<GenericResponse<MinMaxRange>>(
'/api/public/plan-prediction/free/minimum', '/api/public/front/minmaxinvestment',
{ {
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
@ -98,23 +99,32 @@ export const useStore = defineStore('store', () => {
}, },
) )
minValue.value = data minMaxRange.value = data
} }
catch (error) { catch (error) {
console.error('getList error:', error) console.error('getList error:', error)
} }
} }
const getMinAmount = computed(() => {
return Math.ceil(minMaxRange.value.min)
})
const getMaxAmount = computed(() => {
return Math.ceil(minMaxRange.value.max)
})
return { return {
currentPageID, currentPageID,
components, components,
totalInvestment, totalInvestment,
monthlySavings, monthlySavings,
storagePeriod, storagePeriod,
minValue, minMaxRange,
getCalculator, getCalculator,
getComponents, getComponents,
getSections, getSections,
getMinValue, getMinMaxRange,
getMinAmount,
getMaxAmount,
} }
}) })

View File

@ -112,11 +112,6 @@ export interface GenericResponseChildren<Data> {
status: number status: number
} }
export type {
InvestmentPiece,
PlanPrediction,
PeriodToFirstPiece,
} from './planPrediction'
export type { export type {
Product, Product,
ProductItem, ProductItem,
@ -128,3 +123,4 @@ export type {
} from './product' } from './product'
export type { FrontMenu, FrontMenuLang, UIFrontMenu } from './frontMenu' export type { FrontMenu, FrontMenuLang, UIFrontMenu } from './frontMenu'
export type { Contact, Footer, FooterDoc, FooterPdf } from './footer' export type { Contact, Footer, FooterDoc, FooterPdf } from './footer'
export type { CalculatorOutput, PlanPrediction, FeatureCalculator, InvestmentPiece, PeriodToFirstPiece } from './planPrediction'

View File

@ -1,3 +1,8 @@
export interface CalculatorOutput {
calculator_output: PlanPrediction
chart: string
}
export interface PlanPrediction { export interface PlanPrediction {
total_investement_value: number total_investement_value: number
total_input_price_increase: number total_input_price_increase: number
@ -23,10 +28,10 @@ export interface InvestmentPiece {
currency_conversion_rate: string currency_conversion_rate: string
max_comission_value: number max_comission_value: number
average_input_price_increase: number average_input_price_increase: number
features: Feature[] features: FeatureCalculator[]
} }
export interface Feature { export interface FeatureCalculator {
feature_id: number feature_id: number
feature: string feature: string
value_id: number value_id: number
@ -38,3 +43,8 @@ export interface PeriodToFirstPiece {
months: number months: number
days: number days: number
} }
export interface MinMaxRange {
min: number
max: number
}