import { useState, useCallback } from 'react'; import { useNavigate } from 'react-router'; import { motion, AnimatePresence } from 'motion/react'; import { YoutubeFilled, InstagramFilled, FacebookFilled, GlobeFilled, TiktokFilled, } from '../components/icons/FilledIcons'; import type { ComponentType } from 'react'; interface ChannelDef { id: string; name: string; description: string; icon: ComponentType<{ size?: number; className?: string }>; brandColor: string; bgColor: string; borderColor: string; fields: { key: string; label: string; placeholder: string; type?: string }[]; } const CHANNELS: ChannelDef[] = [ { id: 'youtube', name: 'YouTube', description: '채널 연동으로 영상 자동 업로드, 성과 분석', icon: YoutubeFilled, brandColor: '#FF0000', bgColor: '#FFF0F0', borderColor: '#F5D5DC', fields: [ { key: 'channelUrl', label: '채널 URL', placeholder: 'https://youtube.com/@YourChannel' }, ], }, { id: 'instagram_kr', name: 'Instagram KR', description: '한국 계정 — Reels, Feed, Stories 자동 게시', icon: InstagramFilled, brandColor: '#E1306C', bgColor: '#FFF0F5', borderColor: '#F5D0DC', fields: [ { key: 'handle', label: '핸들', placeholder: '@viewclinic_kr' }, ], }, { id: 'instagram_en', name: 'Instagram EN', description: '글로벌 계정 — 해외 환자 대상 콘텐츠', icon: InstagramFilled, brandColor: '#E1306C', bgColor: '#FFF0F5', borderColor: '#F5D0DC', fields: [ { key: 'handle', label: '핸들', placeholder: '@viewplasticsurgery' }, ], }, { id: 'facebook_kr', name: 'Facebook KR', description: '한국 페이지 — 광고 리타겟, 콘텐츠 배포', icon: FacebookFilled, brandColor: '#1877F2', bgColor: '#F0F4FF', borderColor: '#C5D5F5', fields: [ { key: 'pageUrl', label: '페이지 URL', placeholder: 'https://facebook.com/YourPage' }, ], }, { id: 'facebook_en', name: 'Facebook EN', description: '글로벌 페이지 — 해외 환자 유입', icon: FacebookFilled, brandColor: '#1877F2', bgColor: '#F0F4FF', borderColor: '#C5D5F5', fields: [ { key: 'pageUrl', label: '페이지 URL', placeholder: 'https://facebook.com/YourPageEN' }, ], }, { id: 'naver_blog', name: 'Naver Blog', description: 'SEO 블로그 포스트 자동 게시, 키워드 최적화', icon: GlobeFilled, brandColor: '#03C75A', bgColor: '#F0FFF5', borderColor: '#C5F5D5', fields: [ { key: 'blogUrl', label: '블로그 URL', placeholder: 'https://blog.naver.com/yourblog' }, { key: 'apiKey', label: 'API Key', placeholder: 'Naver Open API Key', type: 'password' }, ], }, { id: 'naver_place', name: 'Naver Place', description: '플레이스 정보 동기화, 리뷰 모니터링', icon: GlobeFilled, brandColor: '#03C75A', bgColor: '#F0FFF5', borderColor: '#C5F5D5', fields: [ { key: 'placeUrl', label: '플레이스 URL', placeholder: 'https://map.naver.com/...' }, ], }, { id: 'tiktok', name: 'TikTok', description: 'Shorts 크로스포스팅, 트렌드 콘텐츠', icon: TiktokFilled, brandColor: '#000000', bgColor: '#F5F5F5', borderColor: '#E0E0E0', fields: [ { key: 'handle', label: '핸들', placeholder: '@yourclinic' }, ], }, { id: 'gangnamunni', name: '강남언니', description: '리뷰 모니터링, 평점 추적, 시술 정보 동기화', icon: GlobeFilled, brandColor: '#6B2D8B', bgColor: '#F3F0FF', borderColor: '#D5CDF5', fields: [ { key: 'hospitalUrl', label: '병원 페이지 URL', placeholder: 'https://gangnamunni.com/hospitals/...' }, ], }, { id: 'website', name: 'Website', description: '홈페이지 SEO 모니터링, 트래킹 픽셀 관리', icon: GlobeFilled, brandColor: '#6C5CE7', bgColor: '#F3F0FF', borderColor: '#D5CDF5', fields: [ { key: 'url', label: '웹사이트 URL', placeholder: 'https://www.yourclinic.com' }, { key: 'gaId', label: 'Google Analytics ID', placeholder: 'G-XXXXXXXXXX' }, ], }, ]; type ConnectionStatus = 'disconnected' | 'connecting' | 'connected'; interface ChannelState { status: ConnectionStatus; values: Record; } export default function ChannelConnectPage() { const navigate = useNavigate(); const [channels, setChannels] = useState>(() => { const init: Record = {}; for (const ch of CHANNELS) { init[ch.id] = { status: 'disconnected', values: {} }; } return init; }); const [expandedId, setExpandedId] = useState(null); const handleFieldChange = useCallback((channelId: string, fieldKey: string, value: string) => { setChannels(prev => ({ ...prev, [channelId]: { ...prev[channelId], values: { ...prev[channelId].values, [fieldKey]: value }, }, })); }, []); const handleConnect = useCallback((channelId: string) => { setChannels(prev => ({ ...prev, [channelId]: { ...prev[channelId], status: 'connecting' }, })); // Simulate connection setTimeout(() => { setChannels(prev => ({ ...prev, [channelId]: { ...prev[channelId], status: 'connected' }, })); }, 2000); }, []); const handleDisconnect = useCallback((channelId: string) => { setChannels(prev => ({ ...prev, [channelId]: { status: 'disconnected', values: {} }, })); }, []); const connectedCount = (Object.values(channels) as ChannelState[]).filter(c => c.status === 'connected').length; return (
{/* Header */}

Channel Integration

채널 연결

소셜 미디어와 플랫폼을 연결하여 콘텐츠를 자동으로 배포하고 성과를 추적하세요.

{/* Connection Summary + Distribute Button */}
0 ? 'bg-[#6C5CE7]' : 'bg-slate-300'}`} /> {connectedCount} / {CHANNELS.length} 연결됨
{connectedCount > 0 && ( )}
{/* Channel Grid */}
{CHANNELS.map(ch => { const state = channels[ch.id]; const isExpanded = expandedId === ch.id; const Icon = ch.icon; const allFieldsFilled = ch.fields.every(f => (state.values[f.key] ?? '').trim().length > 0); return ( {/* Card Header */} {/* Expanded Content */} {isExpanded && (
{state.status === 'connected' ? (
연결 상태: 활성
{ch.fields.map(f => (
{f.label}

{f.type === 'password' ? '••••••••' : state.values[f.key]}

))}
) : (
{ch.fields.map(f => (
handleFieldChange(ch.id, f.key, e.target.value)} placeholder={f.placeholder} className="w-full px-4 py-3 rounded-xl border border-slate-200 text-sm text-slate-700 placeholder:text-slate-300 focus:outline-none focus:border-[#6C5CE7] focus:ring-1 focus:ring-[#6C5CE7]/20 transition-all" />
))}
)}
)} ); })}
); }