product page and linter

This commit is contained in:
2025-07-03 11:13:42 +02:00
parent fbb6c071af
commit 90e1d70f64
72 changed files with 12667 additions and 6578 deletions

View File

@ -1,96 +1,98 @@
import type { GenericResponse, GenericResponseItems, UserCart } from "~/types";
import type { AddressesList, UserAddressOfficial } from "~/types/checkout";
import { validation } from "../utils/validation";
import { REGEX_PHONE } from "../utils/regex";
import type { CartProduct } from "~/types/product";
import { validation } from '../utils/validation'
import { REGEX_PHONE } from '../utils/regex'
import type { GenericResponse, GenericResponseItems, UserCart } from '~/types'
import type { AddressesList, UserAddressOfficial } from '~/types/checkout'
import type { CartProduct } from '~/types/product'
export const useCheckoutStore = defineStore("checkoutStore", () => {
const { $toast } = useNuxtApp();
const menuStore = useMenuStore();
const selectedIso = ref(menuStore.selectedCountry);
const showSummary = ref(false);
export const useCheckoutStore = defineStore('checkoutStore', () => {
const { $toast } = useNuxtApp()
const menuStore = useMenuStore()
const selectedIso = ref(menuStore.selectedCountry)
const showSummary = ref(false)
// get address list
const addressesList = ref<AddressesList[]>();
const activeAddress = ref<AddressesList | null>();
const addressesList = ref<AddressesList[]>()
const activeAddress = ref<AddressesList | null>()
async function getAddressList() {
try {
const { data } = await useMyFetch<GenericResponse<AddressesList[]>>(
`/api/restricted/user/addresses`,
{
headers: {
"Content-Type": "application/json",
'Content-Type': 'application/json',
},
onErrorOccured: async (_, status) => {
throw createError({
statusCode: status,
statusMessage: `HTTP error: ${status}`,
});
})
},
}
);
},
)
addressesList.value = data;
activeAddress.value = addressesList.value[0];
} catch (error) {
console.error("restrictedAddress error:", error);
addressesList.value = data
activeAddress.value = addressesList.value[0]
}
catch (error) {
console.error('restrictedAddress error:', error)
}
}
// get user data
const userName = ref("");
const lastName = ref("");
const address = ref("");
const postCode = ref("");
const city = ref("");
const country = ref("");
const phoneNumber = ref("");
const accountPhoneNumber = ref("");
const userName = ref('')
const lastName = ref('')
const address = ref('')
const postCode = ref('')
const city = ref('')
const country = ref('')
const phoneNumber = ref('')
const accountPhoneNumber = ref('')
async function getUserData() {
try {
const { data } = await useMyFetch<GenericResponse<UserAddressOfficial>>(
`/api/restricted/user/address/official`,
{
headers: {
"Content-Type": "application/json",
'Content-Type': 'application/json',
},
onErrorOccured: async (_, status) => {
throw createError({
statusCode: status,
statusMessage: `HTTP error: ${status}`,
});
})
},
}
);
},
)
userName.value = data.address.name;
lastName.value = data.address.surname;
address.value = data.address.street;
postCode.value = data.address.postcode;
city.value = data.address.city;
country.value = data.address.country.country_lang[0].name;
} catch (error) {
console.error("getUserData error:", error);
userName.value = data.address.name
lastName.value = data.address.surname
address.value = data.address.street
postCode.value = data.address.postcode
city.value = data.address.city
country.value = data.address.country.country_lang[0].name
}
catch (error) {
console.error('getUserData error:', error)
}
}
// upload new address
const vNewAddressName = ref("");
const vNewAddressSurname = ref("");
const vNewAddressAddress = ref("");
const vNewAddressCode = ref("");
const vNewAddressCity = ref("");
const vNewAddressCountry = ref();
const vUseAccountPhoneNumber = ref(false);
const isOpen = ref<boolean>(false);
const vNewAddressName = ref('')
const vNewAddressSurname = ref('')
const vNewAddressAddress = ref('')
const vNewAddressCode = ref('')
const vNewAddressCity = ref('')
const vNewAddressCountry = ref()
const vUseAccountPhoneNumber = ref(false)
const isOpen = ref<boolean>(false)
async function uploadAddress() {
try {
const res = await useMyFetch<GenericResponse<object>>(
`/api/restricted/user/address`,
{
method: "POST",
method: 'POST',
headers: {
"Content-Type": "application/json",
'Content-Type': 'application/json',
},
body: JSON.stringify({
address: {
@ -106,59 +108,61 @@ export const useCheckoutStore = defineStore("checkoutStore", () => {
throw createError({
statusCode: status,
statusMessage: `HTTP error: ${status}`,
});
})
},
}
);
},
)
if (res.status === 200) {
$toast.success("Address successfully added", {
$toast.success('Address successfully added', {
autoClose: 5000,
dangerouslyHTMLString: true,
});
isOpen.value = false;
getAddressList();
} else {
$toast.error("Failed to add address. Please try again.", {
autoClose: 5000,
dangerouslyHTMLString: true,
});
})
isOpen.value = false
getAddressList()
}
} catch (error) {
console.error("uploadAddress error:", error);
else {
$toast.error('Failed to add address. Please try again.', {
autoClose: 5000,
dangerouslyHTMLString: true,
})
}
}
catch (error) {
console.error('uploadAddress error:', error)
}
}
const currentPrefix = ref<string | number>(
menuStore.selectedCountry.call_prefix
);
menuStore.selectedCountry.call_prefix,
)
const changePrefix = (item: string) => {
currentPrefix.value = item;
};
const phoneValidation = ref<boolean | null>(null);
currentPrefix.value = item
}
const phoneValidation = ref<boolean | null>(null)
const userStore = useUserStore();
const userStore = useUserStore()
// send form
async function sendForm() {
let phoneNum = vUseAccountPhoneNumber.value
const phoneNum = vUseAccountPhoneNumber.value
? accountPhoneNumber.value
: `${currentPrefix.value}${phoneNumber.value}`.replaceAll(" ", "").trim();
: `${currentPrefix.value}${phoneNumber.value}`.replaceAll(' ', '').trim()
// if (vUseAccountPhoneNumber.value) {
// phoneNum = phoneNumber.value;
// }
phoneValidation.value = validation(phoneNum, 1, 49, REGEX_PHONE);
phoneValidation.value = validation(phoneNum, 1, 49, REGEX_PHONE)
if (!phoneValidation.value && !vUseAccountPhoneNumber.value) {
return;
return
}
try {
const res = await useMyFetch<GenericResponse<object>>(
`/api/restricted/cart/checkout/delivery`,
{
method: "PUT",
method: 'PUT',
headers: {
"Content-Type": "application/json",
'Content-Type': 'application/json',
},
body: JSON.stringify({
address: {
@ -176,154 +180,160 @@ export const useCheckoutStore = defineStore("checkoutStore", () => {
throw createError({
statusCode: status,
statusMessage: `HTTP error: ${status}`,
});
})
},
}
);
},
)
if (res.status === 200) {
$toast.success("Form successfully sent", {
$toast.success('Form successfully sent', {
autoClose: 5000,
dangerouslyHTMLString: true,
});
})
// redirectToSummary();
showSummary.value = true;
} else {
$toast.error("Failed to send form. Please try again.", {
showSummary.value = true
}
else {
$toast.error('Failed to send form. Please try again.', {
autoClose: 5000,
dangerouslyHTMLString: true,
});
})
}
} catch (error) {
console.error("uploadAddress error:", error);
}
catch (error) {
console.error('uploadAddress error:', error)
}
}
const changeActive = (item: any) => {
activeAddress.value = item;
};
activeAddress.value = item
}
async function getCheckout() {
try {
const res = await useMyFetch<GenericResponse<object>>(
await useMyFetch<GenericResponse<object>>(
`/api/restricted/cart/checkout`,
{
method: "PUT",
method: 'PUT',
headers: {
"Content-Type": "application/json",
'Content-Type': 'application/json',
},
onErrorOccured: async (_, status) => {
throw createError({
statusCode: status,
statusMessage: `HTTP error: ${status}`,
});
})
},
}
);
} catch (error) {
console.error("uploadAddress error:", error);
},
)
}
catch (error) {
console.error('uploadAddress error:', error)
}
}
// get user cart
const products = ref<CartProduct[]>();
const fullPrice = ref();
const fullProductsPrice = ref();
const products = ref<CartProduct[]>()
const fullPrice = ref()
const fullProductsPrice = ref()
async function getUserCart() {
try {
const { data } = await useMyFetch<GenericResponse<UserCart>>(
`/api/public/user/cart`,
{
headers: {
"Content-Type": "application/json",
'Content-Type': 'application/json',
},
onErrorOccured: async (_, status) => {
throw createError({
statusCode: status,
statusMessage: `HTTP error: ${status}`,
});
})
},
}
);
},
)
products.value = data.cart_items;
fullPrice.value = data.total_value;
fullProductsPrice.value = data.total_value;
fullPrice.value = Number(fullPrice.value) + Number(shippingPrice.value);
} catch (error) {
console.error("getUserCart error:", error);
products.value = data.cart_items
fullPrice.value = data.total_value
fullProductsPrice.value = data.total_value
fullPrice.value = Number(fullPrice.value) + Number(shippingPrice.value)
}
catch (error) {
console.error('getUserCart error:', error)
}
}
// get delivery options
const deliveryOption = ref();
const currentDelivery = ref();
const shippingPrice = ref();
const deliveryOption = ref()
const currentDelivery = ref()
const shippingPrice = ref()
async function getDeliveryOptions() {
try {
const { data } = await useMyFetch<
GenericResponseItems<{
items: [
{
country_iso: string;
country_name: string;
delivery_supplier_id: number;
delivery_supplier_name: string;
id: number;
shippment_price: string;
}
];
country_iso: string
country_name: string
delivery_supplier_id: number
delivery_supplier_name: string
id: number
shippment_price: string
},
]
}>
>(`/api/restricted/cart/checkout/delivery-options`, {
headers: {
"Content-Type": "application/json",
'Content-Type': 'application/json',
},
onErrorOccured: async (_, status) => {
throw createError({
statusCode: status,
statusMessage: `HTTP error: ${status}`,
});
})
},
});
})
console.log(data);
deliveryOption.value = data.items;
currentDelivery.value = data.items[0];
shippingPrice.value = data.items[0].shippment_price;
fullPrice.value = Number(fullPrice.value) + Number(shippingPrice.value);
} catch (error) {
console.error("getUserCart error:", error);
console.log(data)
deliveryOption.value = data.items
currentDelivery.value = data.items[0]
shippingPrice.value = data.items[0].shippment_price
fullPrice.value = Number(fullPrice.value) + Number(shippingPrice.value)
}
catch (error) {
console.error('getUserCart error:', error)
}
}
const defaultAddress = ref();
const defaultAddress = ref()
async function getDefAddress() {
try {
const { data } = await useMyFetch<
GenericResponse<{
addresses: [
{
is_default: string;
}
];
is_default: string
},
]
}>
>(`/api/public/user`, {
headers: {
"Content-Type": "application/json",
'Content-Type': 'application/json',
},
onErrorOccured: async (_, status) => {
throw createError({
statusCode: status,
statusMessage: `HTTP error: ${status}`,
});
})
},
});
})
defaultAddress.value = data.addresses.find(
(el: any) => el.is_default === true
);
} catch (error) {
console.error("getUserCart error:", error);
(el: any) => el.is_default === true,
)
}
catch (error) {
console.error('getUserCart error:', error)
}
}
@ -371,5 +381,5 @@ export const useCheckoutStore = defineStore("checkoutStore", () => {
getUserCart,
getDeliveryOptions,
getDefAddress,
};
});
}
})

