global data avec useState
This commit is contained in:
		
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -5,6 +5,7 @@
 | 
			
		||||
.nitro
 | 
			
		||||
.cache
 | 
			
		||||
dist
 | 
			
		||||
public/api
 | 
			
		||||
 | 
			
		||||
# Node dependencies
 | 
			
		||||
node_modules
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										22
									
								
								app.vue
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								app.vue
									
									
									
									
									
								
							@@ -5,23 +5,17 @@
 | 
			
		||||
  </main>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
export default {
 | 
			
		||||
  setup() {
 | 
			
		||||
    const global = ref([]);
 | 
			
		||||
<script setup>
 | 
			
		||||
    let globalData = useState('globalData');
 | 
			
		||||
    
 | 
			
		||||
    const { data, error } = useFetch('/api/items/global', {
 | 
			
		||||
      server: true,
 | 
			
		||||
      onResponse({ request, response, options }) {
 | 
			
		||||
        global.value = response._data.data;
 | 
			
		||||
      },
 | 
			
		||||
    });
 | 
			
		||||
    
 | 
			
		||||
    provide('globalData', global);
 | 
			
		||||
    await callOnce(async () => {
 | 
			
		||||
      globalData.value = await $fetch('/api/items/global')
 | 
			
		||||
      globalData = globalData.value.data
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    useSeoMeta({
 | 
			
		||||
      ogImage: '/card.jpg',
 | 
			
		||||
      ogImageAlt: global.value.contact_image_titre,
 | 
			
		||||
      ogImageAlt: globalData.contact_image_titre,
 | 
			
		||||
      twitterImage: '/card.jpg',
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
@@ -37,8 +31,6 @@ export default {
 | 
			
		||||
        }
 | 
			
		||||
      ]
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="scss">
 | 
			
		||||
 
 | 
			
		||||
@@ -34,8 +34,12 @@
 | 
			
		||||
<script>
 | 
			
		||||
    export default {
 | 
			
		||||
        setup() {
 | 
			
		||||
            const globalData = inject('globalData');
 | 
			
		||||
            return { globalData };
 | 
			
		||||
            let globalData = useState('globalData');
 | 
			
		||||
            globalData = globalData.value.data;
 | 
			
		||||
            
 | 
			
		||||
            return {
 | 
			
		||||
                globalData
 | 
			
		||||
            };
 | 
			
		||||
        },
 | 
			
		||||
        methods: {
 | 
			
		||||
            isActive(path) {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										35
									
								
								error.vue
									
									
									
									
									
								
							
							
						
						
									
										35
									
								
								error.vue
									
									
									
									
									
								
							@@ -4,35 +4,34 @@
 | 
			
		||||
      <h1 v-if="error.statusCode === 404">Erreur 404</h1>
 | 
			
		||||
      <p v-if="error.statusCode === 404">La page {{ error.url }} n'existe pas</p>
 | 
			
		||||
      <img 
 | 
			
		||||
            v-if="global.error_img"
 | 
			
		||||
            v-if="globalData != null"
 | 
			
		||||
            :src="`/api/assets/${globalData.error_img}.webp`"
 | 
			
		||||
            :alt="global.error_img_title" />
 | 
			
		||||
    </div>
 | 
			
		||||
</template>
 | 
			
		||||
  
 | 
			
		||||
<script>
 | 
			
		||||
  export default {
 | 
			
		||||
    setup() {
 | 
			
		||||
      const global = ref([]);
 | 
			
		||||
      
 | 
			
		||||
      const { data, error } = useFetch('/api/items/global', {
 | 
			
		||||
        server: true,
 | 
			
		||||
        onResponse({ request, response, options }) {
 | 
			
		||||
          global.value = response._data.data;
 | 
			
		||||
        },
 | 
			
		||||
      });
 | 
			
		||||
      
 | 
			
		||||
      provide('globalData', global);
 | 
			
		||||
export default {
 | 
			
		||||
  setup() {
 | 
			
		||||
    let globalData = useState('globalData');
 | 
			
		||||
 | 
			
		||||
      return {
 | 
			
		||||
        globalData
 | 
			
		||||
      }
 | 
			
		||||
    async function fetchGlobalData() {
 | 
			
		||||
      await callOnce(async () => {
 | 
			
		||||
        globalData.value = await $fetch('/api/items/global')
 | 
			
		||||
        globalData = globalData.value.data;
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    },
 | 
			
		||||
    fetchGlobalData();    
 | 
			
		||||
      
 | 
			
		||||
    return {
 | 
			
		||||
      globalData
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
    props: {
 | 
			
		||||
      error: Object
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
  
 | 
			
		||||
<style scoped>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,13 +1,15 @@
 | 
			
		||||
// nitro hook to get Directus files working on ssg
 | 
			
		||||
// https://github.com/codepie-io/nuxt3-dynamic-routes/blob/main/nuxt.config.ts
 | 
			
		||||
// + ssg homemade caching to not retrieve all the files each generation
 | 
			
		||||
 | 
			
		||||
import { createDirectus, staticToken, rest, readFiles } from '@directus/sdk';
 | 
			
		||||
import fs from 'fs';
 | 
			
		||||
import path from 'path';
 | 
			
		||||
import { promisify } from 'util';
 | 
			
		||||
 | 
			
		||||
export default defineNuxtConfig({
 | 
			
		||||
  devtools: { enabled: true },
 | 
			
		||||
  modules: [
 | 
			
		||||
    'nuxt-directus',
 | 
			
		||||
    '@nuxt/image',
 | 
			
		||||
    '@nuxtjs/seo'
 | 
			
		||||
  ],
 | 
			
		||||
  runtimeConfig: {
 | 
			
		||||
@@ -17,6 +19,7 @@ export default defineNuxtConfig({
 | 
			
		||||
  nitro: {
 | 
			
		||||
    hooks: {
 | 
			
		||||
      async 'prerender:routes'(routes) {
 | 
			
		||||
        
 | 
			
		||||
        const client = createDirectus(process.env.DIRECTUS_URL)
 | 
			
		||||
          .with(staticToken(process.env.DIRECTUS_API_TOKEN))
 | 
			
		||||
          .with(rest());
 | 
			
		||||
@@ -34,12 +37,77 @@ export default defineNuxtConfig({
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        for (let image of directusFiles) {
 | 
			
		||||
          // @TODO: vérifier si le fichier existe pas déjà
 | 
			
		||||
          //        avant de l'ajouter aux routes à prerender
 | 
			
		||||
          routes.add(`/api/assets/${image.id}.webp`);
 | 
			
		||||
          const fileExists = async (filePath) => !!(await fs.promises.access(filePath, fs.constants.F_OK).then(() => true).catch(() => false));
 | 
			
		||||
 | 
			
		||||
          const filePath = `./public/api/assets/${image.id}.webp`;
 | 
			
		||||
          fileExists(filePath)
 | 
			
		||||
              .then(exists => {
 | 
			
		||||
                  if (!exists) {
 | 
			
		||||
                    routes.add(`/api/assets/${image.id}.webp`);
 | 
			
		||||
                  }
 | 
			
		||||
              })
 | 
			
		||||
              .catch(error => console.error('Error:', error));
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
  hooks: {
 | 
			
		||||
    'nitro:build:public-assets': () => {
 | 
			
		||||
      if (!fs.existsSync('./public/api/assets')) fs.mkdirSync('./public/api/assets', { recursive: true });
 | 
			
		||||
 | 
			
		||||
      const readdir = promisify(fs.readdir);
 | 
			
		||||
      const stat = promisify(fs.stat);
 | 
			
		||||
      const copyFile = promisify(fs.copyFile);
 | 
			
		||||
 | 
			
		||||
      async function directoryExists(directoryPath) {
 | 
			
		||||
        try {
 | 
			
		||||
            const stats = await fs.promises.stat(directoryPath);
 | 
			
		||||
            return stats.isDirectory();
 | 
			
		||||
        } catch (error) {
 | 
			
		||||
            if (error.code === 'ENOENT') {
 | 
			
		||||
                return false;
 | 
			
		||||
            } else {
 | 
			
		||||
                throw error;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      async function copyFilesIfNotExist(sourceFolder, destinationFolder) {
 | 
			
		||||
        try {
 | 
			
		||||
          const exists = await directoryExists(sourceFolder);
 | 
			
		||||
          if (!exists) {
 | 
			
		||||
              console.log(`Source folder '${sourceFolder}' does not exist.`);
 | 
			
		||||
              return;
 | 
			
		||||
          }
 | 
			
		||||
          
 | 
			
		||||
          const files = await readdir(sourceFolder);
 | 
			
		||||
          for (const file of files) {
 | 
			
		||||
              const sourceFilePath = path.join(sourceFolder, file);
 | 
			
		||||
              const destinationFilePath = path.join(destinationFolder, file);
 | 
			
		||||
              const sourceFileStat = await stat(sourceFilePath);
 | 
			
		||||
  
 | 
			
		||||
              if (sourceFileStat.isFile()) {
 | 
			
		||||
                  try {
 | 
			
		||||
                      await stat(destinationFilePath);
 | 
			
		||||
                  } catch (error) {
 | 
			
		||||
                      if (error.code === 'ENOENT') {
 | 
			
		||||
                          await copyFile(sourceFilePath, destinationFilePath);
 | 
			
		||||
                          console.log(`Copied '${file}' to '${destinationFolder}'.`);
 | 
			
		||||
                      } else {
 | 
			
		||||
                          throw error;
 | 
			
		||||
                      }
 | 
			
		||||
                  }
 | 
			
		||||
              }
 | 
			
		||||
          }
 | 
			
		||||
          console.log('Files copied successfully.');
 | 
			
		||||
        } catch (error) {
 | 
			
		||||
            console.error('Error:', error);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      const sourceFolder = './.output/public/api/assets';      
 | 
			
		||||
      const destinationFolder = './public/api/assets';
 | 
			
		||||
      copyFilesIfNotExist(sourceFolder, destinationFolder);
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  app: {
 | 
			
		||||
@@ -50,13 +118,5 @@ export default defineNuxtConfig({
 | 
			
		||||
    defaultLocale: 'fr',
 | 
			
		||||
    name: 'Mahée Auffret',
 | 
			
		||||
    description: 'Portfolio de l\'artiste-peintre basée à Rennes Mahée Auffret'
 | 
			
		||||
  },    
 | 
			
		||||
  directus: {
 | 
			
		||||
    url: process.env.DIRECTUS_URL,
 | 
			
		||||
    token: process.env.DIRECTUS_API_TOKEN
 | 
			
		||||
  },
 | 
			
		||||
  image: {
 | 
			
		||||
    provider: 'ipx',
 | 
			
		||||
    // domains: [ `${process.env.URL}/api/assets/` ]
 | 
			
		||||
  }
 | 
			
		||||
})
 | 
			
		||||
 
 | 
			
		||||
@@ -13,8 +13,17 @@
 | 
			
		||||
    </main>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup>
 | 
			
		||||
    const globalData = inject('globalData');
 | 
			
		||||
<script>
 | 
			
		||||
export default {
 | 
			
		||||
    setup() {
 | 
			
		||||
        let globalData = useState('globalData');
 | 
			
		||||
        globalData = globalData.value.data;
 | 
			
		||||
    
 | 
			
		||||
        return {
 | 
			
		||||
            globalData
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="scss">
 | 
			
		||||
 
 | 
			
		||||
@@ -9,16 +9,16 @@ export default {
 | 
			
		||||
    setup() {
 | 
			
		||||
        const galerie = ref([]);
 | 
			
		||||
 | 
			
		||||
        const { data: itemsData, error: itemsError } = useFetch('/api/items/galerie', { server: true });
 | 
			
		||||
        const { data: itemsData } = useFetch('/api/items/galerie', { server: true });
 | 
			
		||||
        
 | 
			
		||||
        onMounted(async () => {
 | 
			
		||||
            if (!itemsError.value && itemsData.value) {
 | 
			
		||||
            if (itemsData.value) {
 | 
			
		||||
                galerie.value = itemsData.value.data;
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
            galerie,
 | 
			
		||||
            itemsError
 | 
			
		||||
            galerie
 | 
			
		||||
        };
 | 
			
		||||
    },
 | 
			
		||||
    components: {
 | 
			
		||||
 
 | 
			
		||||
@@ -12,20 +12,20 @@ export default {
 | 
			
		||||
    setup() {
 | 
			
		||||
        const magasin = ref([]);
 | 
			
		||||
 | 
			
		||||
        const { data: itemsData, error: itemsError } = useFetch('/api/items/magasin', { server: true });
 | 
			
		||||
        const { data: itemsData } = useFetch('/api/items/magasin', { server: true });
 | 
			
		||||
 | 
			
		||||
        onBeforeMount(async () => {
 | 
			
		||||
            if (!itemsError.value && itemsData.value) {
 | 
			
		||||
            if (itemsData.value) {
 | 
			
		||||
                magasin.value = itemsData.value.data;
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        const globalData = inject('globalData');
 | 
			
		||||
        let globalData = useState('globalData');
 | 
			
		||||
        globalData = globalData.value.data;
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
            globalData,
 | 
			
		||||
            magasin,
 | 
			
		||||
            itemsError
 | 
			
		||||
            magasin
 | 
			
		||||
        };
 | 
			
		||||
    },
 | 
			
		||||
    components: {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user