cart pop-up

This commit is contained in:
2025-06-24 15:53:07 +02:00
parent 5de09aa13b
commit 98a4125804
5 changed files with 101 additions and 70 deletions

View File

@ -1,31 +1,58 @@
<template>
<div class="w-full p-[50px] bg-bg-light dark:bg-bg-dark border border-button rounded-2xl h-full">
<div class="flex items-center h-[205px]" v-if="productStore.productList">
<div class="w-[205px] h-full flex items-center justify-center">
<img :src="`https://www.yourgold.cz/api/public/file/${productStore.productList[0]?.cover_picture_uuid}.webp`"
alt="pics" class="w-auto h-full" />
</div>
<div class="flex flex-col justify-between h-full w-full gap-[7px] sm:gap-[15px] max-w-[250px]"
@click="productStore.addToCart(productStore.productList[0])">
<h3
class="text-[10px] sm:text-base md:text-lg text-xl font-bold leading-[130%] sm:leading-[150%] text-bg-dark">
{{ productStore.productList[0]?.name }}
</h3>
<div class="">
<div ref="dropdownRef">
<i @click="openCart = !openCart" class="uil uil-shopping-cart text-[31px] cursor-pointer"></i>
<div v-if="openCart" class="max-w-[1067px] w-full absolute top-[130px] z-50 right-20">
<div
class="w-full p-[50px] bg-bg-light dark:bg-bg-dark border border-button rounded-2xl h-full space-y-[55px]">
<div class="pb-[25px] border-b border-block" v-if="productStore.productList">
<div class="flex items-center h-[205px]">
<div class="w-[205px] h-full flex items-center justify-center">
<img :src="`https://www.yourgold.cz/api/public/file/${productStore.productList[0]?.cover_picture_uuid}.webp`"
alt="pics" class="w-auto h-full" />
</div>
<div class="flex flex-col justify-between h-full w-full gap-[7px] sm:gap-[15px]"
@click="productStore.addToCart(productStore.productList[0])">
<h3
class="text-[10px] sm:text-base md:text-lg text-xl font-bold leading-[130%] sm:leading-[150%] text-bg-dark max-w-[250px]">
{{ productStore.productList[0]?.name }}
</h3>
<div class="flex flex-col gap-[10px]">
<p
class="text-accent-green-light font-inter text-[12px] sm:text-[21px] md:text-2xl leading-[150%] font-bold">
{{ productStore.productList[0]?.formatted_price }}
</p>
<div class="flex items-center gap-4 text-xl">
<p class="cursor-pointer">-</p>
<div class="w-11 min-h-11 border border-button flex items-center justify-center">{{
count }}
</div>
<p>+</p>
</div>
</div>
</div>
</div>
</div>
<div class="flex items-center justify-between">
<h4 class="h4-uppercase-bold-inter">Celková částka</h4>
<p
class="text-accent-green-light font-inter text-[12px] sm:text-[21px] md:text-2xl leading-[150%] font-bold">
{{ productStore.productList[0]?.formatted_price }}
</p>
<div class="">
</div>
</div>
<UiButtonArrow class="w-full" type="fill" :arrow="true" :full="true">Přejít k pokladně</UiButtonArrow>
</div>
</div>
<UiButtonArrow class="w-full" type="fill" :arrow="true">Přejít k pokladně</UiButtonArrow>
</div>
</template>
<script lang="ts" setup>
import { onClickOutside } from "@vueuse/core";
const count = ref(1)
const productStore = useProductStore()
const openCart = ref(false);
const dropdownRef = ref(null);
onClickOutside(dropdownRef, () => {
openCart.value = false
});
</script>

View File

@ -18,7 +18,7 @@
<div class="w-full flex items-center justify-between">
<div class="flex items-center gap-[30px]">
<i class="uil uil-user text-[31px] cursor-pointer"></i>
<i @click="openCart = !openCart" class="uil uil-shopping-cart text-[31px] cursor-pointer"></i>
<CartPopup />
</div>
<div class="flex">
<LangSwitcher />
@ -30,9 +30,6 @@
{{ $t('eshop') }}
</button>
</div>
<div v-if="openCart" class="max-w-[1067px] w-full absolute top-[130px] z-50 right-20">
<CartPopup />
</div>
</div>
</UiContainer>
</div>
@ -219,7 +216,6 @@ import LangSwitcher from "./LangSwitcher.vue";
const menuStore = useMenuStore();
const productStore = useProductStore();
const open = ref(false);
const openCart = ref(false);
const colorMode = useColorMode();
// productStore.getCart()

View File

@ -10,6 +10,7 @@
: type === 'border'
? 'border-button text-button group-hover:border-button-hover group-hover:text-button-hover border'
: 'border-button text-button dark:border-block dark:text-block group-hover:border-button-hover group-hover:text-button-hover border',
full && 'w-full'
]"
>
<slot />
@ -48,5 +49,8 @@ defineProps({
arrow: {
type: Boolean,
},
full: {
type: Boolean,
},
});
</script>

View File

