designtopack/src/components/project/ProjectStep.vue
2025-02-19 09:38:15 +01:00

97 lines
2.4 KiB
Vue

<template>
<section
class="flex-1"
:aria-labelledby="step.id"
:data-status="setStatus(page.steps, page.content.currentstep, step)"
>
<h2 :id="step.id">
<span :data-icon="step.id">{{ step.label }}</span>
</h2>
<div
ref="cards-node"
class="cards | flow"
:class="{ new: hasUnreadNotifications }"
>
<component :is="cardsMap[step.id]" :step="step" />
</div>
</section>
</template>
<script setup>
import dayjs from 'dayjs';
import 'dayjs/locale/fr';
import { usePageStore } from '../../stores/page';
import { computed, onMounted, useTemplateRef } from 'vue';
import { useProjectStore } from '../../stores/project';
import ClientBrief from './cards/ClientBrief.vue';
import MultipleDocuments from './cards/MultipleDocuments.vue';
import SimpleDocument from './cards/SimpleDocument.vue';
import VirtualSample from './cards/VirtualSample.vue';
import PhysicalSample from './cards/PhysicalSample.vue';
import { useUserStore } from '../../stores/user';
const { step } = defineProps({
step: Object,
});
const cardsMap = {
clientBrief: ClientBrief,
proposal: MultipleDocuments,
extendedBrief: SimpleDocument,
industrialIdeation: SimpleDocument,
virtualSample: VirtualSample,
physicalSample: PhysicalSample,
};
dayjs.locale('fr');
const { page } = usePageStore();
const { setStatus } = useProjectStore();
const cardsNode = useTemplateRef('cards-node');
const { user } = useUserStore();
// Hooks
onMounted(() => {
if (step.id === page.content.currentstep) {
cardsNode.value.scrollIntoView({
behavior: 'smooth',
inline: 'center',
});
}
});
const correspondingNotifications = computed(() => {
return page.notifications.filter((notification) =>
notification.location.page.uri.includes(step.slug)
);
});
const hasUnreadNotifications = computed(() => {
return correspondingNotifications.value.some(
(notification) =>
!notification.readby.includes(user.uuid) &&
notification.author.uuid !== user.uuid
);
});
</script>
<style scoped>
.physical-sample header {
color: var(--color-white);
background: linear-gradient(
90deg,
hsla(0, 0%, 10%, 0.5) 0%,
hsla(0, 0%, 10%, 0.9) 50%,
hsla(0, 0%, 10%, 0.9) 100%
),
var(--cover), var(--color-black);
background-repeat: no-repeat;
background-size: cover;
}
.physical-sample header > * {
padding-inline: var(--space-16);
}
.physical-sample header h3 {
position: initial;
}
</style>