1+ import React from 'react' ;
2+ import Header from '../components/header' ;
3+ import Footer from '../components/footer' ;
4+ import DevTools from '../components/devtools' ;
5+ import { getHeaderRes , getFooterRes , getAllEntries } from '../helper' ;
6+ import { HeaderProps , FooterProps } from "../typescript/layout" ;
7+ import { Page } from '@/typescript/pages' ;
8+ import { unstable_cache } from 'next/cache' ;
9+ import { initializeLivePreview } from '@/helper/live-preview' ;
10+
11+ const getCachedNavigation = unstable_cache (
12+ async ( entries : Page [ ] , header : HeaderProps , footer : FooterProps ) => {
13+ return dynamicHeadersAndFooter ( entries , header , footer ) ;
14+ } ,
15+ [ 'navigation-data' ] ,
16+ ) ;
17+ // dynamically update header and footer page links
18+ const dynamicHeadersAndFooter = ( entries : Page [ ] , header : HeaderProps , footer : FooterProps ) : [ HeaderProps , FooterProps ] => {
19+ const newHeader = { ...header } ;
20+ const newFooter = { ...footer } ;
21+
22+ if ( entries . length > 0 && newHeader . navigation_menu ) {
23+ entries . forEach ( ( entry ) => {
24+ // Only process entries with valid title and URL
25+ if ( ! entry . title || ! entry . url ) return ;
26+
27+ const hFound = newHeader . navigation_menu . find (
28+ ( navLink ) => navLink . label === entry . title
29+ ) ;
30+
31+ if ( ! hFound ) {
32+ newHeader . navigation_menu . push ( {
33+ label : entry . title ,
34+ page_reference : [
35+ //@ts -ignore
36+ { title : entry . title , url : entry . url , $ : entry . $ } ,
37+ ] ,
38+ $ : { } ,
39+ } ) ;
40+ }
41+
42+ const fFound = newFooter . navigation . link . find (
43+ ( nlink ) => nlink . title === entry . title
44+ ) ;
45+
46+ if ( ! fFound ) {
47+ newFooter . navigation . link . push ( {
48+ title : entry . title ,
49+ href : entry . url ,
50+ //@ts -ignore
51+ $ : entry . $ ,
52+ } ) ;
53+ }
54+ } ) ;
55+ }
56+
57+ return [ newHeader , newFooter ] ;
58+ }
59+
60+ export default async function AppLayout ( {
61+ children,
62+ hasLivePreview = false ,
63+ } : {
64+ children : React . ReactNode ;
65+ hasLivePreview ?: boolean ;
66+ } ) {
67+ try {
68+ // Initialize LivePreview if the middleware detected LivePreview parameters
69+ if ( hasLivePreview ) {
70+ await initializeLivePreview ( ) ;
71+ }
72+
73+ const [ headerData , footerData , entriesData ] = await Promise . all ( [
74+ getHeaderRes ( ) ,
75+ getFooterRes ( ) ,
76+ getAllEntries ( )
77+ ] ) ;
78+
79+ const [ dynamicHeader , dynamicFooter ] = await getCachedNavigation ( entriesData , headerData , footerData ) ;
80+
81+ const JSON_DATA = {
82+ header : dynamicHeader ,
83+ footer : dynamicFooter
84+ } ;
85+
86+ return (
87+ < >
88+ { dynamicHeader && < Header header = { dynamicHeader } entries = { entriesData } /> }
89+ < main className = "mainClass" >
90+ { children }
91+ < DevTools response = { JSON_DATA } />
92+ </ main >
93+ { dynamicFooter && < Footer footer = { dynamicFooter } entries = { entriesData } /> }
94+ </ >
95+ ) ;
96+ } catch ( error ) {
97+ console . error ( 'Error in AppLayout:' , error ) ;
98+ return (
99+ < >
100+ < main className = "mainClass" >
101+ { children }
102+ </ main >
103+ </ >
104+ ) ;
105+ }
106+ }
0 commit comments