@extends('documentation.application.squelette') @section('titre') {{ __("Frontend PWA (Vue 3)") }} @endsection @section('menu') @endsection @section('contenu')

Service Worker

Configuration


// vite.config.ts
VitePWA({
    registerType: 'prompt',
    injectRegister: false,
    workbox: {
        globPatterns: ['**/*.{js,css,html,svg,png,ico}'],
        cleanupOutdatedCaches: true,
        clientsClaim: true,
    }
})
                

Composant de mise à jour PWA


// components/PWABadge.vue
<script setup lang="ts">
import { useRegisterSW } from 'virtual:pwa-register/vue'

const { needRefresh, updateServiceWorker } = useRegisterSW({
    immediate: true,
    onRegistered(r) {
        console.log('SW Registered:', r)
    },
    onRegisterError(error) {
        console.log('SW registration error', error)
    },
})
</script>
                

Gestion d'État (Pinia)

Configuration des Stores

Les stores sont organisés par fonctionnalité :

  • auth : Gestion de l'authentification
  • interventions : Gestion des interventions
  • notifications : Gestion des notifications

Store d'Authentification


// stores/auth.ts
export const useAuthStore = defineStore({
    id: "auth",
    state: (): AuthState => ({
        user: null,
        error: null,
        clientLogo: null
    }),
    getters: {
        isAuthenticated: (state): boolean => !!state.user
    },
    actions: {
        async login(email: string, password: string) {...},
        async checkAuth(): Promise {...},
        logout(): void {...}
    },
    persist: {
        key: 'auth',
        storage: localStorage,
    }
})
                

Routage et Navigation

Configuration des Routes


// router/index.ts
const routes = [
    {
        path: '/',
        component: () => import('@/views/Home.vue'),
        meta: { requiresAuth: true }
    },
    {
        path: '/login',
        component: () => import('@/views/Login.vue'),
        meta: { guest: true }
    }
]

const router = createRouter({
    history: createWebHistory(),
    routes
})
                

Navigation Guards


router.beforeEach(async (to, from, next) => {
    const authStore = useAuthStore();

    if (to.meta.requiresAuth && !authStore.isAuthenticated) {
        next('/login');
    } else if (to.meta.guest && authStore.isAuthenticated) {
        next('/');
    } else {
        next();
    }
});
                

Gestion des APIs

Configuration d'Axios


// config/axios.ts
const getApiUrl = () => {
    if (import.meta.env.DEV) {
        return import.meta.env.VITE_API_URL;
    }
    
    const hostname = window.location.hostname;
    const domainMappings = {
        'application.demo-elanmaintenance.com': 'https://application-back.demoelan.com/api',
    };
    
    return domainMappings[hostname] || 'https://application-back.demoelan.com/api';
};

const apiClient = axios.create({
    baseURL: getApiUrl(),
    withCredentials: true,
    headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json'
    }
});

// Intercepteur pour ajouter le token JWT
apiClient.interceptors.request.use(
    config => {
        const token = localStorage.getItem('token');
        if (token) {
            config.headers.Authorization = `Bearer ${token}`;
        }
        return config;
    },
    error => Promise.reject(error)
);
                

Authentification

L'authentification utilise JWT avec :

  • Stockage du token dans localStorage
  • Vérification automatique du token
  • Rafraîchissement du token

Composants Principaux

Composant Description Utilisation
PWABadge Gestion des mises à jour PWA Global
NavigationBar Barre de navigation principale Layout
AuthForm Formulaire de connexion Page Login
@endsection