diff --git a/frontend/src/components/Map.vue b/frontend/src/components/Map.vue
index 1bc8f13..3e2e12e 100644
--- a/frontend/src/components/Map.vue
+++ b/frontend/src/components/Map.vue
@@ -48,6 +48,7 @@
         <div class="controls">
           <div class="form-container" v-if="showControls">
             <FilterForm :value="locationQuery"
+                        :countries="countries"
                         :devices="devices"
                         :disabled="loading"
                         :resolution="resolutionMeters"
@@ -110,6 +111,7 @@ import { useGeographic } from 'ol/proj';
 import type { Optional } from '../models/Types';
 import Api from '../mixins/Api.vue';
 import ConfirmDialog from '../elements/ConfirmDialog.vue';
+import Country from '../models/Country';
 import Dates from '../mixins/Dates.vue';
 import Feature from 'ol/Feature';
 import FilterButton from './filter/ToggleButton.vue';
@@ -118,11 +120,13 @@ import FloatingButton from '../elements/FloatingButton.vue';
 import GPSPoint from '../models/GPSPoint';
 import LocationQuery from '../models/LocationQuery';
 import LocationQueryMixin from '../mixins/LocationQuery.vue';
+import LocationStats from '../models/LocationStats';
 import MapSelectOverlay from './MapSelectOverlay.vue';
 import MapView from '../mixins/MapView.vue';
 import Paginate from '../mixins/Paginate.vue';
 import Points from '../mixins/Points.vue';
 import Routes from '../mixins/Routes.vue';
+import StatsRequest from '../models/StatsRequest';
 import Timeline from './Timeline.vue';
 import TimelineMetricsConfiguration from '../models/TimelineMetricsConfiguration';
 import URLQueryHandler from '../mixins/URLQueryHandler.vue';
