add element child list

This commit is contained in:
Yisroel Baum 2026-05-26 20:16:22 +03:00
parent aa746fe3f0
commit 7350d747f3
Signed by: yisroelbaum
GPG key ID: 0FA60884F75520A9
9 changed files with 186 additions and 10 deletions

View file

@ -8,17 +8,20 @@ export interface Element {
interface ElementResponse {
element: Element
childElements: Element[]
}
const API_BASE_URL = import.meta.env.VITE_API_BASE_URL as string
export const useElementsStore = defineStore('elements', () => {
const element = ref<Element | null>(null)
const childElements = ref<Element[]>([])
const isLoading = ref(false)
const error = ref<string | null>(null)
async function fetchElement(elementId: string): Promise<void> {
element.value = null
childElements.value = []
error.value = null
isLoading.value = true
@ -39,12 +42,14 @@ export const useElementsStore = defineStore('elements', () => {
const data: ElementResponse = await response.json()
element.value = data.element
childElements.value = data.childElements
} catch {
childElements.value = []
error.value = 'Network error - could not load element'
} finally {
isLoading.value = false
}
}
return { element, isLoading, error, fetchElement }
return { element, childElements, isLoading, error, fetchElement }
})

View file

@ -7,7 +7,7 @@ import { useElementsStore } from '@/stores/elements'
const route = useRoute()
const elementsStore = useElementsStore()
const { element, isLoading, error } = storeToRefs(elementsStore)
const { element, childElements, isLoading, error } = storeToRefs(elementsStore)
const elementId = computed(() => {
const routeElementId = route.params.id
@ -44,9 +44,33 @@ watch(
>
{{ error }}
</p>
<h1 v-else-if="element" class="element-page__heading">
{{ element.title }}
</h1>
<section v-else-if="element" class="element-page__content">
<h1 class="element-page__heading">
{{ element.title }}
</h1>
<nav
v-if="childElements.length > 0"
class="element-page__children"
aria-label="Child elements"
>
<ul class="element-page__child-list" data-cy="child-element-list">
<li
v-for="childElement in childElements"
:key="childElement.id"
class="element-page__child-item"
>
<RouterLink
:to="{ name: 'element', params: { id: childElement.id } }"
class="element-page__child-link"
data-cy="child-element-link"
>
{{ childElement.title }}
</RouterLink>
</li>
</ul>
</nav>
</section>
</main>
</div>
</template>
@ -62,6 +86,11 @@ watch(
padding: 5.1rem 4.15rem 5rem;
}
.element-page__content {
max-width: 48rem;
margin: 0 auto;
}
.element-page__heading {
margin: 0;
color: #2c2c2c;
@ -72,6 +101,48 @@ watch(
text-align: center;
}
.element-page__children {
margin-top: 3rem;
}
.element-page__child-list {
display: grid;
margin: 0;
padding: 0;
gap: 0.85rem;
list-style: none;
}
.element-page__child-link {
display: block;
padding: 1rem 1.2rem;
background: var(--color-white);
border: 1px solid #e5cf9f;
border-radius: 8px;
color: #333333;
font-family: var(--font-serif);
font-size: 1.25rem;
line-height: 1.25;
text-align: center;
text-decoration: none;
transition:
border-color 180ms ease,
box-shadow 180ms ease,
transform 180ms ease;
}
.element-page__child-link:hover,
.element-page__child-link:focus-visible {
border-color: #d4ad5f;
box-shadow: 0 10px 28px rgb(44 44 44 / 9%);
transform: translateY(-1px);
}
.element-page__child-link:focus-visible {
outline: 3px solid rgb(212 173 95 / 45%);
outline-offset: 4px;
}
.element-page__status {
max-width: 48rem;
margin: 0 auto;
@ -92,5 +163,9 @@ watch(
.element-page__main {
padding: 3rem 1rem;
}
.element-page__children {
margin-top: 2rem;
}
}
</style>