disable optimization request btn if already sent

This commit is contained in:
isUnknown 2025-02-05 11:22:09 +01:00
parent 77a0a42606
commit c73b9d671b
7 changed files with 114 additions and 81 deletions

View file

@ -1,20 +1,21 @@
<?php <?php
$project = [ $project = [
"title" => $page->title()->value(), 'title' => $page->title()->value(),
"url" => $page->url(), 'url' => $page->url(),
"modified" => $page->modified("Y-MM-d"), 'modified' => $page->modified('Y-MM-d'),
"status" => $page->status(), 'status' => $page->status(),
"logo" => $page->client()->isNotEmpty() && $page->client()->toPage() 'logo' => $page->client()->isNotEmpty() && $page->client()->toPage()
? $page->client()->toPage()->logo()->toFile()->url() ? $page->client()->toPage()->logo()->toFile()->url()
: null, : null,
"steps" => $page->getSteps(), 'steps' => $page->getSteps(),
"designToLight" => $page->isDTLEnabled() == "true" ? processDTLProposals($page) : null, 'designToLight' => $page->isDTLEnabled()->isTrue() ? processDTLProposals($page) : null,
'hasOptimizationRequest' => $page->hasOptimizationRequest()->isTrue(),
]; ];
$pageData = array_merge($genericData, $project); $pageData = array_merge($genericData, $project);
echo json_encode([ echo json_encode([
"page" => $pageData, 'page' => $pageData,
"user" => $userData, 'user' => $userData,
]); ]);

View file

@ -1,41 +1,44 @@
<?php <?php
function getProjectData($project) {
function getProjectData($project)
{
$data = [ $data = [
"title" => $project->title()->value(), 'title' => $project->title()->value(),
"url" => $project->url(), 'url' => $project->url(),
"uri" => "/" . $project->uri(), 'uri' => '/' . $project->uri(),
"modified" => $project->modified("Y-MM-d"), 'modified' => $project->modified('Y-MM-d'),
"currentStep" => $project->currentStep()->value(), 'currentStep' => $project->currentStep()->value(),
"status" => $project->status(), 'status' => $project->status(),
"logo" => $project->client()->toPage() ? $project->client()->toPage()->logo()->toFile()->url() : "", 'logo' => $project->client()->toPage() ? $project->client()->toPage()->logo()->toFile()->url() : '',
"steps" => $project->getSteps(), 'steps' => $project->getSteps(),
"notifications" => Yaml::decode($project->notifications()->value), 'notifications' => Yaml::decode($project->notifications()->value),
"uuid" => (string) $project->uuid(), 'uuid' => (string) $project->uuid(),
"slug" => (string) $project->slug(), 'slug' => (string) $project->slug(),
"isDTLEnabled" => $project->isDTLEnabled()->value() == "true" ? true : false 'isDTLEnabled' => $project->isDTLEnabled()->isTrue(),
'hasOptimizationRequest' => $project->hasOptimizationRequest()->isTrue(),
]; ];
if ($project->isDTLEnabled()) { if ($project->isDTLEnabled()) {
$data["designToLight"] = processDTLProposals($project); $data['designToLight'] = processDTLProposals($project);
} }
return $data; return $data;
} }
try { try {
$children = $kirby->user()->role() == "admin" ? $page->childrenAndDrafts()->map(fn($project) => getProjectData($project))->values() : $kirby->user()->projects()->toPages()->map(fn($project) => getProjectData($project))->values(); $children = $kirby->user()->role() == 'admin' ? $page->childrenAndDrafts()->map(fn($project) => getProjectData($project))->values() : $kirby->user()->projects()->toPages()->map(fn($project) => getProjectData($project))->values();
} catch (\Throwable $th) { } catch (\Throwable $th) {
throw new Exception($th->getMessage() . " line " . $th->getLine(), 1); throw new Exception($th->getMessage() . ' line ' . $th->getLine(), 1);
$children = []; $children = [];
} }
$specificData = [ $specificData = [
"children" => $children, 'children' => $children,
]; ];
$pageData = array_merge($genericData, $specificData); $pageData = array_merge($genericData, $specificData);
echo json_encode([ echo json_encode([
"page" => $pageData, 'page' => $pageData,
"user" => $userData 'user' => $userData,
]); ]);

View file

