o2o-infinith-demo/templates/supporters-astro/src/pages/posts/index.astro
Haewon Kam 7e515b70ae feat(supporters): 승인 UI·입력 반영·워커 — §7-5 ClinicInputsPanel + supporter_builds/inputs 마이그레이션 + apply_inputs, §12-2 상단 고지·개설자 승인·색인 빌드 필터, §7-6 워커 E2E(뷰성형외과 URL → 5편 → 게이트 0오류)
- 게이트: DISCLOSURE_TOP_MISSING, APPROVED_*, UNAPPROVED_IN_INDEXABLE_BUILD, PRESS_VOICE 규칙화, 픽스처 추가 (16/16)
- 생성기: --site 옵션, 병원 확인 답변(clinicAnswers) 근거 [A]
- default_briefs.mjs 첫 배치 자동 기획, workers/supporters-build/run.mjs
- 랜딩: SAMPLE REPORT 라벨 "실제 사례"로 (haewon 지시)
- v2 §11-6·§11-7 기록, E2E 리포트

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-07 17:07:06 +09:00

42 lines
2.8 KiB
Plaintext

---
import { getCollection } from 'astro:content';
import Base from '../../layouts/Base.astro';
import PostCard from '../../components/PostCard.astro';
import { CATEGORY_LABELS, SITE_NAME, fact, v, isPublishable } from '../../lib';
const posts = (await getCollection('posts')).filter(isPublishable).sort((a, b) => b.data.dateModified.localeCompare(a.data.dateModified));
const cats = Object.keys(CATEGORY_LABELS);
const site = Astro.site!.toString().replace(/\/$/, '');
const ld = { '@type': 'CollectionPage', '@id': `${site}/posts#page`, name: '전체 글', url: `${site}/posts`, inLanguage: 'ko', publisher: { '@type': 'Organization', name: SITE_NAME, url: site }, hasPart: posts.map((p) => ({ '@type': 'Article', headline: p.data.title, url: `${site}/posts/${p.id}`, dateModified: p.data.dateModified })) };
---
<Base title="전체 글" description={`${v(fact.shortName, '병원')}에 대해 자주 묻는 질문과 답을 주제별로 모았습니다.`} jsonLd={ld}>
<div class="wrap-wide" style="padding-bottom:4rem">
<header class="article-head"><div class="eyebrow">Archive</div><h1 class="serif">All Answers</h1><p style="color:var(--slate-600);margin-top:0.6rem">궁금한 주제를 골라 보세요. 글 하나가 질문 하나에 답합니다.</p></header>
{!posts.length && <p class="sub" style="color:var(--slate-500);margin-top:1.5rem">아직 발행한 글이 없습니다. 검토를 마친 글부터 차례로 올립니다.</p>}
<div class="cat-grid">
{cats.map((c) => {
const list = posts.filter((p) => p.data.category === c);
if (!list.length) return null;
return (<section id={`cat-${c}`} class={`cat span-${Math.min(list.length, 3)}`}><div class="section-title"><h2>{c}. {CATEGORY_LABELS[c]}</h2><span style="color:var(--slate-500);font-size:0.9rem">{list.length}편</span></div><div class="grid">{list.map((p) => <PostCard post={p} />)}</div></section>);
})}
</div>
</div>
</Base>
<style>
/* 카테고리 블록이 글 수만큼만 칸을 차지한다. 데스크톱 3열 → 태블릿 2열 → 모바일 1열 */
.cat-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 2.4rem 1.25rem; margin-top: 2.4rem; align-items: start; }
.cat { scroll-margin-top: 90px; min-width: 0; }
.cat .section-title { margin-bottom: 1rem; }
.cat .grid { grid-template-columns: repeat(var(--cols, 1), minmax(0, 1fr)); }
.span-1 { grid-column: span 1; --cols: 1; }
.span-2 { grid-column: span 2; --cols: 2; }
.span-3 { grid-column: span 3; --cols: 3; }
@media (max-width: 1000px) {
.cat-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.span-3 { grid-column: span 2; --cols: 2; }
}
@media (max-width: 660px) {
.cat-grid { grid-template-columns: 1fr; gap: 2rem; }
.span-2, .span-3 { grid-column: span 1; --cols: 1; }
}
</style>