사장님이 고를 수 있는 숙박 템플릿이 고택 하나뿐이었다. 모두 stay2 콘텐츠(날씨·미니 블로그· 지역 이야기·객실·축제·일정·후기·엽서·노래)를 그대로 싣고 모양만 다르다. - layouts/<id>/: 템플릿별 Frame·섹션·CSS. 데스크톱은 넓은 배치(1024px 이상), 모바일 우선 - layouts/kit/kit.css: 탭 전환·시트·예약 폼·접기 등 공통 구조 - shared templates.json · builder.ts · catalog.ts: 템플릿·LayoutId 등록 - seo/head.ts: 템플릿별 한글 웹폰트 — 서로 겹치지 않게 배정 - paper Frame·Intro: 같은 탭을 다시 눌러도 맨 위로, 미니 블로그를 글 여러 개로 - docs/TEMPLATES.md · TEMPLATE_DESIGN.md: 목록과 화면 규칙(간격·접기·✓ 표시·글꼴) eslint·tsc 통과, vitest 123 passed, 템플릿 9개 굽기 성공 · 간격 검사 0건
38 lines
1.2 KiB
TypeScript
38 lines
1.2 KiB
TypeScript
import {SourceType} from '@o2o/shared';
|
|
import {useSite} from '@site/lib/site-context';
|
|
import {faqList} from '@site/lib/derive';
|
|
|
|
const FIRST = 6;
|
|
|
|
export function Faq() {
|
|
const payload = useSite();
|
|
const faqs = faqList(payload);
|
|
if (faqs.length === 0) return null;
|
|
const verified = !faqs.some((faq) => faq.sourceType === SourceType.TEMPLATE);
|
|
const item = (faq: (typeof faqs)[number]) => (
|
|
<details key={faq.faqId}>
|
|
<summary>{faq.question}</summary>
|
|
<p>{faq.answer}</p>
|
|
</details>
|
|
);
|
|
|
|
return (
|
|
<section className="sec" id="faq" aria-labelledby="faq-heading">
|
|
<p className="kicker">Q & A</p>
|
|
<h2 id="faq-heading">
|
|
자주 묻는 질문 <span className="sub">{faqs.length}</span>
|
|
</h2>
|
|
{verified && <p className="lead small">아래 답변은 모두 사업자가 확인한 내용입니다.</p>}
|
|
<div className="faq">
|
|
{faqs.slice(0, FIRST).map(item)}
|
|
{faqs.length > FIRST && (
|
|
<details className="rest">
|
|
<summary className="more">{faqs.length - FIRST}개 더 보기</summary>
|
|
{faqs.slice(FIRST).map(item)}
|
|
</details>
|
|
)}
|
|
</div>
|
|
</section>
|
|
);
|
|
}
|