View File

@ -1,3 +1,4 @@
import { useStore } from './store'
import type {
Country,
Currency,
@ -6,146 +7,159 @@ import type {
GenericResponseItems,
Language,
UIFrontMenu,
} from "~/types";
import { useStore } from "./store";
import { useMyFetch } from "#imports";
// import { useSession } from "~/plugins/01_i18n";
} from '~/types'
import { useMyFetch } from '#imports'
function buildTreeRecursive(
data: (FrontMenu | UIFrontMenu)[],
parentId: number
parentId: number,
): UIFrontMenu[] {
const children = data.filter(
(item): item is UIFrontMenu =>
item.id_parent === parentId && !item.is_default
);
item.id_parent === parentId && !item.is_default,
)
return children.map((item) => ({
return children.map(item => ({
...item,
children: buildTreeRecursive(data, item.id),
}));
}))
}
export const useMenuStore = defineStore("menuStore", () => {
const store = useStore();
const { $i18n } = useNuxtApp();
export const useMenuStore = defineStore('menuStore', () => {
const store = useStore()
const { $i18n } = useNuxtApp()
// const session = useSession();
const { $session } = useNuxtApp();
const router = useRouter();
const route = useRoute();
const { $session } = useNuxtApp()
const router = useRouter()
const route = useRoute()
const openMenu = ref(false);
const openDropDown = ref(false);
const openMenu = ref(false)
const openDropDown = ref(false)
const defaultMenu = ref();
const menu = ref([] as UIFrontMenu[]);
const menuItems = ref([] as FrontMenu[]);
const defaultMenu = ref()
const menu = ref([] as UIFrontMenu[])
const menuItems = ref([] as FrontMenu[])
// curr/country
const selectedCountry = ref({} as Country);
const selectedPhoneCountry = ref({} as Country);
const selectedCurrency = ref({} as Currency);
const selectedLanguage = ref({} as Language);
const selectedCountry = ref({} as Country)
const selectedPhoneCountry = ref({} as Country)
const selectedCurrency = ref({} as Currency)
const selectedLanguage = ref({} as Language)
const countries = ref([] as Country[]);
const currencies = ref([] as Currency[]);
const languages = ref([] as Language[]);
const countries = ref([] as Country[])
const currencies = ref([] as Currency[])
const languages = ref([] as Language[])
const getLocales = async () => {
const { data: countriesList } = await useMyFetch<GenericResponse<Country[]>>(`/api/public/country/list`);
countries.value = countriesList;
selectedCountry.value = countriesList.find((country) => country.iso_code === $session.currentCountryIso.value) as Country;
selectedPhoneCountry.value = countriesList.find((country) => country.iso_code === $session.currentCountryIso.value) as Country;
const { data: countriesList } = await useMyFetch<
GenericResponse<Country[]>
>(`/api/public/country/list`)
countries.value = countriesList
selectedCountry.value = countriesList.find(
country => country.iso_code === $session.currentCountryIso.value,
) as Country
selectedPhoneCountry.value = countriesList.find(
country => country.iso_code === $session.currentCountryIso.value,
) as Country
const { data: currenciesList } = await useMyFetch<
GenericResponseItems<Currency[]>
>(`/api/public/currencies`)
currencies.value = currenciesList.items
selectedCurrency.value = currenciesList.items.find(
currency => currency.iso_code === $session.currentCurrencyIso.value,
) as Currency
const { data: currenciesList } = await useMyFetch<GenericResponseItems<Currency[]>>(`/api/public/currencies`)
currencies.value = currenciesList.items;
selectedCurrency.value = currenciesList.items.find((currency) => currency.iso_code === $session.currentCurrencyIso.value) as Currency;
const { data: languagesList } = await useMyFetch<GenericResponseItems<Language[]>>(`/api/public/languages`)
languages.value = languagesList.items;
selectedLanguage.value = languagesList.items.find((language) => language.iso_code === $session.currentLanguageIso.value) as Language;
};
const { data: languagesList } = await useMyFetch<
GenericResponseItems<Language[]>
>(`/api/public/languages`)
languages.value = languagesList.items
selectedLanguage.value = languagesList.items.find(
language => language.iso_code === $session.currentLanguageIso.value,
) as Language
}
const loadMenu = async () => {
try {
const { data } = await useMyFetch<GenericResponse<FrontMenu[]>>(
`/api/public/front/menu`,
{
onErrorOccured: (err, status) => {
console.log(err, status);
console.log(err, status)
},
}
);
},
)
menuItems.value = data;
menuItems.value = data
const root = data.find((item) => item.is_root) as UIFrontMenu;
defaultMenu.value = data.find((item) => item.is_default);
const root = data.find(item => item.is_root) as UIFrontMenu
defaultMenu.value = data.find(item => item.is_default)
if (root) {
menu.value = buildTreeRecursive(data, root.id);
} else {
console.warn("Root menu item not found");
menu.value = [];
menu.value = buildTreeRecursive(data, root.id)
}
else {
console.warn('Root menu item not found')
menu.value = []
}
} catch (error) {
console.log(error);
}
};
catch (error) {
console.log(error)
}
}
const navigateToItem = (item?: UIFrontMenu) => {
if (item) {
router.push({
params: { slug: item.front_menu_lang[0].link_rewrite, id: item.id },
name: `id-slug___${$i18n.locale.value}`,
});
openDropDown.value = false;
} else {
})
openDropDown.value = false
}
else {
router.push({
params: {
slug: defaultMenu.value.front_menu_lang[0].link_rewrite,
id: defaultMenu.value.id,
},
name: `id-slug___${$i18n.locale.value}`,
});
})
}
};
function navigateToShop() {
navigateToItem(menuItems.value?.find((item) => item.id === 5));
}
const getFirstImage = (size: "l" | "m" | "s" = "m", needbaseurl: boolean) => {
const req = useRequestEvent();
const url = useRequestURL();
function navigateToShop() {
navigateToItem(menuItems.value?.find(item => item.id === 5))
}
function getProductMenu() {
return menuItems.value?.find(item => item.id === 13)
}
const getFirstImage = (size: 'l' | 'm' | 's' = 'm', needbaseurl: boolean) => {
const req = useRequestEvent()
const url = useRequestURL()
// let img = "";
const img: string[] = []
for (const s in store.components) {
if (store.components[s].front_section.img.length === 0) continue;
img.push(`/api/public/file/${store.components[s].front_section.img[0]}_${size}.webp`)
if (img.length > 0) break;;
if (store.components[s].front_section.img.length === 0) continue
img.push(
`/api/public/file/${store.components[s].front_section.img[0]}_${size}.webp`,
)
if (img.length > 0) break
}
if (img.length > 0) {
if (needbaseurl) {
return `${req?.headers.get("x-forwarded-proto") || url.protocol}://${req?.headers.get("x-forwarded-host") || url.host || req?.headers.get("host")}${img[0]}`;
return `${req?.headers.get('x-forwarded-proto') || url.protocol}://${req?.headers.get('x-forwarded-host') || url.host || req?.headers.get('host')}${img[0]}`
}
return img[0];
return img[0]
}
return "";
};
return ''
}
const headMeta = computed(() => {
const item = menuItems.value?.find(
(item) => item.id.toString() === route.params.id
);
item => item.id.toString() === route.params.id,
)
const meta = {
title: item?.front_menu_lang[0].meta_title,
@ -154,59 +168,66 @@ export const useMenuStore = defineStore("menuStore", () => {
},
link: [
// { rel: "manifest", href: "/api/manifest.json" }
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.png' },
],
script:[
{src:"https://leiadmin.com/leitag.js?lei=894500UT83EISNNA8D04&color=dark"}
script: [
{
src: 'https://leiadmin.com/leitag.js?lei=894500UT83EISNNA8D04&color=dark',
defer: true,
},
],
meta: [
{
hid: "description",
name: "description",
hid: 'description',
name: 'description',
content: item?.front_menu_lang[0].meta_description,
},
{
property: "og:title",
property: 'og:title',
content: item?.front_menu_lang[0].meta_title,
},
{
property: "og:description",
property: 'og:description',
content: item?.front_menu_lang[0].meta_description,
},
{
property: "og:image",
content: getFirstImage("m", true),
property: 'og:image',
content: getFirstImage('m', true),
},
{
property: "twitter:title",
property: 'twitter:title',
content: item?.front_menu_lang[0].meta_title,
},
{
property: "twitter:description",
property: 'twitter:description',
content: item?.front_menu_lang[0].meta_description,
},
{
property: "twitter:image",
content: getFirstImage("m", true),
property: 'twitter:image',
content: getFirstImage('m', true),
},
],
};
const preload = getFirstImage("l", false);
if (preload) {
meta.link.push({ rel: "preload", as: "image", href: preload } as never);
}
return meta;
const preload = getFirstImage('l', false)
if (preload) {
meta.link.push({ rel: 'preload', as: 'image', href: preload } as never)
}
});
return meta
})
// watches
watch(() => $session.cookieData, async () => {
await getLocales();
await loadMenu();
await store.getMinValue();
await store.getCalculator();
}, { deep: true });
// watches
watch(
() => $session.cookieData,
async () => {
await getLocales()
await loadMenu()
await store.getMinValue()
await store.getCalculator()
},
{ deep: true },
)
return {
menu,
@ -226,5 +247,6 @@ export const useMenuStore = defineStore("menuStore", () => {
loadMenu,
navigateToItem,
getLocales,
};
});
getProductMenu,
}
})

