wip: Extract country list generation into utility
Some checks failed
Build / build (pull_request) Successful in 1m8s
Check formatting / check-formatting (pull_request) Failing after 20s

This commit is contained in:
Magnus Leßmann (@Mark.TwoFive) 2025-07-12 12:22:59 +02:00
parent 46f31de837
commit e7ada4b47d
Signed by: Mark.TwoFive
GPG key ID: 58204042FE30B10C
2 changed files with 52 additions and 37 deletions

View file

@ -1,15 +1,7 @@
<script setup lang="ts">
import { ref, useId, useTemplateRef } from "vue";
import iso3166 from "iso-3166-1";
import CountryListItem from "./CountryListItem.vue";
// Define interface for a country object
interface Country {
country: string;
alpha2: string;
alpha3: string;
numeric: string;
}
import { Country, getAvailableCountries } from "../utils/countries";
const formModel = ref(false);
const formRef = useTemplateRef("form");
@ -29,38 +21,11 @@ const countryName = ref("");
const state = ref("");
const locality = ref("");
// Get user's locale from browser
const userLocale = ref<string>(navigator.language || navigator.languages?.[0] || 'en-US');
const userCountryCode = ref<string>(userLocale.value.split('-')[1]?.toUpperCase() || '');
const userCountry = ref<Country | undefined>(undefined);
// Countries data for autocomplete
const allCountries = iso3166.all() as Country[];
const countries = ref<(Country | { divider: boolean; header: string })[]>([]);
// Prepare countries list with user's country at the top
function prepareCountriesList() {
// Find user's country based on browser locale
userCountry.value = allCountries.find(c => c.alpha2 === userCountryCode.value);
// Create the countries list
countries.value = [];
// Add user's country at the top if found
if (userCountry.value) {
countries.value.push(userCountry.value);
countries.value.push({ divider: true, header: 'All Countries' });
// Add all countries except the user's country to avoid duplicates
countries.value.push(...allCountries.filter(c => c.alpha2 !== userCountryCode.value));
} else {
// Add all countries if user's country not found
countries.value.push(...allCountries);
}
}
// Initialize countries list
prepareCountriesList();
countries.value = getAvailableCountries();
// Certificate settings
const keyLength = ref(4096);

View file

@ -0,0 +1,50 @@
import iso3166 from "iso-3166-1";
/**
* While the iso-3166-1 library does provide a country interface, said interface is not exported.
* We re-define it to make it usable for our purposes.
*/
export type Country = ReturnType<typeof iso3166.all>[number];
// Define interface for divider/header items
export interface CountryDivider {
divider: boolean;
header: string;
}
// Define a type that can be either a Country or a Divider
export type CountryListItemType = Country | CountryDivider;
// Get all countries from iso3166
export const allCountries = iso3166.all() as Country[];
// Get user's locale from browser (module-scoped)
export const userLocale = navigator.language || navigator.languages?.[0] || 'en-US';
export const userCountryCode = userLocale.split('-')[1]?.toUpperCase() || '';
// Find user's country based on browser locale (module-scoped)
export const userCountry = allCountries.find(c => c.alpha2 === userCountryCode);
/**
* Prepares a list of countries with the user's country at the top (if available)
* @returns An array of countries and dividers for use in selection components
*/
export function getAvailableCountries(): CountryListItemType[] {
// Create the country list
const countries: CountryListItemType[] = [];
// Add user's country at the top if found
if (userCountry) {
countries.push(userCountry);
countries.push({ divider: true, header: 'All Countries' });
// Add all countries except the user's country to avoid duplicates
countries.push(...allCountries.filter(c => c.alpha2 !== userCountryCode));
} else {
// Add all countries if user's country not found
countries.push(...allCountries);
}
return countries;
}