feat: 사이트 3구역 개편 + AI 상품 결제 연결 + SEO 업데이트

- 사이드바: AI상품/무료도구/외주의뢰 3그룹 구조로 개편 (ARIA 시맨틱)
- 홈페이지: AI 상품 중심 재작성 (히어로+상품카드+무료도구+외주축소)
- SEO: 메타데이터·OG태그·JSON-LD를 AI 상품 포지셔닝으로 변경
- 프롬프트 페이지: 프리미엄 상품 5개에 PortOne PaymentButton 연결
- AI 키트 페이지: 월 구독 CTA 2곳에 PaymentButton 연결
- 사주: 유료 전환 복원(4,900원) + PaymentButton 연결
- 코드 품질: 인라인 스타일→globals.css, emoji→SVG, 미사용 데이터 제거
- DB 마이그레이션 005: 전체 18개 상품 등록 SQL 추가

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-08 01:29:42 +09:00
parent 769544b453
commit 9433a3664c
12 changed files with 590 additions and 677 deletions

View File

@@ -38,7 +38,7 @@ export default function PaymentButton({ productId, className, style, children, r
await supabase.from('profiles').upsert({ id: user.id, email: user.email }, { onConflict: 'id' });
// 3. Supabase에 order 생성
const paymentId = `order_${Date.now()}_${crypto.randomUUID().slice(0, 8)}`;
const paymentId = crypto.randomUUID();
const { error: orderError } = await supabase
.from('orders')
.insert({
@@ -53,10 +53,8 @@ export default function PaymentButton({ productId, className, style, children, r
if (orderError) throw new Error('주문 생성 실패: ' + orderError.message);
// 4. 포트원 V2 결제 요청
const storeId = process.env.NEXT_PUBLIC_PORTONE_STORE_ID!;
const response = await PortOne.requestPayment({
storeId,
storeId: process.env.NEXT_PUBLIC_PORTONE_STORE_ID ?? '',
channelKey: channel.channelKey,
paymentId,
orderName: product.name,
@@ -122,7 +120,7 @@ export default function PaymentButton({ productId, className, style, children, r
if (!product) return null;
const isTestMode = process.env.NEXT_PUBLIC_PORTONE_STORE_ID?.includes('test')
const isTestMode = !process.env.NEXT_PUBLIC_PORTONE_STORE_ID
|| process.env.NODE_ENV === 'development';
return (