Files
your-gold/stores/menuStore.ts
2025-06-26 03:21:46 +02:00

230 lines
6.2 KiB
TypeScript

import type {
Country,
Currency,
FrontMenu,
GenericResponse,
GenericResponseItems,
Language,
UIFrontMenu,
} from "~/types";
import { useStore } from "./store";
import { useMyFetch } from "#imports";
// import { useSession } from "~/plugins/01_i18n";
function buildTreeRecursive(
data: (FrontMenu | UIFrontMenu)[],
parentId: number
): UIFrontMenu[] {
const children = data.filter(
(item): item is UIFrontMenu =>
item.id_parent === parentId && !item.is_default
);
return children.map((item) => ({
...item,
children: buildTreeRecursive(data, item.id),
}));
}
export const useMenuStore = defineStore("menuStore", () => {
const store = useStore();
const { $i18n } = useNuxtApp();
// const session = useSession();
const { $session } = useNuxtApp();
const router = useRouter();
const route = useRoute();
const openMenu = ref(false);
const openDropDown = ref(false);
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 countries = ref([] as Country[]);
const currencies = ref([] as Currency[]);
const languages = ref([] as Language[]);
const getLocales = async () => {
const { data: countrriesList } = await useMyFetch<GenericResponse<Country[]>>(`/api/public/country/list`);
countries.value = countrriesList;
selectedCountry.value = countrriesList.find((country) => country.iso_code === $session.currentCountryIso.value) as Country;
selectedPhoneCountry.value = countrriesList.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: 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);
},
}
);
menuItems.value = data;
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 = [];
}
} 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 {
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();
// 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 (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 img[0];
}
return "";
};
const headMeta = computed(() => {
const item = menuItems.value?.find(
(item) => item.id.toString() === route.params.id
);
const meta = {
title: item?.front_menu_lang[0].meta_title,
htmlAttrs: {
lang: $i18n.locale.value,
},
link: [
// { rel: "manifest", href: "/api/manifest.json" }
],
meta: [
{
hid: "description",
name: "description",
content: item?.front_menu_lang[0].meta_description,
},
{
property: "og:title",
content: item?.front_menu_lang[0].meta_title,
},
{
property: "og:description",
content: item?.front_menu_lang[0].meta_description,
},
{
property: "og:image",
content: getFirstImage("m", true),
},
{
property: "twitter:title",
content: item?.front_menu_lang[0].meta_title,
},
{
property: "twitter:description",
content: item?.front_menu_lang[0].meta_description,
},
{
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;
});
// watches
watch(() => $session.cookieData, async () => {
await getLocales();
await loadMenu();
await store.getMinValue();
await store.getCalculator();
}, { deep: true });
return {
menu,
menuItems,
openMenu,
openDropDown,
currencies,
languages,
countries,
selectedCountry,
selectedCurrency,
selectedPhoneCountry,
selectedLanguage,
defaultMenu,
headMeta,
navigateToShop,
loadMenu,
navigateToItem,
getLocales,
};
});