1
0
Fork 0
mirror of https://github.com/seanmorley15/AdventureLog.git synced 2025-08-09 07:05:18 +02:00

feat: show country name in current locale if translation exists

This commit is contained in:
JYYYeung 2025-02-26 10:34:48 +00:00
parent 3e0639e6f7
commit bc1f36bf6c
10 changed files with 106 additions and 10 deletions

1
.gitignore vendored
View file

@ -1,3 +1,4 @@
# Ignore everything in the .venv folder
.venv/
.vscode/settings.json
.pnpm-store/

13
.vscode/settings.json vendored
View file

@ -25,5 +25,16 @@
"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"
],
"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
View 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

View file

@ -51,8 +51,6 @@ else:
EOF
fi
# Sync the countries and world travel regions
# Sync the countries and world travel regions
python manage.py download-countries
if [ $? -eq 137 ]; then

View file

@ -92,6 +92,7 @@ class Command(BaseCommand):
country_capital = country['capital']
longitude = round(float(country['longitude']), 6) if country['longitude'] else None
latitude = round(float(country['latitude']), 6) if country['latitude'] else None
translations = country['translations']
processed_country_codes.add(country_code)
@ -102,6 +103,7 @@ class Command(BaseCommand):
country_obj.capital = country_capital
country_obj.longitude = longitude
country_obj.latitude = latitude
country_obj.translations = translations
countries_to_update.append(country_obj)
else:
country_obj = Country(
@ -110,7 +112,8 @@ class Command(BaseCommand):
subregion=country_subregion,
capital=country_capital,
longitude=longitude,
latitude=latitude
latitude=latitude,
translations=translations
)
countries_to_create.append(country_obj)
@ -213,7 +216,7 @@ class Command(BaseCommand):
batch = countries_to_update[i:i + batch_size]
for i in tqdm(range(0, len(countries_to_update), batch_size), desc="Updating countries"):
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"):
batch = regions_to_update[i:i + batch_size]

View file

@ -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),
),
]

View file

@ -18,6 +18,7 @@ class Country(models.Model):
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)
insert_id = models.UUIDField(unique=False, blank=True, null=True)
translations = models.JSONField(default=dict, blank=True)
class Meta:
verbose_name = "Country"

View file

@ -29,7 +29,7 @@ class CountrySerializer(serializers.ModelSerializer):
class Meta:
model = Country
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):

View file

@ -1,13 +1,41 @@
<script lang="ts">
import { goto } from '$app/navigation';
import type { Country } from '$lib/types';
import { createEventDispatcher } from 'svelte';
import { t } from 'svelte-i18n';
import { t, locale } from 'svelte-i18n';
import MapMarkerStar from '~icons/mdi/map-marker-star';
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() {
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" />
</figure>
<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">
{#if country.subregion}
<div class="badge badge-primary">{country.subregion}</div>

View file

@ -54,6 +54,7 @@ export type Country = {
num_visits: number;
longitude: number | null;
latitude: number | null;
translations: Record<string, string>;
};
export type Region = {