/** * PlatformIcon — 플랫폼 식별자 (string variant) 로 lucide line icon 을 반환. * * 입력은 'youtube', 'YouTube', 'naver-blog', '네이버 블로그' 같이 다양한 형태가 * 들어올 수 있어 normalize 후 부분 일치까지 시도합니다. 매칭 실패 시 Globe. */ import { Globe, Instagram, Youtube, Facebook, Music, FileText, Heart, MapPin, Search, type LucideIcon, } from 'lucide-react'; export type PlatformVariant = | 'website' | 'instagram' | 'youtube' | 'facebook' | 'tiktok' | 'naverPlace' | 'naverBlog' | 'naver' | 'gangnamUnni' | 'blog'; export const PLATFORM_ICONS: Record = { website: Globe, instagram: Instagram, youtube: Youtube, facebook: Facebook, tiktok: Music, naverPlace: MapPin, naverBlog: FileText, naver: Search, gangnamUnni: Heart, blog: FileText, }; export const PLATFORM_COLORS: Record = { website: '#6C5CE7', instagram: '#833AB4', youtube: '#FF3D3D', facebook: '#1877F2', tiktok: '#0A1128', naverPlace: '#03C75A', naverBlog: '#03C75A', naver: '#03C75A', gangnamUnni: '#FF6B8A', blog: '#03C75A', }; /** 별칭 → canonical key. lowercase / 한글 / 공백·하이픈 변형을 흡수. */ const ALIAS: Record = { website: 'website', homepage: 'website', web: 'website', site: 'website', 홈페이지: 'website', instagram: 'instagram', ig: 'instagram', 인스타: 'instagram', 인스타그램: 'instagram', youtube: 'youtube', yt: 'youtube', 유튜브: 'youtube', facebook: 'facebook', fb: 'facebook', 페이스북: 'facebook', tiktok: 'tiktok', 틱톡: 'tiktok', naverplace: 'naverPlace', 네이버플레이스: 'naverPlace', 네이버플레이스지도: 'naverPlace', place: 'naverPlace', naverblog: 'naverBlog', 네이버블로그: 'naverBlog', naver: 'naver', 네이버: 'naver', blog: 'blog', 블로그: 'blog', gangnamunni: 'gangnamUnni', 강남언니: 'gangnamUnni', }; /** 자유 문자열 → PlatformVariant. 못 찾으면 undefined. */ export function resolvePlatformVariant(raw: string | null | undefined): PlatformVariant | undefined { if (!raw) return undefined; const norm = raw.toLowerCase().replace(/[\s\-_]+/g, ''); if (norm in ALIAS) return ALIAS[norm]; // 부분 일치 (예: "naver blog" → "naverblog" → naverBlog) for (const key of Object.keys(ALIAS)) { if (norm.includes(key)) return ALIAS[key]; } return undefined; } interface PlatformIconProps { /** 플랫폼 식별 문자열. 'youtube' / 'Instagram' / '네이버 블로그' 등 자유 형식 */ variant: string | null | undefined; size?: number; className?: string; /** 색상을 자동으로 플랫폼 컬러로 채울지 (false 면 현재 텍스트 색 상속) */ colored?: boolean; /** 매칭 실패 시 사용할 fallback icon. 기본 Globe. */ fallback?: LucideIcon; } export function PlatformIcon({ variant, size = 16, className, colored = false, fallback = Globe, }: PlatformIconProps) { const key = resolvePlatformVariant(variant); const Icon = key ? PLATFORM_ICONS[key] : fallback; const color = colored && key ? PLATFORM_COLORS[key] : undefined; return ; }