DTL : optimization appointment request working

This commit is contained in:
isUnknown 2025-01-27 14:39:52 +01:00
parent 11657a5589
commit 54af78e32c
8 changed files with 132 additions and 25 deletions

View file

@ -3,6 +3,15 @@ label: Design to Light
icon: leaf icon: leaf
fields: fields:
hasOptimizationRequest:
type: hidden
default: "false"
optimizationRequestDetails:
label: Demande de rendez-vous
type: textarea
disabled: true
when:
hasOptimizationRequest: "true"
isDTLEnabled: isDTLEnabled:
label: Actif label: Actif
type: toggle type: toggle

View file

@ -29,6 +29,7 @@ return [
require(__DIR__ . '/routes/upload-pdf.php'), require(__DIR__ . '/routes/upload-pdf.php'),
require(__DIR__ . '/routes/validate-brief.php'), require(__DIR__ . '/routes/validate-brief.php'),
require(__DIR__ . '/routes/request-project-creation.php'), require(__DIR__ . '/routes/request-project-creation.php'),
require(__DIR__ . '/routes/request-optimization-appointment.php'),
], ],
'hooks' => [ 'hooks' => [
'page.create:after' => require_once(__DIR__ . '/hooks/create-steps.php'), 'page.create:after' => require_once(__DIR__ . '/hooks/create-steps.php'),

View file

@ -0,0 +1,52 @@
<?php
return [
'pattern' => 'request-optimization-appointment.json',
'method' => 'POST',
'action' => function () {
$json = file_get_contents('php://input');
$data = json_decode($json);
$user = kirby()->user();
$project = page($data->projectUri);
try {
$newProject = $project->update([
"hasOptimizationRequest" => "true",
"optimizationRequestDetails" => esc("De la part de " . kirby()->user()->name() . " (" . kirby()->user()->email() . ") : \n\n" . "Objet : " . $data->subject . "\n" . $data->details)
]);
} catch (\Throwable $th) {
return [
"status" => "error",
"message" => "Can't update project " . $project->title()->value() . ". " . $th->getMessage() . " in " . $th->getFile() . " line " . $th->getLine()
];
}
try {
$date = new DateTime();
$formattedDate = $date->format(DateTime::ISO8601);
$notificationData = [
"location" => [
"page" => $newProject
],
"date" => (string) $formattedDate,
"text" => nl2br(esc($data->details)),
"author" => $user,
"id" => Str::uuid(),
"type" => "appointment-request",
];
$newProject->createNotification($notificationData);
return [
"status" => "success",
];
} catch (\Throwable $th) {
return [
"status" => "error",
"message" => "Can't create notification. " . $th->getMessage() . " in " . $th->getFile() . " line " . $th->getLine()
];
}
}
];

View file

@ -30,7 +30,8 @@ async function handleSubmit() {
isDTLEnabled: isDTLEnabled.value, isDTLEnabled: isDTLEnabled.value,
}; };
const response = await api.requestProjectCreation(formData); const response = await api.post(formData, "request-project-creation.json");
console.log(response);
} }
</script> </script>

View file

@ -145,16 +145,20 @@
</template> </template>
</div> </div>
</div> </div>
<!-- Je laisse pour le moment en suspend l'effet de ce bouton car je ne suis pas sûr de comprendre. J'ai mis un commentaire sur Figma --> <footer v-if="proposals.length > 1" class="p-16">
<footer class="p-16"> <button
<button class="btn btn--white w-full"> class="btn btn--white w-full"
@click="isOptimizationDialogOpen = true"
>
Demander une expertise doptimisation Demander une expertise doptimisation
</button> </button>
</footer> </footer>
</section> </section>
</aside> </aside>
<OptimizationRequestDialog v-if="isOptimizationDialogOpen" />
</template> </template>
<script setup> <script setup>
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";
@ -171,6 +175,8 @@ const isDialogOpen = computed(() => {
return openedFile.value != null; return openedFile.value != null;
}); });
const isOptimizationDialogOpen = ref(false);
dayjs.locale("fr"); dayjs.locale("fr");
const emits = defineEmits(["close"]); const emits = defineEmits(["close"]);
@ -179,13 +185,13 @@ 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) {

View file

@ -1,18 +1,59 @@
<template> <template>
<form action=""> <form @submit.prevent="handleSubmit">
<select name="projects" id="projects"> <select name="projects" id="projects" v-model="projectUri">
<option v-for="project in currentProjects" :value="project.slug"> <option
v-for="project in currentProjects"
:key="project.uri"
:value="project.uri.substring(1)"
>
{{ project.title }} {{ project.title }}
</option> </option>
</select> </select>
<input type="text" value="Design to Light" /> <input type="text" v-model="subject" />
<textarea placeholder="Décrivez votre demande…"> </textarea> <textarea
name="details"
v-model="details"
cols="30"
rows="10"
placeholder="Décrivez votre demande…"
required
></textarea>
<button type="submit">Soumettre</button>
</form> </form>
</template> </template>
<script setup> <script setup>
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 } from "vue";
const { currentProjects } = storeToRefs(useProjectsStore()); const { currentProjects } = storeToRefs(useProjectsStore());
const projectUri = ref("");
const subject = ref("Design to Light");
const details = ref("");
const api = useApiStore();
async function handleSubmit() {
const formData = {
projectUri: projectUri.value,
subject: subject.value,
details: details.value,
};
const response = await api.post(
formData,
"/request-optimization-appointment.json"
);
console.log(response);
}
</script> </script>
<style scoped>
form {
position: fixed;
background-color: #fff;
z-index: 999;
}
</style>

View file

@ -75,24 +75,21 @@ export const useApiStore = defineStore("api", () => {
} }
} }
async function requestProjectCreation(data) { async function post(data, route) {
const headers = { const headers = {
method: "POST", method: "POST",
body: JSON.stringify(data), body: JSON.stringify(data),
}; };
try { try {
const response = await fetch("/request-project-creation.json", headers); const response = await fetch(route, headers);
if (!response.ok) { if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`); throw new Error(`HTTP error! status: ${response.status}`);
} }
const data = await response.json(); const data = await response.json();
console.log(data); return data;
} catch (error) { } catch (error) {
console.error( console.error("Une erreur s'est produite :", error);
"Une erreur s'est produite lors de l'ajout du commentaire :",
error
);
throw error; throw error;
} }
} }
@ -249,6 +246,6 @@ export const useApiStore = defineStore("api", () => {
readNotification, readNotification,
readAllNotifications, readAllNotifications,
validateBrief, validateBrief,
requestProjectCreation, post,
}; };
}); });

View file

@ -27,7 +27,7 @@
</article> </article>
<OptimizationRequestDialog <OptimizationRequestDialog
v-if="isDialogOpen" v-if="isOptimizationDialogOpen"
@close="isDialogOpen = false" @close="isDialogOpen = false"
/> />
</template> </template>
@ -39,5 +39,5 @@ import { ref } from "vue";
const { page } = storeToRefs(usePageStore()); const { page } = storeToRefs(usePageStore());
const isDialogOpen = ref(false); const isOptimizationDialogOpen = ref(false);
</script> </script>