@ -16,8 +16,8 @@
proposals.length === 1 && isDialogOpen proposals.length === 1 && isDialogOpen
? activeProposal.title ? activeProposal.title
? activeProposal.title ? activeProposal.title
: "Design to light" : 'Design to light'
: "Design to light" : 'Design to light'
}} }}
</h2> </h2>
<button <button
@ -41,8 +41,8 @@
proposal.title proposal.title
? proposal.title ? proposal.title
: index === 0 : index === 0
? "Proposition initiale" ? 'Proposition initiale'
: "Alternative " + index : 'Alternative ' + index
}} }}
</button> </button>
</nav> </nav>
@ -163,11 +163,15 @@
</div> </div>
<footer v-if="proposals.length === 1 && !isDialogOpen" class="p-16"> <footer v-if="proposals.length === 1 && !isDialogOpen" class="p-16">
<button <button
disabled :disabled="page.hasOptimizationRequest ? '' : undefined"
class="btn btn--white w-full" class="btn btn--white w-full"
@click="handleOptimizationButtonClick" @click="handleOptimizationButtonClick"
> >
Demander une expertise doptimisation {{
page.hasOptimizationRequest
? "Demande d'expertise en cours de traitement…"
: 'Demander une expertise doptimisation'
}}
</button> </button>
</footer> </footer>
</section> </section>
@ -178,18 +182,19 @@
/> />
</template> </template>
<script setup> <script setup>
import OptimizationRequestDialog from "./OptimizationRequestDialog.vue"; import OptimizationRequestDialog from './OptimizationRequestDialog.vue';
import dayjs from "dayjs"; import dayjs from 'dayjs';
import "dayjs/locale/fr"; import 'dayjs/locale/fr';
import { storeToRefs } from "pinia"; import { storeToRefs } from 'pinia';
import { ref, onBeforeUnmount, computed } from "vue"; import { ref, onBeforeUnmount, computed } from 'vue';
import { useDialogStore } from "../../stores/dialog"; import { useDialogStore } from '../../stores/dialog';
import { useRoute, useRouter } from "vue-router"; import { usePageStore } from '../../stores/page';
const { proposals } = defineProps({ const { proposals } = defineProps({
proposals: Array, proposals: Array,
}); });
const { page } = storeToRefs(usePageStore());
const { openedFile } = storeToRefs(useDialogStore()); const { openedFile } = storeToRefs(useDialogStore());
const isDialogOpen = computed(() => { const isDialogOpen = computed(() => {
@ -202,29 +207,29 @@ const isDialogOpen = computed(() => {
const isOptimizationDialogOpen = ref(false); const isOptimizationDialogOpen = ref(false);
dayjs.locale("fr"); dayjs.locale('fr');
const emits = defineEmits(["close"]); const emits = defineEmits(['close']);
proposals[0].isActive = true; proposals[0].isActive = true;
const activeProposal = ref(proposals[0]); const activeProposal = ref(proposals[0]);
window.addEventListener("keyup", closeOnEscape); window.addEventListener('keyup', closeOnEscape);
window.addEventListener("click", close); window.addEventListener('click', close);
onBeforeUnmount(() => { onBeforeUnmount(() => {
window.removeEventListener("keyup", closeOnEscape); window.removeEventListener('keyup', closeOnEscape);
window.removeEventListener("click", close); window.removeEventListener('click', close);
}); });
// Functions // Functions
function closeOnEscape(event) { function closeOnEscape(event) {
if (event.key === "Escape") emits("close"); if (event.key === 'Escape') emits('close');
} }
function close() { function close() {
emits("close"); emits('close');
} }
function preventClose(event) { function preventClose(event) {

View file

@ -8,6 +8,7 @@
header="Demander un rendez-vous" header="Demander un rendez-vous"
class="dialog" class="dialog"
:closeOnEscape="true" :closeOnEscape="true"
@click="preventClose($event)"
> >
<template #header> <template #header>
<h2 class="font-serif text-lg">Demander un rendez-vous</h2> <h2 class="font-serif text-lg">Demander un rendez-vous</h2>
@ -34,6 +35,7 @@
v-for="project in currentProjects" v-for="project in currentProjects"
:key="project.uri" :key="project.uri"
:value="project.uri.substring(1)" :value="project.uri.substring(1)"
:disabled="project.hasOptimizationRequest ? '' : undefined"
> >
{{ project.title }} {{ project.title }}
</option> </option>
@ -74,26 +76,33 @@
</template> </template>
<script setup> <script setup>
import Dialog from "primevue/dialog"; import Dialog from 'primevue/dialog';
import { useApiStore } from "../../stores/api"; import { useApiStore } from '../../stores/api';
import { storeToRefs } from "pinia"; import { storeToRefs } from 'pinia';
import { useProjectsStore } from "../../stores/projects"; import { useProjectsStore } from '../../stores/projects';
import { ref, watch } from "vue"; import { usePageStore } from '../../stores/page';
import { ref, watch } from 'vue';
const { page } = storeToRefs(usePageStore());
const { currentProjects } = storeToRefs(useProjectsStore()); const { currentProjects } = storeToRefs(useProjectsStore());
const projectUri = ref(""); const projectUri =
const subject = ref(""); page.value.template === 'project' ? ref(page.value.uri) : ref('');
const details = ref(""); const subject = ref('');
const details = ref('');
const api = useApiStore(); const api = useApiStore();
const isOpen = ref(true); const isOpen = ref(true);
const emits = defineEmits("close"); const emits = defineEmits('close');
watch(isOpen, (newValue) => { watch(isOpen, (newValue) => {
if (!newValue) { if (!newValue) {
emits("close"); emits('close');
} }
}); });
function preventClose(event) {
event.stopImmediatePropagation();
}
async function handleSubmit() { async function handleSubmit() {
const formData = { const formData = {
projectUri: projectUri.value, projectUri: projectUri.value,
@ -103,7 +112,7 @@ async function handleSubmit() {
const response = await api.post( const response = await api.post(
formData, formData,
"/request-optimization-appointment.json" '/request-optimization-appointment.json'
); );
isOpen.value = false; isOpen.value = false;
} }

View file

@ -21,15 +21,22 @@
class="order-last | text-sm text-primary font-medium" class="order-last | text-sm text-primary font-medium"
> >
{{ images[0].comments.length }} commentaire{{ {{ images[0].comments.length }} commentaire{{
images[0].comments.length > 1 ? "s" : "" images[0].comments.length > 1 ? 's' : ''
}} }}
</footer> </footer>
<div class="btn btn--xs btn--dtl | mt-16" v-if="isDesignToLightStep(step)" data-icon="leaf" lang="en">Design to Light</div> <div
class="btn btn--xs btn--dtl | mt-16"
v-if="isDesignToLightStep(step)"
data-icon="leaf"
lang="en"
>
Design to Light
</div>
</article> </article>
</template> </template>
<script setup> <script setup>
import DateTime from "./DateTime.vue"; import DateTime from './DateTime.vue';
import { useDesignToLightStore } from "../../../stores/designToLight"; import { useDesignToLightStore } from '../../../stores/designToLight';
const { images, step, uri } = defineProps({ const { images, step, uri } = defineProps({
images: Array, images: Array,

View file

@ -7,31 +7,39 @@
/> />
</template> </template>
<script setup> <script setup>
import Images from "./Images.vue"; import Images from './Images.vue';
import { computed } from "vue"; import { computed } from 'vue';
const { step } = defineProps({ step: Object }); const { step } = defineProps({ step: Object });
const images = computed(() => { const images = computed(() => {
if (!step.files.dynamic) { if (!step.files.dynamic) {
return [ return [
{ {
url: step.files.static.rawGlass.cover, url: step.files?.static?.rawGlass?.cover,
},
{
url: step.files?.static?.finishedGlass?.cover,
}, },
]; ];
} }
return step.files?.dynamic?.map((track) => getFrontView(track)) ?? [];
return (
step.files?.dynamic?.map(
(track) => (getFrontView(track)['dynamic'] = true)
) ?? []
);
}); });
const uri = "/" + step.uri; const uri = '/' + step.uri;
function getFrontView(track) { function getFrontView(track) {
if (track.files.length === 1) return track.files[0]; if (track.files.length === 1) return track.files[0];
const xMax = parseInt( const xMax = parseInt(
track.files[track.files.length - 1].name.split("_")[1].split(".")[0] track.files[track.files.length - 1].name.split('_')[1].split('.')[0]
); );
const xFrontView = (xMax + 1) / 2; const xFrontView = (xMax + 1) / 2;
const extension = track.files[0].name.split(".")[1]; const extension = track.files[0].name.split('.')[1];
const frontViewName = "0_" + xFrontView + "." + extension; const frontViewName = '0_' + xFrontView + '.' + extension;
const frontView = track.files.find((file) => file.name === frontViewName); const frontView = track.files.find((file) => file.name === frontViewName);
return frontView; return frontView;
} }

View file

@ -68,11 +68,11 @@
/> />
</template> </template>
<script setup> <script setup>
import { storeToRefs } from "pinia"; import { storeToRefs } from 'pinia';
import { usePageStore } from "../stores/page"; import { usePageStore } from '../stores/page';
import OptimizationRequestDialog from "../components/design-to-light/OptimizationRequestDialog.vue"; import OptimizationRequestDialog from '../components/design-to-light/OptimizationRequestDialog.vue';
import ProjectRequestDialog from "../components/ProjectRequestDialog.vue"; import ProjectRequestDialog from '../components/ProjectRequestDialog.vue';
import { computed, ref } from "vue"; import { computed, ref } from 'vue';
const { page } = storeToRefs(usePageStore()); const { page } = storeToRefs(usePageStore());