From 316dcb63395fe3014f580b8d1eafd84f08120455 Mon Sep 17 00:00:00 2001 From: Matthieu Date: Wed, 17 Sep 2025 23:11:13 +0200 Subject: [PATCH] feat: add profile management flow --- app/app.vue | 221 ++- app/components/MachinePrintSelectionModal.vue | 136 ++ app/components/MachinePrintSelectionNode.vue | 63 + app/components/PageHero.vue | 79 + app/components/TypeEditActionsBar.vue | 37 + app/components/TypeEditBaseInfoSection.vue | 103 ++ app/components/TypeEditComponentsSection.vue | 294 ++++ .../TypeEditCustomFieldsSection.vue | 263 +++ app/components/TypeEditForm.vue | 1502 ++--------------- .../TypeEditMachinePiecesSection.vue | 78 + app/components/TypeEditToolbar.vue | 34 + app/components/TypeMachinePieceForm.vue | 70 +- app/composables/useProfileSession.js | 81 + app/composables/useProfiles.js | 67 + app/middleware/profile.global.ts | 12 + app/pages/documents.vue | 15 +- app/pages/generator.vue | 17 +- app/pages/index.vue | 17 +- app/pages/machine/[id].vue | 214 ++- app/pages/machines.vue | 41 +- app/pages/profiles/index.vue | 90 + app/pages/profiles/manage.vue | 174 ++ app/pages/sites.vue | 39 +- app/pages/type/[id].vue | 19 +- app/pages/type/edit/[id].vue | 21 +- app/pages/types.vue | 19 +- app/utils/printTemplates/machineReport.js | 567 +++++++ 27 files changed, 2717 insertions(+), 1556 deletions(-) create mode 100644 app/components/MachinePrintSelectionModal.vue create mode 100644 app/components/MachinePrintSelectionNode.vue create mode 100644 app/components/PageHero.vue create mode 100644 app/components/TypeEditActionsBar.vue create mode 100644 app/components/TypeEditBaseInfoSection.vue create mode 100644 app/components/TypeEditComponentsSection.vue create mode 100644 app/components/TypeEditCustomFieldsSection.vue create mode 100644 app/components/TypeEditMachinePiecesSection.vue create mode 100644 app/components/TypeEditToolbar.vue create mode 100644 app/composables/useProfileSession.js create mode 100644 app/composables/useProfiles.js create mode 100644 app/middleware/profile.global.ts create mode 100644 app/pages/profiles/index.vue create mode 100644 app/pages/profiles/manage.vue create mode 100644 app/utils/printTemplates/machineReport.js diff --git a/app/app.vue b/app/app.vue index 988b270..a82fd95 100644 --- a/app/app.vue +++ b/app/app.vue @@ -10,13 +10,81 @@
@@ -32,13 +100,69 @@
+ + + + @@ -118,10 +275,22 @@ diff --git a/app/components/MachinePrintSelectionModal.vue b/app/components/MachinePrintSelectionModal.vue new file mode 100644 index 0000000..70968c0 --- /dev/null +++ b/app/components/MachinePrintSelectionModal.vue @@ -0,0 +1,136 @@ + + + diff --git a/app/components/MachinePrintSelectionNode.vue b/app/components/MachinePrintSelectionNode.vue new file mode 100644 index 0000000..397b3c5 --- /dev/null +++ b/app/components/MachinePrintSelectionNode.vue @@ -0,0 +1,63 @@ + + + diff --git a/app/components/PageHero.vue b/app/components/PageHero.vue new file mode 100644 index 0000000..342827e --- /dev/null +++ b/app/components/PageHero.vue @@ -0,0 +1,79 @@ + + + diff --git a/app/components/TypeEditActionsBar.vue b/app/components/TypeEditActionsBar.vue new file mode 100644 index 0000000..dfa6b92 --- /dev/null +++ b/app/components/TypeEditActionsBar.vue @@ -0,0 +1,37 @@ + + + diff --git a/app/components/TypeEditBaseInfoSection.vue b/app/components/TypeEditBaseInfoSection.vue new file mode 100644 index 0000000..8ef6c86 --- /dev/null +++ b/app/components/TypeEditBaseInfoSection.vue @@ -0,0 +1,103 @@ + + + diff --git a/app/components/TypeEditComponentsSection.vue b/app/components/TypeEditComponentsSection.vue new file mode 100644 index 0000000..f5a3d50 --- /dev/null +++ b/app/components/TypeEditComponentsSection.vue @@ -0,0 +1,294 @@ + + + diff --git a/app/components/TypeEditCustomFieldsSection.vue b/app/components/TypeEditCustomFieldsSection.vue new file mode 100644 index 0000000..75df437 --- /dev/null +++ b/app/components/TypeEditCustomFieldsSection.vue @@ -0,0 +1,263 @@ + + + diff --git a/app/components/TypeEditForm.vue b/app/components/TypeEditForm.vue index 6d8d7dd..274fd54 100644 --- a/app/components/TypeEditForm.vue +++ b/app/components/TypeEditForm.vue @@ -1,1430 +1,136 @@ diff --git a/app/components/TypeEditMachinePiecesSection.vue b/app/components/TypeEditMachinePiecesSection.vue new file mode 100644 index 0000000..8ffafa8 --- /dev/null +++ b/app/components/TypeEditMachinePiecesSection.vue @@ -0,0 +1,78 @@ + + + diff --git a/app/components/TypeEditToolbar.vue b/app/components/TypeEditToolbar.vue new file mode 100644 index 0000000..ab15cff --- /dev/null +++ b/app/components/TypeEditToolbar.vue @@ -0,0 +1,34 @@ + + + diff --git a/app/components/TypeMachinePieceForm.vue b/app/components/TypeMachinePieceForm.vue index 3832b37..2f4c197 100644 --- a/app/components/TypeMachinePieceForm.vue +++ b/app/components/TypeMachinePieceForm.vue @@ -89,11 +89,10 @@ -
@@ -235,22 +234,44 @@ diff --git a/app/composables/useProfileSession.js b/app/composables/useProfileSession.js new file mode 100644 index 0000000..0e3f44d --- /dev/null +++ b/app/composables/useProfileSession.js @@ -0,0 +1,81 @@ +import { useState, useRequestHeaders, useRuntimeConfig } from '#imports' + +const buildUrl = (path) => { + const config = useRuntimeConfig() + const base = config.public.apiBaseUrl?.replace(/\/$/, '') || '' + return `${base}${path}` +} + +export function useProfileSession() { + const activeProfile = useState('profileSession:active', () => null) + const sessionLoaded = useState('profileSession:loaded', () => false) + const loading = useState('profileSession:loading', () => false) + + const getSessionHeaders = () => { + if (!process.server) return undefined + const headers = useRequestHeaders(['cookie']) + return headers?.cookie ? { cookie: headers.cookie } : undefined + } + + const fetchCurrentProfile = async () => { + loading.value = true + try { + activeProfile.value = await $fetch(buildUrl('/session/profile'), { + method: 'GET', + credentials: 'include', + headers: getSessionHeaders(), + }) + } catch (error) { + if (error?.status === 401) { + activeProfile.value = null + } else { + console.error('Erreur lors du chargement du profil actif', error) + activeProfile.value = null + } + } finally { + sessionLoaded.value = true + loading.value = false + } + return activeProfile.value + } + + const ensureSession = () => { + if (!sessionLoaded.value) { + return fetchCurrentProfile() + } + return Promise.resolve(activeProfile.value) + } + + const activateProfile = async (profileId) => { + await $fetch(buildUrl('/session/profile'), { + method: 'POST', + credentials: 'include', + body: { profileId }, + headers: getSessionHeaders(), + }) + await fetchCurrentProfile() + } + + const logout = async () => { + try { + await $fetch(buildUrl('/session/profile'), { + method: 'DELETE', + credentials: 'include', + headers: getSessionHeaders(), + }) + } finally { + activeProfile.value = null + sessionLoaded.value = true + } + } + + return { + activeProfile, + loading, + sessionLoaded, + ensureSession, + fetchCurrentProfile, + activateProfile, + logout, + } +} diff --git a/app/composables/useProfiles.js b/app/composables/useProfiles.js new file mode 100644 index 0000000..ed2310f --- /dev/null +++ b/app/composables/useProfiles.js @@ -0,0 +1,67 @@ +import { useState, useRequestHeaders, useRuntimeConfig } from '#imports' + +const buildUrl = (path) => { + const config = useRuntimeConfig() + const base = config.public.apiBaseUrl?.replace(/\/$/, '') || '' + return `${base}${path}` +} + +export function useProfiles() { + const profiles = useState('profiles:list', () => []) + const loadingProfiles = useState('profiles:loading', () => false) + const profilesLoaded = useState('profiles:loaded', () => false) + + const getSessionHeaders = () => { + if (!process.server) return undefined + const headers = useRequestHeaders(['cookie']) + return headers?.cookie ? { cookie: headers.cookie } : undefined + } + + const fetchProfiles = async () => { + loadingProfiles.value = true + try { + profiles.value = await $fetch(buildUrl('/profiles'), { + method: 'GET', + credentials: 'include', + headers: getSessionHeaders(), + }) + profilesLoaded.value = true + } catch (error) { + console.error('Erreur lors du chargement des profils', error) + profiles.value = [] + profilesLoaded.value = false + } finally { + loadingProfiles.value = false + } + return profiles.value + } + + const createProfile = async ({ firstName, lastName }) => { + const profile = await $fetch(buildUrl('/profiles'), { + method: 'POST', + credentials: 'include', + body: { firstName, lastName }, + headers: getSessionHeaders(), + }) + await fetchProfiles() + return profile + } + + const deleteProfile = async (profileId) => { + await $fetch(buildUrl(`/profiles/${profileId}`), { + method: 'DELETE', + credentials: 'include', + headers: getSessionHeaders(), + }) + await fetchProfiles() + } + + return { + profiles, + loadingProfiles, + profilesLoaded, + fetchProfiles, + createProfile, + deleteProfile, + } +} diff --git a/app/middleware/profile.global.ts b/app/middleware/profile.global.ts new file mode 100644 index 0000000..32b36a5 --- /dev/null +++ b/app/middleware/profile.global.ts @@ -0,0 +1,12 @@ +import { useProfileSession } from '#imports' + +export default defineNuxtRouteMiddleware(async (to) => { + const { ensureSession, activeProfile } = useProfileSession() + await ensureSession() + + const isProfilesRoute = to.path.startsWith('/profiles') + + if (!activeProfile.value && !isProfilesRoute) { + return navigateTo('/profiles') + } +}) diff --git a/app/pages/documents.vue b/app/pages/documents.vue index ebc4c52..75ba4f5 100644 --- a/app/pages/documents.vue +++ b/app/pages/documents.vue @@ -1,15 +1,9 @@ diff --git a/app/pages/type/[id].vue b/app/pages/type/[id].vue index 8934f37..fddca42 100644 --- a/app/pages/type/[id].vue +++ b/app/pages/type/[id].vue @@ -1,16 +1,14 @@