FAQ/

ナンバード FAQ

Preview

番号付きのアコーディオン形式で、構造化された質問・回答セクション

Source Code
tsx
145 lines
1"use client";
2
3import { useState } from "react";
4
5const faqItems = [
6 {
7 question: "サービスの導入にはどのくらいの期間がかかりますか?",
8 answer:
9 "プロジェクトの規模により異なりますが、標準的な導入で2〜4週間、大規模なカスタマイズが必要な場合は6〜8週間が目安です。初回のヒアリングで正確なスケジュールをご提案いたします。",
10 },
11 {
12 question: "料金体系について教えてください。",
13 answer:
14 "月額サブスクリプション制で、チームの規模と利用機能に応じた3つのプランをご用意しています。年間契約の場合は20%の割引が適用されます。詳細は料金ページをご覧ください。",
15 },
16 {
17 question: "既存のシステムとの連携は可能ですか?",
18 answer:
19 "主要なCRM、ERP、会計ソフトとのAPI連携に対応しています。Webhook による外部サービスとの連携も可能です。連携に関する技術的なご質問はサポートチームにお問い合わせください。",
20 },
21 {
22 question: "データのセキュリティはどのように保証されますか?",
23 answer:
24 "SOC 2 Type II および ISO 27001 の認証を取得しており、すべてのデータは AES-256 で暗号化されます。日次のバックアップと99.9%のアップタイム保証を提供しています。",
25 },
26 {
27 question: "無料トライアルはありますか?",
28 answer:
29 "14日間の無料トライアルをご利用いただけます。クレジットカードの登録は不要で、すべての機能を制限なくお試しいただけます。トライアル期間終了後、自動的に課金されることはありません。",
30 },
31 {
32 question: "サポート体制について教えてください。",
33 answer:
34 "平日9:00〜18:00のチャット・メールサポートを全プランで提供しています。エンタープライズプランでは、24時間365日の優先サポートと専任のカスタマーサクセスマネージャーが対応いたします。",
35 },
36];
37
38export function FaqNumbered001() {
39 const [openIndex, setOpenIndex] = useState<number | null>(null);
40
41 const toggle = (index: number) => {
42 setOpenIndex(openIndex === index ? null : index);
43 };
44
45 return (
46 <section className="bg-background py-28 border-t border-border">
47 <div className="mx-auto max-w-3xl px-4 sm:px-6 lg:px-8">
48 {/* ヘッダー */}
49 <div className="text-center">
50 <p className="text-[10px] uppercase tracking-[0.3em] text-muted-foreground">
51 FAQ
52 </p>
53 <h2 className="mt-3 text-2xl font-medium tracking-wide text-foreground sm:text-3xl">
54 よくあるご質問
55 </h2>
56 <p className="mx-auto mt-4 max-w-md text-sm font-light leading-relaxed text-muted-foreground">
57 お客様からよくいただくご質問をまとめました。その他のご質問はお気軽にお問い合わせください。
58 </p>
59 </div>
60
61 <div className="mt-4 h-px bg-border/40" />
62
63 {/* 質問リスト */}
64 <div className="mt-12">
65 {faqItems.map((item, i) => (
66 <div key={i} className="border-b border-border/60">
67 <button
68 onClick={() => toggle(i)}
69 className="flex w-full items-start gap-6 py-6 text-left transition-colors"
70 >
71 {/* 番号 */}
72 <span className="mt-0.5 shrink-0 text-[10px] tracking-[0.2em] text-muted-foreground/40">
73 {String(i + 1).padStart(2, "0")}
74 </span>
75
76 {/* 質問テキスト */}
77 <span className="flex-1 text-sm font-medium tracking-wide text-foreground">
78 {item.question}
79 </span>
80
81 {/* 開閉アイコン */}
82 <span className="mt-0.5 shrink-0 text-muted-foreground/40 transition-transform duration-200">
83 <svg
84 className={`h-4 w-4 transition-transform duration-300 ${
85 openIndex === i ? "rotate-45" : ""
86 }`}
87 fill="none"
88 stroke="currentColor"
89 viewBox="0 0 24 24"
90 >
91 <path
92 strokeLinecap="round"
93 strokeLinejoin="round"
94 strokeWidth={1.5}
95 d="M12 4v16m8-8H4"
96 />
97 </svg>
98 </span>
99 </button>
100
101 {/* 回答 */}
102 <div
103 className={`overflow-hidden transition-all duration-300 ${
104 openIndex === i
105 ? "max-h-64 pb-6 opacity-100"
106 : "max-h-0 opacity-0"
107 }`}
108 >
109 <p className="pl-[calc(10px+1.5rem)] text-sm font-light leading-relaxed text-muted-foreground sm:pl-[calc(10px+1.5rem)]">
110 {item.answer}
111 </p>
112 </div>
113 </div>
114 ))}
115 </div>
116
117 {/* フッター */}
118 <div className="mt-12 text-center">
119 <p className="text-xs font-light tracking-wide text-muted-foreground/60">
120 お探しの回答が見つかりませんか?
121 </p>
122 <a
123 href="#"
124 className="mt-3 inline-flex items-center gap-2 text-xs tracking-[0.15em] text-muted-foreground transition-colors hover:text-foreground"
125 >
126 お問い合わせ
127 <svg
128 className="h-3 w-3"
129 fill="none"
130 stroke="currentColor"
131 viewBox="0 0 24 24"
132 >
133 <path
134 strokeLinecap="round"
135 strokeLinejoin="round"
136 strokeWidth={1.5}
137 d="M17 8l4 4m0 0l-4 4m4-4H3"
138 />
139 </svg>
140 </a>
141 </div>
142 </div>
143 </section>
144 );
145}