2 Commits

Author SHA1 Message Date
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 class="relative cursor-pointer" @click="openCart = !openCart">
<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">
{{ checkoutStore.products.length }}
{{ checkoutStore.totalNumberOfProducts }}
</div>
</div>
<div v-if="openCart"
@ -69,10 +69,10 @@
</div>
<UiButtonArrow class="w-full" type="fill" :arrow="true" :full="true" @click="() => {
if (userStore.isLogged) {
menuStore.navigateToItem(menuStore.menuItems?.find((item) => item.id === 12))
menuStore.navigateToItem(menuStore.menuItems?.find((item: any) => item.id === 12))
}
else {
menuStore.navigateToItem(menuStore.menuItems?.find((item) => item.id === 11))
menuStore.navigateToItem(menuStore.menuItems?.find((item: any) => item.id === 11))
}
openCart = false
}">

View File

@ -4,38 +4,26 @@
<div class="w-full border-b border-border">
<UiContainer class="relative">
<div class="hidden h-[120px] w-full items-center gap-[145px] xl:flex">
<ul
class="flex items-center justify-between gap-5 whitespace-nowrap w-full"
>
<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',
route.params.id == item.id.toString()
? 'text-accent-green-light dark:text-accent-green-dark font-bold underline'
: false,
]"
@click="menuStore.navigateToItem(item)"
>
<ul class="flex items-center justify-between gap-5 whitespace-nowrap w-full">
<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',
route.params.id == item.id.toString()
? 'text-accent-green-light dark:text-accent-green-dark font-bold underline'
: false,
]" @click="menuStore.navigateToItem(item)">
0{{ index + 1 }} <br>
{{ item.front_menu_lang[0].name }}
</li>
</ul>
<ClientOnly v-if="!colorMode?.forced">
<img
class="cursor-pointer"
:src="isDark ? '/logo-dark.svg' : '/logo.svg'"
alt="logo"
@click="menuStore.navigateToItem()"
>
<img class="cursor-pointer" :src="isDark ? '/logo-dark.svg' : '/logo.svg'" alt="logo"
@click="menuStore.navigateToItem()">
</ClientOnly>
<div class="w-full flex items-center justify-between">
<div class="flex items-center gap-[30px]">
<div>
<i v-if="!userStore.isLogged"
class="uil uil-user text-[31px] cursor-pointer"
@click="menuStore.navigateToItem(menuStore.menuItems?.find((item) => item.id === 11))"></i>
<i v-if="!userStore.isLogged" class="uil uil-user text-[31px] cursor-pointer"
@click="menuStore.navigateToItem(menuStore.menuItems?.find((item:any) => item.id === 11))"></i>
<div v-else class="py-[6px] px-3 border border-block rounded-sm">
{{ userStore.user }}
</div>
@ -47,15 +35,12 @@
<CountryCurrencySelector />
</div>
<ThemeSwitcher />
<button
:class="[
'cursor-pointer transition-all text-inter whitespace-nowrap',
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',
]"
@click="menuStore.navigateToShop"
>
<button :class="[
'cursor-pointer transition-all text-inter whitespace-nowrap',
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',
]" @click="menuStore.navigateToShop">
{{ $t("eshop") }}
</button>
</div>
@ -64,35 +49,19 @@
</div>
<!-- md -->
<div
class="hidden w-full md:flex md:flex-col xl:hidden items-center justify-center"
>
<div class="hidden w-full md:flex md:flex-col xl:hidden items-center justify-center">
<div class="w-full border-border border-b">
<UiContainer class="h-[116px] flex items-center justify-between">
<ClientOnly v-if="!colorMode?.forced">
<img
class="cursor-pointer"
:src="isDark ? '/logo-dark.svg' : '/logo.svg'"
alt="logo"
@click="menuStore.navigateToItem()"
>
<img class="cursor-pointer" :src="isDark ? '/logo-dark.svg' : '/logo.svg'" alt="logo"
@click="menuStore.navigateToItem()">
</ClientOnly>
<div class="flex items-center gap-6">
<div class="flex items-center gap-[30px]">
<div>
<i
v-if="!userStore.isLogged"
class="uil uil-user text-[31px] cursor-pointer"
@click="
menuStore.navigateToItem(
menuStore.menuItems?.find((item) => item.id === 11),
)
"
/>
<div
v-else
class="py-[6px] px-3 border border-block rounded-sm"
>
<i v-if="!userStore.isLogged" class="uil uil-user text-[31px] cursor-pointer" @click="
menuStore.navigateToItem(menuStore.menuItems?.find((item:any) => item.id === 11)) " />
<div v-else class="py-[6px] px-3 border border-block rounded-sm">
{{ userStore.user }}
</div>
</div>
@ -103,54 +72,33 @@
<CountryCurrencySelector />
</div>
<ThemeSwitcher />
<i
variant="subtle"
block
class="uil uil-apps text-[33px] cursor-pointer"
@click="open = !open"
/>
<i variant="subtle" block class="uil uil-apps text-[33px] cursor-pointer" @click="open = !open" />
</div>
</UiContainer>
</div>
<UCollapsible
v-model:open="open"
:ui="{ content: 'w-full' }"
class="w-full"
>
<UCollapsible v-model:open="open" :ui="{ content: 'w-full' }" class="w-full">
<template #content>
<div class="w-full border-border border-b pt-6 pb-8">
<UiContainer class="flex flex-col gap-[30px]">
<div
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',
route.params.slug === item.front_menu_lang[0].link_rewrite
&& 'text-accent-green-light dark:text-accent-green-dark font-bold underline',
]"
@click="
() => {
menuStore.navigateToItem(item);
open = false;
}
"
>
<div 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',
route.params.slug === item.front_menu_lang[0].link_rewrite
&& 'text-accent-green-light dark:text-accent-green-dark font-bold underline',
]" @click="
() => {
menuStore.navigateToItem(item);
open = false;
}
">
<div class="leading-[70%] text-inter">
<span class="mr-4">0{{ index + 1 }}</span>
{{ item.front_menu_lang[0].name }}
</div>
<!-- <i class="uil uil-arrow-up-right text-[35px]"></i> -->
<svg
width="20"
height="20"
viewBox="0 0 26 26"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<svg width="20" height="20" viewBox="0 0 26 26" fill="none" xmlns="http://www.w3.org/2000/svg">
<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"
fill="currentColor"
/>
fill="currentColor" />
</svg>
</div>
</UiContainer>
@ -160,88 +108,51 @@
</div>
<!-- sm -->
<div
class="hidden w-full items-center justify-between sm:flex sm:flex-col md:hidden"
>
<div class="hidden w-full items-center justify-between sm:flex sm:flex-col md:hidden">
<div class="w-full border-border border-b">
<UiContainer class="h-[84px] flex items-center justify-between">
<ClientOnly v-if="!colorMode?.forced">
<img
class="cursor-pointer"
:src="isDark ? '/logo-dark.svg' : '/logo.svg'"
alt="logo"
@click="menuStore.navigateToItem()"
>
<img class="cursor-pointer" :src="isDark ? '/logo-dark.svg' : '/logo.svg'" alt="logo"
@click="menuStore.navigateToItem()">
</ClientOnly>
<div class="flex items-center gap-6">
<div class="flex items-center gap-[30px]">
<div>
<i
v-if="!userStore.isLogged"
class="uil uil-user text-[31px] cursor-pointer"
@click="
menuStore.navigateToItem(
menuStore.menuItems?.find((item) => item.id === 11),
)
"
/>
<div
v-else
class="py-[6px] px-3 border border-block rounded-sm"
>
<i v-if="!userStore.isLogged" class="uil uil-user text-[31px] cursor-pointer" @click="
menuStore.navigateToItem(menuStore.menuItems?.find((item:any) => item.id === 11)) " />
<div v-else class="py-[6px] px-3 border border-block rounded-sm">
{{ userStore.user }}
</div>
</div>
<CartPopup />
</div>
<i
variant="subtle"
block
class="uil uil-apps text-[30px] cursor-pointer"
@click="open = !open"
/>
<i variant="subtle" block class="uil uil-apps text-[30px] cursor-pointer" @click="open = !open" />
</div>
</UiContainer>
</div>
<UCollapsible
v-model:open="open"
:ui="{ content: 'w-full' }"
class="w-full"
>
<UCollapsible v-model:open="open" :ui="{ content: 'w-full' }" class="w-full">
<template #content>
<div class="w-full border-border border-b pt-6 pb-8">
<UiContainer class="flex flex-col gap-[30px]">
<div
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',
route.params.slug === item.front_menu_lang[0].link_rewrite
&& 'text-accent-green-light dark:text-accent-green-dark font-bold underline',
]"
@click="
() => {
menuStore.navigateToItem(item);
open = false;
}
"
>
<div 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',
route.params.slug === item.front_menu_lang[0].link_rewrite
&& 'text-accent-green-light dark:text-accent-green-dark font-bold underline',
]" @click="
() => {
menuStore.navigateToItem(item);
open = false;
}
">
<div class="leading-[70%] text-inter">
<span class="mr-4">0{{ index + 1 }}</span>
{{ item.front_menu_lang[0].name }}
</div>
<!-- <i class="uil uil-arrow-up-right text-[35px]"></i> -->
<svg
width="20"
height="20"
viewBox="0 0 26 26"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<svg width="20" height="20" viewBox="0 0 26 26" fill="none" xmlns="http://www.w3.org/2000/svg">
<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"
fill="currentColor"
/>
fill="currentColor" />
</svg>
</div>
<div class="flex items-center justify-between">
@ -273,74 +184,41 @@
<div class="w-full border-border border-b">
<UiContainer class="h-[84px] flex items-center justify-between">
<ClientOnly v-if="!colorMode?.forced">
<img
class="cursor-pointer"
:src="isDark ? '/logo-dark.svg' : '/logo.svg'"
alt="logo"
@click="menuStore.navigateToItem()"
>
<img class="cursor-pointer" :src="isDark ? '/logo-dark.svg' : '/logo.svg'" alt="logo"
@click="menuStore.navigateToItem()">
</ClientOnly>
<div class="flex items-center gap-6">
<div>
<i
class="uil uil-user text-[30px] cursor-pointer"
@click="
!userStore.isLogged
&& menuStore.navigateToItem(
menuStore.menuItems?.find((item) => item.id === 11),
)
"
/>
<i class="uil uil-user text-[30px] cursor-pointer" @click=" !userStore.isLogged && menuStore.navigateToItem(menuStore.menuItems?.find((item:any) => item.id === 11)) " />
</div>
<CartPopup />
<i
variant="subtle"
block
class="uil uil-apps text-[30px] cursor-pointer"
@click="open = !open"
/>
<i variant="subtle" block class="uil uil-apps text-[30px] cursor-pointer" @click="open = !open" />
</div>
</UiContainer>
</div>
<UCollapsible
v-model:open="open"
:ui="{ content: 'w-full' }"
class="w-full"
>
<UCollapsible v-model:open="open" :ui="{ content: 'w-full' }" class="w-full">
<template #content>
<div class="w-full border-border border-b pt-6 pb-8">
<UiContainer class="flex flex-col gap-[30px]">
<div
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',
route.params.slug === item.front_menu_lang[0].link_rewrite
&& 'text-accent-green-light dark:text-accent-green-dark font-bold underline',
]"
@click="
() => {
menuStore.navigateToItem(item);
open = false;
}
"
>
<div 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',
route.params.slug === item.front_menu_lang[0].link_rewrite
&& 'text-accent-green-light dark:text-accent-green-dark font-bold underline',
]" @click="
() => {
menuStore.navigateToItem(item);
open = false;
}
">
<div class="leading-[70%] text-inter">
<span class="mr-4">0{{ index + 1 }}</span>
{{ item.front_menu_lang[0].name }}
</div>
<!-- <i class="uil uil-arrow-up-right text-[35px]"></i> -->
<svg
width="20"
height="20"
viewBox="0 0 26 26"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<svg width="20" height="20" viewBox="0 0 26 26" fill="none" xmlns="http://www.w3.org/2000/svg">
<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"
fill="currentColor"
/>
fill="currentColor" />
</svg>
</div>
<div class="flex items-center justify-between">