View File

@ -1,17 +1,16 @@
import { useMyFetch } from "#imports";
import { useMyFetch } from '#imports'
import type {
CartItem,
GenericResponse,
GenericResponseChildren,
GenericResponseItems,
UserCart,
} from "~/types";
import type { Product } from "~/types/product";
} from '~/types'
import type { Product } from '~/types/product'
export const useProductStore = defineStore("productStore", () => {
const { $toast } = useNuxtApp();
const productList = ref<Product[]>();
const modules = ref();
export const useProductStore = defineStore('productStore', () => {
const { $toast } = useNuxtApp()
const productList = ref<Product[]>()
const modules = ref()
async function getList(count: number, categoryId = 1) {
try {
@ -19,21 +18,22 @@ export const useProductStore = defineStore("productStore", () => {
`/api/public/products/category/${categoryId}?p=1&elems=${count}`,
{
headers: {
"Content-Type": "application/json",
'Content-Type': 'application/json',
},
onErrorOccured: async (_, status) => {
// await navigateTo("/error", { replace: true });
throw createError({
statusCode: status,
statusMessage: `HTTP error: ${status}`,
});
})
},
}
);
},
)
productList.value = data.items;
} catch (error) {
console.error("getList error:", error);
productList.value = data.items
}
catch (error) {
console.error('getList error:', error)
}
}
@ -43,20 +43,21 @@ export const useProductStore = defineStore("productStore", () => {
`/api/public/module/e_shop`,
{
headers: {
"Content-Type": "application/json",
'Content-Type': 'application/json',
},
onErrorOccured: (_, status) => {
throw new Error(`HTTP error: ${status}`);
throw new Error(`HTTP error: ${status}`)
},
}
);
},
)
modules.value = data.children.find(
(item: { id: number; name: string }) =>
item.name === "currency_rates_bar"
);
} catch (error) {
console.error("getList error:", error);
(item: { id: number, name: string }) =>
item.name === 'currency_rates_bar',
)
}
catch (error) {
console.error('getList error:', error)
}
}
@ -65,34 +66,36 @@ export const useProductStore = defineStore("productStore", () => {
const res = await useMyFetch<GenericResponse<object>>(
`/api/public/user/cart/item/add/${id}/1`,
{
method: "PUT",
method: 'PUT',
headers: {
"Content-Type": "application/json",
'Content-Type': 'application/json',
},
onErrorOccured: (_, status) => {
throw new Error(`HTTP error: ${status}`);
throw new Error(`HTTP error: ${status}`)
},
}
);
},
)
if (res.status === 200) {
$toast.success("Item successfully added to your cart.", {
$toast.success('Item successfully added to your cart.', {
autoClose: 5000,
dangerouslyHTMLString: true,
});
getCart();
} else {
$toast.error("Failed to add item to cart. Please try again.", {
autoClose: 5000,
dangerouslyHTMLString: true,
});
})
getCart()
}
} catch (error) {
$toast.error("An unexpected error occurred while updating your cart.", {
else {
$toast.error('Failed to add item to cart. Please try again.', {
autoClose: 5000,
dangerouslyHTMLString: true,
})
}
}
catch (error) {
$toast.error('An unexpected error occurred while updating your cart.', {
autoClose: 5000,
dangerouslyHTMLString: true,
});
console.error("incrementCartItem error:", error);
})
console.error('incrementCartItem error:', error)
}
}
@ -101,34 +104,36 @@ export const useProductStore = defineStore("productStore", () => {
const res = await useMyFetch<GenericResponse<object>>(
`/api/public/user/cart/item/subtract/${id}/1`,
{
method: "PUT",
method: 'PUT',
headers: {
"Content-Type": "application/json",
'Content-Type': 'application/json',
},
onErrorOccured: (_, status) => {
throw new Error(`HTTP error: ${status}`);
throw new Error(`HTTP error: ${status}`)
},
}
);
},
)
if (res.status === 200) {
$toast.success("Item successfully removed from your cart.", {
$toast.success('Item successfully removed from your cart.', {
autoClose: 5000,
dangerouslyHTMLString: true,
});
getCart();
} else {
$toast.error("Failed to removed item from cart. Please try again.", {
autoClose: 5000,
dangerouslyHTMLString: true,
});
})
getCart()
}
} catch (error) {
$toast.error("An unexpected error occurred while updating your cart.", {
else {
$toast.error('Failed to removed item from cart. Please try again.', {
autoClose: 5000,
dangerouslyHTMLString: true,
})
}
}
catch (error) {
$toast.error('An unexpected error occurred while updating your cart.', {
autoClose: 5000,
dangerouslyHTMLString: true,
});
console.error("decrementCartItem error:", error);
})
console.error('decrementCartItem error:', error)
}
}
@ -137,55 +142,58 @@ export const useProductStore = defineStore("productStore", () => {
const res = await useMyFetch<GenericResponse<object>>(
`/api/public/user/cart/item/${id}`,
{
method: "DELETE",
method: 'DELETE',
headers: {
"Content-Type": "application/json",
'Content-Type': 'application/json',
},
onErrorOccured: (_, status) => {
throw new Error(`HTTP error: ${status}`);
throw new Error(`HTTP error: ${status}`)
},
}
);
},
)
if (res.status === 200) {
$toast.success("Item successfully removed from your cart.", {
$toast.success('Item successfully removed from your cart.', {
autoClose: 5000,
dangerouslyHTMLString: true,
});
getCart();
} else {
$toast.error("Failed to removed item from cart. Please try again.", {
autoClose: 5000,
dangerouslyHTMLString: true,
});
})
getCart()
}
} catch (error) {
$toast.error("An unexpected error occurred while updating your cart.", {
else {
$toast.error('Failed to removed item from cart. Please try again.', {
autoClose: 5000,
dangerouslyHTMLString: true,
})
}
}
catch (error) {
$toast.error('An unexpected error occurred while updating your cart.', {
autoClose: 5000,
dangerouslyHTMLString: true,
});
console.error("deleteCartItem error:", error);
})
console.error('deleteCartItem error:', error)
}
}
const cart = ref({} as UserCart);
const cart = ref({} as UserCart)
async function getCart() {
try {
const { data } = await useMyFetch<GenericResponse<UserCart>>(
`/api/public/user/cart`,
{
headers: {
"Content-Type": "application/json",
'Content-Type': 'application/json',
},
onErrorOccured: (_, status) => {
throw new Error(`HTTP error: ${status}`);
throw new Error(`HTTP error: ${status}`)
},
}
);
},
)
cart.value = data;
} catch (error) {
console.error("getList error:", error);
cart.value = data
}
catch (error) {
console.error('getList error:', error)
}
}
@ -199,5 +207,5 @@ export const useProductStore = defineStore("productStore", () => {
decrementCartItem,
deleteCartItem,
getCart,
};
});
}
})

