finish client brief step
This commit is contained in:
parent
e4f06ad854
commit
cdeebbf8c8
11 changed files with 162 additions and 234 deletions
|
|
@ -1,8 +1,5 @@
|
||||||
title: PDF
|
title: PDF
|
||||||
|
|
||||||
accept:
|
|
||||||
mime: application/pdf
|
|
||||||
extension: pdf
|
|
||||||
focus: false
|
focus: false
|
||||||
fields:
|
fields:
|
||||||
comments:
|
comments:
|
||||||
|
|
|
||||||
|
|
@ -27,10 +27,8 @@ tabs:
|
||||||
pdf:
|
pdf:
|
||||||
label: PDF
|
label: PDF
|
||||||
type: files
|
type: files
|
||||||
multiple: false
|
|
||||||
template: pdf
|
template: pdf
|
||||||
accept:
|
multiple: false
|
||||||
extension: pdf
|
|
||||||
description:
|
description:
|
||||||
type: textarea
|
type: textarea
|
||||||
size: tiny
|
size: tiny
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ return [
|
||||||
'content' => [
|
'content' => [
|
||||||
'date' => date('Y-m-d h:i')
|
'date' => date('Y-m-d h:i')
|
||||||
]
|
]
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$newPage = $page->update([
|
$newPage = $page->update([
|
||||||
"pdf" => $newFile->id()
|
"pdf" => $newFile->id()
|
||||||
|
|
@ -50,7 +50,7 @@ return [
|
||||||
|
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
return [
|
return [
|
||||||
'error' => $e->getMessage(),
|
'error' => $e->getMessage() . " in " . $e->getFile() . " line " . $e->getLine(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,10 @@ function getFileData($file) {
|
||||||
'quality' => 80,
|
'quality' => 80,
|
||||||
'format' => 'webp'
|
'format' => 'webp'
|
||||||
])->url(),
|
])->url(),
|
||||||
|
'parent' => [
|
||||||
|
"title" => (string) $file->parent()->title(),
|
||||||
|
"uri" => $file->parent()->uri()
|
||||||
|
],
|
||||||
'uuid' => (string) $file->uuid(),
|
'uuid' => (string) $file->uuid(),
|
||||||
'name' => $file->filename(),
|
'name' => $file->filename(),
|
||||||
'label' => (string) $file->label(),
|
'label' => (string) $file->label(),
|
||||||
|
|
|
||||||
|
|
@ -8,210 +8,7 @@
|
||||||
<span :data-icon="step.id">{{ step.label }}</span>
|
<span :data-icon="step.id">{{ step.label }}</span>
|
||||||
</h2>
|
</h2>
|
||||||
<div class="cards | flow">
|
<div class="cards | flow">
|
||||||
<template
|
<component :is="cardsMap[step.id]" :step="step" />
|
||||||
v-if="
|
|
||||||
step.id === 'clientBrief' ||
|
|
||||||
step.files.dynamic ||
|
|
||||||
step.files.static ||
|
|
||||||
step.files.length
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<article
|
|
||||||
class="card"
|
|
||||||
v-if="
|
|
||||||
step.id !== 'proposal' &&
|
|
||||||
step.id !== 'industrialIdeation' &&
|
|
||||||
step.id !== 'physicalSample' &&
|
|
||||||
step.id === 'clientBrief' &&
|
|
||||||
step.files.some((file) => file.type === 'image')
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<hgroup class="order-last">
|
|
||||||
<h3 class="card__title | font-serif | text-lg">
|
|
||||||
<router-link
|
|
||||||
:to="
|
|
||||||
step.id === 'clientBrief'
|
|
||||||
? '/' + page.uri + '/client-brief'
|
|
||||||
: '/' + step.uri
|
|
||||||
"
|
|
||||||
class="link-full"
|
|
||||||
>{{ step.label }}</router-link
|
|
||||||
>
|
|
||||||
</h3>
|
|
||||||
</hgroup>
|
|
||||||
<div class="card__meta | flex">
|
|
||||||
<time
|
|
||||||
class="card__date | text-grey-700"
|
|
||||||
:datetime="dayjs(step.modified).format('YYYY-M-DD')"
|
|
||||||
>{{ dayjs(step.modified).format("DD MMMM YYYY") }}</time
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
<!-- All images -->
|
|
||||||
<figure
|
|
||||||
v-if="step.id === 'clientBrief' && step.files[0]?.type === 'image'"
|
|
||||||
class="card__images"
|
|
||||||
:data-count="
|
|
||||||
step.files.filter((file) => file.type === 'image').length
|
|
||||||
"
|
|
||||||
:data-plus="
|
|
||||||
step.files.length > 3 ? step.files.length - 3 : undefined
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<template v-for="image in step.files.slice(0, 3)" :key="image.uuid">
|
|
||||||
<img
|
|
||||||
v-if="image.type === 'image'"
|
|
||||||
:src="image.url"
|
|
||||||
:alt="image.alt"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
</figure>
|
|
||||||
<figure
|
|
||||||
v-if="step.id === 'virtualSample'"
|
|
||||||
class="card__images"
|
|
||||||
:data-count="step.files.dynamic.length"
|
|
||||||
:data-plus="
|
|
||||||
step.files.dynamic.length > 3
|
|
||||||
? step.files.dynamic.length - 3
|
|
||||||
: undefined
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
v-for="track in step.files.dynamic"
|
|
||||||
:key="track.files.slug"
|
|
||||||
:src="getFrontView(track).url"
|
|
||||||
:alt="getFrontView(track).alt"
|
|
||||||
/>
|
|
||||||
</figure>
|
|
||||||
<!-- Document -->
|
|
||||||
<div
|
|
||||||
v-if="step.files[0]?.type === 'document'"
|
|
||||||
class="card__images"
|
|
||||||
data-icon="document"
|
|
||||||
></div>
|
|
||||||
<footer
|
|
||||||
v-if="step?.files[0]?.comments?.length > 0"
|
|
||||||
class="order-last | text-sm text-primary font-medium"
|
|
||||||
>
|
|
||||||
{{ step.files[0].comments.length }} commentaire{{
|
|
||||||
step.files[0].comments.length > 1 ? "s" : ""
|
|
||||||
}}
|
|
||||||
</footer>
|
|
||||||
</article>
|
|
||||||
|
|
||||||
<template
|
|
||||||
v-if="
|
|
||||||
(step.id == 'clientBrief' &&
|
|
||||||
step.files.find((file) => file.type === 'document')) ||
|
|
||||||
step.id == 'proposal' ||
|
|
||||||
(step.id == 'industrialIdeation' && step.files.length)
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<template v-for="(file, index) in step.files" :key="file.name">
|
|
||||||
<article class="card" v-if="file.type === 'document'">
|
|
||||||
<hgroup class="order-last">
|
|
||||||
<h3 class="card__title | font-serif | text-lg">
|
|
||||||
<router-link
|
|
||||||
:to="'/' + step.uri + '&fileIndex=' + index"
|
|
||||||
class="link-full"
|
|
||||||
>
|
|
||||||
{{
|
|
||||||
file.label.length
|
|
||||||
? file.label
|
|
||||||
: file.name.replace(".pdf", "")
|
|
||||||
}}
|
|
||||||
</router-link>
|
|
||||||
</h3>
|
|
||||||
</hgroup>
|
|
||||||
<div class="card__meta | flex">
|
|
||||||
<time
|
|
||||||
class="card__date | text-grey-700"
|
|
||||||
:datetime="dayjs(file.modified).format('YYYY-M-DD')"
|
|
||||||
>{{ dayjs(file.modified).format("DD MMMM YYYY") }}</time
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
<template v-if="step.id === 'clientBrief' || index === 0">
|
|
||||||
<figure
|
|
||||||
v-if="file.cover"
|
|
||||||
class="card__images pdf-cover"
|
|
||||||
style="aspect-ratio: unset"
|
|
||||||
>
|
|
||||||
<img :src="file.cover" alt="" />
|
|
||||||
</figure>
|
|
||||||
<div v-else class="card__images" data-icon="document"></div>
|
|
||||||
</template>
|
|
||||||
<footer
|
|
||||||
v-if="file.comments?.length > 0"
|
|
||||||
class="order-last | text-sm text-primary font-medium"
|
|
||||||
>
|
|
||||||
<template v-if="step.id === 'proposal'">
|
|
||||||
<router-link
|
|
||||||
:to="'/' + step.uri + '&fileIndex=' + index + '&comments'"
|
|
||||||
>
|
|
||||||
{{ file.comments.length }} commentaire{{
|
|
||||||
file.comments.length > 1 ? "s" : ""
|
|
||||||
}}
|
|
||||||
</router-link>
|
|
||||||
</template>
|
|
||||||
<template v-else>
|
|
||||||
<router-link :to="'/' + step.uri + '&comments=true'">
|
|
||||||
{{ file.comments.length }} commentaire{{
|
|
||||||
file.comments.length > 1 ? "s" : ""
|
|
||||||
}}
|
|
||||||
</router-link>
|
|
||||||
</template>
|
|
||||||
</footer>
|
|
||||||
</article>
|
|
||||||
</template>
|
|
||||||
</template>
|
|
||||||
<template v-if="step.id === 'clientBrief' && hasOneBriefType()">
|
|
||||||
<button
|
|
||||||
v-if="step.files.find((file) => file.type === 'document')"
|
|
||||||
class="btn | w-full"
|
|
||||||
@click="toImagesBrief()"
|
|
||||||
>
|
|
||||||
Ajouter un brief via la plateforme
|
|
||||||
</button>
|
|
||||||
<div class="btn | w-full" v-else>
|
|
||||||
<label for="upload-pdf">
|
|
||||||
Ajouter brief PDF
|
|
||||||
<input
|
|
||||||
id="upload-pdf"
|
|
||||||
type="file"
|
|
||||||
@change="addPdf($event, step.uri)"
|
|
||||||
accept="application/pdf"
|
|
||||||
ref="pdfInput"
|
|
||||||
hidden
|
|
||||||
/>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template v-if="step.id === 'physicalSample' && step.files[0]">
|
|
||||||
<div class="card | physical-sample">
|
|
||||||
<header
|
|
||||||
class="text-center rounded-lg py-32"
|
|
||||||
:style="'--cover: url(' + step.cover + ')'"
|
|
||||||
>
|
|
||||||
<h3 class="text-lg font-serif">
|
|
||||||
<router-link :to="'/' + step.uri" class="link-full">{{
|
|
||||||
step.title
|
|
||||||
}}</router-link>
|
|
||||||
</h3>
|
|
||||||
<time class="font-medium text-sm py-8" :datetime="step.date">{{
|
|
||||||
step.date
|
|
||||||
}}</time>
|
|
||||||
<p>{{ step.description }}</p>
|
|
||||||
</header>
|
|
||||||
<img
|
|
||||||
:src="step.files[0].url"
|
|
||||||
alt=""
|
|
||||||
loading="lazy"
|
|
||||||
class="rounded-lg mt-16"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<template v-else></template>
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -223,19 +20,22 @@ import { usePageStore } from "../../stores/page";
|
||||||
import { computed } from "vue";
|
import { computed } from "vue";
|
||||||
import { useProjectStore } from "../../stores/project";
|
import { useProjectStore } from "../../stores/project";
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter } from "vue-router";
|
||||||
import { useBriefStore } from "../../stores/brief";
|
import ClientBrief from "./cards/ClientBrief.vue";
|
||||||
|
|
||||||
const { step } = defineProps({
|
const { step } = defineProps({
|
||||||
step: Object,
|
step: Object,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const cardsMap = {
|
||||||
|
clientBrief: ClientBrief,
|
||||||
|
};
|
||||||
|
|
||||||
const emit = defineEmits(["update:file"]);
|
const emit = defineEmits(["update:file"]);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
dayjs.locale("fr");
|
dayjs.locale("fr");
|
||||||
|
|
||||||
const { page } = usePageStore();
|
const { page } = usePageStore();
|
||||||
const { addPdf } = useBriefStore();
|
|
||||||
const { setStatus } = useProjectStore();
|
const { setStatus } = useProjectStore();
|
||||||
|
|
||||||
const steps = page.steps.map((item) => {
|
const steps = page.steps.map((item) => {
|
||||||
|
|
@ -262,16 +62,6 @@ function getFrontView(track) {
|
||||||
const frontView = track.files.find((file) => file.name === frontViewName);
|
const frontView = track.files.find((file) => file.name === frontViewName);
|
||||||
return frontView;
|
return frontView;
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasOneBriefType() {
|
|
||||||
const hasImage = step.files.some((file) => file.type === "image");
|
|
||||||
const hasDocument = step.files.some((file) => file.type === "document");
|
|
||||||
return hasImage ^ hasDocument;
|
|
||||||
}
|
|
||||||
|
|
||||||
function toImagesBrief() {
|
|
||||||
router.push(location.pathname + "/client-brief?step=images");
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|
|
||||||
49
src/components/project/cards/ClientBrief.vue
Normal file
49
src/components/project/cards/ClientBrief.vue
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
<template>
|
||||||
|
<Images v-if="images.length > 0" :step="step" :images="images" />
|
||||||
|
<Document v-if="pdf" :step="step" :pdf="pdf" />
|
||||||
|
|
||||||
|
<button
|
||||||
|
v-if="images.length === 0"
|
||||||
|
class="btn | w-full"
|
||||||
|
@click="goToImagesBrief()"
|
||||||
|
>
|
||||||
|
Ajouter un brief via la plateforme
|
||||||
|
</button>
|
||||||
|
<div class="btn | w-full" v-if="!pdf">
|
||||||
|
<label for="upload-pdf">
|
||||||
|
Ajouter brief PDF
|
||||||
|
<input
|
||||||
|
id="upload-pdf"
|
||||||
|
type="file"
|
||||||
|
@change="addPdf($event, step.uri)"
|
||||||
|
accept="application/pdf"
|
||||||
|
ref="pdfInput"
|
||||||
|
hidden
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { computed } from "vue";
|
||||||
|
import Images from "./Images.vue";
|
||||||
|
import Document from "./Document.vue";
|
||||||
|
import { useBriefStore } from "../../../stores/brief";
|
||||||
|
import { useRouter } from "vue-router";
|
||||||
|
|
||||||
|
const { step } = defineProps({ step: Object });
|
||||||
|
const { addPdf } = useBriefStore();
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
const images = computed(() => {
|
||||||
|
return step.files.filter((file) => file.type === "image");
|
||||||
|
});
|
||||||
|
|
||||||
|
const pdf = computed(() => {
|
||||||
|
return step.files.find((file) => file.type === "document");
|
||||||
|
});
|
||||||
|
|
||||||
|
function goToImagesBrief() {
|
||||||
|
router.push(location.pathname + "/client-brief?step=images");
|
||||||
|
}
|
||||||
|
</script>
|
||||||
16
src/components/project/cards/DateTime.vue
Normal file
16
src/components/project/cards/DateTime.vue
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
<template>
|
||||||
|
<div class="card__meta | flex">
|
||||||
|
<time
|
||||||
|
class="card__date | text-grey-700"
|
||||||
|
:datetime="dayjs(date).format('YYYY-M-DD')"
|
||||||
|
>{{ dayjs(date).format("DD MMMM YYYY") }}</time
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
import "dayjs/locale/fr";
|
||||||
|
|
||||||
|
const { date } = defineProps({ date: String });
|
||||||
|
</script>
|
||||||
48
src/components/project/cards/Document.vue
Normal file
48
src/components/project/cards/Document.vue
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
<template>
|
||||||
|
<article class="card">
|
||||||
|
<hgroup class="order-last">
|
||||||
|
<h3 class="card__title | font-serif | text-lg">
|
||||||
|
<router-link
|
||||||
|
:to="'/' + step.uri + '&fileIndex=' + index"
|
||||||
|
class="link-full"
|
||||||
|
>
|
||||||
|
{{ pdf.label.length ? pdf.label : pdf.name.replace(".pdf", "") }}
|
||||||
|
</router-link>
|
||||||
|
</h3>
|
||||||
|
</hgroup>
|
||||||
|
|
||||||
|
<DateTime :date="pdf.modified" />
|
||||||
|
|
||||||
|
<figure
|
||||||
|
v-if="pdf.cover"
|
||||||
|
class="card__images pdf-cover"
|
||||||
|
style="aspect-ratio: unset"
|
||||||
|
>
|
||||||
|
<img :src="pdf.cover" alt="" />
|
||||||
|
</figure>
|
||||||
|
<div v-else class="card__images" data-icon="document"></div>
|
||||||
|
|
||||||
|
<footer
|
||||||
|
v-if="pdf.comments?.length > 0"
|
||||||
|
class="order-last | text-sm text-primary font-medium"
|
||||||
|
>
|
||||||
|
<router-link :to="'/' + step.uri + '?comments=true'">
|
||||||
|
{{ pdf.comments.length }} commentaire{{
|
||||||
|
pdf.comments.length > 1 ? "s" : ""
|
||||||
|
}}
|
||||||
|
</router-link>
|
||||||
|
</footer>
|
||||||
|
</article>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import DateTime from "./DateTime.vue";
|
||||||
|
|
||||||
|
const { step, pdf, index } = defineProps({
|
||||||
|
step: Object,
|
||||||
|
pdf: Object,
|
||||||
|
index: {
|
||||||
|
default: 0,
|
||||||
|
type: Number,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
36
src/components/project/cards/Images.vue
Normal file
36
src/components/project/cards/Images.vue
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
<template>
|
||||||
|
<article class="card">
|
||||||
|
<hgroup class="order-last">
|
||||||
|
<h3 class="card__title | font-serif | text-lg">
|
||||||
|
<router-link :to="'/' + step.uri" class="link-full">{{
|
||||||
|
step.label
|
||||||
|
}}</router-link>
|
||||||
|
</h3>
|
||||||
|
</hgroup>
|
||||||
|
<DateTime :date="step.modified" />
|
||||||
|
<figure
|
||||||
|
class="card__images"
|
||||||
|
:data-count="images.length"
|
||||||
|
:data-plus="images.length > 3 ? images.length - 3 : undefined"
|
||||||
|
>
|
||||||
|
<template v-for="image in images.slice(0, 3)" :key="image.uuid">
|
||||||
|
<img :src="image.url" :alt="image.alt" />
|
||||||
|
</template>
|
||||||
|
</figure>
|
||||||
|
<!-- <footer
|
||||||
|
v-if="images[0]?.comments?.length > 0"
|
||||||
|
class="order-last | text-sm text-primary font-medium"
|
||||||
|
>
|
||||||
|
{{ images[0].comments.length }} commentaire{{
|
||||||
|
images[0].comments.length > 1 ? "s" : ""
|
||||||
|
}}
|
||||||
|
</footer> -->
|
||||||
|
</article>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import DateTime from "./DateTime.vue";
|
||||||
|
import { usePageStore } from "../../../stores/page";
|
||||||
|
|
||||||
|
const { images, step } = defineProps({ images: Array, step: Object });
|
||||||
|
const { page } = usePageStore();
|
||||||
|
</script>
|
||||||
|
|
@ -21,15 +21,6 @@ export const useBriefStore = defineStore("brief", () => {
|
||||||
|
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
page.value = result;
|
page.value = result;
|
||||||
if (redirectToParent) {
|
|
||||||
location.href =
|
|
||||||
location.origin +
|
|
||||||
"/" +
|
|
||||||
page.value.parent +
|
|
||||||
"?dialog=client-brief";
|
|
||||||
} else {
|
|
||||||
location.href = location.href + "?dialog=client-brief";
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
console.error("Error uploading file:", result.error);
|
console.error("Error uploading file:", result.error);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ export const useDialogStore = defineStore("dialog", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
function updateFile(newFile) {
|
function updateFile(newFile) {
|
||||||
console.log(newFile);
|
|
||||||
openedFile.value = newFile;
|
openedFile.value = newFile;
|
||||||
|
|
||||||
// if (!content.value.files) return;
|
// if (!content.value.files) return;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue