aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/components/QuestionSummary.astro
blob: 9b709559be70280e7f79e1dd024778e553b52fec (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
---
/**
 * QuestionSummary — 一般質問の「まとめ」表と FAQPage JSON-LD を単一のデータ源から生成。
 *
 * ## 使い方(新規一般質問ページを作成する際のルール)
 *
 * 1. Markdown の表(| 質問 | 答弁概要 |)は **書かない**。
 * 2. 代わりにこのコンポーネントを import して使う:
 *
 * ```mdx
 * import QuestionSummary from '@/components/QuestionSummary.astro';
 *
 * <QuestionSummary
 *   headline="ページのタイトル"
 *   about="障害者虐待"
 *   datePublished="2025-06-06"
 *   qa={[
 *     { question: "① 質問文", answer: "答弁テキスト", anchor: "-見出し名" },
 *     { question: "② 質問文", answer: "答弁テキスト", anchor: "-見出し名" },
 *   ]}
 * />
 * ```
 *
 * 3. 表の更新は qa 配列を編集するだけ。表表示と JSON-LD が自動で同期される。
 *
 * - question: 表の「質問」列の内容(番号付きで)
 * - answer: 表の「答弁概要」列のテキスト(リンク構文なしのプレーンテキスト)
 * - anchor: 詳細セクションへのアンカー(見出しから自動生成されるID)
 * - headline: ページのタイトル
 * - about: 質問の主題(1〜3語のキーワード。JSON-LD WebPage.about に使われる)
 * - datePublished: 質問日(ISO 8601: YYYY-MM-DD)
 */

export interface QA {
  /** 質問文(例: "通報後に作成する文書と保存期間は。") */
  question: string;
  /** 答弁概要のテキスト(リンク構文を含まないプレーンテキスト) */
  answer: string;
  /** 詳細セクションへのアンカー(例: "-通報後に作成する文書と保存期間は") */
  anchor: string;
}

export interface Props {
  /** Q&A の配列 */
  qa: QA[];
  /** ページの表題 */
  headline?: string;
  /** 質問の主題(1〜3語。例: "障害者虐待"、"いじめ重大事態"、"公文書管理") */
  about?: string;
  /** 公開日(ISO 8601形式: YYYY-MM-DD) */
  datePublished?: string;
}

const { qa, headline, about, datePublished } = Astro.props;
---

{
  qa.length > 0 && (
    <script type="application/ld+json" is:inline set:html={JSON.stringify({
      "@context": "https://schema.org",
      "@graph": [
        {
          "@type": "WebPage",
          ...(headline && { name: headline }),
          ...(about && { about: { "@type": "Thing", name: about } }),
          ...(datePublished && { datePublished }),
          "mainEntity": { "@id": "#faq" },
        },
        {
          "@type": "FAQPage",
          "@id": "#faq",
          ...(headline && { headline }),
          "mainEntity": qa.map((item) => ({
            "@type": "Question",
            "name": item.question,
            "acceptedAnswer": {
              "@type": "Answer",
              "text": item.answer,
            },
          })),
        },
      ].filter(Boolean),
    })} />
  )
}

<!-- まとめ表(人間向け) -->
<table>
  <thead>
    <tr>
      <th>質問</th>
      <th>答弁概要(クリックで詳細)</th>
    </tr>
  </thead>
  <tbody>
    {qa.map((item) => (
      <tr>
        <td>{item.question}</td>
        <td><a href={`#${item.anchor}`}>{item.answer}</a></td>
      </tr>
    ))}
  </tbody>
</table>