o2o-site-AEO/solution/frontend/src/pages/PricingPage.tsx
Mina Choi af391b4c56 [feat] solution/frontend,docs: 랜딩 · 요금 · 쇼케이스 — 로그인 전 화면이 없었다
`/` 가 곧장 위저드로 튀어서 이 제품이 무엇을 파는 물건인지 말할 자리가 없었다.
처음 온 사람이 업종 선택 화면부터 만난다.

- router: `/` 는 비로그인 랜딩 · 로그인 /sites. /pricing · /showcase 추가
- MarketingShell: 사이드바 없는 문서형 껍데기. AppShell(작업 화면)과 나눴다
- 랜딩 상단은 상호명 한 칸. 문구는 SEO·AEO 축으로만 쓴다 —
  '쉽게·빠르게'로 말하면 홈페이지 빌더와 같은 자리에서 비교당한다(PRODUCT 1절)
- ShowcaseGrid: 발행 썸네일을 그대로 건다. 예시 데이터로 채우지 않고, 없으면 섹션을 감춘다.
  ★ 생성 클라이언트를 안 쓴다 — 토큰 길목을 지나면 비로그인에서 못 부른다
- 요금은 플랜 하나(70만원/월) + 월 산출물. 비교표를 만들지 않는다

tsc·eslint·vite build 통과
2026-09-03 10:21:16 +09:00

110 lines
4.8 KiB
TypeScript

import {Link} from 'react-router';
import {Check} from 'lucide-react';
import {MarketingShell, Section} from '@/components/layout/MarketingShell';
import {Button} from '@/components/ui/button';
/**
* 요금 — 플랜 하나다.
*
* ★ 플랜을 여럿 늘어놓지 않는다. 이건 셀프서비스 구독이 아니라 **월 단위로 사람이 붙는
* 서비스**라 고를 것이 가격대가 아니라 "할 것이냐"뿐이다. 비교표를 만들면 없는 선택지를
* 지어내게 된다.
*/
const INCLUDED = ['AI 노출 진단 리포트', '최적화 가이드', '영상 콘텐츠 2종', '페이지 제작 1회'];
const TERMS: {label: string; value: string}[] = [
{label: '무엇을 넣나', value: '운영 중인 홈페이지'},
{label: '무엇이 나오나', value: '진단 리포트 + 최적화 가이드 + 페이지'},
{label: '월 산출물', value: '리포트 1회 · 영상 2종 · 페이지 1회'},
{label: '확인 절차', value: '리포트 리뷰 미팅'},
];
export function PricingPage() {
return (
<MarketingShell>
<Section>
<header className="mb-12 text-center">
<h1 className="text-3xl font-bold tracking-tight text-balance sm:text-4xl">요금</h1>
<p className="mx-auto mt-3 max-w-lg text-sm text-muted-foreground">
매달 진단하고, 고치고, 결과를 같이 봅니다.
</p>
</header>
<div className="mx-auto max-w-2xl rounded-2xl border border-border bg-card p-7 sm:p-9">
<div className="flex flex-wrap items-baseline justify-between gap-3">
<h2 className="text-2xl font-bold tracking-tight">Web4AI</h2>
<p className="text-2xl font-bold tracking-tight">
70만원
<span className="ml-1 text-sm font-medium text-muted-foreground">/ 월</span>
</p>
</div>
<p className="mt-7 text-base font-semibold tracking-tight">AI가 우리를 찾아내게 만듭니다</p>
<p className="mt-2 text-sm leading-relaxed text-muted-foreground">
ChatGPT·제미나이·퍼플렉시티 답변에 우리 정보가 인용되도록 홈페이지를 진단하고 고칩니다.
</p>
<ul className="mt-6 flex flex-wrap gap-2">
{INCLUDED.map((item) => (
<li
key={item}
className="inline-flex items-center gap-1.5 rounded-full border border-border px-3.5 py-1.5 text-[13px]"
>
<Check className="size-3.5 text-success" aria-hidden />
{item}
</li>
))}
</ul>
<dl className="mt-8 grid gap-3 border-t border-border pt-7 text-sm sm:grid-cols-[7rem_1fr]">
{TERMS.map(({label, value}) => (
<div key={label} className="grid gap-1 sm:col-span-2 sm:grid-cols-subgrid">
<dt className="text-muted-foreground">{label}</dt>
<dd className="m-0">{value}</dd>
</div>
))}
</dl>
<Link to="/builder?new=1" className="mt-8 block">
<Button variant="primary" size="lg" className="w-full">
먼저 만들어 보기
</Button>
</Link>
<p className="mt-3 text-center text-xs text-muted-foreground">
가입하지 않아도 끝까지 만들어 볼 수 있습니다.
</p>
</div>
</Section>
<Section muted>
<h2 className="mb-8 text-xl font-bold tracking-tight">자주 묻는 질문</h2>
<dl className="grid gap-6 sm:grid-cols-2">
{[
{
q: '네이버 플레이스랑 뭐가 다른가요?',
a: '네이버는 AI 크롤러를 막습니다. 그래서 네이버에 올린 정보는 ChatGPT 같은 AI가 읽지 못합니다. 이 홈페이지는 AI가 읽을 수 있게 만듭니다.',
},
{
q: '홈페이지가 이미 있는데도 필요한가요?',
a: '있는 홈페이지가 AI에게 읽히는지가 관건입니다. 화면에는 보이는데 크롤러에게는 빈 페이지인 경우가 많습니다. 진단이 그걸 먼저 봅니다.',
},
{
q: '무엇을 준비해야 하나요?',
a: '지금 운영 중인 홈페이지 주소 하나면 시작합니다. 없으면 여기서 만드는 것부터 합니다.',
},
{
q: '결과는 어떻게 확인하나요?',
a: '매달 진단 리포트를 드리고, 리뷰 미팅에서 무엇이 달라졌는지 같이 봅니다.',
},
].map(({q, a}) => (
<div key={q}>
<dt className="text-sm font-semibold">{q}</dt>
<dd className="mt-1.5 text-sm leading-relaxed text-muted-foreground">{a}</dd>
</div>
))}
</dl>
</Section>
</MarketingShell>
);
}