@ -1,15 +1,20 @@
import { NuxtErrorBoundary } from "#components";
import { useMyFetch } from "#imports";
import type { GenericResponse, GenericResponseItems, UserCart } from "~/types";
import type {
GenericResponse,
GenericResponseChildren,
GenericResponseItems,
UserCart,
} from "~/types";
import type { Product } from "~/types/product";
export const useProductStore = defineStore("productStore", () => {
const productList = ref<Product>();
const productList = ref<Product[]>();
const modules = ref();
async function getList(count: number, categoryId = 1) {
try {
const { data } = await useMyFetch<GenericResponseItems<Product>>(
const { data } = await useMyFetch<GenericResponseItems<[]>>(
`/api/public/products/category/${categoryId}?p=1&elems=${count}`,
{
headers: {
@ -33,20 +38,18 @@ export const useProductStore = defineStore("productStore", () => {
async function getModules() {
try {
const res = await fetch(
`http://127.0.0.1:4000/api/public/module/e_shop`,
const { data } = await useMyFetch<GenericResponseChildren<[]>>(
`/api/public/module/e_shop`,
{
headers: {
"Content-Type": "application/json",
},
onErrorOccured: (_, status) => {
throw new Error(`HTTP error: ${status}`);
},
}
);
if (!res.ok) {
throw new Error(`HTTP error: ${res.status}`);
}
const data = await res.json();
modules.value = data.children.find(
(item: { id: number; name: string }) =>
item.name === "currency_rates_bar"
@ -58,22 +61,18 @@ export const useProductStore = defineStore("productStore", () => {
async function addToCart(product: Product) {
try {
const res = await fetch(
`http://127.0.0.1:4000/api/public/user/cart/item/add/${product.id}/1`,
const { data } = await useMyFetch<GenericResponse<UserCart>>(
`/api/public/user/cart/item/add/${product.id}/1`,
{
method: "PUT",
headers: {
"Content-Type": "application/json",
},
onErrorOccured: (_, status) => {
throw new Error(`HTTP error: ${status}`);
},
}
);
if (!res.ok) {
throw new Error(`HTTP error: ${res.status}`);
}
const data = await res.json();
console.log(data);
} catch (error) {
console.error("getList error:", error);
}

View File

@ -1,6 +1,11 @@
import { useMyFetch } from "#imports";
import { usePB } from "~/composables/usePB";
import type { componentsListType, GenericResponse, PBPageItem, PlanPrediction } from "~/types";
import type {
componentsListType,
GenericResponse,
PBPageItem,
PlanPrediction,
} from "~/types";
// import { useI18n } from "vue-i18n";
export const useStore = defineStore("store", () => {
@ -11,20 +16,21 @@ export const useStore = defineStore("store", () => {
// calculator
const monthlySavings = ref(137);
const storagePeriod = ref(10);
const totalInvestment:Ref<number> = ref(0)
const minValue = ref()
const totalInvestment: Ref<number> = ref(0);
const minValue = ref();
// login
const email = ref()
const password = ref()
const email = ref();
const password = ref();
const components = ref({} as PBPageItem[]);
const getSections = async (id: string) => {
pb.cancelRequest("menu_view");
components.value = (
await pb.collection<PBPageItem>("page_view").getList(1, 50, {
filter: `id="${id}"&&(section_lang_id_lang="${$i18n.locale.value
}"||section_is_no_lang=${true})`,
filter: `id="${id}"&&(section_lang_id_lang="${
$i18n.locale.value
}"||section_is_no_lang=${true})`,
sort: "page_section_id_position",
})
).items as PBPageItem[];
@ -72,18 +78,19 @@ export const useStore = defineStore("store", () => {
async function getCalculator() {
try {
const {data} = await useMyFetch<GenericResponse<PlanPrediction>>(
const { data } = await useMyFetch<GenericResponse<PlanPrediction>>(
`/api/public/plan-prediction/easy/calculate?monthly_deposit=${monthlySavings.value}&years=${storagePeriod.value}`,
{
headers: {
"Content-Type": "application/json",
},
onErrorOccured: (_, status) => { throw new Error(`HTTP error: ${status}`) },
onErrorOccured: (_, status) => {
throw new Error(`HTTP error: ${status}`);
},
}
);
totalInvestment.value = data.total_investement_value
totalInvestment.value = data.total_investement_value;
} catch (error) {
console.error("getList error:", error);
}
@ -91,13 +98,15 @@ export const useStore = defineStore("store", () => {
async function getMinValue() {
try {
const {data} = await useMyFetch<GenericResponse<number>>(
'/api/public/plan-prediction/free/minimum',
const { data } = await useMyFetch<GenericResponse<number>>(
"/api/public/plan-prediction/free/minimum",
{
headers: {
"Content-Type": "application/json",
},
onErrorOccured: (_, status) => { throw new Error(`HTTP error: ${status}`) },
onErrorOccured: (_, status) => {
throw new Error(`HTTP error: ${status}`);
},
}
);
@ -106,8 +115,7 @@ export const useStore = defineStore("store", () => {
// }
// const data = await res.json();
minValue.value = data
minValue.value = data;
} catch (error) {
console.error("getList error:", error);
}
@ -115,34 +123,31 @@ export const useStore = defineStore("store", () => {
async function logIn() {
try {
const res = await fetch(
'http://127.0.0.1:4000/api/public/user/session/start',
const { data } = await useMyFetch<GenericResponse<object>>(
`/api/public/user/session/start`,
{
method: 'POST',
method: "POST",
body: JSON.stringify({
mail: email.value,
password: password.value
password: password.value,
}),
headers: {
"Content-Type": "application/json",
},
onErrorOccured: (_, status) => {
throw new Error(`HTTP error: ${status}`);
},
}
);
if (!res.ok) {
throw new Error(`HTTP error: ${res.status}`);
}
const data = await res.json();
minValue.value = data.data
minValue.value = data;
} catch (error) {
console.error("getList error:", error);
}
}
getCalculator()
getMinValue()
getCalculator();
getMinValue();
return {
currentPageID,