prepare extended brief

This commit is contained in:
isUnknown 2024-11-19 13:59:06 +01:00
parent 86d3f8b22c
commit 984c8b7737
11 changed files with 143 additions and 67 deletions

View file

@ -2,7 +2,7 @@ Alt:
---- ----
Favoriteforusers: - user://WWjXgPWk Favoriteforusers:
---- ----

View file

@ -2,7 +2,7 @@ Alt:
---- ----
Favoriteforusers: - user://WWjXgPWk Favoriteforusers:
---- ----

View file

@ -1,3 +1,7 @@
Alt:
----
Favoriteforusers: Favoriteforusers:
---- ----

View file

@ -2,7 +2,7 @@ Title: Miss Dior Blooming Bouquet
---- ----
Currentstep: proposal Currentstep: extendedBrief
---- ----

View file

@ -15,7 +15,28 @@ options:
sort: false sort: false
tabs: tabs:
contentTab: content:
fields: label: Brief enrichi
stepName: icon: document
type: hidden columns:
- width: 1/1
fields:
stepName:
type: hidden
value: test
pdf:
label: PDF
type: files
multiple: false
uploads: pdf
description:
type: textarea
size: tiny
buttons: false
maxlength: 700
moodboard:
label: Images
type: files
uploads: image
layout: cards
size: medium

View file