View File

@ -2,52 +2,26 @@
<div class="border-t border-border pt-[75px]">
<UiContainer class="flex flex-col gap-24">
<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"
>
<div>
<div
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"
>
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 v-for="(item, key) in contact" :key="key">
<h3 v-if="key == 'header'" class="h4-uppercase-bold-inter">
{{ item }}
</h3>
<div v-else
class="transition-all text-inter"
>
<div v-else class="transition-all text-inter">
{{ item }}
</div>
</div>
<div class="text-red-500">
arina - doadj tu icone i style
</div>
<a
href="/lei_certificate_aurrie.pdf"
target="_blank"
rel="noopener noreferrer"
>{{ $t("Footer.Lei") }}</a>
<a href="/lei_certificate_aurrie.pdf" target="_blank" rel="noopener noreferrer">{{ $t("footer_lei") }}</a>
</div>
<div
v-for="(section, index) in docs"
:key="index"
class="flex flex-col gap-[25px] sm:gap-8 max-w-[280px]"
>
<div 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">
{{ section.translation }}
</h3>
<div v-for="(item, key) in section.data"
: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 v-for="(item, key) in section.data" :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}`">{{
item.translation
}}</a>
</div>
@ -56,12 +30,8 @@
</div>
<ClientOnly v-if="!colorMode?.forced">
<img
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()"
>
<img 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()">
</ClientOnly>
</UiContainer>
</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 justify-between">
<p>{{ $t("monthly_savings") }}</p>
<p
class="text-accent-green-light dark:text-accent-green-dark font-bold"
>
{{ store.monthlySavings }}
{{ menuStore.selectedCurrency?.sign }}
<p class="text-accent-green-light dark:text-accent-green-dark font-bold">
{{ formater.price(store.monthlySavings) }}
</p>
</div>
<input
v-model="store.monthlySavings"
type="range"
max="600"
:min="store.minValue"
class="w-full accent-button cursor-pointer"
@mouseup="store.getCalculator()"
@touchend="store.getCalculator()"
>
<input v-model="store.monthlySavings" type="range" :max="store.getMaxAmount" :min="store.getMinAmount" class="w-full accent-button cursor-pointer" @change="store.getCalculator()">
</div>
<div class="flex flex-col gap-4">
<div class="flex justify-between">
@ -99,14 +88,7 @@
{{ store.storagePeriod }}
</p>
</div>
<input
v-model="store.storagePeriod"
type="range"
max="20"
class="w-full accent-button cursor-pointer"
@mouseup="store.getCalculator()"
@touchend="store.getCalculator()"
>
<input v-model="store.storagePeriod" type="range" max="20" class="w-full accent-button cursor-pointer" @change="store.getCalculator()">
</div>
</div>
<div
@ -117,17 +99,14 @@
<h2
class="h2-bold-bounded text-accent-green-light dark:text-accent-green-dark"
>
{{ menuStore.selectedCurrency?.sign }} {{ store.totalInvestment }}
{{ formater.price(store.totalInvestment) }}
</h2>
</div>
<UiButtonArrow :arrow="true"
type="fill"
class="mx-auto sm:m-0"
>
{{
component.front_section_lang[0].data.button
}}
</UiButtonArrow>
<nuxt-link :to="{ name: `id-slug___${$i18n.locale}`, params: { id: menuStore.getInvestmentCalculatorMenu()?.id, slug: menuStore.getInvestmentCalculatorMenu()?.front_menu_lang.at(0)?.link_rewrite } }">
<UiButtonArrow :arrow="true" type="fill" class="mx-auto sm:m-0">
{{ component.front_section_lang[0].data.button }}
</UiButtonArrow>
</nuxt-link>
</div>
</div>
</div>
@ -168,9 +147,11 @@ defineProps<{
const store = useStore()
const menuStore = useMenuStore()
const { $session } = useNuxtApp()
const itemCount = ref(4)
const productStore = useProductStore()
const formater = useFormater(useNuxtApp())
async function updateItemCount() {
const width = window.innerWidth
@ -185,6 +166,10 @@ watch(itemCount, async () => {
await productStore.getList(itemCount.value)
})
watch($session.cookieData, async () => {
await productStore.getList(itemCount.value)
})
onMounted(async () => {
await updateItemCount()
window.addEventListener('resize', updateItemCount)

View File

@ -46,7 +46,8 @@
<p>
{{ $t("no_account") }}
</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">
{{ $t("sign_up_now") }}
</p>

View File

@ -19,7 +19,7 @@
{{ component.front_section_lang[0].data.title_second }}
</h3>
<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"
type="fill"
>

View File

@ -43,6 +43,7 @@ defineProps<{
const menuStore = useMenuStore()
const itemCount = ref(4)
const productStore = useProductStore()
const { $session } = useNuxtApp()
async function updateItemCount() {
const width = window.innerWidth
@ -57,6 +58,10 @@ watch(itemCount, async () => {
await productStore.getList(itemCount.value)
})
watch($session.cookieData, async () => {
await productStore.getList(itemCount.value)
})
onMounted(async () => {
await 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">
<p
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>
<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"
@ -57,7 +57,7 @@ defineProps<{ product: Product }>()
const productStore = useProductStore()
const menuStore = useMenuStore()
const formater = useFormater(useNuxtApp())
function handleImageError(event: Event) {
const img = event.target as HTMLImageElement
img.src = '/photo.svg'

View File

@ -13,7 +13,7 @@
</button>
</div>
</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]">
<!-- images block -->
<button
@ -70,14 +70,14 @@
}}</span>
</p>
</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
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
</button>
<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
" @click="productStore.incrementCartItem(product.id)">
">
<i class="uil uil-shopping-cart text-[23px] sm:text-[33px]"></i>
</div>
</div>
@ -115,7 +115,7 @@
.link_rewrite,
},
query: { prod_id: item?.id, name: item?.link_rewrite },
}">
}" @click.stop.prevent="scrollToTop">
<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">
<img :src="`/api/public/file/${item.cover_picture_uuid}.webp`" alt="pics"
@ -176,10 +176,11 @@ const menuStore = useMenuStore()
const { $session } = useNuxtApp()
const productStore = useProductStore()
const dropdownRef = ref()
const productBlockRef = ref()
// const addToCart = (p: ProductItem) => {
// alert('add to cart product: ' + p.name)
// }
function scrollToTop() {
productBlockRef.value?.scrollIntoView({ behavior: 'smooth' })
}
const formatPrice = (p: number) => {
const formatdecimal = new Intl.NumberFormat(

View File

@ -1,13 +1,5 @@
<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">
@ -16,155 +8,103 @@
</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()"
>
@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]">
<div class="space-y-[15px]">
<p class="pl-6">
{{ $t("first_name") }}
</p>
<input
:placeholder="$t('first_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") }}
</p>
<input
:placeholder="$t('last_name')"
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") }}
</p>
<input
: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]"
>
<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 class="flex items-center border-2 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>
<div class="flex items-center border border-block rounded-lg">
<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>
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 class="text-sm sm:text-xl font-normal">
{{ menuStore.selectedPhoneCountry.call_prefix }}
<p v-if="!phoneValidation && phoneValidation != null" class="mt-2 text-xs text-red-600">
{{ $t('enter_correct_data') }}
</p>
<input
id="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>
</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',
}"
>
<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-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">
{{
component.front_section_lang
&& component.front_section_lang[0].data.account_types.find(
(item) => item.name === modelValue,
)?.name
}}
{{ component.front_section_lang.at(0).data.account_types.find((item: any) => item.name === modelValue)?.name }}
</p>
<span>
<i
class="uil uil-angle-down text-2xl font-light cursor-pointer"
/></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"
>
<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"
>
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>
@ -175,21 +115,14 @@
<p class="pl-6">
{{ $t("partner_code") }}
</p>
<input
:placeholder="$t('placeholder_password')"
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"
>
<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"
>
<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")
}}
@ -199,7 +132,8 @@
<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 } }">
<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>
@ -211,6 +145,8 @@
<script lang="ts" setup>
import { onClickOutside } from '@vueuse/core'
import CheckoutInput from '../ui/CheckoutInput.vue'
import type { GenericResponse } from '~/types'
const props = defineProps<{
component: {
@ -225,6 +161,7 @@ const props = defineProps<{
account_types: {
id: number
name: string
value: string
}[]
}
id_front_section: number
@ -237,11 +174,70 @@ 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
})

View File

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

View File

@ -1,53 +1,32 @@
<template>
<div class="space-y-[15px]">
<p :for="`base-input-${id}`"
class="pl-6"
>
<p :for="`base-input-${id}`" class="pl-6">
<slot />
</p>
<div class="flex flex-col">
<div class="flex relative">
<input
:id="`base-input-${id}`"
: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"
@input="
$emit(
'update:modelValue',
($event.target as HTMLInputElement).value,
)
"
@focus="$emit('focus')"
@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"
/>
<input :id="`base-input-${id}`" :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"
@input="
$emit(
'update:modelValue',
($event.target as HTMLInputElement).value,
)
" @focus="$emit('focus')" @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
v-if="type === 'password'"
class="order-2 ml-1.5 cursor-pointer"
:title="
!isPasswordVisible ? $t('show_password') : $t('hide_password')
"
@click="isPasswordVisible = !isPasswordVisible"
>
<FaceObserver
class="ml-4 text-xl leading-6"
:is-password-visible="isPasswordVisible"
/>
<div v-if="type === 'password'" class="order-2 ml-1.5 cursor-pointer" :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>
<!-- <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">
{{ validationText }}
</p> -->
<p v-if="!validation && validation != null" class="mt-2 text-xs text-red-600">
{{ validationText }}
</p>
</div>
</div>
</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)
watch(useColorMode(), (color) => {
console.log(color)
})
onMounted(() => {
const anim = gsap.fromTo(
'h1',

View File

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

View File

@ -21,6 +21,7 @@ export const useCheckoutStore = defineStore('checkoutStore', () => {
const vNote = ref('')
const legalValidation = ref(false)
const termsValidation = ref(false)
const totalNumberOfProducts = ref(0)
// get address list
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
fullPrice.value = data.total_value
fullProductsPrice.value = data.total_value
@ -551,6 +559,7 @@ export const useCheckoutStore = defineStore('checkoutStore', () => {
paymentMethods,
currentPayment,
fullAddress,
totalNumberOfProducts,
vLegal,
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)
}
function getRegistrationMenu() {
function getPreRegistrationMenu() {
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)
}
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 req = useRequestEvent()
const url = useRequestURL()
@ -269,7 +277,7 @@ export const useMenuStore = defineStore('menuStore', () => {
async () => {
await getLocales()
await loadMenu()
await store.getMinValue()
await store.getMinMaxRange()
await store.getCalculator()
},
{ deep: true },
@ -296,7 +304,7 @@ export const useMenuStore = defineStore('menuStore', () => {
getLocales,
getProductMenu,
formatPrice,
getRegistrationMenu,
getPreRegistrationMenu,
getLoginMenu,
getInvestitionMenu,
getAboutUsMenu,
@ -304,5 +312,7 @@ export const useMenuStore = defineStore('menuStore', () => {
getAboutGoldMenu,
getContactMenu,
getShopMenu,
getRegistrationMenu,
getInvestmentCalculatorMenu,
}
})

View File

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

View File

@ -112,11 +112,6 @@ export interface GenericResponseChildren<Data> {
status: number
}
export type {
InvestmentPiece,
PlanPrediction,
PeriodToFirstPiece,
} from './planPrediction'
export type {
Product,
ProductItem,
@ -128,3 +123,4 @@ export type {
} from './product'
export type { FrontMenu, FrontMenuLang, UIFrontMenu } from './frontMenu'
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 {
total_investement_value: number
total_input_price_increase: number
@ -23,10 +28,10 @@ export interface InvestmentPiece {
currency_conversion_rate: string
max_comission_value: number
average_input_price_increase: number
features: Feature[]
features: FeatureCalculator[]
}
export interface Feature {
export interface FeatureCalculator {
feature_id: number
feature: string
value_id: number
@ -38,3 +43,8 @@ export interface PeriodToFirstPiece {
months: number
days: number
}
export interface MinMaxRange {
min: number
max: number
}