Merge pull request 'calculator and other cleaning' (#4) from linter into main
Reviewed-on: #4
This commit is contained in:
@ -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
|
||||
}">
|
||||
|
@ -23,7 +23,7 @@
|
||||
<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>
|
||||
@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>
|
||||
@ -60,10 +60,7 @@
|
||||
<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),
|
||||
)
|
||||
" />
|
||||
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>
|
||||
@ -122,10 +119,7 @@
|
||||
<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),
|
||||
)
|
||||
" />
|
||||
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>
|
||||
@ -195,12 +189,7 @@
|
||||
</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" />
|
||||
|
@ -12,7 +12,7 @@
|
||||
{{ item }}
|
||||
</div>
|
||||
</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]">
|
||||
|
248
components/section/InvestmentBlock.vue
Normal file
248
components/section/InvestmentBlock.vue
Normal 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>
|
@ -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
|
||||
}}
|
||||
<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)
|
||||
|
@ -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)
|
||||
|
@ -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'
|
||||
|
@ -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(
|
||||
|
@ -94,12 +94,7 @@
|
||||
<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
|
||||
}}
|
||||
{{ 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>
|
||||
|
@ -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 {
|
||||
|
30
composables/useFormater.ts
Normal file
30
composables/useFormater.ts
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
@ -15,10 +15,6 @@ import ScrollTrigger from 'gsap/ScrollTrigger'
|
||||
|
||||
gsap.registerPlugin(ScrollTrigger)
|
||||
|
||||
watch(useColorMode(), (color) => {
|
||||
console.log(color)
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
const anim = gsap.fromTo(
|
||||
'h1',
|
||||
|
@ -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()
|
||||
})
|
||||
|
@ -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
49
stores/investmentStore.ts
Normal 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,
|
||||
}
|
||||
})
|
@ -171,6 +171,10 @@ export const useMenuStore = defineStore('menuStore', () => {
|
||||
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()
|
||||
@ -273,7 +277,7 @@ export const useMenuStore = defineStore('menuStore', () => {
|
||||
async () => {
|
||||
await getLocales()
|
||||
await loadMenu()
|
||||
await store.getMinValue()
|
||||
await store.getMinMaxRange()
|
||||
await store.getCalculator()
|
||||
},
|
||||
{ deep: true },
|
||||
@ -309,5 +313,6 @@ export const useMenuStore = defineStore('menuStore', () => {
|
||||
getContactMenu,
|
||||
getShopMenu,
|
||||
getRegistrationMenu,
|
||||
getInvestmentCalculatorMenu,
|
||||
}
|
||||
})
|
||||
|
@ -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,
|
||||
}
|
||||
})
|
||||
|
@ -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'
|
||||
|
@ -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
|
||||
}
|
||||
|
Reference in New Issue
Block a user