import { defineStore } from 'pinia' interface CompanyLogo { url: string alternativeText?: string } interface CompanyInfo { company: string street: string postalcode: string city: string phone: string email: string contact: string district?: string latitude?: number longitude?: number web: string invertlogo?: { data?: { attributes?: CompanyLogo } } } interface SEO { pageTitle: string seoDescription: string // Achtung: Schreibfehler wird so übernommen seoKeywords: string type: string seoImage?: CompanyLogo | null } interface PageSection { id: number sectionText: string sectionImage?: CompanyLogo | null } interface FAQ { question: string answer: string } interface Page { id: number pageName: string pageLink: string header_image?: CompanyLogo | null SEO?: SEO | null faqs: FAQ[] pageSections: PageSection[] } interface CustomerProject { id: number projectTitle: string launchDate?: string projectDescription?: string link?: string webpage?: string technologies: { titel: string; icon?: string }[] projectImages: CompanyLogo[] } interface Customer { id: number company: string city: string logo?: CompanyLogo | null invertLogo?: CompanyLogo | null projects: CustomerProject[] } export const useMainStore = defineStore('main', { state: () => ({ menuOpen: false, contactBoxOpen: false, scrollPosition: 0, screenWidth: 1440, companyinfo: null as CompanyInfo | null, pages: [] as Page[], customers: [] as Customer[], dataFetched: false, loading: false, error: null as { message: string; stack?: string } | null, }), getters: { invertLogoUrl: (state) => { const runtimeConfig = useRuntimeConfig() const logoUrl = state.companyinfo?.invertlogo?.data?.attributes?.url return logoUrl ? `${runtimeConfig.public.cmsBaseUrl}${logoUrl}` : '/uploads/dummy_Image_4abc3f04dd.webp' }, isMobile: (state) => state.screenWidth < 768, getPageByLink: (state) => (link: string) => state.pages.find((p) => p.pageLink === link), getCustomerById: (state) => (id: number) => state.customers.find((c) => c.id === id), getFaqsByPageId: (state) => (pageId: number) => state.pages.find((p) => p.id === pageId)?.faqs ?? [], getFaqsByPageLink: (state) => (link: string) => { const page = state.pages.find(p => p.pageLink === link); return page?.faqs ?? []; } }, actions: { toggleMenu() { this.menuOpen = !this.menuOpen }, closeMenu() { this.menuOpen = false }, toggleContactBubble() { this.contactBoxOpen = !this.contactBoxOpen }, setScrollPosition(pos: number) { this.scrollPosition = pos }, setScreenWidth(width: number) { this.screenWidth = width }, async fetchInitialData() { if (this.dataFetched) return this.loading = true const { public: cfg } = useRuntimeConfig() try { const [companyRes, pagesRes, customersRes] = await Promise.all([ $fetch(`${cfg.cmsBaseUrl}/api/companyinfo?populate=*`, { headers: { Authorization: `Bearer ${cfg.cmsToken}` }, }), $fetch(`${cfg.cmsBaseUrl}/api/pages?populate=*`, { headers: { Authorization: `Bearer ${cfg.cmsToken}` }, }), $fetch(`${cfg.cmsBaseUrl}/api/customers?populate=*`, { headers: { Authorization: `Bearer ${cfg.cmsToken}` }, }), ]) // CompanyInfo (Single Type) this.companyinfo = companyRes.data?.attributes ?? companyRes // Pages this.pages = pagesRes.data.map((item: any) => { const a = item.attributes return { id: item.id, pageName: a.pageName, pageLink: a.pageLink, header_image: a.header_image?.data ? { url: a.header_image.data.attributes.url, alternativeText: a.header_image.data.attributes.alternativeText, } : null, SEO: a.SEO ? { pageTitle: a.SEO.pageTitle, seoDescription: a.SEO.seoDesicription, // Fehler absichtlich seoKeywords: a.SEO.seoKeywords, type: a.SEO.type, seoImage: a.SEO.seoImage?.data ? { url: a.SEO.seoImage.data.attributes.url, alternativeText: a.SEO.seoImage.data.attributes.alternativeText, } : null, } : null, faqs: a.faqs?.data?.map((f: any) => ({ question: f.attributes.question, answer: f.attributes.answer, })) ?? [], pageSections: a.pageSections?.map((s: any) => ({ id: s.id, sectionText: s.sectionText, sectionImage: s.sectionImage?.data ? { url: s.sectionImage.data.attributes.url, alternativeText: s.sectionImage.data.attributes.alternativeText, } : null, })) ?? [], } }) // Customers this.customers = customersRes.data.map((item: any) => { const a = item.attributes return { id: item.id, company: a.company, city: a.city, logo: a.logo?.data?.attributes ?? null, invertLogo: a.invertLogo?.data?.attributes ?? null, projects: (a.projects?.data ?? []).map((p: any) => ({ id: p.id, projectTitle: p.attributes.projectTitle, projectImages: p.attributes.projectImages?.data?.map((img: any) => ({ url: img.attributes.url, alternativeText: img.attributes.alternativeText, })) ?? [], launchDate: p.attributes.launchDate, projectDescription: p.attributes.projectDescription, link: p.attributes.link, webpage: p.attributes.webpage, technologies: p.attributes.Technologien?.data?.map((t: any) => ({ titel: t.attributes.titel, icon: t.attributes.icon, })) ?? [], })), } }) this.dataFetched = true } catch (err) { const e = err as Error this.error = { message: e.message, stack: e.stack } console.error('Fetch-Fehler:', e) } finally { this.loading = false } }, }, })