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:
|
||||
|
||||
----
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ Title: Miss Dior Blooming Bouquet
|
|||
|
||||
----
|
||||
|
||||
Currentstep: proposal
|
||||
Currentstep: extendedBrief
|
||||
|
||||
----
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,28 @@ options:
|
|||
sort: false
|
||||
|
||||
tabs:
|
||||
contentTab:
|
||||
fields:
|
||||
stepName:
|
||||
type: hidden
|
||||
content:
|
||||
label: Brief enrichi
|
||||
icon: document
|
||||
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 = [];
|
||||
$uri = null;
|
||||
|
||||
if ($child->stepName() == 'clientBrief') {
|
||||
$this->handleClientBriefStep($child, $files, $uri);
|
||||
if (str_contains($child->stepName()->value(), 'Brief')) {
|
||||
$this->handleBriefStep($child, $files, $uri);
|
||||
}
|
||||
|
||||
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()) {
|
||||
$uri = $child->uri();
|
||||
foreach ($child->moodboard()->toFiles() as $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>
|
||||
<figure
|
||||
v-if="currentTab === 'all' || isFavorite"
|
||||
class="flex"
|
||||
>
|
||||
<figure class="flex">
|
||||
<!-- Favorite button -->
|
||||
<button
|
||||
class="favorite"
|
||||
aria-label="Ajouter aux favoris"
|
||||
:aria-label="isFavorite ? 'Retirer des favoris' : 'Ajouter aux favoris'"
|
||||
:aria-pressed="isFavorite"
|
||||
@click="isFavorite = !isFavorite"
|
||||
@click="toggleFavorite"
|
||||
>
|
||||
<svg
|
||||
width="40"
|
||||
|
|
@ -26,36 +24,62 @@
|
|||
/>
|
||||
</svg>
|
||||
</button>
|
||||
<!-- Image -->
|
||||
<img :src="item.url" :alt="item.alt" :data-id="item.id" />
|
||||
</figure>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch } from "vue";
|
||||
// Imports
|
||||
import { computed } from "vue";
|
||||
import { useUserStore } from "../../stores/user";
|
||||
import { useApiStore } from "../../stores/api";
|
||||
|
||||
// Props
|
||||
const { item, inspirationUri } = defineProps({
|
||||
item: Object,
|
||||
inspirationUri: String,
|
||||
currentTab: String,
|
||||
});
|
||||
|
||||
const toggleFavoriteRoute = "/toggle-favorite.json";
|
||||
const api = useApiStore();
|
||||
// Stores
|
||||
const { user } = useUserStore();
|
||||
const isFavorite = ref(item.favoriteForUsers?.includes(user.uuid) ?? false);
|
||||
const api = useApiStore();
|
||||
|
||||
watch(isFavorite, (value) => {
|
||||
const data = {
|
||||
fileName: item.name,
|
||||
userUuid: user.uuid,
|
||||
inspirationUri,
|
||||
};
|
||||
api.fetchRoute(toggleFavoriteRoute, "POST", data).then((newValue) => {
|
||||
item.favoriteForUsers = newValue;
|
||||
});
|
||||
// State
|
||||
console.log(item.favoriteForUsers);
|
||||
const isFavorite = computed(() => {
|
||||
return item.favoriteForUsers?.includes(user.uuid) ?? false;
|
||||
});
|
||||
|
||||
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>
|
||||
|
||||
<style scoped>
|
||||
figure {
|
||||
position: relative;
|
||||
|
|
|
|||
|
|
@ -20,9 +20,7 @@
|
|||
|
||||
<!-- All images -->
|
||||
<figure
|
||||
v-if="
|
||||
step.value === 'clientBrief' && step.files[0]?.type === 'image'
|
||||
"
|
||||
v-if="step.id.includes('Brief') && step.files[0]?.type === 'image'"
|
||||
class="card__images"
|
||||
:data-count="
|
||||
step.files.length > 3 ? step.files.length - 3 : undefined
|
||||
|
|
@ -37,7 +35,7 @@
|
|||
</figure>
|
||||
|
||||
<!-- First image -->
|
||||
<figure v-if="step.value === 'virtualSample'" class="card__images">
|
||||
<figure v-if="step.id === 'virtualSample'" class="card__images">
|
||||
<img
|
||||
:key="step.files[0].uuid"
|
||||
:src="step.files[0].url"
|
||||
|
|
|
|||
|
|
@ -12,10 +12,7 @@
|
|||
:inspiration="currentInspiration"
|
||||
/>
|
||||
<div class="masonry flow">
|
||||
<template
|
||||
v-for="(item, index) in currentInspiration.media"
|
||||
:key="item.id"
|
||||
>
|
||||
<template v-for="(item, index) in displayedImages" :key="item.id">
|
||||
<Image
|
||||
:item="item"
|
||||
:inspirationUri="currentInspiration.uri"
|
||||
|
|
@ -37,39 +34,50 @@ import { ref, computed } from "vue";
|
|||
import { usePageStore } from "../stores/page";
|
||||
import { storeToRefs } from "pinia";
|
||||
|
||||
// Stores
|
||||
const { page } = storeToRefs(usePageStore());
|
||||
const user = useUserStore().user;
|
||||
const currentTab = ref("all");
|
||||
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 userStore = useUserStore();
|
||||
const user = computed(() => userStore.user);
|
||||
|
||||
const allImages = page.value.inspirations.flatMap(
|
||||
(inspiration) => inspiration.media
|
||||
// Reactive
|
||||
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(() => {
|
||||
return allImages.filter(
|
||||
(image) => image.favoriteForUsers?.includes(user.uuid) ?? false
|
||||
);
|
||||
});
|
||||
const favoriteImages = computed(() =>
|
||||
allImages.value.filter(
|
||||
(image) => image.favoriteForUsers?.includes(user.value.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) {
|
||||
currentTab.value = newValue;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue