ptitlutins/app/components/organisms/ChildrenView.vue
2026-06-15 23:34:49 +02:00

147 lines
3.4 KiB
Vue

<script setup lang="ts">
import type { Node } from "~/types"
const props = withDefaults(
defineProps<{
node: Node
showTrips?: boolean
}>(),
{
showTrips: true,
},
)
defineEmits<{
create: [name: string]
routeTime: [node: Node]
routePlace: [node: Node]
}>()
const children = computed(() => childrenOf(props.node))
const undated = computed(() => undatedChildren(children.value))
const groups = computed(() => groupChildren(children.value))
const datedCount = computed(() =>
groups.value.reduce((a, g) => a + g.events.length, 0),
)
</script>
<template>
<section class="children-view">
<CreateRow
:placeholder="
node.root
? $t('voyage.addRow.placeholder')
: $t('voyage.addRow.placeholderSub')
"
@create="$emit('create', $event)"
/>
<EmptyState
v-if="children.length === 0"
icon="carbon:tree-view-alt"
:message="$t('voyage.emptyChildren')"
/>
<div v-if="undated.length" class="undated">
<SectionLabel icon="carbon:calendar-heat-map" :count="undated.length">
{{ $t("voyage.sansDate.label") }}
</SectionLabel>
<EtapeCard
v-for="ev in undated"
:key="ev.id"
:node="ev"
@route-time="$emit('routeTime', $event)"
@route-place="$emit('routePlace', $event)"
/>
</div>
<div v-if="groups.length" class="programme">
<SectionLabel icon="carbon:roadmap" :count="datedCount">
{{ $t("voyage.frise.programme") }}
</SectionLabel>
<div
v-for="(group, gi) in groups"
:key="group.label || gi"
class="day-group"
>
<DayDivider v-if="group.label" :label="group.label" />
<template v-for="(ev, i) in group.events" :key="ev.id">
<EtapeCard
:node="ev"
@route-time="$emit('routeTime', $event)"
@route-place="$emit('routePlace', $event)"
/>
<template v-if="i < group.events.length - 1">
<div v-if="showTrips" class="trip-connector">
<span
class="trip-connector__line"
:style="{
borderTopColor: ev.trip ? 'var(--color-6)' : 'var(--neutral-30)',
}"
/>
<TripChip v-if="ev.trip" :trip="ev.trip" />
<span v-else class="trip-connector__none">
{{ $t("voyage.frise.noTrip") }}
</span>
<span
class="trip-connector__line"
:style="{
borderTopColor: ev.trip ? 'var(--color-6)' : 'var(--neutral-30)',
}"
/>
</div>
<div v-else class="trip-spacer" />
</template>
</template>
</div>
</div>
</section>
</template>
<style scoped>
.children-view {
display: flex;
flex-direction: column;
gap: 14px;
}
.undated {
display: flex;
flex-direction: column;
gap: 7px;
}
.programme {
display: flex;
flex-direction: column;
gap: var(--space-2);
}
.day-group {
display: flex;
flex-direction: column;
gap: var(--space-2);
}
.trip-connector {
display: flex;
justify-content: center;
align-items: center;
gap: var(--space-2);
}
.trip-connector__line {
width: 18px;
border-top: 2px dashed var(--neutral-30);
}
.trip-connector__none {
font-family: var(--font-body);
font-size: 0.7rem;
color: var(--text-faint);
}
.trip-spacer {
height: 2px;
}
</style>