prepare extended brief
This commit is contained in:
parent
86d3f8b22c
commit
984c8b7737
11 changed files with 143 additions and 67 deletions
|
|
@ -2,7 +2,7 @@ Alt:
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
Favoriteforusers: - user://WWjXgPWk
|
Favoriteforusers:
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ Alt:
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
Favoriteforusers: - user://WWjXgPWk
|
Favoriteforusers:
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
Alt:
|
||||||
|
|
||||||
|
----
|
||||||
|
|
||||||
Favoriteforusers:
|
Favoriteforusers:
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ Title: Miss Dior Blooming Bouquet
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
Currentstep: proposal
|
Currentstep: extendedBrief
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
19
public/site/templates/extended-brief.json.php
Normal file
19
public/site/templates/extended-brief.json.php
Normal 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
|
||||||
|
]);
|
||||||
1
public/site/templates/extended-brief.php
Normal file
1
public/site/templates/extended-brief.php
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
<?php snippet('generic-template') ?>
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue