+
+
diff --git a/resources/js/pages/resumes/Edit.vue b/resources/js/pages/resumes/Edit.vue
index 5a4631b..78970ac 100644
--- a/resources/js/pages/resumes/Edit.vue
+++ b/resources/js/pages/resumes/Edit.vue
@@ -29,6 +29,23 @@ const breadcrumbs: BreadcrumbItem[] = [
},
];
+
+function isSaving() {
+ return resumeStore.isSaving;
+}
+// Confirmation when closing the tab if saving
+window.addEventListener("beforeunload", function (e) {
+ if (!isSaving()) return;
+
+ console.log('Saving in progress, showing confirmation dialog.');
+
+ const confirmationMessage = 'Des changements sont toujours en cours de sauvegarde. '
+ + 'Si vous quittez avant de sauvegarder, vos modifications seront perdues.';
+
+ (e || window.event).returnValue = confirmationMessage; //Gecko + IE
+ return confirmationMessage; //Gecko + Webkit, Safari, Chrome etc.
+});
+
diff --git a/resources/js/stores/resume.ts b/resources/js/stores/resume.ts
index 495b60c..410187f 100644
--- a/resources/js/stores/resume.ts
+++ b/resources/js/stores/resume.ts
@@ -10,6 +10,8 @@ const useResumesStore = defineStore('resumes', {
resumesAreFetched: false as boolean,
currentResumeIndex: -1 as number,
selectedResumePlacementIndex: -1 as number,
+ isSaving: false as boolean,
+ savingError: null as string | null,
}),
getters: {
hasResumes: (state) => computed(() => state.resumes.length > 0),
@@ -48,9 +50,19 @@ const useResumesStore = defineStore('resumes', {
},
},
actions: {
+ setIsSaving(saving: boolean) {
+ this.isSaving = saving;
+ if (saving) {
+ this.savingError = null;
+ }
+ },
+ setSavingError(error: string | null) {
+ this.setIsSaving(false);
+ this.savingError = error;
+ },
async fetchResumes() {
try {
- this.resumesAreFetched = false;
+ this.setIsSaving(true);
// get from cache
const cachedResumes = localStorage.resumes;
if (cachedResumes) {
@@ -59,10 +71,14 @@ const useResumesStore = defineStore('resumes', {
const { data: resumes, error } = await httpApi(route("resumes.index"));
if (error || !resumes) {
- console.error('Failed to fetch resumes:', error);
- return;
+ console.error('Failed to fetch resumes:', error);
+ this.setSavingError(error);
+ return;
}
+
+ this.setIsSaving(false);
this.setResumes(resumes);
+ this.resumesAreFetched = false;
// Store in cache
this.saveResumesToCache();
@@ -70,6 +86,7 @@ const useResumesStore = defineStore('resumes', {
this.resumesAreFetched = true;
} catch (error) {
console.error('Failed to fetch resumes:', error);
+ this.setSavingError(error as string);
}
},
async updateResumeToApi(resumeIndex: number) {
@@ -83,6 +100,7 @@ const useResumesStore = defineStore('resumes', {
return;
}
+ this.setIsSaving(true);
const resumeToUpdate = this.resumes[resumeIndex];
const { data: updatedResume, error } = await httpApi(route("resumes.update", { resume: resumeToUpdate.id }), {
method: 'PUT',
@@ -93,12 +111,16 @@ const useResumesStore = defineStore('resumes', {
},
body: JSON.stringify(resumeToUpdate),
});
+ this.setIsSaving(false);
+ this.setSavingError("Poor nigga detected !");
if (error || !updatedResume) {
console.error('Failed to update resumes:', error);
+ this.setSavingError(error as string);
return;
}
} catch (error) {
console.error('Failed to update resumes:', error);
+ this.setSavingError(error as string);
}
},
async updateCurrentResumeToApi() {
@@ -108,7 +130,38 @@ const useResumesStore = defineStore('resumes', {
localStorage.resumes = JSON.stringify(this.resumes);
},
setResumes(resumes: Array) {
- this.resumes = resumes;
+ // this.resumes = resumes;
+ // for (const resume of resumes) {
+ // const existingResume = this.resumes.find(r => r.id === resume.id);
+ // if (existingResume) {
+ // Object.assign(existingResume, resume);
+ // if (this.currentResumeIndex >= 0 && this.resumes[this.currentResumeIndex].id === resume.id) {
+ // // Update the current resume reference if it's the same resume
+ // this.currentResumeIndex = this.resumes.indexOf(existingResume);
+ // }
+ // } else {
+ // this.resumes.push(resume);
+ // }
+ // }
+
+ // Do a copy of the resumes array
+ // Set the resumes array to resumes
+ // For each old resume, look for it in the new resumes array by id
+ // If found, keep the reference of the old resume (to keep reactivity)
+ // If not found, add the new resume to the array
+ const currentResumeId = this.currentResumeIndex >= 0 && this.currentResumeIndex < this.resumes.length ? this.resumes[this.currentResumeIndex].id : null;
+ // this.resumes = resumes;
+ for (const oldResume of this.resumes) {
+ const existingResume = resumes.find(r => r.id === oldResume.id);
+ if (existingResume) {
+ existingResume.components_placements = oldResume.components_placements;
+ if (oldResume.id === currentResumeId) {
+ this.currentResumeIndex = this.resumes.indexOf(oldResume);
+ }
+ }
+ }
+
+ this.resumes = resumes
},
addResume(resume: Resume) {
this.resumes.push(resume);
@@ -141,11 +194,15 @@ const useResumesStore = defineStore('resumes', {
this.updateCurrentResume(resume);
},
setAndUpdateCurrentResumeWhenFetched(resume: Resume) {
- watch(() => this.resumesAreFetched, (newVal) => {
- if (newVal === true) {
- this.setAndUpdateCurrentResume(resume);
- }
- });
+ if (this.resumesAreFetched) {
+ this.setAndUpdateCurrentResume(resume);
+ } else {
+ watch(() => this.resumesAreFetched, (newVal) => {
+ if (newVal === true) {
+ this.setAndUpdateCurrentResume(resume);
+ }
+ });
+ }
},
updateCurrentResume(updatedResume: Resume) {
if (this.currentResumeIndex < 0 || this.currentResumeIndex >= this.resumes.length) return;
@@ -191,6 +248,7 @@ const useResumesStore = defineStore('resumes', {
}
console.debug("Updating component placement:", componentPlacement);
+ this.setIsSaving(true);
const { data: updatedPlacement, error } = await httpApi(route("resume-component-placements.update", componentPlacement.id), {
method: 'PUT',
headers: {
@@ -200,8 +258,10 @@ const useResumesStore = defineStore('resumes', {
},
body: JSON.stringify(componentPlacement),
});
+ this.setIsSaving(false);
if (error || !updatedPlacement) {
console.error('Failed to update resume placements:', error);
+ this.setSavingError(error as string);
return;
}
@@ -210,6 +270,7 @@ const useResumesStore = defineStore('resumes', {
this.saveResumesToCache();
} catch (error) {
console.error('Failed to update resume placements:', error);
+ this.setSavingError(error as string);
}
},
setSelectedResumePlacement(index: number) {
@@ -238,6 +299,10 @@ const useResumesStore = defineStore('resumes', {
if (!this.hasCurrentSelectedResumePlacement.value) return;
this.modifyResumePlacements(this.selectedResumePlacementIndex, updatedPlacement);
},
+ modifyCurrentSelectedResumePlacementToApi(updatedPlacement: ResumeComponentPlacement) {
+ this.modifyCurrentSelectedResumePlacement(updatedPlacement);
+ this.updateCurrentResumePlacementsToApi(this.selectedResumePlacementIndex);
+ },
swapComponentsPlacementsOrder(indexA: number, indexB: number) {
if (!this.hasCurrentResume.value || !this.currentResume.value?.components_placements) return;
const currentResume = this.currentResume.value;
@@ -266,6 +331,7 @@ const useResumesStore = defineStore('resumes', {
// It will return the new component_data that need to be set to the placement
const placementToUnlink = currentResume.components_placements![index];
try {
+ this.setIsSaving(true);
const { data: newComponentData, error } = await httpApi(route("resume-component-placements.unlink", placementToUnlink.id), {
method: 'PUT',
headers: {
@@ -274,8 +340,10 @@ const useResumesStore = defineStore('resumes', {
'Accept': 'application/json'
},
});
+ this.setIsSaving(false);
if (error || !newComponentData) {
console.error('Failed to unlink resume placement:', error);
+ this.setSavingError(error as string);
return;
}
@@ -286,6 +354,7 @@ const useResumesStore = defineStore('resumes', {
this.saveResumesToCache();
} catch (error) {
console.error('Failed to unlink resume placement:', error);
+ this.setSavingError(error as string);
}
},
async deleteComponentPlacement(index: number) {
@@ -295,6 +364,7 @@ const useResumesStore = defineStore('resumes', {
const placementToDelete = currentResume.components_placements![index];
try {
+ this.setIsSaving(true);
const { error } = await httpApi(route("resume-component-placements.destroy", placementToDelete.id), {
method: 'DELETE',
headers: {
@@ -302,8 +372,10 @@ const useResumesStore = defineStore('resumes', {
'Accept': 'application/json'
},
});
+ this.setIsSaving(false);
if (error) {
console.error('Failed to delete resume placement:', error);
+ this.setSavingError(error as string);
return;
}
@@ -317,6 +389,7 @@ const useResumesStore = defineStore('resumes', {
}
} catch (error) {
console.error('Failed to delete resume placement:', error);
+ this.setSavingError(error as string);
}
},
clearSelectedResumePlacement() {