131 lines
2.9 KiB
Vue
131 lines
2.9 KiB
Vue
<script setup>
|
|
// ITEM FETCHING //
|
|
// set initial sort order
|
|
const sortVariable = ref(["reserved", "date_created"]);
|
|
const reservedVariable = ref(true);
|
|
// fetch data
|
|
const { homepage } = await GqlGetHomepage();
|
|
const { data, refresh } = await useAsyncData("gifts", () =>
|
|
GqlGifts({ sort: sortVariable.value })
|
|
);
|
|
// update sort param
|
|
function sortList(param) {
|
|
sortVariable.value = param;
|
|
// refetch query (expose token or access pubic data)
|
|
refresh();
|
|
}
|
|
// filter out already reserved items
|
|
const filteredList = computed(() => {
|
|
const list = data;
|
|
return list;
|
|
});
|
|
|
|
// CHANGE DISPLAY //
|
|
const listDisplay = ref(false);
|
|
function toggleDisplay() {
|
|
listDisplay.value = !listDisplay.value;
|
|
}
|
|
|
|
// ITEM RESERVATION //
|
|
// no error to start
|
|
const errorStatus = ref(false);
|
|
const statusMessage = ref("");
|
|
// update the chosen item's reservation status
|
|
async function runMutation(payload) {
|
|
try {
|
|
const result = await GqlUpdateItem({
|
|
id: payload.id,
|
|
reserved: payload.reserve,
|
|
name: payload.name,
|
|
});
|
|
} catch (error) {
|
|
// if error, set the status to true
|
|
console.log("---ERREUR---", error);
|
|
errorStatus.value = true;
|
|
} finally {
|
|
if (errorStatus.value) {
|
|
// if error is true, show an error notice
|
|
statusMessage.value = "Une erreur est survenue… ¯\\_(ツ)_/¯";
|
|
// cleanup the error status
|
|
errorStatus.value = false;
|
|
} else {
|
|
// if all is well, show a success notice
|
|
statusMessage.value = `C'est noté merci beaucoup ${payload.name} 🥰`;
|
|
setTimeout(() => {
|
|
refresh();
|
|
}, 3500);
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<main class="flow">
|
|
<h1>Liste de naissance</h1>
|
|
<section class="intro sidebar--reverse" data-direction="rtl">
|
|
<article v-html="homepage.content" class="editorial" />
|
|
<img
|
|
src="~/assets/images/jungle.jpg"
|
|
class="intro__image"
|
|
width="400"
|
|
height="600"
|
|
alt=""
|
|
/>
|
|
</section>
|
|
<hr />
|
|
<SortFilter :onSort="sortList" :onDisplay="toggleDisplay" />
|
|
<hr />
|
|
<ul
|
|
class="gifts gifts--grid"
|
|
:class="{ 'gifts--list': listDisplay }"
|
|
role="list"
|
|
>
|
|
<li v-for="gift of data?.gifts" :key="gift.id" class="gift-item">
|
|
<GiftCard
|
|
:item="gift"
|
|
:onReserved="runMutation"
|
|
v-model:status-message="statusMessage"
|
|
/>
|
|
</li>
|
|
</ul>
|
|
</main>
|
|
</template>
|
|
|
|
<style scoped>
|
|
h1 {
|
|
text-align: center;
|
|
}
|
|
.intro {
|
|
--sidebar-target-width: 400px;
|
|
--sidebar-target-grow: 0;
|
|
margin: var(--space-m-l) auto;
|
|
max-inline-size: 90ch;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
.intro__image {
|
|
mix-blend-mode: multiply;
|
|
filter: brightness(110%);
|
|
height: 600px;
|
|
width: 400px;
|
|
object-fit: cover;
|
|
}
|
|
hr {
|
|
margin-block: var(--space-xs-s);
|
|
border-bottom: 3px dotted var(--color-yellow-dark);
|
|
}
|
|
.gifts {
|
|
display: grid;
|
|
gap: var(--space-s-m);
|
|
}
|
|
.gifts--grid {
|
|
grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
|
|
}
|
|
.gifts--grid .gift-item > :deep(:first-child) {
|
|
height: 100%;
|
|
}
|
|
.gifts--list {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
</style>
|