View File

@ -1,65 +1,66 @@
import { useMyFetch } from "#imports";
import { useMyFetch } from '#imports'
import type {
componentsListType,
GenericResponse,
PlanPrediction,
} from "~/types";
import type { FrontPageSection } from "~/types/frontSection";
} from '~/types'
import type { FrontPageSection } from '~/types/frontSection'
export const useStore = defineStore("store", () => {
const currentPageID = ref("");
const { $toast } = useNuxtApp();
export const useStore = defineStore('store', () => {
const currentPageID = ref('')
// calculator
const monthlySavings = ref(137);
const storagePeriod = ref(10);
const totalInvestment: Ref<number> = ref(0);
const minValue = ref();
const monthlySavings = ref(137)
const storagePeriod = ref(10)
const totalInvestment: Ref<number> = ref(0)
const minValue = ref()
const components = ref({} as FrontPageSection[]);
const components = ref({} as FrontPageSection[])
const getSections = async (id: string) => {
const { data } = await useMyFetch<GenericResponse<FrontPageSection[]>>(
`/api/public/front/sections/${id}`
);
components.value = data;
};
`/api/public/front/sections/${id}`,
)
components.value = data
}
async function getComponents(): Promise<componentsListType[]> {
try {
const children = components.value;
const children = components.value
if (!children || !Array.isArray(children)) {
console.warn("No components available in store.");
return [];
console.warn('No components available in store.')
return []
}
const componentsList = [] as componentsListType[];
const componentsList = [] as componentsListType[]
for (const child of children) {
const componentName = child.front_section.component_name;
if (!componentName) continue;
const componentName = child.front_section.component_name
if (!componentName) continue
try {
const componentInstance = (
await import(`@/components/section/${componentName}.vue`)
).default;
).default
const nonReactiveComponent = markRaw(componentInstance);
const nonReactiveComponent = markRaw(componentInstance)
componentsList.push({
name: componentName,
component: child.front_section,
componentInstance: nonReactiveComponent,
});
} catch (error) {
console.error(`Failed to load component ${componentName}`, error);
})
}
catch (error) {
console.error(`Failed to load component ${componentName}`, error)
}
}
return componentsList;
} catch (error) {
console.error("Failed to process components list", error);
return componentsList
}
return [];
catch (error) {
console.error('Failed to process components list', error)
}
return []
}
async function getCalculator() {
@ -68,37 +69,39 @@ export const useStore = defineStore("store", () => {
`/api/public/plan-prediction/easy/calculate?monthly_deposit=${monthlySavings.value}&years=${storagePeriod.value}`,
{
headers: {
"Content-Type": "application/json",
'Content-Type': 'application/json',
},
onErrorOccured: (_, status) => {
throw new Error(`HTTP error: ${status}`);
throw new Error(`HTTP error: ${status}`)
},
}
);
},
)
totalInvestment.value = data.total_investement_value;
} catch (error) {
console.error("getList error:", error);
totalInvestment.value = data.total_investement_value
}
catch (error) {
console.error('getList error:', error)
}
}
async function getMinValue() {
try {
const { data } = await useMyFetch<GenericResponse<number>>(
"/api/public/plan-prediction/free/minimum",
'/api/public/plan-prediction/free/minimum',
{
headers: {
"Content-Type": "application/json",
'Content-Type': 'application/json',
},
onErrorOccured: (_, status) => {
throw new Error(`HTTP error: ${status}`);
throw new Error(`HTTP error: ${status}`)
},
}
);
},
)
minValue.value = data;
} catch (error) {
console.error("getList error:", error);
minValue.value = data
}
catch (error) {
console.error('getList error:', error)
}
}
@ -113,5 +116,5 @@ export const useStore = defineStore("store", () => {
getComponents,
getSections,
getMinValue,
};
});
}
})

View File

@ -1,16 +1,16 @@
import type { GenericResponse } from "~/types";
import type { Customer } from "~/types/user";
import type { GenericResponse } from '~/types'
import type { Customer } from '~/types/user'
export const useUserStore = defineStore("userStore", () => {
const store = useStore();
const menuStore = useMenuStore();
const checkoutStore = useCheckoutStore();
export const useUserStore = defineStore('userStore', () => {
const store = useStore()
const menuStore = useMenuStore()
const checkoutStore = useCheckoutStore()
const { $toast } = useNuxtApp();
const { $toast } = useNuxtApp()
const fullUserData = ref<Customer | null>(null);
const isLogged = ref<boolean>(true);
const user = ref<string | null>(null);
const fullUserData = ref<Customer | null>(null)
const isLogged = ref<boolean>(true)
const user = ref<string | null>(null)
async function checkIsLogged() {
try {
@ -18,120 +18,128 @@ export const useUserStore = defineStore("userStore", () => {
`/api/public/user`,
{
headers: {
"Content-Type": "application/json",
'Content-Type': 'application/json',
},
onErrorOccured: async (_, status) => {
throw createError({
statusCode: status,
statusMessage: `HTTP error: ${status}`,
});
})
},
}
);
},
)
if ("loggedin" in data && data.loggedin === true) {
isLogged.value = true;
user.value = `${data.first_name} ${data.last_name}` as any;
fullUserData.value = data;
checkoutStore.accountPhoneNumber = fullUserData.value.phone_number;
} else {
isLogged.value = false;
user.value = null;
fullUserData.value = null;
if ('loggedin' in data && data.loggedin === true) {
isLogged.value = true
user.value = `${data.first_name} ${data.last_name}` as string
fullUserData.value = data
checkoutStore.accountPhoneNumber = fullUserData.value.phone_number
}
} catch (error) {
console.error("checkIsLogged error:", error);
else {
isLogged.value = false
user.value = null
fullUserData.value = null
}
}
catch (error) {
console.error('checkIsLogged error:', error)
}
}
// login
const email = ref();
const password = ref();
const vLogin = ref<boolean>(true);
const vCodeVerify = ref<boolean>(false);
const vCode = ref<number | null>(null);
const email = ref()
const password = ref()
const vLogin = ref<boolean>(true)
const vCodeVerify = ref<boolean>(false)
const vCode = ref<number | null>(null)
async function logIn() {
try {
const data = await useMyFetch<GenericResponse<object>>(
`/api/public/user/session/start`,
{
method: "POST",
method: 'POST',
body: JSON.stringify({
mail: email.value,
password: password.value,
}),
headers: {
"Content-Type": "application/json",
'Content-Type': 'application/json',
},
onErrorOccured: (_, status) => {
throw new Error(`HTTP error: ${status}`);
throw new Error(`HTTP error: ${status}`)
},
}
);
},
)
if (data.status === 200 || data.status === 201) {
console.log(vCodeVerify.value);
console.log(vCodeVerify.value)
$toast.success("Code successfully sent to your email", {
$toast.success('Code successfully sent to your email', {
autoClose: 5000,
dangerouslyHTMLString: true,
});
vLogin.value = false;
vCodeVerify.value = true;
} else {
$toast.error("Failed to sent code to your email. Please try again.", {
})
vLogin.value = false
vCodeVerify.value = true
}
else {
$toast.error('Failed to sent code to your email. Please try again.', {
autoClose: 5000,
dangerouslyHTMLString: true,
});
})
}
store.minValue = data;
} catch (error) {
console.error("getList error:", error);
store.minValue = data
}
catch (error) {
console.error('getList error:', error)
}
}
const sendFormCode = async (redirect?: boolean) => {
try {
const data = await useMyFetch<GenericResponse<object>>(
await useMyFetch<GenericResponse<object>>(
`/api/public/user/session/confirm`,
{
method: "POST",
method: 'POST',
body: JSON.stringify({
code: vCode.value,
mail: email.value,
}),
headers: {
"Content-Type": "application/json",
'Content-Type': 'application/json',
},
onErrorOccured: (_, status) => {
throw new Error(`HTTP error: ${status}`);
throw new Error(`HTTP error: ${status}`)
},
}
);
},
)
await checkIsLogged();
await checkIsLogged()
if (isLogged.value) {
if (redirect) {
console.log(isLogged.value);
menuStore.navigateToItem();
} else {
console.log(isLogged.value)
menuStore.navigateToItem()
}
else {
// window.location.href = atob(redirect);
}
} else {
}
else {
useNuxtApp().$toast.error(`Error occurred: Failed to confirm code`, {
autoClose: 5000,
dangerouslyHTMLString: true,
});
})
}
} catch (e) {
}
catch (e) {
console.error(e)
useNuxtApp().$toast.error(`Invalid code provided`, {
autoClose: 5000,
dangerouslyHTMLString: true,
});
})
}
};
}
return {
isLogged,
@ -144,5 +152,5 @@ export const useUserStore = defineStore("userStore", () => {
logIn,
checkIsLogged,
sendFormCode,
};
});
}
})