- Institution Browser: multi-select for types and countries - URL query param sync for shareable filter URLs - New utility: countryNames.ts with flag emoji support - New utility: imageProxy.ts for image URL handling - New component: SearchableMultiSelect dropdown - Career timeline CSS and component updates - Media gallery improvements - Lazy load error boundary component - Version check utility
367 lines
14 KiB
TypeScript
367 lines
14 KiB
TypeScript
/**
|
|
* Country Names Mapping
|
|
* ISO 3166-1 alpha-2 country codes to full names in Dutch and English
|
|
*
|
|
* Comprehensive mapping for heritage custodian data across 190+ countries
|
|
*/
|
|
|
|
export interface CountryInfo {
|
|
nl: string;
|
|
en: string;
|
|
flag?: string; // Flag emoji (generated from code)
|
|
}
|
|
|
|
// Convert ISO 3166-1 alpha-2 country code to Unicode flag emoji
|
|
export function getFlagEmoji(countryCode: string): string {
|
|
if (!countryCode || countryCode.length !== 2) return '';
|
|
const code = countryCode.toUpperCase();
|
|
const codePoints = code
|
|
.split('')
|
|
.map(char => 127397 + char.charCodeAt(0));
|
|
return String.fromCodePoint(...codePoints);
|
|
}
|
|
|
|
// Complete ISO 3166-1 alpha-2 country code to name mapping
|
|
export const COUNTRY_NAMES: Record<string, CountryInfo> = {
|
|
// A
|
|
'AD': { nl: 'Andorra', en: 'Andorra' },
|
|
'AE': { nl: 'Verenigde Arabische Emiraten', en: 'United Arab Emirates' },
|
|
'AF': { nl: 'Afghanistan', en: 'Afghanistan' },
|
|
'AG': { nl: 'Antigua en Barbuda', en: 'Antigua and Barbuda' },
|
|
'AI': { nl: 'Anguilla', en: 'Anguilla' },
|
|
'AL': { nl: 'Albanië', en: 'Albania' },
|
|
'AM': { nl: 'Armenië', en: 'Armenia' },
|
|
'AO': { nl: 'Angola', en: 'Angola' },
|
|
'AQ': { nl: 'Antarctica', en: 'Antarctica' },
|
|
'AR': { nl: 'Argentinië', en: 'Argentina' },
|
|
'AS': { nl: 'Amerikaans-Samoa', en: 'American Samoa' },
|
|
'AT': { nl: 'Oostenrijk', en: 'Austria' },
|
|
'AU': { nl: 'Australië', en: 'Australia' },
|
|
'AW': { nl: 'Aruba', en: 'Aruba' },
|
|
'AX': { nl: 'Åland', en: 'Åland Islands' },
|
|
'AZ': { nl: 'Azerbeidzjan', en: 'Azerbaijan' },
|
|
|
|
// B
|
|
'BA': { nl: 'Bosnië en Herzegovina', en: 'Bosnia and Herzegovina' },
|
|
'BB': { nl: 'Barbados', en: 'Barbados' },
|
|
'BD': { nl: 'Bangladesh', en: 'Bangladesh' },
|
|
'BE': { nl: 'België', en: 'Belgium' },
|
|
'BF': { nl: 'Burkina Faso', en: 'Burkina Faso' },
|
|
'BG': { nl: 'Bulgarije', en: 'Bulgaria' },
|
|
'BH': { nl: 'Bahrein', en: 'Bahrain' },
|
|
'BI': { nl: 'Burundi', en: 'Burundi' },
|
|
'BJ': { nl: 'Benin', en: 'Benin' },
|
|
'BL': { nl: 'Saint-Barthélemy', en: 'Saint Barthélemy' },
|
|
'BM': { nl: 'Bermuda', en: 'Bermuda' },
|
|
'BN': { nl: 'Brunei', en: 'Brunei' },
|
|
'BO': { nl: 'Bolivia', en: 'Bolivia' },
|
|
'BQ': { nl: 'Caribisch Nederland', en: 'Caribbean Netherlands' },
|
|
'BR': { nl: 'Brazilië', en: 'Brazil' },
|
|
'BS': { nl: 'Bahama\'s', en: 'Bahamas' },
|
|
'BT': { nl: 'Bhutan', en: 'Bhutan' },
|
|
'BV': { nl: 'Bouveteiland', en: 'Bouvet Island' },
|
|
'BW': { nl: 'Botswana', en: 'Botswana' },
|
|
'BY': { nl: 'Wit-Rusland', en: 'Belarus' },
|
|
'BZ': { nl: 'Belize', en: 'Belize' },
|
|
|
|
// C
|
|
'CA': { nl: 'Canada', en: 'Canada' },
|
|
'CC': { nl: 'Cocoseilanden', en: 'Cocos (Keeling) Islands' },
|
|
'CD': { nl: 'Congo-Kinshasa', en: 'DR Congo' },
|
|
'CF': { nl: 'Centraal-Afrikaanse Republiek', en: 'Central African Republic' },
|
|
'CG': { nl: 'Congo-Brazzaville', en: 'Republic of the Congo' },
|
|
'CH': { nl: 'Zwitserland', en: 'Switzerland' },
|
|
'CI': { nl: 'Ivoorkust', en: 'Ivory Coast' },
|
|
'CK': { nl: 'Cookeilanden', en: 'Cook Islands' },
|
|
'CL': { nl: 'Chili', en: 'Chile' },
|
|
'CM': { nl: 'Kameroen', en: 'Cameroon' },
|
|
'CN': { nl: 'China', en: 'China' },
|
|
'CO': { nl: 'Colombia', en: 'Colombia' },
|
|
'CR': { nl: 'Costa Rica', en: 'Costa Rica' },
|
|
'CU': { nl: 'Cuba', en: 'Cuba' },
|
|
'CV': { nl: 'Kaapverdië', en: 'Cape Verde' },
|
|
'CW': { nl: 'Curaçao', en: 'Curaçao' },
|
|
'CX': { nl: 'Christmaseiland', en: 'Christmas Island' },
|
|
'CY': { nl: 'Cyprus', en: 'Cyprus' },
|
|
'CZ': { nl: 'Tsjechië', en: 'Czechia' },
|
|
|
|
// D
|
|
'DE': { nl: 'Duitsland', en: 'Germany' },
|
|
'DJ': { nl: 'Djibouti', en: 'Djibouti' },
|
|
'DK': { nl: 'Denemarken', en: 'Denmark' },
|
|
'DM': { nl: 'Dominica', en: 'Dominica' },
|
|
'DO': { nl: 'Dominicaanse Republiek', en: 'Dominican Republic' },
|
|
'DZ': { nl: 'Algerije', en: 'Algeria' },
|
|
|
|
// E
|
|
'EC': { nl: 'Ecuador', en: 'Ecuador' },
|
|
'EE': { nl: 'Estland', en: 'Estonia' },
|
|
'EG': { nl: 'Egypte', en: 'Egypt' },
|
|
'EH': { nl: 'Westelijke Sahara', en: 'Western Sahara' },
|
|
'ER': { nl: 'Eritrea', en: 'Eritrea' },
|
|
'ES': { nl: 'Spanje', en: 'Spain' },
|
|
'ET': { nl: 'Ethiopië', en: 'Ethiopia' },
|
|
|
|
// F
|
|
'FI': { nl: 'Finland', en: 'Finland' },
|
|
'FJ': { nl: 'Fiji', en: 'Fiji' },
|
|
'FK': { nl: 'Falklandeilanden', en: 'Falkland Islands' },
|
|
'FM': { nl: 'Micronesia', en: 'Micronesia' },
|
|
'FO': { nl: 'Faeröer', en: 'Faroe Islands' },
|
|
'FR': { nl: 'Frankrijk', en: 'France' },
|
|
|
|
// G
|
|
'GA': { nl: 'Gabon', en: 'Gabon' },
|
|
'GB': { nl: 'Verenigd Koninkrijk', en: 'United Kingdom' },
|
|
'GD': { nl: 'Grenada', en: 'Grenada' },
|
|
'GE': { nl: 'Georgië', en: 'Georgia' },
|
|
'GF': { nl: 'Frans-Guyana', en: 'French Guiana' },
|
|
'GG': { nl: 'Guernsey', en: 'Guernsey' },
|
|
'GH': { nl: 'Ghana', en: 'Ghana' },
|
|
'GI': { nl: 'Gibraltar', en: 'Gibraltar' },
|
|
'GL': { nl: 'Groenland', en: 'Greenland' },
|
|
'GM': { nl: 'Gambia', en: 'Gambia' },
|
|
'GN': { nl: 'Guinee', en: 'Guinea' },
|
|
'GP': { nl: 'Guadeloupe', en: 'Guadeloupe' },
|
|
'GQ': { nl: 'Equatoriaal-Guinea', en: 'Equatorial Guinea' },
|
|
'GR': { nl: 'Griekenland', en: 'Greece' },
|
|
'GS': { nl: 'Zuid-Georgia en de Zuidelijke Sandwicheilanden', en: 'South Georgia' },
|
|
'GT': { nl: 'Guatemala', en: 'Guatemala' },
|
|
'GU': { nl: 'Guam', en: 'Guam' },
|
|
'GW': { nl: 'Guinee-Bissau', en: 'Guinea-Bissau' },
|
|
'GY': { nl: 'Guyana', en: 'Guyana' },
|
|
|
|
// H
|
|
'HK': { nl: 'Hongkong', en: 'Hong Kong' },
|
|
'HM': { nl: 'Heard en McDonaldeilanden', en: 'Heard Island and McDonald Islands' },
|
|
'HN': { nl: 'Honduras', en: 'Honduras' },
|
|
'HR': { nl: 'Kroatië', en: 'Croatia' },
|
|
'HT': { nl: 'Haïti', en: 'Haiti' },
|
|
'HU': { nl: 'Hongarije', en: 'Hungary' },
|
|
|
|
// I
|
|
'ID': { nl: 'Indonesië', en: 'Indonesia' },
|
|
'IE': { nl: 'Ierland', en: 'Ireland' },
|
|
'IL': { nl: 'Israël', en: 'Israel' },
|
|
'IM': { nl: 'Man', en: 'Isle of Man' },
|
|
'IN': { nl: 'India', en: 'India' },
|
|
'IO': { nl: 'Brits Indische Oceaanterritorium', en: 'British Indian Ocean Territory' },
|
|
'IQ': { nl: 'Irak', en: 'Iraq' },
|
|
'IR': { nl: 'Iran', en: 'Iran' },
|
|
'IS': { nl: 'IJsland', en: 'Iceland' },
|
|
'IT': { nl: 'Italië', en: 'Italy' },
|
|
|
|
// J
|
|
'JE': { nl: 'Jersey', en: 'Jersey' },
|
|
'JM': { nl: 'Jamaica', en: 'Jamaica' },
|
|
'JO': { nl: 'Jordanië', en: 'Jordan' },
|
|
'JP': { nl: 'Japan', en: 'Japan' },
|
|
|
|
// K
|
|
'KE': { nl: 'Kenia', en: 'Kenya' },
|
|
'KG': { nl: 'Kirgizië', en: 'Kyrgyzstan' },
|
|
'KH': { nl: 'Cambodja', en: 'Cambodia' },
|
|
'KI': { nl: 'Kiribati', en: 'Kiribati' },
|
|
'KM': { nl: 'Comoren', en: 'Comoros' },
|
|
'KN': { nl: 'Saint Kitts en Nevis', en: 'Saint Kitts and Nevis' },
|
|
'KP': { nl: 'Noord-Korea', en: 'North Korea' },
|
|
'KR': { nl: 'Zuid-Korea', en: 'South Korea' },
|
|
'KW': { nl: 'Koeweit', en: 'Kuwait' },
|
|
'KY': { nl: 'Kaaimaneilanden', en: 'Cayman Islands' },
|
|
'KZ': { nl: 'Kazachstan', en: 'Kazakhstan' },
|
|
|
|
// L
|
|
'LA': { nl: 'Laos', en: 'Laos' },
|
|
'LB': { nl: 'Libanon', en: 'Lebanon' },
|
|
'LC': { nl: 'Saint Lucia', en: 'Saint Lucia' },
|
|
'LI': { nl: 'Liechtenstein', en: 'Liechtenstein' },
|
|
'LK': { nl: 'Sri Lanka', en: 'Sri Lanka' },
|
|
'LR': { nl: 'Liberia', en: 'Liberia' },
|
|
'LS': { nl: 'Lesotho', en: 'Lesotho' },
|
|
'LT': { nl: 'Litouwen', en: 'Lithuania' },
|
|
'LU': { nl: 'Luxemburg', en: 'Luxembourg' },
|
|
'LV': { nl: 'Letland', en: 'Latvia' },
|
|
'LY': { nl: 'Libië', en: 'Libya' },
|
|
|
|
// M
|
|
'MA': { nl: 'Marokko', en: 'Morocco' },
|
|
'MC': { nl: 'Monaco', en: 'Monaco' },
|
|
'MD': { nl: 'Moldavië', en: 'Moldova' },
|
|
'ME': { nl: 'Montenegro', en: 'Montenegro' },
|
|
'MF': { nl: 'Sint-Maarten (Frans)', en: 'Saint Martin' },
|
|
'MG': { nl: 'Madagaskar', en: 'Madagascar' },
|
|
'MH': { nl: 'Marshalleilanden', en: 'Marshall Islands' },
|
|
'MK': { nl: 'Noord-Macedonië', en: 'North Macedonia' },
|
|
'ML': { nl: 'Mali', en: 'Mali' },
|
|
'MM': { nl: 'Myanmar', en: 'Myanmar' },
|
|
'MN': { nl: 'Mongolië', en: 'Mongolia' },
|
|
'MO': { nl: 'Macau', en: 'Macau' },
|
|
'MP': { nl: 'Noordelijke Marianen', en: 'Northern Mariana Islands' },
|
|
'MQ': { nl: 'Martinique', en: 'Martinique' },
|
|
'MR': { nl: 'Mauritanië', en: 'Mauritania' },
|
|
'MS': { nl: 'Montserrat', en: 'Montserrat' },
|
|
'MT': { nl: 'Malta', en: 'Malta' },
|
|
'MU': { nl: 'Mauritius', en: 'Mauritius' },
|
|
'MV': { nl: 'Maldiven', en: 'Maldives' },
|
|
'MW': { nl: 'Malawi', en: 'Malawi' },
|
|
'MX': { nl: 'Mexico', en: 'Mexico' },
|
|
'MY': { nl: 'Maleisië', en: 'Malaysia' },
|
|
'MZ': { nl: 'Mozambique', en: 'Mozambique' },
|
|
|
|
// N
|
|
'NA': { nl: 'Namibië', en: 'Namibia' },
|
|
'NC': { nl: 'Nieuw-Caledonië', en: 'New Caledonia' },
|
|
'NE': { nl: 'Niger', en: 'Niger' },
|
|
'NF': { nl: 'Norfolk', en: 'Norfolk Island' },
|
|
'NG': { nl: 'Nigeria', en: 'Nigeria' },
|
|
'NI': { nl: 'Nicaragua', en: 'Nicaragua' },
|
|
'NL': { nl: 'Nederland', en: 'Netherlands' },
|
|
'NO': { nl: 'Noorwegen', en: 'Norway' },
|
|
'NP': { nl: 'Nepal', en: 'Nepal' },
|
|
'NR': { nl: 'Nauru', en: 'Nauru' },
|
|
'NU': { nl: 'Niue', en: 'Niue' },
|
|
'NZ': { nl: 'Nieuw-Zeeland', en: 'New Zealand' },
|
|
|
|
// O
|
|
'OM': { nl: 'Oman', en: 'Oman' },
|
|
|
|
// P
|
|
'PA': { nl: 'Panama', en: 'Panama' },
|
|
'PE': { nl: 'Peru', en: 'Peru' },
|
|
'PF': { nl: 'Frans-Polynesië', en: 'French Polynesia' },
|
|
'PG': { nl: 'Papoea-Nieuw-Guinea', en: 'Papua New Guinea' },
|
|
'PH': { nl: 'Filipijnen', en: 'Philippines' },
|
|
'PK': { nl: 'Pakistan', en: 'Pakistan' },
|
|
'PL': { nl: 'Polen', en: 'Poland' },
|
|
'PM': { nl: 'Saint-Pierre en Miquelon', en: 'Saint Pierre and Miquelon' },
|
|
'PN': { nl: 'Pitcairneilanden', en: 'Pitcairn Islands' },
|
|
'PR': { nl: 'Puerto Rico', en: 'Puerto Rico' },
|
|
'PS': { nl: 'Palestina', en: 'Palestine' },
|
|
'PT': { nl: 'Portugal', en: 'Portugal' },
|
|
'PW': { nl: 'Palau', en: 'Palau' },
|
|
'PY': { nl: 'Paraguay', en: 'Paraguay' },
|
|
|
|
// Q
|
|
'QA': { nl: 'Qatar', en: 'Qatar' },
|
|
|
|
// R
|
|
'RE': { nl: 'Réunion', en: 'Réunion' },
|
|
'RO': { nl: 'Roemenië', en: 'Romania' },
|
|
'RS': { nl: 'Servië', en: 'Serbia' },
|
|
'RU': { nl: 'Rusland', en: 'Russia' },
|
|
'RW': { nl: 'Rwanda', en: 'Rwanda' },
|
|
|
|
// S
|
|
'SA': { nl: 'Saoedi-Arabië', en: 'Saudi Arabia' },
|
|
'SB': { nl: 'Salomonseilanden', en: 'Solomon Islands' },
|
|
'SC': { nl: 'Seychellen', en: 'Seychelles' },
|
|
'SD': { nl: 'Soedan', en: 'Sudan' },
|
|
'SE': { nl: 'Zweden', en: 'Sweden' },
|
|
'SG': { nl: 'Singapore', en: 'Singapore' },
|
|
'SH': { nl: 'Sint-Helena', en: 'Saint Helena' },
|
|
'SI': { nl: 'Slovenië', en: 'Slovenia' },
|
|
'SJ': { nl: 'Spitsbergen en Jan Mayen', en: 'Svalbard and Jan Mayen' },
|
|
'SK': { nl: 'Slowakije', en: 'Slovakia' },
|
|
'SL': { nl: 'Sierra Leone', en: 'Sierra Leone' },
|
|
'SM': { nl: 'San Marino', en: 'San Marino' },
|
|
'SN': { nl: 'Senegal', en: 'Senegal' },
|
|
'SO': { nl: 'Somalië', en: 'Somalia' },
|
|
'SR': { nl: 'Suriname', en: 'Suriname' },
|
|
'SS': { nl: 'Zuid-Soedan', en: 'South Sudan' },
|
|
'ST': { nl: 'Sao Tomé en Principe', en: 'São Tomé and Príncipe' },
|
|
'SV': { nl: 'El Salvador', en: 'El Salvador' },
|
|
'SX': { nl: 'Sint Maarten', en: 'Sint Maarten' },
|
|
'SY': { nl: 'Syrië', en: 'Syria' },
|
|
'SZ': { nl: 'Eswatini', en: 'Eswatini' },
|
|
|
|
// T
|
|
'TC': { nl: 'Turks- en Caicoseilanden', en: 'Turks and Caicos Islands' },
|
|
'TD': { nl: 'Tsjaad', en: 'Chad' },
|
|
'TF': { nl: 'Franse Zuidelijke Gebieden', en: 'French Southern Territories' },
|
|
'TG': { nl: 'Togo', en: 'Togo' },
|
|
'TH': { nl: 'Thailand', en: 'Thailand' },
|
|
'TJ': { nl: 'Tadzjikistan', en: 'Tajikistan' },
|
|
'TK': { nl: 'Tokelau', en: 'Tokelau' },
|
|
'TL': { nl: 'Oost-Timor', en: 'Timor-Leste' },
|
|
'TM': { nl: 'Turkmenistan', en: 'Turkmenistan' },
|
|
'TN': { nl: 'Tunesië', en: 'Tunisia' },
|
|
'TO': { nl: 'Tonga', en: 'Tonga' },
|
|
'TR': { nl: 'Turkije', en: 'Turkey' },
|
|
'TT': { nl: 'Trinidad en Tobago', en: 'Trinidad and Tobago' },
|
|
'TV': { nl: 'Tuvalu', en: 'Tuvalu' },
|
|
'TW': { nl: 'Taiwan', en: 'Taiwan' },
|
|
'TZ': { nl: 'Tanzania', en: 'Tanzania' },
|
|
|
|
// U
|
|
'UA': { nl: 'Oekraïne', en: 'Ukraine' },
|
|
'UG': { nl: 'Oeganda', en: 'Uganda' },
|
|
'UM': { nl: 'Kleine afgelegen eilanden van de VS', en: 'U.S. Minor Outlying Islands' },
|
|
'US': { nl: 'Verenigde Staten', en: 'United States' },
|
|
'UY': { nl: 'Uruguay', en: 'Uruguay' },
|
|
'UZ': { nl: 'Oezbekistan', en: 'Uzbekistan' },
|
|
|
|
// V
|
|
'VA': { nl: 'Vaticaanstad', en: 'Vatican City' },
|
|
'VC': { nl: 'Saint Vincent en de Grenadines', en: 'Saint Vincent and the Grenadines' },
|
|
'VE': { nl: 'Venezuela', en: 'Venezuela' },
|
|
'VG': { nl: 'Britse Maagdeneilanden', en: 'British Virgin Islands' },
|
|
'VI': { nl: 'Amerikaanse Maagdeneilanden', en: 'U.S. Virgin Islands' },
|
|
'VN': { nl: 'Vietnam', en: 'Vietnam' },
|
|
'VU': { nl: 'Vanuatu', en: 'Vanuatu' },
|
|
|
|
// W
|
|
'WF': { nl: 'Wallis en Futuna', en: 'Wallis and Futuna' },
|
|
'WS': { nl: 'Samoa', en: 'Samoa' },
|
|
|
|
// X - User-assigned codes (for special entities)
|
|
'XK': { nl: 'Kosovo', en: 'Kosovo' },
|
|
|
|
// Y
|
|
'YE': { nl: 'Jemen', en: 'Yemen' },
|
|
'YT': { nl: 'Mayotte', en: 'Mayotte' },
|
|
|
|
// Z
|
|
'ZA': { nl: 'Zuid-Afrika', en: 'South Africa' },
|
|
'ZM': { nl: 'Zambia', en: 'Zambia' },
|
|
'ZW': { nl: 'Zimbabwe', en: 'Zimbabwe' },
|
|
};
|
|
|
|
/**
|
|
* Get the country name with flag emoji for display
|
|
* @param code ISO 3166-1 alpha-2 country code
|
|
* @param language 'nl' or 'en'
|
|
* @returns Formatted string like "🇳🇱 Nederland" or the code if not found
|
|
*/
|
|
export function getCountryLabel(code: string, language: 'nl' | 'en' = 'en'): string {
|
|
const upperCode = code.toUpperCase();
|
|
const country = COUNTRY_NAMES[upperCode];
|
|
const flag = getFlagEmoji(upperCode);
|
|
|
|
if (country) {
|
|
return `${flag} ${country[language]}`.trim();
|
|
}
|
|
|
|
// Fallback: return code with flag if possible
|
|
return flag ? `${flag} ${upperCode}` : upperCode;
|
|
}
|
|
|
|
/**
|
|
* Get just the country name without flag
|
|
* @param code ISO 3166-1 alpha-2 country code
|
|
* @param language 'nl' or 'en'
|
|
* @returns Country name or the code if not found
|
|
*/
|
|
export function getCountryName(code: string, language: 'nl' | 'en' = 'en'): string {
|
|
const upperCode = code.toUpperCase();
|
|
const country = COUNTRY_NAMES[upperCode];
|
|
return country ? country[language] : upperCode;
|
|
}
|
|
|
|
/**
|
|
* Check if a country code is valid (exists in our mapping)
|
|
* @param code ISO 3166-1 alpha-2 country code
|
|
* @returns boolean
|
|
*/
|
|
export function isValidCountryCode(code: string): boolean {
|
|
return code.toUpperCase() in COUNTRY_NAMES;
|
|
}
|