@ -17,8 +17,8 @@ class ProjectPage extends Page {
$files = []; $files = [];
$uri = null; $uri = null;
if ($child->stepName() == 'clientBrief') { if (str_contains($child->stepName()->value(), 'Brief')) {
$this->handleClientBriefStep($child, $files, $uri); $this->handleBriefStep($child, $files, $uri);
} }
if ($child->stepName() == 'proposal') { if ($child->stepName() == 'proposal') {
@ -40,9 +40,10 @@ class ProjectPage extends Page {
]; ];
} }
private function handleClientBriefStep($child, &$files, &$uri) { private function handleBriefStep($child, &$files, &$uri) {
$uri = $child->uri();
if ($child->moodboard()->isNotEmpty()) { if ($child->moodboard()->isNotEmpty()) {
$uri = $child->uri();
foreach ($child->moodboard()->toFiles() as $file) { foreach ($child->moodboard()->toFiles() as $file) {
$files[] = getFileData($file); $files[] = getFileData($file);
} }

View file

@ -0,0 +1,19 @@
<?php
$moodboard = [];
foreach ($page->moodboard()->toFiles() as $image) {
$moodboard[] = getFileData($image);
}
$specificData = [
"tags" => $page->parent()->parent()->clientBriefImageTags()->split(),
"moodboard" => $moodboard
];
$pageData = array_merge($genericData, $specificData);
echo json_encode([
"page" => $pageData,
"user" => $userData
]);

View file

@ -0,0 +1 @@
<?php snippet('generic-template') ?>

View file

@ -1,13 +1,11 @@
<template> <template>
<figure <figure class="flex">
v-if="currentTab === 'all' || isFavorite" <!-- Favorite button -->
class="flex"
>
<button <button
class="favorite" class="favorite"
aria-label="Ajouter aux favoris" :aria-label="isFavorite ? 'Retirer des favoris' : 'Ajouter aux favoris'"
:aria-pressed="isFavorite" :aria-pressed="isFavorite"
@click="isFavorite = !isFavorite" @click="toggleFavorite"
> >
<svg <svg
width="40" width="40"
@ -26,36 +24,62 @@
/> />
</svg> </svg>
</button> </button>
<!-- Image -->
<img :src="item.url" :alt="item.alt" :data-id="item.id" /> <img :src="item.url" :alt="item.alt" :data-id="item.id" />
</figure> </figure>
</template> </template>
<script setup> <script setup>
import { ref, watch } from "vue"; // Imports
import { computed } from "vue";
import { useUserStore } from "../../stores/user"; import { useUserStore } from "../../stores/user";
import { useApiStore } from "../../stores/api"; import { useApiStore } from "../../stores/api";
// Props
const { item, inspirationUri } = defineProps({ const { item, inspirationUri } = defineProps({
item: Object, item: Object,
inspirationUri: String, inspirationUri: String,
currentTab: String,
}); });
const toggleFavoriteRoute = "/toggle-favorite.json"; // Stores
const api = useApiStore();
const { user } = useUserStore(); const { user } = useUserStore();
const isFavorite = ref(item.favoriteForUsers?.includes(user.uuid) ?? false); const api = useApiStore();
watch(isFavorite, (value) => { // State
const data = { console.log(item.favoriteForUsers);
fileName: item.name, const isFavorite = computed(() => {
userUuid: user.uuid, return item.favoriteForUsers?.includes(user.uuid) ?? false;
inspirationUri,
};
api.fetchRoute(toggleFavoriteRoute, "POST", data).then((newValue) => {
item.favoriteForUsers = newValue;
});
}); });
console.log(item.favoriteForUsers);
console.log(user.uuid);
// Methods
async function toggleFavorite() {
const previousState = isFavorite.value;
isFavorite.value = !isFavorite.value;
try {
const data = {
fileName: item.name,
userUuid: user.uuid,
inspirationUri,
};
const newFavoriteUsers = await api.fetchRoute(
"/toggle-favorite.json",
"POST",
data
);
// Update item favorite users list based on API response
item.favoriteForUsers = newFavoriteUsers;
} catch (error) {
console.error("Failed to toggle favorite:", error);
isFavorite.value = previousState; // Rollback on failure
}
}
</script> </script>
<style scoped> <style scoped>
figure { figure {
position: relative; position: relative;

View file

@ -20,9 +20,7 @@
<!-- All images --> <!-- All images -->
<figure <figure
v-if=" v-if="step.id.includes('Brief') && step.files[0]?.type === 'image'"
step.value === 'clientBrief' && step.files[0]?.type === 'image'
"
class="card__images" class="card__images"
:data-count=" :data-count="
step.files.length > 3 ? step.files.length - 3 : undefined step.files.length > 3 ? step.files.length - 3 : undefined
@ -37,7 +35,7 @@
</figure> </figure>
<!-- First image --> <!-- First image -->
<figure v-if="step.value === 'virtualSample'" class="card__images"> <figure v-if="step.id === 'virtualSample'" class="card__images">
<img <img
:key="step.files[0].uuid" :key="step.files[0].uuid"
:src="step.files[0].url" :src="step.files[0].url"

View file

@ -12,10 +12,7 @@
:inspiration="currentInspiration" :inspiration="currentInspiration"
/> />
<div class="masonry flow"> <div class="masonry flow">
<template <template v-for="(item, index) in displayedImages" :key="item.id">
v-for="(item, index) in currentInspiration.media"
:key="item.id"
>
<Image <Image
:item="item" :item="item"
:inspirationUri="currentInspiration.uri" :inspirationUri="currentInspiration.uri"
@ -37,39 +34,50 @@ import { ref, computed } from "vue";
import { usePageStore } from "../stores/page"; import { usePageStore } from "../stores/page";
import { storeToRefs } from "pinia"; import { storeToRefs } from "pinia";
// Stores
const { page } = storeToRefs(usePageStore()); const { page } = storeToRefs(usePageStore());
const user = useUserStore().user; const userStore = useUserStore();
const currentTab = ref("all"); const user = computed(() => userStore.user);
const tabs = computed(() => {
return [
{
label: "Les Inspirations",
id: "all",
icon: null,
count: currentInspiration.value.media.length,
isActive: currentTab.value === "all",
},
{
label: "Mes Favoris",
id: "favorites",
icon: "favorite",
count: favoriteImages.value.length,
isActive: currentTab.value === "favorites",
},
];
});
const allImages = page.value.inspirations.flatMap( // Reactive
(inspiration) => inspiration.media const currentTab = ref("all");
const currentInspiration = ref(page.value.inspirations[0]);
// Computed
const allImages = computed(() =>
page.value.inspirations.flatMap((inspiration) => inspiration.media)
); );
const currentInspiration = ref(page.value.inspirations[0]); const favoriteImages = computed(() =>
const favoriteImages = computed(() => { allImages.value.filter(
return allImages.filter( (image) => image.favoriteForUsers?.includes(user.value.uuid) ?? false
(image) => image.favoriteForUsers?.includes(user.uuid) ?? false )
); );
});
const tabs = computed(() => [
{
label: "Les Inspirations",
id: "all",
icon: null,
count: currentInspiration.value.media.length,
isActive: currentTab.value === "all",
},
{
label: "Mes Favoris",
id: "favorites",
icon: "favorite",
count: favoriteImages.value.length,
isActive: currentTab.value === "favorites",
},
]);
const displayedImages = computed(() =>
currentTab.value === "favorites"
? favoriteImages.value
: currentInspiration.value.media
);
// Methods
function changeTab(newValue) { function changeTab(newValue) {
currentTab.value = newValue; currentTab.value = newValue;
} }