import {Phone} from 'lucide-react'; import {selectPublishable} from '@o2o/shared'; import {useSite} from '@/lib/site-context'; import {bookingLinks, channelLabel, essentialRows} from '@/lib/derive'; import {formatKoreanDate} from '@/lib/format'; /** * 이용안내 및 예약. * * ★ 마크업은 목업(/s/stay 의 `
`)에서 그대로 옮겼다. * ★ 표를 두 덩이로 가른다 — "예약 전 확인"(critical)과 "시설 · 편의". * critical 은 틀리면 예약 클레임이 나는 항목이라 손님이 먼저 봐야 하고, * 와이파이·주차와 같은 무게로 섞이면 그 위계가 사라진다. * ★ 예약 버튼이 이 섹션 안에 있다. 규정을 읽은 자리에서 바로 예약으로 이어지지 않으면 * 손님은 다시 위로 올라가야 한다. * ★ "확인 중인 항목 N개"를 숨기지 않는다 — 없는 척하면 손님이 다른 데서 틀린 값을 찾아 온다. */ export function EssentialInfoSection() { const payload = useSite(); const rows = essentialRows(payload); if (rows.length === 0) return null; // critical 여부는 fact 에만 있다. 표 행(label/value)에 다시 붙여 둘로 가른다. const criticalLabels = new Set( selectPublishable(payload.facts) .filter((fact) => fact.scope === 'place' && fact.critical) .map((fact) => fact.label), ); const groups = [ {title: '예약 전 확인', accent: true, rows: rows.filter((row) => criticalLabels.has(row.label))}, {title: '시설 · 편의', accent: false, rows: rows.filter((row) => !criticalLabels.has(row.label))}, ].filter((group) => group.rows.length > 0); const hiddenCount = payload.facts.filter( (fact) => fact.scope === 'place' && !rows.some((row) => row.label === fact.label), ).length; const links = bookingLinks(payload); const phone = payload.place.phone; return (