DTL : optimization appointment request working
This commit is contained in:
parent
11657a5589
commit
54af78e32c
8 changed files with 132 additions and 25 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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'),
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
@ -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>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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 d’optimisation
|
Demander une expertise d’optimisation
|
||||||
</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) {
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue