193 lines
4.7 KiB
TypeScript
193 lines
4.7 KiB
TypeScript
import { usePB } from "~/composables/usePB";
|
|
import type {
|
|
FooterListResponse,
|
|
MenuListResponse,
|
|
PBFooterItem,
|
|
PBMenuItem,
|
|
UIMenuItem,
|
|
} from "~/types";
|
|
import { useStore } from "./store";
|
|
import { ref, watch } from "vue";
|
|
|
|
function buildTreeRecursive(
|
|
data: (PBMenuItem | UIMenuItem)[],
|
|
parentId: string
|
|
): UIMenuItem[] {
|
|
const children = data.filter(
|
|
(item): item is UIMenuItem =>
|
|
item.id_parent === parentId && !item.is_default
|
|
);
|
|
|
|
return children.map((item) => ({
|
|
...item,
|
|
children: buildTreeRecursive(data, item.id),
|
|
}));
|
|
}
|
|
|
|
export const useMenuStore = defineStore("menuStore", () => {
|
|
const pb = usePB();
|
|
const store = useStore();
|
|
const { $i18n } = useNuxtApp();
|
|
const router = useRouter();
|
|
const openMenu = ref(false);
|
|
const openDropDown = ref(false);
|
|
|
|
const defaultMenu = ref();
|
|
const menu = ref<UIMenuItem[]>([]);
|
|
const menuItems = ref<MenuListResponse>();
|
|
const footerItems = ref<FooterListResponse>();
|
|
|
|
const loadMenu = async () => {
|
|
try {
|
|
menuItems.value = (await pb
|
|
.collection("menu_view")
|
|
.getList<PBMenuItem>(1, 50, {
|
|
filter: `id_lang="${$i18n.locale.value}"&&active=true`,
|
|
sort: "position_id",
|
|
})) as MenuListResponse;
|
|
|
|
const root = menuItems.value.items.find((item) => item.is_root);
|
|
defaultMenu.value = menuItems.value.items.find((item) => item.is_default);
|
|
|
|
if (root) {
|
|
menu.value = buildTreeRecursive(menuItems.value.items, root.id);
|
|
store.currentPageID = menu.value[0]?.id_page || "";
|
|
} else {
|
|
console.warn("Root menu item not found");
|
|
menu.value = [];
|
|
}
|
|
} catch (error) {
|
|
console.log(error);
|
|
}
|
|
};
|
|
|
|
const loadFooter = async () => {
|
|
try {
|
|
footerItems.value = (await pb
|
|
.collection("footer_view")
|
|
.getList<PBFooterItem>(1, 50, {
|
|
filter: `id_lang="${$i18n.locale.value}"`,
|
|
})) as FooterListResponse;
|
|
} catch (error) {
|
|
console.log(error);
|
|
}
|
|
};
|
|
|
|
const navigateToItem = (item?: UIMenuItem) => {
|
|
if (item) {
|
|
router.push({
|
|
params: { slug: item.link_rewrite, id: item.id_page },
|
|
name: `id-slug___${$i18n.locale.value}`,
|
|
});
|
|
openDropDown.value = false;
|
|
} else {
|
|
router.push({
|
|
params: {
|
|
slug: defaultMenu.value.link_rewrite,
|
|
id: defaultMenu.value.id_page,
|
|
},
|
|
name: `id-slug___${$i18n.locale.value}`,
|
|
});
|
|
}
|
|
};
|
|
|
|
watch($i18n.locale, async () => {
|
|
await loadMenu();
|
|
await loadFooter();
|
|
});
|
|
|
|
const getFirstImage = () => {
|
|
const req = useRequestEvent();
|
|
const url = useRequestURL();
|
|
let img = "";
|
|
for (const s in store.components) {
|
|
store.components[s].section_img.map((item) => {
|
|
img = `${req?.headers.get("x-forwarded-proto") || url.protocol}://${
|
|
req?.headers.get("x-forwarded-host") || req?.headers.get("host")
|
|
}/api/files/${store.components[s].image_collection}/${
|
|
store.components[s].section_id
|
|
}/${item}?thumb=400x0`;
|
|
});
|
|
if (img.length > 0) return img;
|
|
}
|
|
return "";
|
|
};
|
|
|
|
const route = useRoute();
|
|
const headMeta = computed(() => {
|
|
const item = menuItems.value?.items.find(
|
|
(item) => item.id_page === route.params.id
|
|
);
|
|
return {
|
|
title: item?.meta_title,
|
|
htmlAttrs: {
|
|
lang: $i18n.locale.value,
|
|
},
|
|
link: [{ rel: "manifest", href: "/api/manifest.json" }],
|
|
meta: [
|
|
{
|
|
hid: "description",
|
|
name: "description",
|
|
content: item?.meta_description,
|
|
},
|
|
{
|
|
property: "og:title",
|
|
content: item?.meta_title,
|
|
},
|
|
{
|
|
property: "og:description",
|
|
content: item?.meta_description,
|
|
},
|
|
{
|
|
property: "og:image",
|
|
content: getFirstImage(),
|
|
},
|
|
{
|
|
property: "twitter:title",
|
|
content: item?.meta_title,
|
|
},
|
|
{
|
|
property: "twitter:description",
|
|
content: item?.meta_description,
|
|
},
|
|
{
|
|
property: "twitter:image",
|
|
content: getFirstImage(),
|
|
},
|
|
],
|
|
};
|
|
});
|
|
|
|
function redirectToPage(link_rewrite: string) {
|
|
const page = menuItems.value?.items.find(
|
|
(item) => item.link_rewrite === link_rewrite
|
|
);
|
|
|
|
if (!page?.id_page || !page?.link_rewrite) {
|
|
console.warn(`Page not found or missing data for name: ${link_rewrite}`);
|
|
return;
|
|
}
|
|
|
|
router.push({
|
|
params: {
|
|
id: page?.id_page,
|
|
slug: page?.link_rewrite,
|
|
},
|
|
});
|
|
}
|
|
|
|
return {
|
|
menu,
|
|
menuItems,
|
|
footerItems,
|
|
openMenu,
|
|
openDropDown,
|
|
loadMenu,
|
|
loadFooter,
|
|
navigateToItem,
|
|
redirectToPage,
|
|
defaultMenu,
|
|
headMeta,
|
|
};
|
|
});
|