/** * Flag — renders a country flag image from an ISO 3166-1 alpha-2 code. * Images served from flagcdn.com (free, no auth required). */ const COUNTRY_NAMES: Record = { RU: "Россия", DE: "Германия", NL: "Нидерланды", SG: "Сингапур", US: "США", GB: "Великобритания", FR: "Франция", FI: "Финляндия", SE: "Швеция", PL: "Польша", UA: "Украина", TR: "Турция", JP: "Япония", HK: "Гонконг", } /** Country name in Russian (fallback to code) */ export function countryName(code: string): string { return COUNTRY_NAMES[code.toUpperCase()] ?? code } interface FlagProps { code: string /** px size — width of the flag image (height auto-scales 3:2 ratio) */ size?: number className?: string } // flagcdn.com supports only these widths const CDN_SIZES = [20, 40, 80, 160, 320, 640, 1280, 2560] function nearestCdnSize(px: number): number { return CDN_SIZES.find(s => s >= px) ?? CDN_SIZES[CDN_SIZES.length - 1] } /** * Renders a flag for a given ISO 3166-1 alpha-2 country code. * Source: https://flagcdn.com — free CDN, no API key needed. */ export function Flag({ code, size = 20, className }: FlagProps) { if (!code) return null const lower = code.toLowerCase() const name = countryName(code.toUpperCase()) const cdnSrc = nearestCdnSize(size) const cdnSrc2x = nearestCdnSize(size * 2) return ( // Внешний CDN (динамический URL) — next/image без remotePatterns не подходит // eslint-disable-next-line @next/next/no-img-element -- flagcdn.com, размеры задаём явно {name} ) }