Files
pokopiawiki.tootaio.com/frontend/src/views/HabitatList.vue
xiaomai 6812ddc428 feat(ui): use modal dialogs for entity creation and editing
Introduce reusable Modal component for forms
Update router to preserve scroll position when toggling modals
Refactor admin and entity views to render editors as overlays
2026-05-01 13:44:34 +08:00

61 lines
2.3 KiB
Vue

<script setup lang="ts">
import { computed, onMounted, ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRoute } from 'vue-router';
import EditMeta from '../components/EditMeta.vue';
import EntityChips from '../components/EntityChips.vue';
import EntityCard from '../components/EntityCard.vue';
import PageHeader from '../components/PageHeader.vue';
import Skeleton from '../components/Skeleton.vue';
import { api, type Habitat } from '../services/api';
import HabitatEdit from './HabitatEdit.vue';
const habitats = ref<Habitat[]>([]);
const route = useRoute();
const { t } = useI18n();
const loading = ref(true);
const skeletonCardCount = 6;
const showEditor = computed(() => route.name === 'habitat-new');
onMounted(async () => {
habitats.value = await api.habitats();
loading.value = false;
});
</script>
<template>
<section class="page-stack">
<PageHeader :title="t('pages.habitats.title')" :subtitle="t('pages.habitats.subtitle')">
<template #kicker>Habitats</template>
<template #actions>
<RouterLink class="ui-button ui-button--primary ui-button--small" to="/habitats/new">{{ t('common.add') }}</RouterLink>
</template>
</PageHeader>
<div v-if="loading" class="entity-grid" aria-busy="true" :aria-label="t('pages.habitats.loadingList')">
<article v-for="index in skeletonCardCount" :key="index" class="entity-card entity-card--skeleton">
<Skeleton variant="box" width="42px" height="42px" class="skeleton-entity-mark" />
<div class="entity-card__content">
<Skeleton width="68%" height="24px" />
<Skeleton width="66%" />
<div class="skeleton-chip-row">
<Skeleton v-for="chipIndex in 3" :key="`recipe-${chipIndex}`" width="70px" class="skeleton-chip" />
</div>
<div class="skeleton-chip-row">
<Skeleton v-for="chipIndex in 2" :key="`pokemon-${chipIndex}`" width="82px" class="skeleton-chip" />
</div>
</div>
</article>
</div>
<div v-else class="entity-grid">
<EntityCard v-for="item in habitats" :key="item.id" :title="item.name" :to="`/habitats/${item.id}`" marker="◎">
<EditMeta :entity="item" />
<EntityChips :items="item.recipe" />
<EntityChips :items="item.pokemon ?? []" />
</EntityCard>
</div>
<HabitatEdit v-if="showEditor" />
</section>
</template>