diff --git a/app/components/PaymentButton.tsx b/app/components/PaymentButton.tsx index 37ebc6d..250f017 100644 --- a/app/components/PaymentButton.tsx +++ b/app/components/PaymentButton.tsx @@ -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 ( diff --git a/app/components/Sidebar.tsx b/app/components/Sidebar.tsx index 85c6897..dbc4323 100644 --- a/app/components/Sidebar.tsx +++ b/app/components/Sidebar.tsx @@ -5,76 +5,134 @@ import { usePathname, useRouter } from 'next/navigation'; import { useEffect, useState } from 'react'; import { createClient } from '@/lib/supabase/client'; -const navItems = [ +/* ── 3구역 네비게이션 구조 ─────────────────────────────────── */ + +interface NavItem { + href: string; + label: string; + badge?: string; + icon: React.ReactNode; +} + +interface NavGroup { + title: string; + items: NavItem[]; +} + +const navGroups: NavGroup[] = [ { - href: '/', - label: '홈', - icon: ( - - - - ), + title: 'AI 상품', + items: [ + { + href: '/services/prompt', + label: '프롬프트 스토어', + badge: 'HOT', + icon: ( + + + + ), + }, + { + href: '/services/automation', + label: '업무 자동화', + icon: ( + + + + + ), + }, + { + href: '/services/ai-kit', + label: 'AI 자동화 키트', + badge: '구독', + icon: ( + + + + ), + }, + ], }, { - href: '/services/website', - label: '홈페이지 제작', - badge: 'NEW', - icon: ( - - - - ), + title: '무료 도구', + items: [ + { + href: '/saju', + label: 'AI 사주 분석', + badge: '무료', + icon: ( + + + + ), + }, + { + href: '/services/lotto', + label: '로또 번호 추천', + badge: '무료', + icon: ( + + + + ), + }, + { + href: '/tools', + label: '도구 쇼케이스', + badge: 'DEMO', + icon: ( + + + + ), + }, + ], }, { - href: '/services/automation', - label: '업무 자동화', - icon: ( - - - - - ), - }, - { - href: '/services/prompt', - label: '프롬프트 엔지니어링', - icon: ( - - - - ), - }, - { - href: '/services/ai-kit', - label: 'AI 자동화 키트', - badge: 'NEW', - icon: ( - - - - ), - }, - { - href: '/saju', - label: 'AI 사주 분석', - icon: ( - - - - ), - }, - { - href: '/tools', - label: '여긴 뭐 만들어요?', - badge: 'DEMO', - icon: ( - - - - ), + title: '외주 의뢰', + items: [ + { + href: '/freelance', + label: '외주 개발 문의', + icon: ( + + + + ), + }, + { + href: '/services/website', + label: '홈페이지 제작', + icon: ( + + + + ), + }, + ], }, ]; +/* ── 배지 색상 ─────────────────────────────────────────────── */ +function badgeStyle(badge: string) { + switch (badge) { + case 'HOT': + return 'bg-rose-500/15 text-rose-400'; + case '구독': + return 'bg-violet-500/15 text-violet-400'; + case '무료': + return 'bg-sky-500/15 text-sky-400'; + case 'DEMO': + return 'bg-amber-500/15 text-amber-400'; + default: + return 'bg-emerald-500/15 text-emerald-400'; + } +} + +/* ── 컴포넌트 ──────────────────────────────────────────────── */ + interface SidebarProps { isOpen: boolean; onClose: () => void; @@ -129,7 +187,7 @@ export default function Sidebar({ isOpen, onClose }: SidebarProps) {
쟁승메이드
-

박재오의 개발 공방

+

AI 프롬프트 · 자동화 스토어

@@ -137,34 +195,68 @@ export default function Sidebar({ isOpen, onClose }: SidebarProps) {
{/* Navigation */} -