From b89fd67d57c96afb412891b4cfaebd9e155dc043 Mon Sep 17 00:00:00 2001 From: Matthias Guillitte Date: Sat, 27 Sep 2025 14:09:05 +0200 Subject: [PATCH] Bug fixes + Save status --- .../ResumeComponentPlacementController.php | 1 + .../UpdateResumeComponentPlacementRequest.php | 2 +- package.json | 2 +- pnpm-lock.yaml | 21 +++-- resources/js/components/SaveStatusIcon.vue | 58 ++++++++++++ resources/js/components/SidebarResumeList.vue | 2 +- .../components/resume/ResumeComponentEdit.vue | 29 +++--- .../js/components/resume/ResumeEditPanel.vue | 4 +- resources/js/pages/resumes/Edit.vue | 17 ++++ resources/js/stores/resume.ts | 91 +++++++++++++++++-- 10 files changed, 194 insertions(+), 33 deletions(-) create mode 100644 resources/js/components/SaveStatusIcon.vue diff --git a/app/Http/Controllers/ResumeComponentPlacementController.php b/app/Http/Controllers/ResumeComponentPlacementController.php index 830ff94..f646822 100644 --- a/app/Http/Controllers/ResumeComponentPlacementController.php +++ b/app/Http/Controllers/ResumeComponentPlacementController.php @@ -97,6 +97,7 @@ class ResumeComponentPlacementController extends Controller $resumeComponentPlacement->push(); $resumeComponentPlacement->refresh(); + $resumeComponentPlacement->load('componentData.component', 'componentData.inputData.componentInput.dataType'); return response()->json($resumeComponentPlacement); } diff --git a/app/Http/Requests/UpdateResumeComponentPlacementRequest.php b/app/Http/Requests/UpdateResumeComponentPlacementRequest.php index ca7c5cc..c2de964 100644 --- a/app/Http/Requests/UpdateResumeComponentPlacementRequest.php +++ b/app/Http/Requests/UpdateResumeComponentPlacementRequest.php @@ -28,7 +28,7 @@ class UpdateResumeComponentPlacementRequest extends FormRequest 'component_data.component.id' => 'required|exists:resume_components,id', 'component_data.input_data' => 'required|array', 'component_data.input_data.*.id' => 'required|exists:resume_component_input_data,id', - 'component_data.input_data.*.value' => 'required|string', + 'component_data.input_data.*.value' => 'present', 'component_data.input_data.*.component_input.id' => 'required|exists:resume_component_inputs,id', ]; } diff --git a/package.json b/package.json index cb75a85..2fab789 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "concurrently": "^9.0.1", "jspdf": "^3.0.1", "laravel-vite-plugin": "^2.0.0", - "lucide-vue-next": "^0.468.0", + "lucide-vue-next": "^0.512.0", "pinia": "^3.0.3", "reka-ui": "^2.2.0", "tailwind-merge": "^3.2.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e65faad..9f13462 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -36,8 +36,8 @@ importers: specifier: ^2.0.0 version: 2.0.0(vite@7.1.2(@types/node@22.17.2)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)) lucide-vue-next: - specifier: ^0.468.0 - version: 0.468.0(vue@3.5.18(typescript@5.9.2)) + specifier: ^0.512.0 + version: 0.512.0(vue@3.5.18(typescript@5.9.2)) pinia: specifier: ^3.0.3 version: 3.0.3(typescript@5.9.2)(vue@3.5.18(typescript@5.9.2)) @@ -526,6 +526,9 @@ packages: '@jridgewell/trace-mapping@0.3.30': resolution: {integrity: sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==} + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -1624,8 +1627,8 @@ packages: lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} - lucide-vue-next@0.468.0: - resolution: {integrity: sha512-quV/6T8YB1XK0VOEnebg3Byd8Rsan5/m95cvjnuHV4vcS3qEnLAybkrSh0hk3ppavx+V7R1PjNW+mGDvcBdz4A==} + lucide-vue-next@0.512.0: + resolution: {integrity: sha512-FNZSsb/0ieJ1b10B3HjGFNGPXOtVEeKqSeEW/m2Is5hy7CrkkBTrTMloTw9tQ3pitfMwvAHLg5MnhWJLULKr1w==} peerDependencies: vue: '>=3.0.1' @@ -2693,7 +2696,7 @@ snapshots: '@jridgewell/source-map@0.3.11': dependencies: '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.30 + '@jridgewell/trace-mapping': 0.3.31 optional: true '@jridgewell/sourcemap-codec@1.5.5': {} @@ -2703,6 +2706,12 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + optional: true + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -3836,7 +3845,7 @@ snapshots: dependencies: yallist: 3.1.1 - lucide-vue-next@0.468.0(vue@3.5.18(typescript@5.9.2)): + lucide-vue-next@0.512.0(vue@3.5.18(typescript@5.9.2)): dependencies: vue: 3.5.18(typescript@5.9.2) diff --git a/resources/js/components/SaveStatusIcon.vue b/resources/js/components/SaveStatusIcon.vue new file mode 100644 index 0000000..91a8fbf --- /dev/null +++ b/resources/js/components/SaveStatusIcon.vue @@ -0,0 +1,58 @@ + + + + + diff --git a/resources/js/components/SidebarResumeList.vue b/resources/js/components/SidebarResumeList.vue index d07a4a5..ffae420 100644 --- a/resources/js/components/SidebarResumeList.vue +++ b/resources/js/components/SidebarResumeList.vue @@ -40,7 +40,7 @@ function removeResume(deletedResume: Resume) { if (resumeStore.resumes.length > 0) { window.location.href = route("resumes.edit", resumeStore.resumes[0], false); } else { - window.location.href = route("resumes.create"); + window.location.href = route("dashboard"); } } } diff --git a/resources/js/components/resume/ResumeComponentEdit.vue b/resources/js/components/resume/ResumeComponentEdit.vue index d8d961a..15989a3 100644 --- a/resources/js/components/resume/ResumeComponentEdit.vue +++ b/resources/js/components/resume/ResumeComponentEdit.vue @@ -28,20 +28,21 @@ async function sendChangedData(newData: ResumeInputData[]) { clearTimeout(delayedSendTimeout); } delayedSendTimeout = setTimeout(async () => { - const { data, error } = await httpApi(route('resume-component-placements.update', newSelectedComponent), { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') || '', - 'Accept': 'application/json' - }, - body: JSON.stringify({ ...newSelectedComponent, _method: 'PUT' }) - }, {immediate: true}); - // Handle error - if (error) { - console.error('Failed to update component placement:', error, data); - return; - } + // const { data, error } = await httpApi(route('resume-component-placements.update', newSelectedComponent), { + // method: 'POST', + // headers: { + // 'Content-Type': 'application/json', + // 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') || '', + // 'Accept': 'application/json' + // }, + // body: JSON.stringify({ ...newSelectedComponent, _method: 'PUT' }) + // }, {immediate: true}); + // // Handle error + // if (error) { + // console.error('Failed to update component placement:', error, data); + // return; + // } + resumeStore.modifyCurrentSelectedResumePlacementToApi(newSelectedComponent!); }, SEND_CHANGED_DATA_DELAY); diff --git a/resources/js/components/resume/ResumeEditPanel.vue b/resources/js/components/resume/ResumeEditPanel.vue index e271637..f528426 100644 --- a/resources/js/components/resume/ResumeEditPanel.vue +++ b/resources/js/components/resume/ResumeEditPanel.vue @@ -5,6 +5,7 @@ import ComponentsSelectionList from './ComponentsSelectionList.vue'; import { computed } from 'vue'; import { useResumesStore } from '@/stores/resume'; import { useShowComponentSelectionStore } from '@/stores/ui'; +import SaveStatusIcon from '../SaveStatusIcon.vue'; const resumeStore = useResumesStore(); const selectedComponent = resumeStore.currentSelectedResumePlacement; @@ -14,7 +15,8 @@ const showComponentSelection = computed(() => showComponentSelectionSto