mirror of
https://github.com/seanmorley15/AdventureLog.git
synced 2025-08-09 15:15:18 +02:00
feat: show country name in current locale if translation exists
This commit is contained in:
parent
3e0639e6f7
commit
bc1f36bf6c
10 changed files with 106 additions and 10 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,3 +1,4 @@
|
||||||
# Ignore everything in the .venv folder
|
# Ignore everything in the .venv folder
|
||||||
.venv/
|
.venv/
|
||||||
.vscode/settings.json
|
.vscode/settings.json
|
||||||
|
.pnpm-store/
|
13
.vscode/settings.json
vendored
13
.vscode/settings.json
vendored
|
@ -25,5 +25,16 @@
|
||||||
"backend/server/backend/lib/python3.12/site-packages/django/contrib/sites/locale",
|
"backend/server/backend/lib/python3.12/site-packages/django/contrib/sites/locale",
|
||||||
"backend/server/backend/lib/python3.12/site-packages/rest_framework/templates/rest_framework/docs/langs"
|
"backend/server/backend/lib/python3.12/site-packages/rest_framework/templates/rest_framework/docs/langs"
|
||||||
],
|
],
|
||||||
"i18n-ally.keystyle": "nested"
|
"i18n-ally.keystyle": "nested",
|
||||||
|
"sqltools.connections": [
|
||||||
|
{
|
||||||
|
"previewLimit": 50,
|
||||||
|
"server": "localhost",
|
||||||
|
"port": 5432,
|
||||||
|
"driver": "PostgreSQL",
|
||||||
|
"name": "default",
|
||||||
|
"database": "adventurelog",
|
||||||
|
"username": "admin"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
35
Makefile
Normal file
35
Makefile
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
# Makefile for AdventureLog project
|
||||||
|
DOCKER_COMPOSE = docker compose -f docker-compose.yml
|
||||||
|
DOCKER_COMPOSE_TRAEFIK = docker compose -f docker-compose-traefik.yaml
|
||||||
|
|
||||||
|
.PHONY: help
|
||||||
|
help: ## Display this help
|
||||||
|
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n\nTargets:\n"} /^[a-zA-Z_-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 }' $(MAKEFILE_LIST)
|
||||||
|
|
||||||
|
all: dev ## Build all services (alias for dev)
|
||||||
|
|
||||||
|
download-countries: ## Download countries
|
||||||
|
@cd backend/server && mkdir -p media
|
||||||
|
@cd backend/server && python manage.py download-countries --force
|
||||||
|
|
||||||
|
dev-db: dev ## Start development database
|
||||||
|
# If adventurelog-development container not exists, create it
|
||||||
|
@docker ps -q -f name=adventurelog-development || docker run --name adventurelog-development -e POSTGRES_USER=admin -e POSTGRES_PASSWORD=admin -e POSTGRES_DB=adventurelog -p 5432:5432 -d postgis/postgis:15-3.3
|
||||||
|
@echo "Please update the backend/.env file with the correct database credentials (uncomment the lines starting with # PGHOST, PGDATABASE, PGUSER, PGPASSWORD)"
|
||||||
|
|
||||||
|
web: dev ## Start web service
|
||||||
|
@cd frontend && pnpm dev
|
||||||
|
|
||||||
|
django: dev ## Start Django server
|
||||||
|
@cd backend/server && python manage.py migrate
|
||||||
|
@cd frontend && pnpm django
|
||||||
|
|
||||||
|
dev: download-countries ## Setup Development Environment
|
||||||
|
@[ -f backend/server/.env ] || cp backend/server/.env.example backend/server/.env
|
||||||
|
@[ -f frontend/.env ] || cp frontend/.env.example frontend/.env
|
||||||
|
@cd frontend && pnpm install
|
||||||
|
@[ -d .venv ] || python -m venv .venv
|
||||||
|
@source .venv/bin/activate
|
||||||
|
@pip install -r backend/server/requirements.txt
|
||||||
|
|
||||||
|
|
|
@ -51,8 +51,6 @@ else:
|
||||||
EOF
|
EOF
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
# Sync the countries and world travel regions
|
|
||||||
# Sync the countries and world travel regions
|
# Sync the countries and world travel regions
|
||||||
python manage.py download-countries
|
python manage.py download-countries
|
||||||
if [ $? -eq 137 ]; then
|
if [ $? -eq 137 ]; then
|
||||||
|
|
|
@ -92,6 +92,7 @@ class Command(BaseCommand):
|
||||||
country_capital = country['capital']
|
country_capital = country['capital']
|
||||||
longitude = round(float(country['longitude']), 6) if country['longitude'] else None
|
longitude = round(float(country['longitude']), 6) if country['longitude'] else None
|
||||||
latitude = round(float(country['latitude']), 6) if country['latitude'] else None
|
latitude = round(float(country['latitude']), 6) if country['latitude'] else None
|
||||||
|
translations = country['translations']
|
||||||
|
|
||||||
processed_country_codes.add(country_code)
|
processed_country_codes.add(country_code)
|
||||||
|
|
||||||
|
@ -102,6 +103,7 @@ class Command(BaseCommand):
|
||||||
country_obj.capital = country_capital
|
country_obj.capital = country_capital
|
||||||
country_obj.longitude = longitude
|
country_obj.longitude = longitude
|
||||||
country_obj.latitude = latitude
|
country_obj.latitude = latitude
|
||||||
|
country_obj.translations = translations
|
||||||
countries_to_update.append(country_obj)
|
countries_to_update.append(country_obj)
|
||||||
else:
|
else:
|
||||||
country_obj = Country(
|
country_obj = Country(
|
||||||
|
@ -110,7 +112,8 @@ class Command(BaseCommand):
|
||||||
subregion=country_subregion,
|
subregion=country_subregion,
|
||||||
capital=country_capital,
|
capital=country_capital,
|
||||||
longitude=longitude,
|
longitude=longitude,
|
||||||
latitude=latitude
|
latitude=latitude,
|
||||||
|
translations=translations
|
||||||
)
|
)
|
||||||
countries_to_create.append(country_obj)
|
countries_to_create.append(country_obj)
|
||||||
|
|
||||||
|
@ -213,7 +216,7 @@ class Command(BaseCommand):
|
||||||
batch = countries_to_update[i:i + batch_size]
|
batch = countries_to_update[i:i + batch_size]
|
||||||
for i in tqdm(range(0, len(countries_to_update), batch_size), desc="Updating countries"):
|
for i in tqdm(range(0, len(countries_to_update), batch_size), desc="Updating countries"):
|
||||||
batch = countries_to_update[i:i + batch_size]
|
batch = countries_to_update[i:i + batch_size]
|
||||||
Country.objects.bulk_update(batch, ['name', 'subregion', 'capital', 'longitude', 'latitude'])
|
Country.objects.bulk_update(batch, ['name', 'subregion', 'capital', 'longitude', 'latitude', 'translations'])
|
||||||
|
|
||||||
for i in tqdm(range(0, len(regions_to_update), batch_size), desc="Updating regions"):
|
for i in tqdm(range(0, len(regions_to_update), batch_size), desc="Updating regions"):
|
||||||
batch = regions_to_update[i:i + batch_size]
|
batch = regions_to_update[i:i + batch_size]
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 5.0.8 on 2025-01-13 17:50
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('worldtravel', '0015_city_insert_id_country_insert_id_region_insert_id'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='country',
|
||||||
|
name='translations',
|
||||||
|
field=models.JSONField(default=dict, blank=True),
|
||||||
|
),
|
||||||
|
]
|
|
@ -18,6 +18,7 @@ class Country(models.Model):
|
||||||
longitude = models.DecimalField(max_digits=9, decimal_places=6, null=True, blank=True)
|
longitude = models.DecimalField(max_digits=9, decimal_places=6, null=True, blank=True)
|
||||||
latitude = models.DecimalField(max_digits=9, decimal_places=6, null=True, blank=True)
|
latitude = models.DecimalField(max_digits=9, decimal_places=6, null=True, blank=True)
|
||||||
insert_id = models.UUIDField(unique=False, blank=True, null=True)
|
insert_id = models.UUIDField(unique=False, blank=True, null=True)
|
||||||
|
translations = models.JSONField(default=dict, blank=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = "Country"
|
verbose_name = "Country"
|
||||||
|
|
|
@ -29,7 +29,7 @@ class CountrySerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Country
|
model = Country
|
||||||
fields = '__all__'
|
fields = '__all__'
|
||||||
read_only_fields = ['id', 'name', 'country_code', 'subregion', 'flag_url', 'num_regions', 'num_visits', 'longitude', 'latitude', 'capital']
|
read_only_fields = ['id', 'name', 'country_code', 'subregion', 'flag_url', 'num_regions', 'num_visits', 'longitude', 'latitude', 'capital', 'translations']
|
||||||
|
|
||||||
|
|
||||||
class RegionSerializer(serializers.ModelSerializer):
|
class RegionSerializer(serializers.ModelSerializer):
|
||||||
|
|
|
@ -1,13 +1,41 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
import type { Country } from '$lib/types';
|
import type { Country } from '$lib/types';
|
||||||
import { createEventDispatcher } from 'svelte';
|
import { t, locale } from 'svelte-i18n';
|
||||||
import { t } from 'svelte-i18n';
|
|
||||||
|
|
||||||
import MapMarkerStar from '~icons/mdi/map-marker-star';
|
import MapMarkerStar from '~icons/mdi/map-marker-star';
|
||||||
|
|
||||||
export let country: Country;
|
export let country: Country;
|
||||||
|
|
||||||
|
// Country name in the current locale
|
||||||
|
let country_name_locale = country.name;
|
||||||
|
|
||||||
|
// Subscribe to locale changes
|
||||||
|
locale.subscribe((lang) => {
|
||||||
|
country_name_locale = get_country_name(lang);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the country name in the current locale
|
||||||
|
* @param lang - The current locale
|
||||||
|
* @returns The country name in the current locale
|
||||||
|
*/
|
||||||
|
function get_country_name(lang: string | null | undefined) {
|
||||||
|
if (!lang) {
|
||||||
|
return country.name;
|
||||||
|
}
|
||||||
|
const translations = country.translations;
|
||||||
|
if (translations[lang]) {
|
||||||
|
return translations[lang];
|
||||||
|
}
|
||||||
|
for (const [key, value] of Object.entries(translations)) {
|
||||||
|
if (key.toLowerCase().includes(lang.toLowerCase())) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return country.name;
|
||||||
|
}
|
||||||
|
|
||||||
async function nav() {
|
async function nav() {
|
||||||
goto(`/worldtravel/${country.country_code}`);
|
goto(`/worldtravel/${country.country_code}`);
|
||||||
}
|
}
|
||||||
|
@ -21,7 +49,7 @@
|
||||||
<img src={country.flag_url} alt="No image available" class="w-full h-48 object-cover" />
|
<img src={country.flag_url} alt="No image available" class="w-full h-48 object-cover" />
|
||||||
</figure>
|
</figure>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h2 class="card-title overflow-ellipsis">{country.name}</h2>
|
<h2 class="card-title overflow-ellipsis">{country_name_locale}</h2>
|
||||||
<div class="flex flex-wrap gap-2">
|
<div class="flex flex-wrap gap-2">
|
||||||
{#if country.subregion}
|
{#if country.subregion}
|
||||||
<div class="badge badge-primary">{country.subregion}</div>
|
<div class="badge badge-primary">{country.subregion}</div>
|
||||||
|
|
|
@ -54,6 +54,7 @@ export type Country = {
|
||||||
num_visits: number;
|
num_visits: number;
|
||||||
longitude: number | null;
|
longitude: number | null;
|
||||||
latitude: number | null;
|
latitude: number | null;
|
||||||
|
translations: Record<string, string>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Region = {
|
export type Region = {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue