diff --git a/README.md b/README.md
index b5b2950..8273234 100644
--- a/README.md
+++ b/README.md
@@ -36,3 +36,16 @@ npm run build
You can preview the production build with `npm run preview`.
> To deploy your app, you may need to install an [adapter](https://svelte.dev/docs/kit/adapters) for your target environment.
+
+```sql
+select count(*) from cities where cities.country_id IS NOT NULL;
+select distinct country from cities c where country_id IS NULL;
+SELECT DISTINCT c.id, c.name, c.emoji
+FROM countries c
+INNER JOIN cities ci ON c.id = ci.country_id ORDER BY c.name;
+select count(*) from cities where capital in ('capital', 'admin') or (population >= 100000 and population != '');
+```
+
+```
+
+```
diff --git a/bun.lock b/bun.lock
index 2838db6..539f339 100644
--- a/bun.lock
+++ b/bun.lock
@@ -12,11 +12,13 @@
"@tailwindcss/forms": "^0.5.9",
"@tailwindcss/typography": "^0.5.15",
"@tailwindcss/vite": "^4.0.0",
+ "@types/fuzzy-search": "^2.1.5",
"bun-types": "^1.2.4",
"daisyui": "^5.0.0",
"eslint": "^9.18.0",
"eslint-config-prettier": "^10.0.1",
"eslint-plugin-svelte": "^3.0.0",
+ "fuzzy-search": "^3.2.1",
"globals": "^16.0.0",
"prettier": "^3.4.2",
"prettier-plugin-svelte": "^3.3.3",
@@ -217,6 +219,8 @@
"@types/estree": ["@types/estree@1.0.6", "", {}, "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw=="],
+ "@types/fuzzy-search": ["@types/fuzzy-search@2.1.5", "", {}, "sha512-Yw8OsjhVKbKw83LMDOZ9RXc+N+um48DmZYMrz7QChpHkQuygsc5O40oCL7SfvWgpaaviCx2TbNXYUBwhMtBH5w=="],
+
"@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="],
"@types/node": ["@types/node@22.13.8", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-G3EfaZS+iOGYWLLRCEAXdWK9my08oHNZ+FHluRiggIYJPOXzhOiDgpVCUHaUvyIC5/fj7C/p637jdzC666AOKQ=="],
@@ -359,6 +363,8 @@
"function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="],
+ "fuzzy-search": ["fuzzy-search@3.2.1", "", {}, "sha512-vAcPiyomt1ioKAsAL2uxSABHJ4Ju/e4UeDM+g1OlR0vV4YhLGMNsdLNvZTpEDY4JCSt0E4hASCNM5t2ETtsbyg=="],
+
"glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="],
"globals": ["globals@16.0.0", "", {}, "sha512-iInW14XItCXET01CQFqudPOWP2jYMl7T+QRQT+UNcR/iQncN/F0UNpgd76iFkBPgNQb4+X3LV9tLJYzwh+Gl3A=="],
diff --git a/package.json b/package.json
index 33989bf..137d8f8 100644
--- a/package.json
+++ b/package.json
@@ -10,11 +10,13 @@
"@tailwindcss/forms": "^0.5.9",
"@tailwindcss/typography": "^0.5.15",
"@tailwindcss/vite": "^4.0.0",
+ "@types/fuzzy-search": "^2.1.5",
"bun-types": "^1.2.4",
"daisyui": "^5.0.0",
"eslint": "^9.18.0",
"eslint-config-prettier": "^10.0.1",
"eslint-plugin-svelte": "^3.0.0",
+ "fuzzy-search": "^3.2.1",
"globals": "^16.0.0",
"prettier": "^3.4.2",
"prettier-plugin-svelte": "^3.3.3",
diff --git a/rest.http b/rest.http
new file mode 100644
index 0000000..5045597
--- /dev/null
+++ b/rest.http
@@ -0,0 +1,5 @@
+@PORT=3000
+@HOSTNAME=localhost
+@HOST={{HOSTNAME}}:{{PORT}}
+
+GET http://{{HOST}}/api
diff --git a/src/lib/components/ComboBox.svelte b/src/lib/components/ComboBox.svelte
new file mode 100644
index 0000000..3b8d83a
--- /dev/null
+++ b/src/lib/components/ComboBox.svelte
@@ -0,0 +1,123 @@
+
+
+
+
+ {#if focused}
+
+ {#each filteredOptions as option (option.id)}
+ -
+
+
+ {/each}
+
+ {/if}
+
+
+
diff --git a/src/lib/components/icons/ChevronDown.svelte b/src/lib/components/icons/ChevronDown.svelte
new file mode 100644
index 0000000..5ade786
--- /dev/null
+++ b/src/lib/components/icons/ChevronDown.svelte
@@ -0,0 +1,10 @@
+
diff --git a/src/lib/components/icons/ChevronUp.svelte b/src/lib/components/icons/ChevronUp.svelte
new file mode 100644
index 0000000..6d61d00
--- /dev/null
+++ b/src/lib/components/icons/ChevronUp.svelte
@@ -0,0 +1,10 @@
+
diff --git a/src/lib/components/icons/XMark.svelte b/src/lib/components/icons/XMark.svelte
new file mode 100644
index 0000000..42de9af
--- /dev/null
+++ b/src/lib/components/icons/XMark.svelte
@@ -0,0 +1,10 @@
+
diff --git a/src/lib/db/queries.ts b/src/lib/db/queries.ts
index 8080769..0881fe9 100644
--- a/src/lib/db/queries.ts
+++ b/src/lib/db/queries.ts
@@ -1,3 +1,13 @@
import db from ".";
-export const allCountries = db.prepare('SELECT id, name, native, emoji FROM countries')
+// export const allCountries = db.query('SELECT id, name, native, emoji FROM countries');
+export const allCountries = db.query(`
+ SELECT id, name, native, emoji
+ FROM countries
+ WHERE id IN(
+ SELECT DISTINCT country_id
+ FROM cities
+ WHERE capital IN('capital', 'admin') OR(population >= 100000 AND population IS NOT NULL)
+ )
+`);
+export const allCities = db.query("SELECT id, city, country_id FROM cities WHERE capital IN ('capital', 'admin') OR (population >= 100000 AND population != '')");
diff --git a/src/lib/types.ts b/src/lib/types.ts
index 0b5e943..ca02240 100644
--- a/src/lib/types.ts
+++ b/src/lib/types.ts
@@ -1,6 +1,18 @@
-export type CountryBasics = {
+export type CountryBasic = {
id: number;
name: string;
native: string;
emoji: string;
+};
+
+export type CityBasic = {
+ id: number;
+ city: string;
+ country_id: number;
+};
+
+export type ComboOption = {
+ id: number;
+ name: string;
+ emoji?: string;
}
diff --git a/src/routes/+page.server.ts b/src/routes/+page.server.ts
index 7a8e1a7..1a27252 100644
--- a/src/routes/+page.server.ts
+++ b/src/routes/+page.server.ts
@@ -1,20 +1,20 @@
-import { allCountries } from "$lib/db/queries";
-import type { CountryBasics } from "$lib/types";
-import type { PageServerData } from "./$types";
+import { allCities, allCountries } from '$lib/db/queries';
+import type { CityBasic, CountryBasic } from '$lib/types';
+import type { PageServerLoad } from './$types';
-
-export const load: PageServerData = () => {
- try {
- const countries = allCountries.all() as CountryBasics[]
- return {
- countries
- }
-
- } catch (error) {
- console.log(error);
- return {
- countries: [] as CountryBasics[]
- }
-
- }
-}
+export const load: PageServerLoad = () => {
+ try {
+ const countries = allCountries.all() as CountryBasic[];
+ const cities = allCities.all() as CityBasic[];
+ return {
+ countries,
+ cities
+ };
+ } catch (error) {
+ console.log(error);
+ return {
+ countries: [],
+ cities: []
+ };
+ }
+};
diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte
index afc458d..2d464e6 100644
--- a/src/routes/+page.svelte
+++ b/src/routes/+page.svelte
@@ -1,25 +1,26 @@
@@ -29,66 +30,27 @@
with ease! 🎉✨
+
+ setCountryCities(null)} />
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {#each data.countries as country, idx (country.id)}
- - {country.name} - {country.emoji}
- {/each}
-
-
+
+
+
+ {#each filteredCities as city (city.id)}
+ - {city.city}
+ {/each}
+
+
+
diff --git a/src/server/meteoService.ts b/src/server/meteoService.ts
new file mode 100644
index 0000000..e69de29