766 lines
21 KiB
Vue
766 lines
21 KiB
Vue
<template>
|
||
<div class="th-page order-detail-view">
|
||
<div
|
||
v-if="loading"
|
||
class="th-section order-state"
|
||
>
|
||
{{ t('common.loading') }}
|
||
</div>
|
||
<div
|
||
v-else-if="errorMessage"
|
||
class="th-section order-state order-state--error"
|
||
>
|
||
{{ errorMessage }}
|
||
</div>
|
||
|
||
<template v-else-if="detail">
|
||
<section class="th-section order-summary">
|
||
<header>
|
||
<div>
|
||
<p>{{ t('order.summary') }}</p>
|
||
<h1>{{ detail.order.display_name }}</h1>
|
||
</div>
|
||
<ReservationStatusBadge :status="detail.order.order_status" />
|
||
</header>
|
||
|
||
<dl>
|
||
<div>
|
||
<dt>{{ t('order.groupCode') }}</dt>
|
||
<dd>{{ detail.order.group_code ?? '-' }}</dd>
|
||
</div>
|
||
<div>
|
||
<dt>{{ t('order.confirmationNumber') }}</dt>
|
||
<dd>{{ detail.order.confirmation_number ?? '-' }}</dd>
|
||
</div>
|
||
<div>
|
||
<dt>{{ t('order.temporaryOrderNo') }}</dt>
|
||
<dd>{{ detail.order.temporary_order_no ?? '-' }}</dd>
|
||
</div>
|
||
<div>
|
||
<dt>{{ t('order.blockCode') }}</dt>
|
||
<dd>{{ detail.order.block_code ?? '-' }}</dd>
|
||
</div>
|
||
<div>
|
||
<dt>{{ t('order.createdAt') }}</dt>
|
||
<dd>{{ formatReservationDateTime(detail.order.created_at) }}</dd>
|
||
</div>
|
||
<div>
|
||
<dt>{{ t('order.updatedAt') }}</dt>
|
||
<dd>{{ formatReservationDateTime(detail.order.updated_at) }}</dd>
|
||
</div>
|
||
</dl>
|
||
</section>
|
||
|
||
<div class="overview-layout">
|
||
<section class="th-section overview-section">
|
||
<div class="th-section-header">
|
||
<div>
|
||
<h2 class="th-section-title">
|
||
{{ t('order.v4OverviewTitle') }}
|
||
</h2>
|
||
<p class="th-muted">
|
||
{{ t('order.v4OverviewSubtitle') }}
|
||
</p>
|
||
</div>
|
||
</div>
|
||
|
||
<template v-if="hasOrderOverview">
|
||
<dl class="overview-facts">
|
||
<div
|
||
v-for="fact in overviewFacts"
|
||
:key="fact.label"
|
||
>
|
||
<dt>{{ fact.label }}</dt>
|
||
<dd>{{ fact.value }}</dd>
|
||
</div>
|
||
</dl>
|
||
|
||
<div class="room-summary">
|
||
<span>{{ t('order.roomItems') }}</span>
|
||
<div
|
||
v-if="overviewRoomItems.length"
|
||
class="room-summary__items"
|
||
>
|
||
<strong
|
||
v-for="room in overviewRoomItems"
|
||
:key="`${room.room_type_code ?? '-'}-${room.room_count ?? '-'}`"
|
||
>
|
||
{{ formatRoomSummary(room) }}
|
||
</strong>
|
||
</div>
|
||
<strong v-else>-</strong>
|
||
</div>
|
||
|
||
<div class="overview-statuses">
|
||
<div
|
||
v-for="statusItem in overviewStatuses"
|
||
:key="statusItem.label"
|
||
>
|
||
<span>{{ statusItem.label }}</span>
|
||
<ReservationStatusBadge
|
||
v-if="statusItem.status"
|
||
:status="statusItem.status"
|
||
/>
|
||
<strong v-else>-</strong>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
<p
|
||
v-else
|
||
class="empty-copy"
|
||
>
|
||
{{ t('order.v4OverviewEmpty') }}
|
||
</p>
|
||
</section>
|
||
|
||
<section class="th-section next-action-section">
|
||
<div class="th-section-header">
|
||
<div>
|
||
<h2 class="th-section-title">
|
||
{{ t('order.nextV4ActionTitle') }}
|
||
</h2>
|
||
<p class="th-muted">
|
||
{{ t('order.nextV4ActionSubtitle') }}
|
||
</p>
|
||
</div>
|
||
</div>
|
||
|
||
<template v-if="hasNextV4Action && nextV4Action">
|
||
<dl class="next-action-facts">
|
||
<div>
|
||
<dt>{{ t('order.nextV4ActionType') }}</dt>
|
||
<dd>{{ formatNextActionType(nextV4Action.action_type) }}</dd>
|
||
</div>
|
||
<div>
|
||
<dt>{{ t('order.nextV4ActionStatus') }}</dt>
|
||
<dd>
|
||
<ReservationStatusBadge
|
||
v-if="nextV4Action.action_status"
|
||
:status="nextV4Action.action_status"
|
||
/>
|
||
<span v-else>-</span>
|
||
</dd>
|
||
</div>
|
||
<div>
|
||
<dt>{{ t('order.openOrderTaskCount') }}</dt>
|
||
<dd>{{ nextV4Action.open_order_task_count ?? 0 }}</dd>
|
||
</div>
|
||
<div>
|
||
<dt>{{ t('order.nextV4CardId') }}</dt>
|
||
<dd>{{ nextV4Action.card_id ?? '-' }}</dd>
|
||
</div>
|
||
</dl>
|
||
<RouterLink
|
||
class="primary-link"
|
||
:to="`/reservation/order-tasks/${nextV4Action.order_task_id}`"
|
||
>
|
||
{{ t('order.enterV4Task') }}
|
||
</RouterLink>
|
||
</template>
|
||
<p
|
||
v-else
|
||
class="empty-copy"
|
||
>
|
||
{{ t('order.nextV4ActionEmpty') }}
|
||
</p>
|
||
</section>
|
||
</div>
|
||
|
||
<section class="th-section source-section">
|
||
<div class="th-section-header">
|
||
<div>
|
||
<h2 class="th-section-title">
|
||
{{ t('order.relatedSourceMessages') }}
|
||
</h2>
|
||
<p class="th-muted">
|
||
{{ t('order.relatedSourceMessagesHint') }}
|
||
</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div
|
||
v-if="relatedSourceMessages.length"
|
||
class="source-list"
|
||
>
|
||
<article
|
||
v-for="sourceMessage in relatedSourceMessages"
|
||
:key="sourceMessage.source_message_id"
|
||
class="source-item"
|
||
>
|
||
<div>
|
||
<strong>{{ sourceMessage.subject ?? t('taskList.noSourceSubject') }}</strong>
|
||
<span>{{ sourceMessage.sender_summary ?? '-' }}</span>
|
||
</div>
|
||
<dl>
|
||
<div>
|
||
<dt>{{ t('task.sourceReceivedAt') }}</dt>
|
||
<dd>{{ formatReservationDateTime(sourceMessage.received_at) }}</dd>
|
||
</div>
|
||
<div>
|
||
<dt>{{ t('order.conversationMessageCount') }}</dt>
|
||
<dd>{{ sourceMessage.conversation_message_count ?? '-' }}</dd>
|
||
</div>
|
||
<div>
|
||
<dt>{{ t('order.externalConversationId') }}</dt>
|
||
<dd>{{ sourceMessage.external_conversation_id ?? '-' }}</dd>
|
||
</div>
|
||
</dl>
|
||
<RouterLink
|
||
class="source-link"
|
||
:to="`/reservation/source-messages/${sourceMessage.source_message_id}/conversation`"
|
||
>
|
||
{{ t('task.viewConversation') }}
|
||
</RouterLink>
|
||
</article>
|
||
</div>
|
||
<p
|
||
v-else
|
||
class="empty-copy"
|
||
>
|
||
{{ t('order.relatedSourceMessagesEmpty') }}
|
||
</p>
|
||
</section>
|
||
|
||
<section class="th-section v4-timeline-section">
|
||
<div class="th-section-header">
|
||
<div>
|
||
<h2 class="th-section-title">
|
||
{{ t('order.v4TaskTimeline') }}
|
||
</h2>
|
||
<p class="th-muted">
|
||
{{ t('order.v4TaskTimelineHint') }}
|
||
</p>
|
||
</div>
|
||
</div>
|
||
|
||
<p
|
||
v-if="!v4OrderTasks.length"
|
||
class="empty-copy"
|
||
>
|
||
{{ t('order.v4TaskTimelineEmpty') }}
|
||
</p>
|
||
<div
|
||
v-else
|
||
class="v4-timeline-list"
|
||
>
|
||
<article
|
||
v-for="item in v4OrderTasks"
|
||
:key="item.order_task_id"
|
||
class="v4-timeline-item"
|
||
>
|
||
<RouterLink
|
||
class="v4-timeline-item__main"
|
||
:to="`/reservation/order-tasks/${item.order_task_id}`"
|
||
>
|
||
<span>
|
||
<strong>{{ v4OrderReference(item) }}</strong>
|
||
<small>{{ item.source_message_summary?.subject ?? t('taskList.noSourceSubject') }}</small>
|
||
</span>
|
||
<ReservationStatusBadge :status="item.order_task_status" />
|
||
</RouterLink>
|
||
|
||
<dl class="timeline-meta">
|
||
<div>
|
||
<dt>{{ t('taskList.cardCountsTotal', { total: item.card_counts.total_count }) }}</dt>
|
||
<dd>
|
||
{{ t('taskList.cardCountsPending', { count: item.card_counts.pending_confirm_count }) }}
|
||
·
|
||
{{ t('taskList.cardCountsReview', { count: item.card_counts.review_required_count }) }}
|
||
·
|
||
{{ t('taskList.cardCountsConfirmed', { count: item.card_counts.confirmed_count }) }}
|
||
</dd>
|
||
</div>
|
||
<div>
|
||
<dt>{{ t('task.sourceReceivedAt') }}</dt>
|
||
<dd>{{ formatReservationDateTime(item.source_received_at) }}</dd>
|
||
</div>
|
||
<div>
|
||
<dt>{{ t('order.latestActivityAt') }}</dt>
|
||
<dd>{{ formatReservationDateTime(item.latest_activity_at ?? item.updated_at ?? item.created_at) }}</dd>
|
||
</div>
|
||
</dl>
|
||
|
||
<div
|
||
v-if="item.cards.length"
|
||
class="card-summary-list"
|
||
>
|
||
<article
|
||
v-for="card in item.cards"
|
||
:key="card.card_id"
|
||
class="card-summary"
|
||
>
|
||
<div class="card-summary__heading">
|
||
<span>
|
||
<strong>{{ cardTimelineTitle(card) }}</strong>
|
||
<small>{{ card.event_type ?? '-' }}</small>
|
||
</span>
|
||
<ReservationStatusBadge :status="card.card_status" />
|
||
</div>
|
||
<dl>
|
||
<div>
|
||
<dt>{{ t('order.cardId') }}</dt>
|
||
<dd>{{ card.card_id }}</dd>
|
||
</div>
|
||
<div>
|
||
<dt>{{ t('order.reviewStatus') }}</dt>
|
||
<dd>
|
||
<ReservationStatusBadge
|
||
v-if="card.review_status"
|
||
:status="card.review_status"
|
||
/>
|
||
<span v-else>-</span>
|
||
</dd>
|
||
</div>
|
||
<div>
|
||
<dt>{{ t('order.confirmedBy') }}</dt>
|
||
<dd>{{ card.confirmed_by ?? '-' }}</dd>
|
||
</div>
|
||
<div>
|
||
<dt>{{ t('order.confirmedAt') }}</dt>
|
||
<dd>{{ formatReservationDateTime(card.confirmed_at) }}</dd>
|
||
</div>
|
||
<div>
|
||
<dt>{{ t('order.latestActivityAt') }}</dt>
|
||
<dd>{{ formatReservationDateTime(card.latest_activity_at) }}</dd>
|
||
</div>
|
||
</dl>
|
||
</article>
|
||
</div>
|
||
<p
|
||
v-else
|
||
class="empty-copy empty-copy--compact"
|
||
>
|
||
{{ t('order.v4CardsEmpty') }}
|
||
</p>
|
||
</article>
|
||
</div>
|
||
</section>
|
||
</template>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { computed, ref, watch } from 'vue'
|
||
import { RouterLink, useRoute } from 'vue-router'
|
||
import { useI18n } from 'vue-i18n'
|
||
|
||
import ReservationStatusBadge from '@/components/reservation/ReservationStatusBadge.vue'
|
||
import { fetchReservationOrderDetail } from '@/services/reservationService'
|
||
import { useAuthStore } from '@/stores/authStore'
|
||
import type {
|
||
ReservationOrderDetailResult,
|
||
ReservationOrderV4NextActionResult,
|
||
ReservationOrderV4RoomSummary,
|
||
ReservationOrderV4TaskCardTimelineItem,
|
||
ReservationV4OrderTaskTimelineItem,
|
||
} from '@/types/reservation'
|
||
import { formatReservationTaskCard } from '@/utils/reservationDisplay'
|
||
import { formatReservationDateTime } from '@/utils/reservationFormat'
|
||
|
||
const route = useRoute()
|
||
const { t } = useI18n()
|
||
const authStore = useAuthStore()
|
||
const loading = ref(false)
|
||
const errorMessage = ref('')
|
||
const detail = ref<ReservationOrderDetailResult | null>(null)
|
||
|
||
const orderId = computed(() => String(route.params.orderId ?? ''))
|
||
const orderOverview = computed(() => detail.value?.order_overview ?? null)
|
||
const nextV4Action = computed(() => detail.value?.next_v4_action ?? null)
|
||
const relatedSourceMessages = computed(() => detail.value?.related_source_messages ?? [])
|
||
const v4OrderTasks = computed(() => detail.value?.v4_order_tasks ?? [])
|
||
const overviewRoomItems = computed(() => orderOverview.value?.room_items ?? [])
|
||
const hasNextV4Action = computed(() => {
|
||
const action = nextV4Action.value
|
||
return Boolean(action?.order_task_id && action.action_type && action.action_type !== 'NONE')
|
||
})
|
||
const hasOrderOverview = computed(() => {
|
||
const overview = orderOverview.value
|
||
if (!overview) {
|
||
return false
|
||
}
|
||
return Boolean(
|
||
overview.account_code ||
|
||
overview.account_name ||
|
||
overview.market_code ||
|
||
overview.source_code ||
|
||
overview.arrival_date ||
|
||
overview.departure_date ||
|
||
overview.rate_code ||
|
||
overview.room_items.length ||
|
||
overview.trace_card_status ||
|
||
overview.rooming_list_card_status ||
|
||
overview.payment_card_status ||
|
||
overview.latest_confirmed_at,
|
||
)
|
||
})
|
||
const overviewFacts = computed(() => {
|
||
const overview = orderOverview.value
|
||
if (!overview) {
|
||
return []
|
||
}
|
||
return [
|
||
{ label: t('order.accountCode'), value: displayValue(overview.account_code) },
|
||
{ label: t('order.accountName'), value: displayValue(overview.account_name) },
|
||
{ label: t('order.marketCode'), value: displayValue(overview.market_code) },
|
||
{ label: t('order.sourceCode'), value: displayValue(overview.source_code) },
|
||
{ label: t('order.arrivalDate'), value: displayValue(overview.arrival_date) },
|
||
{ label: t('order.departureDate'), value: displayValue(overview.departure_date) },
|
||
{ label: t('order.rateCode'), value: displayValue(overview.rate_code) },
|
||
{ label: t('order.latestConfirmedAt'), value: formatReservationDateTime(overview.latest_confirmed_at) },
|
||
]
|
||
})
|
||
const overviewStatuses = computed(() => {
|
||
const overview = orderOverview.value
|
||
return [
|
||
{ label: t('order.traceCardStatus'), status: overview?.trace_card_status ?? null },
|
||
{ label: t('order.roomingListCardStatus'), status: overview?.rooming_list_card_status ?? null },
|
||
{ label: t('order.paymentCardStatus'), status: overview?.payment_card_status ?? null },
|
||
]
|
||
})
|
||
|
||
watch(
|
||
orderId,
|
||
(nextOrderId) => {
|
||
void loadOrder(nextOrderId)
|
||
},
|
||
{ immediate: true },
|
||
)
|
||
|
||
watch(
|
||
() => authStore.selectedHotelId,
|
||
(nextHotelId, previousHotelId) => {
|
||
if (!nextHotelId || nextHotelId === previousHotelId) {
|
||
return
|
||
}
|
||
void loadOrder(orderId.value)
|
||
},
|
||
)
|
||
|
||
async function loadOrder(nextOrderId: string): Promise<void> {
|
||
loading.value = true
|
||
errorMessage.value = ''
|
||
try {
|
||
detail.value = await fetchReservationOrderDetail(nextOrderId)
|
||
} catch (error) {
|
||
detail.value = null
|
||
errorMessage.value = error instanceof Error ? error.message : String(error)
|
||
} finally {
|
||
loading.value = false
|
||
}
|
||
}
|
||
|
||
function displayValue(value: string | null | undefined): string {
|
||
return value?.trim() || '-'
|
||
}
|
||
|
||
function formatRoomSummary(room: ReservationOrderV4RoomSummary): string {
|
||
return `${displayValue(room.room_type_code)} × ${room.room_count ?? '-'}`
|
||
}
|
||
|
||
function formatNextActionType(actionType: ReservationOrderV4NextActionResult['action_type']): string {
|
||
if (actionType === 'CONFIRM') {
|
||
return t('order.nextActionConfirm')
|
||
}
|
||
if (actionType === 'REVIEW') {
|
||
return t('order.nextActionReview')
|
||
}
|
||
if (actionType === 'NONE') {
|
||
return t('order.nextActionNone')
|
||
}
|
||
return actionType ?? '-'
|
||
}
|
||
|
||
function v4OrderReference(item: ReservationV4OrderTaskTimelineItem): string {
|
||
return item.order_ref?.trim() || item.source_message_summary?.subject?.trim() || `#${item.order_task_id}`
|
||
}
|
||
|
||
function cardTimelineTitle(card: ReservationOrderV4TaskCardTimelineItem): string {
|
||
const title = formatReservationTaskCard(t, card.card_type, card.card_type)
|
||
const index = card.source_event_index == null ? '' : ` · ${t('order.sourceEventIndex', { index: card.source_event_index })}`
|
||
return `${title}${index}`
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
.order-detail-view {
|
||
max-width: 1320px;
|
||
}
|
||
|
||
.order-state {
|
||
min-height: 260px;
|
||
display: grid;
|
||
place-items: center;
|
||
color: var(--th-color-slate-500);
|
||
font-weight: 700;
|
||
}
|
||
|
||
.order-state--error {
|
||
color: var(--th-color-danger);
|
||
}
|
||
|
||
.order-summary,
|
||
.overview-section,
|
||
.next-action-section,
|
||
.source-section,
|
||
.v4-timeline-section {
|
||
display: grid;
|
||
gap: 18px;
|
||
padding: 20px;
|
||
}
|
||
|
||
.order-summary header {
|
||
display: flex;
|
||
align-items: flex-start;
|
||
justify-content: space-between;
|
||
gap: 16px;
|
||
}
|
||
|
||
.order-summary p,
|
||
.order-summary h1,
|
||
.order-summary dl,
|
||
.empty-copy,
|
||
.th-muted {
|
||
margin: 0;
|
||
}
|
||
|
||
.order-summary p {
|
||
color: var(--th-color-blue-600);
|
||
font-size: 12px;
|
||
font-weight: 800;
|
||
}
|
||
|
||
.order-summary h1 {
|
||
margin-top: 4px;
|
||
color: var(--th-color-slate-900);
|
||
font-size: 26px;
|
||
}
|
||
|
||
.order-summary dl,
|
||
.overview-facts,
|
||
.next-action-facts,
|
||
.source-item dl,
|
||
.timeline-meta,
|
||
.card-summary dl {
|
||
display: grid;
|
||
gap: 16px;
|
||
}
|
||
|
||
.order-summary dl,
|
||
.overview-facts {
|
||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||
}
|
||
|
||
.next-action-facts,
|
||
.source-item dl,
|
||
.timeline-meta {
|
||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||
}
|
||
|
||
.card-summary dl {
|
||
grid-template-columns: repeat(5, minmax(0, 1fr));
|
||
}
|
||
|
||
.order-summary dt,
|
||
.overview-facts dt,
|
||
.next-action-facts dt,
|
||
.source-item dt,
|
||
.timeline-meta dt,
|
||
.card-summary dt {
|
||
color: var(--th-color-slate-500);
|
||
font-size: 12px;
|
||
font-weight: 700;
|
||
}
|
||
|
||
.order-summary dd,
|
||
.overview-facts dd,
|
||
.next-action-facts dd,
|
||
.source-item dd,
|
||
.timeline-meta dd,
|
||
.card-summary dd {
|
||
margin: 5px 0 0;
|
||
color: var(--th-color-slate-900);
|
||
font-size: 13px;
|
||
font-weight: 800;
|
||
overflow-wrap: anywhere;
|
||
}
|
||
|
||
.overview-layout {
|
||
display: grid;
|
||
grid-template-columns: minmax(0, 2fr) minmax(300px, 0.9fr);
|
||
gap: 18px;
|
||
align-items: start;
|
||
}
|
||
|
||
.th-muted,
|
||
.empty-copy {
|
||
color: var(--th-color-slate-500);
|
||
font-size: 13px;
|
||
line-height: 1.6;
|
||
}
|
||
|
||
.empty-copy--compact {
|
||
font-size: 12px;
|
||
}
|
||
|
||
.room-summary,
|
||
.overview-statuses {
|
||
display: grid;
|
||
gap: 8px;
|
||
border-top: 1px solid var(--th-color-slate-100);
|
||
padding-top: 14px;
|
||
}
|
||
|
||
.room-summary > span,
|
||
.overview-statuses span {
|
||
color: var(--th-color-slate-500);
|
||
font-size: 12px;
|
||
font-weight: 800;
|
||
}
|
||
|
||
.room-summary__items,
|
||
.overview-statuses {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 8px;
|
||
}
|
||
|
||
.room-summary__items strong {
|
||
border-radius: 999px;
|
||
background: var(--th-color-slate-100);
|
||
color: var(--th-color-slate-900);
|
||
padding: 5px 10px;
|
||
font-size: 13px;
|
||
}
|
||
|
||
.overview-statuses div {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
}
|
||
|
||
.primary-link,
|
||
.source-link {
|
||
color: var(--th-color-blue-600);
|
||
font-size: 13px;
|
||
font-weight: 800;
|
||
text-decoration: none;
|
||
}
|
||
|
||
.primary-link {
|
||
width: fit-content;
|
||
border-radius: var(--th-radius-sm);
|
||
background: var(--th-color-blue-600);
|
||
color: var(--th-color-white);
|
||
padding: 9px 12px;
|
||
}
|
||
|
||
.source-list,
|
||
.v4-timeline-list,
|
||
.card-summary-list {
|
||
display: grid;
|
||
gap: 12px;
|
||
}
|
||
|
||
.source-item,
|
||
.v4-timeline-item,
|
||
.card-summary {
|
||
display: grid;
|
||
gap: 12px;
|
||
border: 1px solid var(--th-color-slate-200);
|
||
border-radius: var(--th-radius-sm);
|
||
background: var(--th-color-white);
|
||
padding: 14px;
|
||
}
|
||
|
||
.source-item > div,
|
||
.v4-timeline-item__main,
|
||
.card-summary__heading {
|
||
display: flex;
|
||
align-items: flex-start;
|
||
justify-content: space-between;
|
||
gap: 12px;
|
||
}
|
||
|
||
.source-item > div {
|
||
align-items: center;
|
||
}
|
||
|
||
.source-item > div > strong,
|
||
.source-item > div > span,
|
||
.v4-timeline-item__main span,
|
||
.card-summary__heading span {
|
||
min-width: 0;
|
||
}
|
||
|
||
.source-item > div > strong,
|
||
.v4-timeline-item__main strong,
|
||
.card-summary__heading strong {
|
||
color: var(--th-color-slate-900);
|
||
font-size: 14px;
|
||
overflow-wrap: anywhere;
|
||
}
|
||
|
||
.source-item > div > span,
|
||
.v4-timeline-item__main small,
|
||
.card-summary__heading small {
|
||
color: var(--th-color-slate-500);
|
||
font-size: 12px;
|
||
font-weight: 700;
|
||
overflow-wrap: anywhere;
|
||
}
|
||
|
||
.v4-timeline-item__main {
|
||
align-items: center;
|
||
color: inherit;
|
||
text-decoration: none;
|
||
}
|
||
|
||
.v4-timeline-item__main span,
|
||
.card-summary__heading span {
|
||
display: grid;
|
||
gap: 3px;
|
||
}
|
||
|
||
.card-summary-list {
|
||
border-top: 1px solid var(--th-color-slate-100);
|
||
padding-top: 12px;
|
||
}
|
||
|
||
.card-summary {
|
||
background: var(--th-color-slate-50);
|
||
}
|
||
|
||
@media (max-width: 1100px) {
|
||
.overview-layout {
|
||
grid-template-columns: 1fr;
|
||
}
|
||
|
||
.order-summary dl,
|
||
.overview-facts,
|
||
.next-action-facts,
|
||
.source-item dl,
|
||
.timeline-meta,
|
||
.card-summary dl {
|
||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||
}
|
||
}
|
||
|
||
@media (max-width: 680px) {
|
||
.order-summary dl,
|
||
.overview-facts,
|
||
.next-action-facts,
|
||
.source-item dl,
|
||
.timeline-meta,
|
||
.card-summary dl {
|
||
grid-template-columns: 1fr;
|
||
}
|
||
|
||
.source-item > div,
|
||
.v4-timeline-item__main,
|
||
.card-summary__heading {
|
||
display: grid;
|
||
}
|
||
}
|
||
</style>
|