60 lines
2.5 KiB
Vue
60 lines
2.5 KiB
Vue
<script setup lang="ts">
|
|
import OverseasDetailShell from './OverseasDetailShell.vue'
|
|
|
|
interface DetailGroup {
|
|
title: string
|
|
fields: string[]
|
|
}
|
|
|
|
defineProps<{
|
|
title: string
|
|
referenceLabel: string
|
|
referenceValue: string
|
|
backLabel: string
|
|
domain: string
|
|
groups: DetailGroup[]
|
|
fieldValues?: Record<string, string | number>
|
|
pending?: boolean
|
|
statusText?: string
|
|
loading?: boolean
|
|
showContent?: boolean
|
|
}>()
|
|
|
|
defineEmits<{ back: [] }>()
|
|
</script>
|
|
|
|
<template>
|
|
<OverseasDetailShell
|
|
:title="title"
|
|
:reference-label="referenceLabel"
|
|
:reference-value="referenceValue"
|
|
:back-label="backLabel"
|
|
:domain="domain"
|
|
:pending="pending"
|
|
:status-text="statusText"
|
|
@back="$emit('back')"
|
|
>
|
|
<slot name="state" />
|
|
<section v-if="showContent !== false" v-loading="loading" class="read-only-detail" :aria-label="title" :aria-busy="loading">
|
|
<section v-for="group in groups" :key="group.title" class="detail-group" :aria-label="group.title">
|
|
<h2>{{ group.title }}</h2>
|
|
<dl class="detail-fields"><div v-for="field in group.fields" :key="field"><dt>{{ field }}</dt><dd>{{ fieldValues?.[field] ?? '—' }}</dd></div></dl>
|
|
</section>
|
|
<slot name="content-after" />
|
|
</section>
|
|
</OverseasDetailShell>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.read-only-detail { display: grid; min-width: 0; grid-template-columns: repeat(2, minmax(0, 1fr)); border: 1px solid var(--cc-border); background: #fff; }
|
|
.detail-group { min-width: 0; padding: 16px 18px 18px; border-right: 1px solid var(--cc-border); border-bottom: 1px solid var(--cc-border); }
|
|
.detail-group:nth-child(even) { border-right: 0; }
|
|
.detail-group h2 { margin: 0 0 12px; color: var(--cc-text); font-size: 15px; }
|
|
.detail-fields { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); margin: 0; border-top: 1px solid var(--cc-border); border-left: 1px solid var(--cc-border); }
|
|
.detail-fields > div { display: grid; min-width: 0; min-height: 46px; grid-template-columns: 126px minmax(0, 1fr); border-right: 1px solid var(--cc-border); border-bottom: 1px solid var(--cc-border); }
|
|
.detail-fields dt, .detail-fields dd { display: flex; min-width: 0; align-items: center; padding: 8px 10px; }
|
|
.detail-fields dt { background: #f8fafc; color: var(--cc-muted); font-size: 12px; }
|
|
.detail-fields dd { margin: 0; color: var(--cc-text); overflow-wrap: anywhere; }
|
|
@media (max-width: 1100px) { .read-only-detail, .detail-fields { grid-template-columns: 1fr; } .detail-group { border-right: 0; } }
|
|
</style>
|