wip
This commit is contained in:
@@ -22,7 +22,7 @@ export default function Button({
|
||||
as = 'button',
|
||||
...props
|
||||
}: ButtonProps) {
|
||||
const baseStyles = 'min-h-[44px] rounded-full px-6 py-3 text-sm font-semibold transition-all duration-75 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 hover:scale-[1.03] active:scale-95';
|
||||
const baseStyles = 'inline-flex items-center min-h-[44px] rounded-full px-6 py-3 text-sm font-semibold transition-all duration-75 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 hover:scale-[1.03] active:scale-95';
|
||||
|
||||
const variantStyles = {
|
||||
primary: 'bg-primary-blue text-white shadow-[0_0_15px_rgba(25,140,255,0.4)] hover:shadow-[0_0_25px_rgba(25,140,255,0.6)] active:ring-2 active:ring-primary-blue focus-visible:outline-primary-blue',
|
||||
|
||||
130
apps/website/components/ui/CountryFlag.tsx
Normal file
130
apps/website/components/ui/CountryFlag.tsx
Normal file
@@ -0,0 +1,130 @@
|
||||
'use client';
|
||||
|
||||
import { useState } from 'react';
|
||||
|
||||
// ISO 3166-1 alpha-2 country code to full country name mapping
|
||||
const countryNames: Record<string, string> = {
|
||||
'US': 'United States',
|
||||
'GB': 'United Kingdom',
|
||||
'CA': 'Canada',
|
||||
'AU': 'Australia',
|
||||
'NZ': 'New Zealand',
|
||||
'DE': 'Germany',
|
||||
'FR': 'France',
|
||||
'IT': 'Italy',
|
||||
'ES': 'Spain',
|
||||
'NL': 'Netherlands',
|
||||
'BE': 'Belgium',
|
||||
'SE': 'Sweden',
|
||||
'NO': 'Norway',
|
||||
'DK': 'Denmark',
|
||||
'FI': 'Finland',
|
||||
'PL': 'Poland',
|
||||
'CZ': 'Czech Republic',
|
||||
'AT': 'Austria',
|
||||
'CH': 'Switzerland',
|
||||
'PT': 'Portugal',
|
||||
'IE': 'Ireland',
|
||||
'BR': 'Brazil',
|
||||
'MX': 'Mexico',
|
||||
'AR': 'Argentina',
|
||||
'JP': 'Japan',
|
||||
'CN': 'China',
|
||||
'KR': 'South Korea',
|
||||
'IN': 'India',
|
||||
'SG': 'Singapore',
|
||||
'TH': 'Thailand',
|
||||
'MY': 'Malaysia',
|
||||
'ID': 'Indonesia',
|
||||
'PH': 'Philippines',
|
||||
'ZA': 'South Africa',
|
||||
'RU': 'Russia',
|
||||
'MC': 'Monaco',
|
||||
'TR': 'Turkey',
|
||||
'GR': 'Greece',
|
||||
'HU': 'Hungary',
|
||||
'RO': 'Romania',
|
||||
'BG': 'Bulgaria',
|
||||
'HR': 'Croatia',
|
||||
'SI': 'Slovenia',
|
||||
'SK': 'Slovakia',
|
||||
'LT': 'Lithuania',
|
||||
'LV': 'Latvia',
|
||||
'EE': 'Estonia',
|
||||
};
|
||||
|
||||
// ISO 3166-1 alpha-2 country code to flag emoji conversion
|
||||
const countryCodeToFlag = (countryCode: string): string => {
|
||||
if (!countryCode || countryCode.length !== 2) return '🏁';
|
||||
|
||||
// Convert ISO 3166-1 alpha-2 to regional indicator symbols
|
||||
const codePoints = countryCode
|
||||
.toUpperCase()
|
||||
.split('')
|
||||
.map(char => 127397 + char.charCodeAt(0));
|
||||
return String.fromCodePoint(...codePoints);
|
||||
};
|
||||
|
||||
interface CountryFlagProps {
|
||||
/**
|
||||
* ISO 3166-1 alpha-2 country code (e.g., 'US', 'GB', 'DE')
|
||||
*/
|
||||
countryCode: string;
|
||||
/**
|
||||
* Size of the flag emoji
|
||||
* @default 'md'
|
||||
*/
|
||||
size?: 'sm' | 'md' | 'lg';
|
||||
/**
|
||||
* Additional CSS classes
|
||||
*/
|
||||
className?: string;
|
||||
/**
|
||||
* Whether to show tooltip with country name
|
||||
* @default true
|
||||
*/
|
||||
showTooltip?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reusable component for displaying country flags with tooltips
|
||||
*
|
||||
* @example
|
||||
* <CountryFlag countryCode="US" />
|
||||
* <CountryFlag countryCode="GB" size="lg" />
|
||||
* <CountryFlag countryCode="DE" showTooltip={false} />
|
||||
*/
|
||||
export default function CountryFlag({
|
||||
countryCode,
|
||||
size = 'md',
|
||||
className = '',
|
||||
showTooltip = true
|
||||
}: CountryFlagProps) {
|
||||
const [showTooltipState, setShowTooltipState] = useState(false);
|
||||
|
||||
const sizeClasses = {
|
||||
sm: 'text-xs',
|
||||
md: 'text-sm',
|
||||
lg: 'text-base'
|
||||
};
|
||||
|
||||
const flag = countryCodeToFlag(countryCode);
|
||||
const countryName = countryNames[countryCode.toUpperCase()] || countryCode;
|
||||
|
||||
return (
|
||||
<span
|
||||
className={`inline-flex items-center relative ${sizeClasses[size]} ${className}`}
|
||||
onMouseEnter={() => setShowTooltipState(true)}
|
||||
onMouseLeave={() => setShowTooltipState(false)}
|
||||
title={showTooltip ? countryName : undefined}
|
||||
>
|
||||
<span className="select-none">{flag}</span>
|
||||
{showTooltip && showTooltipState && (
|
||||
<span className="absolute bottom-full left-1/2 -translate-x-1/2 mb-1 px-2 py-1 text-xs font-medium text-white bg-deep-graphite border border-charcoal-outline rounded shadow-lg whitespace-nowrap z-50">
|
||||
{countryName}
|
||||
<span className="absolute top-full left-1/2 -translate-x-1/2 -mt-px border-4 border-transparent border-t-charcoal-outline"></span>
|
||||
</span>
|
||||
)}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import { useState, useRef, useEffect } from 'react';
|
||||
import { Globe, Search, ChevronDown, Check } from 'lucide-react';
|
||||
import CountryFlag from './CountryFlag';
|
||||
|
||||
export interface Country {
|
||||
code: string;
|
||||
@@ -51,14 +52,6 @@ export const COUNTRIES: Country[] = [
|
||||
{ code: 'UA', name: 'Ukraine' },
|
||||
];
|
||||
|
||||
function getCountryFlag(countryCode: string): string {
|
||||
const code = countryCode.toUpperCase();
|
||||
if (code.length === 2) {
|
||||
const codePoints = [...code].map(char => 127397 + char.charCodeAt(0));
|
||||
return String.fromCodePoint(...codePoints);
|
||||
}
|
||||
return '🏁';
|
||||
}
|
||||
|
||||
interface CountrySelectProps {
|
||||
value: string;
|
||||
@@ -130,7 +123,7 @@ export default function CountrySelect({
|
||||
<Globe className="w-4 h-4 text-gray-500" />
|
||||
{selectedCountry ? (
|
||||
<span className="flex items-center gap-2">
|
||||
<span className="text-lg">{getCountryFlag(selectedCountry.code)}</span>
|
||||
<CountryFlag countryCode={selectedCountry.code} size="md" showTooltip={false} />
|
||||
<span>{selectedCountry.name}</span>
|
||||
</span>
|
||||
) : (
|
||||
@@ -173,7 +166,7 @@ export default function CountrySelect({
|
||||
}`}
|
||||
>
|
||||
<span className="flex items-center gap-3">
|
||||
<span className="text-lg">{getCountryFlag(country.code)}</span>
|
||||
<CountryFlag countryCode={country.code} size="md" showTooltip={false} />
|
||||
<span>{country.name}</span>
|
||||
</span>
|
||||
{value === country.code && (
|
||||
|
||||
Reference in New Issue
Block a user