@@ -155,6 +159,7 @@ export default {
 
   data() {
     return {
+      countries: [] as string[],
       devices: [] as UserDevice[],
       loading: false,
       map: null as Optional<Map>,
@@ -302,6 +307,21 @@ export default {
       await this.processQueryChange(this.locationQuery, oldQuery)
     },
 
+    async getCountries() {
+      return (
+        await this.getStats(
+          new StatsRequest({
+            userId: this.$root.user.id,
+            groupBy: ['country'],
+            order: 'desc',
+          })
+        )
+      )
+      .filter((record: LocationStats) => !!record.key.country)
+      .map((record: LocationStats) => Country.fromCode(record.key.country))
+      .filter((country: Optional<Country>) => !!country)
+    },
+
     createMap(): Map {
       this.pointsLayer = this.createPointsLayer(Object.values(this.mappedPoints) as Point[])
       this.routesLayer = this.createRoutesLayer(Object.values(this.mappedPoints) as Point[])
@@ -575,6 +595,7 @@ export default {
     ])
 
     this.map = this.createMap()
+    this.countries = await this.getCountries()
   },
 }
 </script>
@@ -608,6 +629,7 @@ main {
     position: absolute;
     bottom: 0;
     left: 0;
+    max-height: calc(100% + 4em);
     display: flex;
     flex-direction: column;
     padding: 0.5em;
@@ -618,6 +640,7 @@ main {
     }
 
     .form-container {
+      max-height: calc(100% - 8em);
       margin-bottom: 0.5em;
       animation: unroll 0.25s ease-out;
     }
diff --git a/frontend/src/components/filter/Form.vue b/frontend/src/components/filter/Form.vue
index d6394ad..8c0de79 100644
--- a/frontend/src/components/filter/Form.vue
+++ b/frontend/src/components/filter/Form.vue
@@ -1,97 +1,99 @@
 <template>
   <form class="filter-view" @submit.prevent.stop="handleSubmit">
-    <h2>Filter</h2>
+    <header>
+      <h2>Filter</h2>
+    </header>
 
-    <div class="date-range-toggle">
-      <input type="checkbox"
-             id="date-range-toggle"
-             name="date-range-toggle"
-             v-model="enableDateRange"
-             :disabled="disabled" />
-      <label for="date-range-toggle">Enable Date Range</label>
-    </div>
+    <main>
+      <div class="date-range-toggle">
+        <input type="checkbox"
+               id="date-range-toggle"
+               name="date-range-toggle"
+               v-model="enableDateRange"
+               :disabled="disabled" />&nbsp;
+        <label for="date-range-toggle">Set Date Range</label>
+      </div>
 
-    <div class="date-selectors" v-if="enableDateRange">
-      <div class="date-selector">
-        <label for="start-date">
-          <font-awesome-icon icon="fas fa-calendar-day" />
-          Start Date
-        </label>
-        <input type="datetime-local"
-               id="start-date"
-               name="start-date"
-               @input="newFilter.startDate = startPlusHours($event, 0)"
-               @change="newFilter.startDate = startPlusHours($event, 0)"
-               :value="toLocalString(newFilter.startDate)"
-               :disabled="disabled"
-               :max="maxDate" />
+      <div class="date-selectors" v-if="enableDateRange">
+        <div class="date-selector">
+          <label for="start-date">
+            <font-awesome-icon icon="fas fa-calendar-day" />
+            Start Date
+          </label>
+          <input type="datetime-local"
+                 id="start-date"
+                 name="start-date"
+                 @input="newFilter.startDate = startPlusHours($event, 0)"
+                 @change="newFilter.startDate = startPlusHours($event, 0)"
+                 :value="toLocalString(newFilter.startDate)"
+                 :disabled="disabled"
+                 :max="maxDate" />
 
-        <div class="footer">
-          <button type="button"
-                  @click="newFilter.startDate = startPlusDays(newFilter.startDate, -7)"
-                  :disabled="disabled || !newFilter.startDate">-1w</button>
-          <button type="button"
-                  @click="newFilter.startDate = startPlusDays(newFilter.startDate, -1)"
-                  :disabled="disabled || !newFilter.startDate">-1d</button>
-          <button type="button"
-                  @click="newFilter.startDate = startPlusHours(newFilter.startDate, -1)"
-                  :disabled="disabled || !newFilter.startDate">-1h</button>
-          <button type="button"
-                  @click="newFilter.startDate = startPlusDays(new Date(), 0)"
-                  :disabled="disabled || !newFilter.startDate">Now</button>
-          <button type="button"
-                  @click="newFilter.startDate = startPlusHours(newFilter.startDate, 1)"
-                  :disabled="disabled || !newFilter.startDate">+1h</button>
-          <button type="button"
-                  @click="newFilter.startDate = startPlusDays(newFilter.startDate, 1)"
-                  :disabled="disabled || !newFilter.startDate">+1d</button>
-          <button type="button"
-                  @click="newFilter.startDate = startPlusDays(newFilter.startDate, 7)"
-                  :disabled="disabled || !newFilter.startDate">+1w</button>
+          <div class="footer">
+            <button type="button"
+                    @click="newFilter.startDate = startPlusDays(newFilter.startDate, -7)"
+                    :disabled="disabled || !newFilter.startDate">-1w</button>
+            <button type="button"
+                    @click="newFilter.startDate = startPlusDays(newFilter.startDate, -1)"
+                    :disabled="disabled || !newFilter.startDate">-1d</button>
+            <button type="button"
+                    @click="newFilter.startDate = startPlusHours(newFilter.startDate, -1)"
+                    :disabled="disabled || !newFilter.startDate">-1h</button>
+            <button type="button"
+                    @click="newFilter.startDate = startPlusDays(new Date(), 0)"
+                    :disabled="disabled || !newFilter.startDate">Now</button>
+            <button type="button"
+                    @click="newFilter.startDate = startPlusHours(newFilter.startDate, 1)"
+                    :disabled="disabled || !newFilter.startDate">+1h</button>
+            <button type="button"
+                    @click="newFilter.startDate = startPlusDays(newFilter.startDate, 1)"
+                    :disabled="disabled || !newFilter.startDate">+1d</button>
+            <button type="button"
+                    @click="newFilter.startDate = startPlusDays(newFilter.startDate, 7)"
+                    :disabled="disabled || !newFilter.startDate">+1w</button>
+          </div>
+        </div>
+
+        <div class="date-selector">
+          <label for="end-date">
+            <font-awesome-icon icon="fas fa-calendar-day" />
+            End Date
+          </label>
+          <input type="datetime-local"
+                 id="end-date"
+                 name="end-date"
+                 @input="newFilter.endDate = endPlusHours($event, 0)"
+                 @change="newFilter.endDate = endPlusHours($event, 0)"
+                 :value="toLocalString(newFilter.endDate)"
+                 :disabled="disabled"
+                 :max="maxDate" />
+
+          <div class="footer">
+            <button type="button"
+                    @click="newFilter.endDate = endPlusDays(newFilter.endDate, -7)"
+                    :disabled="disabled || !newFilter.endDate">-1w</button>
+            <button type="button"
+                    @click="newFilter.endDate = endPlusDays(newFilter.endDate, -1)"
+                    :disabled="disabled || !newFilter.endDate">-1d</button>
+            <button type="button"
+                    @click="newFilter.endDate = endPlusHours(newFilter.endDate, -1)"
+                    :disabled="disabled || !newFilter.endDate">-1h</button>
+            <button type="button"
+                    @click="newFilter.endDate = endPlusDays(new Date(), 0)"
+                    :disabled="disabled || !newFilter.endDate">Now</button>
+            <button type="button"
+                    @click="newFilter.endDate = endPlusHours(newFilter.endDate, 1)"
+                    :disabled="disabled || !newFilter.endDate">+1h</button>
+            <button type="button"
+                    @click="newFilter.endDate = endPlusDays(newFilter.endDate, 1)"
+                    :disabled="disabled || !newFilter.endDate">+1d</button>
+            <button type="button"
+                    @click="newFilter.endDate = endPlusDays(newFilter.endDate, 7)"
+                    :disabled="disabled || !newFilter.endDate">+1w</button>
+          </div>
         </div>
       </div>
 
-      <div class="date-selector">
-        <label for="end-date">
-          <font-awesome-icon icon="fas fa-calendar-day" />
-          End Date
-        </label>
-        <input type="datetime-local"
-               id="end-date"
-               name="end-date"
-               @input="newFilter.endDate = endPlusHours($event, 0)"
-               @change="newFilter.endDate = endPlusHours($event, 0)"
-               :value="toLocalString(newFilter.endDate)"
-               :disabled="disabled"
-               :max="maxDate" />
-
-        <div class="footer">
-          <button type="button"
-                  @click="newFilter.endDate = endPlusDays(newFilter.endDate, -7)"
-                  :disabled="disabled || !newFilter.endDate">-1w</button>
-          <button type="button"
-                  @click="newFilter.endDate = endPlusDays(newFilter.endDate, -1)"
-                  :disabled="disabled || !newFilter.endDate">-1d</button>
-          <button type="button"
-                  @click="newFilter.endDate = endPlusHours(newFilter.endDate, -1)"
-                  :disabled="disabled || !newFilter.endDate">-1h</button>
-          <button type="button"
-                  @click="newFilter.endDate = endPlusDays(new Date(), 0)"
-                  :disabled="disabled || !newFilter.endDate">Now</button>
-          <button type="button"
-                  @click="newFilter.endDate = endPlusHours(newFilter.endDate, 1)"
-                  :disabled="disabled || !newFilter.endDate">+1h</button>
-          <button type="button"
-                  @click="newFilter.endDate = endPlusDays(newFilter.endDate, 1)"
-                  :disabled="disabled || !newFilter.endDate">+1d</button>
-          <button type="button"
-                  @click="newFilter.endDate = endPlusDays(newFilter.endDate, 7)"
-                  :disabled="disabled || !newFilter.endDate">+1w</button>
-        </div>
-      </div>
-    </div>
-
-    <div class="form-row">
       <div class="container limit-container">
         <label for="limit">
           <font-awesome-icon icon="fas fa-list-ol" />
@@ -120,9 +122,7 @@
           <option value="desc">Newest points first</option>
         </select>
       </div>
-    </div>
 
-    <div class="form-row">
       <div class="container resolution-container">
         <label for="resolution">
           <p class="title">
@@ -158,19 +158,105 @@
           <option v-for="device in devices" :key="device.id" :value="device.id">{{ device.name }}</option>
         </select>
       </div>
-    </div>
 
-    <div class="footer">
+      <div class="container country-container">
+        <label for="country">
+          <p class="title">
+            <font-awesome-icon icon="fas fa-globe" />
+            Country
+          </p>
+        </label>
+
+        <Autocomplete
+          id="country"
+          name="country"
+          placeholder="Filter by country"
+          allow-only-values
+          v-model="newFilter.country"
+          :values="autocompleteCountries"
+          :disabled="disabled"
+          @input="newFilter.country = $event" />
+      </div>
+
+      <div class="container locality-container">
+        <label for="locality">
+          <p class="title">
+            <font-awesome-icon icon="fas fa-map-marker-alt" />
+            Locality
+          </p>
+        </label>
+
+        <input type="text"
+               id="locality"
+               name="locality"
+               placeholder="Filter by locality"
+               v-model="newFilter.locality"
+               :disabled="disabled" />
+      </div>
+
+      <div class="container address-container">
+        <label for="address">
+          <p class="title">
+            <font-awesome-icon icon="fas fa-home" />
+            Address
+          </p>
+        </label>
+
+        <input type="text"
+               id="address"
+               name="address"
+               placeholder="Filter by address"
+               v-model="newFilter.address"
+               :disabled="disabled" />
+      </div>
+
+      <div class="container postal-code-container col-s-12">
+        <label for="postal-code">
+          <p class="title">
+            <font-awesome-icon icon="fas fa-mail-bulk" />
+            Postal Code
+          </p>
+        </label>
+
+        <input type="text"
+               id="postal-code"
+               name="postal-code"
+               placeholder="Filter by postal code"
+               v-model="newFilter.postalCode"
+               :disabled="disabled" />
+      </div>
+
+      <div class="container description-container">
+        <label for="description">
+          <p class="title">
+          <font-awesome-icon icon="fas fa-comment" />
+            Description
+          </p>
+        </label>
+
+        <input type="text"
+               id="description"
+               name="description"
+               placeholder="Filter by description"
+               v-model="newFilter.description"
+               :disabled="disabled" />
+      </div>
+    </main>
+
+    <footer>
       <button type="submit" :disabled="disabled || !changed">
         <font-awesome-icon icon="fas fa-check" />&nbsp;Apply
       </button>
-    </div>
+    </footer>
   </form>
 </template>
 
 <script lang="ts">
 import _ from 'lodash'
 
+import Autocomplete from '../../elements/Autocomplete.vue'
+import AutocompleteValue from '../../models/AutocompleteValue'
+import Country from '../../models/Country'
 import LocationQuery from '../../models/LocationQuery'
 import LocationQueryMixin from '../../mixins/LocationQuery.vue'
 import UserDevice from '../../models/UserDevice'
@@ -182,8 +268,16 @@ export default {
     'set-resolution',
   ],
 
+  components: {
+    Autocomplete,
+  },
+
   props: {
     value: LocationQuery,
+    countries: {
+      type: Array as () => Country[],
+      default: () => [],
+    },
     devices: {
       type: Array as () => UserDevice[],
       default: () => [],
@@ -199,6 +293,13 @@ export default {
   },
 
   computed: {
+    autocompleteCountries(): AutocompleteValue[] {
+      return this.countries.map((country: Country) => ({
+        value: country.code,
+        label: `${country.flag} ${country.name}`,
+        data: country,
+      }))
+    },
     maxDate() {
       return this.toLocalString(this.endPlusHours(new Date(), 0))
     }
@@ -340,26 +441,95 @@ export default {
 <style lang="scss" scoped>
 @use "@/styles/common.scss" as *;
 
+$header-height: 2.5em;
+$footer-height: 3.5em;
+
 .filter-view {
   height: 100%;
   background: var(--color-background);
   display: flex;
   flex-direction: column;
   align-items: center;
+  padding: 1em 0;
   justify-content: center;
-  padding: 1em;
   border: 1px solid var(--color-border);
   border-radius: 0.5em;
   margin-bottom: 0.25em;
   box-shadow: 0 0 0.5em rgba(0, 0, 0, 0.66);
 
-  @include media(mobile) {
+  @include until(desktop) {
     width: calc(100vw - 2em);
   }
 
-  @include media(tablet) {
+  @include from(desktop) {
+    width: 50em;
+  }
+
+  header {
     width: 100%;
-    min-width: 45em;
+    height: $header-height;
+    display: flex;
+    justify-content: center;
+  }
+
+  footer {
+    width: 100%;
+    height: $footer-height;
+    display: flex;
+    justify-content: center;
+
+    button {
+      height: 2.5em;
+    }
+  }
+
+  main {
+    height: calc(100% - $header-height - $footer-height - 5em);
+    max-height: 25em;
+    overflow-y: auto;
+    overflow-x: hidden;
+    display: flex;
+    padding: 1em;
+
+    @include until(tablet) {
+      flex-direction: column;
+      flex-wrap: nowrap;
+    }
+
+    @include from(tablet) {
+      flex-direction: row;
+      flex-wrap: wrap;
+    }
+
+    .container {
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      padding: 0.5em 1em;
+      flex-direction: column;
+
+      @include until(tablet) {
+        width: 100%;
+      }
+
+      @include from(tablet) {
+        width: 50%;
+      }
+
+      label {
+        margin-bottom: 0.25em;
+        @include until(tablet) {
+          margin-top: 0.75em;
+        }
+      }
+
+      input {
+        width: 100%;
+        @include until(tablet) {
+          margin-bottom: 0.5em;
+        }
+      }
+    }
   }
 
   .date-selectors {
@@ -403,40 +573,16 @@ export default {
   }
 
   .date-range-toggle {
+    width: 100%;
     display: flex;
     align-items: center;
-    margin: 0.5em 0 -0.5em 0;
+    justify-content: center;
 
     input {
       margin-right: 0.25em;
     }
   }
 
-  .form-row {
-    width: 100%;
-    display: flex;
-    flex-direction: row;
-    justify-content: space-between;
-    align-items: center;
-    margin: 0.5em;
-
-    .container {
-      width: 100%;
-      display: flex;
-      flex-direction: column;
-      align-items: center;
-      padding: 0 1em;
-    }
-
-    label {
-      margin-bottom: 0.25em;
-    }
-
-    input {
-      width: 100%;
-    }
-  }
-
   .limit-container {
     display: flex;
     flex-direction: column;
@@ -444,11 +590,6 @@ export default {
   }
 
   .resolution-container {
-    display: flex;
-    flex-direction: column;
-    align-items: center;
-    margin: 0.5em;
-
     label {
       margin-bottom: 0.25em;
       display: flex;
diff --git a/frontend/src/elements/Autocomplete.vue b/frontend/src/elements/Autocomplete.vue
new file mode 100644
index 0000000..a2df131
--- /dev/null
+++ b/frontend/src/elements/Autocomplete.vue
@@ -0,0 +1,179 @@
+<template>
+  <div class="autocomplete">
+    <div class="input">
+      <input
+        type="text"
+        :id="id"
+        :name="name"
+        :placeholder="placeholder"
+        v-model="newValue"
+        @focus="onFocus"
+        @blur="onBlur"
+        ref="input"
+      />
+    </div>
+    <div class="values" v-if="showValues" @click.stop>
+      <ul>
+        <li v-for="value in filteredValues"
+            :key="value.value"
+            @click.stop="onItemClick(value)">
+          {{ value.label }}
+        </li>
+      </ul>
+    </div>
+  </div>
+</template>
+
+<script lang="ts">
+import AutocompleteValue from '../models/AutocompleteValue';
+
+export default {
+  emits: ['input'],
+
+  props: {
+    id: {
+      type: String,
+      default: '',
+    },
+
+    name: {
+      type: String,
+      default: '',
+    },
+
+    value: {
+      type: String,
+      default: '',
+    },
+
+    values: {
+      type: Array as () => AutocompleteValue[],
+      default: () => [],
+    },
+
+    allowOnlyValues: {
+      type: Boolean,
+      default: false,
+    },
+
+    placeholder: {
+      type: String,
+      default: 'Search...',
+    },
+  },
+
+  data() {
+    return {
+      newValue: '' + this.value,
+      showValues: false,
+    };
+  },
+
+  computed: {
+    filteredValues() {
+      if (!this.newValue?.length) {
+        return this.values;
+      }
+
+      let matches = this.values.filter((value: AutocompleteValue) =>
+        value.value.toLowerCase() === this.newValue.toLowerCase()
+      ) as AutocompleteValue[];
+
+      if (!matches.length) {
+        matches = this.values.filter((value: AutocompleteValue) =>
+          value.label.toLowerCase().includes(this.newValue.toLowerCase())
+        ) as AutocompleteValue[];
+      }
+
+      return matches;
+    },
+
+    indexedValues() {
+      return Object.fromEntries(
+        this.values.map((value: AutocompleteValue) => [
+          value.value,
+          value,
+        ])
+      );
+    },
+  },
+
+  methods: {
+    onFocus() {
+      this.showValues = true;
+    },
+
+    onBlur() {
+      setTimeout(() => {
+        this.showValues = false;
+        this.emitInput();
+      }, 500);
+    },
+
+    onItemClick(value: AutocompleteValue) {
+      this.newValue = value.value;
+      this.showValues = false;
+      this.emitInput();
+    },
+
+    emitInput() {
+      this.$emit(
+        'input',
+        this.allowOnlyValues
+          ? this.indexedValues[this.newValue]?.value
+          : this.newValue
+      )
+    }
+  },
+
+  watch: {
+    value(newValue: string) {
+      this.newValue = newValue;
+    },
+
+    newValue() {
+      this.emitInput();
+    },
+  },
+}
+</script>
+
+<style lang="scss" scoped>
+.autocomplete {
+  width: 100%;
+  position: relative;
+
+  .input {
+    input {
+      width: 100%;
+    }
+  }
+
+  .values {
+    position: absolute;
+    top: 100%;
+    left: 0;
+    right: 0;
+    max-height: 20em;
+    overflow: auto;
+    background-color: var(--color-background);
+    z-index: 10;
+    box-shadow: 0 0 0.5rem 0 rgba(0, 0, 0, 0.5);
+
+    ul {
+      list-style-type: none;
+      margin: 0;
+      padding: 0;
+
+      li {
+        padding: 0.8em;
+        cursor: pointer;
+
+        &:hover {
+          background-color: var(--color-accent-bg);
+        }
+      }
+    }
+  }
+}
+</style>
diff --git a/frontend/src/mixins/LocationQuery.vue b/frontend/src/mixins/LocationQuery.vue
index 541212d..ef5ed5f 100644
--- a/frontend/src/mixins/LocationQuery.vue
+++ b/frontend/src/mixins/LocationQuery.vue
@@ -14,18 +14,22 @@ export default {
       newValue?: LocationQuery,
       oldValue?: LocationQuery,
     }): boolean {
-      return !_.isEqual(
-        {
-          ...(oldValue || {}),
-          startDate: this.normalizeDate(oldValue?.startDate),
-          endDate: this.normalizeDate(oldValue?.endDate),
-        },
-        {
-          ...(newValue || {}),
-          startDate: this.normalizeDate(newValue?.startDate),
-          endDate: this.normalizeDate(newValue?.endDate),
-        }
+      const values = [oldValue, newValue].map((value) =>
+        Object.entries(value || {}).reduce((acc, [key, val]) => {
+          // Replace all undefined values with null to avoid the comparison from breaking
+          // when an attribute is not set and it's undefined on one side and null on the other
+          acc[key] = val === undefined ? null : val
+
+          // Normalize dates to avoid issues with different date formats
+          if (key === 'startDate' || key === 'endDate') {
+            acc[key] = this.normalizeDate(val)
+          }
+
+          return acc
+        }, {} as Record<string, any>)
       )
+
+      return !_.isEqual(values[0], values[1])
     },
   }
 }
diff --git a/frontend/src/models/AutocompleteValue.ts b/frontend/src/models/AutocompleteValue.ts
new file mode 100644
index 0000000..4580677
--- /dev/null
+++ b/frontend/src/models/AutocompleteValue.ts
@@ -0,0 +1,21 @@
+class AutocompleteValue {
+  value: string;
+  label: string;
+  data?: any | null = undefined;
+
+  constructor(record: {
+    value: string;
+    label: string;
+    data?: any | null;
+  }) {
+    this.value = record.value;
+    this.label = record.label;
+    this.data = record.data;
+  }
+
+  toString(): string {
+    return this.label;
+  }
+}
+
+export default AutocompleteValue;
diff --git a/frontend/src/models/Country.ts b/frontend/src/models/Country.ts
new file mode 100644
index 0000000..a6fcec4
--- /dev/null
+++ b/frontend/src/models/Country.ts
@@ -0,0 +1,36 @@
+import type { TCountryCode } from 'countries-list';
+import { getCountryData, getEmojiFlag } from 'countries-list';
+
+class Country {
+  name: string;
+  code: string;
+  continent: string;
+  flag: string;
+
+  constructor(data: {
+    name: string;
+    code: string;
+    continent: string;
+    flag: string;
+  }) {
+    this.name = data.name;
+    this.code = data.code;
+    this.continent = data.continent;
+    this.flag = data.flag;
+  }
+
+  public static fromCode(code: string | TCountryCode): Country | null {
+    const cc = code.toUpperCase() as TCountryCode;
+    const countryData = getCountryData(cc);
+    if (!countryData) return null;
+
+    return new Country({
+      name: countryData.name,
+      code: code,
+      continent: countryData.continent,
+      flag: getEmojiFlag(cc),
+    });
+  }
+}
+
+export default Country;
diff --git a/frontend/src/styles/layout.scss b/frontend/src/styles/layout.scss
index 6b2f213..6c024fd 100644
--- a/frontend/src/styles/layout.scss
+++ b/frontend/src/styles/layout.scss
@@ -16,6 +16,23 @@ $breakpoints: (
   }
 }
 
+// Generate col-<breakpoint>-<number> classes
+$screen-size-to-breakpoint: (
+  s:mobile,
+  m:tablet,
+  l:desktop
+);
+
+@for $i from 1 through 12 {
+  @each $screen-size, $breakpoint in $screen-size-to-breakpoint {
+    .col-#{$screen-size}-#{$i} {
+      @media (min-width: map.get($breakpoints, $breakpoint)) {
+        width: (100% / 12) * $i;
+      }
+    }
+  }
+}
+
 .hidden {
   display: none !important;
 }
diff --git a/src/requests/LocationRequest.ts b/src/requests/LocationRequest.ts
index 44b3a90..a1bb7c8 100644
--- a/src/requests/LocationRequest.ts
+++ b/src/requests/LocationRequest.ts
@@ -58,7 +58,7 @@ class LocationRequest {
     this.initNumber('maxLatitude', req, parseFloat);
     this.initNumber('minLongitude', req, parseFloat);
     this.initNumber('maxLongitude', req, parseFloat);
-    this.country = req.country;
+    this.country = req.country?.toLowerCase();
     this.locality = req.locality;
     this.postalCode = req.postalCode;
     this.description = req.description;