diff --git a/backend/server/adventures/models.py b/backend/server/adventures/models.py index 62f73ec..a8460d7 100644 --- a/backend/server/adventures/models.py +++ b/backend/server/adventures/models.py @@ -111,7 +111,16 @@ class Adventure(models.Model): if force_insert and force_update: raise ValueError("Cannot force both insert and updating in model saving.") if not self.category: - self.category = Category.objects.get_or_create(user_id=self.user_id, name='general', display_name='General', icon='🌍')[0] + category, created = Category.objects.get_or_create( + user_id=self.user_id, + name='general', + defaults={ + 'display_name': 'General', + 'icon': '🌍' + } + ) + self.category = category + return super().save(force_insert, force_update, using, update_fields) def __str__(self): @@ -273,4 +282,4 @@ class Category(models.Model): def __str__(self): - return self.name \ No newline at end of file + return self.name + ' - ' + self.display_name + ' - ' + self.icon \ No newline at end of file diff --git a/backend/server/adventures/serializers.py b/backend/server/adventures/serializers.py index c4ce818..9b538ed 100644 --- a/backend/server/adventures/serializers.py +++ b/backend/server/adventures/serializers.py @@ -118,6 +118,7 @@ class AdventureSerializer(CustomModelSerializer): def create(self, validated_data): visits_data = validated_data.pop('visits', []) category_data = validated_data.pop('category', None) + print(category_data) adventure = Adventure.objects.create(**validated_data) for visit_data in visits_data: Visit.objects.create(adventure=adventure, **visit_data) diff --git a/frontend/src/lib/components/AdventureCard.svelte b/frontend/src/lib/components/AdventureCard.svelte index c8f0de3..ef0f1f1 100644 --- a/frontend/src/lib/components/AdventureCard.svelte +++ b/frontend/src/lib/components/AdventureCard.svelte @@ -130,7 +130,7 @@
- {`${adventure.category.display_name} ${adventure.category.icon}`} + {adventure.category?.display_name + ' ' + adventure.category?.icon}
{adventure.is_visited ? $t('adventures.visited') : $t('adventures.planned')} diff --git a/frontend/src/lib/components/CategoryDropdown.svelte b/frontend/src/lib/components/CategoryDropdown.svelte index acffa2b..5d86822 100644 --- a/frontend/src/lib/components/CategoryDropdown.svelte +++ b/frontend/src/lib/components/CategoryDropdown.svelte @@ -31,13 +31,6 @@ selectCategory(new_category); } - // function removeCategory(categoryName: string) { - // categories = categories.filter((category) => category.name !== categoryName); - // if (selected_category && selected_category.name === categoryName) { - // selected_category = null; - // } - // } - // Close dropdown when clicking outside let dropdownRef: HTMLDivElement; @@ -59,7 +52,7 @@ {#if isOpen} @@ -69,13 +62,13 @@
@@ -93,13 +86,6 @@ on:click={() => selectCategory(category)} > {category.display_name} {category.icon} ({category.num_adventures}) -
{/each}
diff --git a/frontend/src/lib/components/CategoryModal.svelte b/frontend/src/lib/components/CategoryModal.svelte index c997a6b..bb60725 100644 --- a/frontend/src/lib/components/CategoryModal.svelte +++ b/frontend/src/lib/components/CategoryModal.svelte @@ -20,7 +20,7 @@ let category_fetch = await fetch('/api/categories/categories'); categories = await category_fetch.json(); // remove the general category if it exists - categories = categories.filter((c) => c.name !== 'general'); + // categories = categories.filter((c) => c.name !== 'general'); }); async function saveCategory() { @@ -73,7 +73,7 @@ {/each} {#if categories.length === 0} -

No categories found.

+

{$t('categories.no_categories_found')}

{/if} {#if category_to_edit} -

Edit Category

+

{$t('categories.edit_category')}

- + {/if} @@ -127,7 +131,7 @@ d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" > - The adventure cards will be updated once you refresh the page. + {$t('categories.update_after_refresh')}
{/if} diff --git a/frontend/src/lib/components/Navbar.svelte b/frontend/src/lib/components/Navbar.svelte index 7ea414c..d0e15e2 100644 --- a/frontend/src/lib/components/Navbar.svelte +++ b/frontend/src/lib/components/Navbar.svelte @@ -15,6 +15,7 @@ import PaletteOutline from '~icons/mdi/palette-outline'; import { page } from '$app/stores'; import { t, locale, locales } from 'svelte-i18n'; + import { themes } from '$lib'; let query: string = ''; @@ -214,57 +215,40 @@ + +

{$t('navbar.language_selection')}

+
+ + +

{$t('navbar.theme_selection')}

-
  • - -
  • -
  • - -
  • -
  • - -
  • -
  • - - - - -
  • -

    {$t('navbar.language_selection')}

    - - - -
    + {#each themes as theme} +
  • + +
  • + {/each} diff --git a/frontend/src/lib/index.ts b/frontend/src/lib/index.ts index 813d87a..0426345 100644 --- a/frontend/src/lib/index.ts +++ b/frontend/src/lib/index.ts @@ -305,3 +305,13 @@ export function findFirstValue(obj: any): any { } } } + +export let themes = [ + { name: 'light', label: 'Light' }, + { name: 'dark', label: 'Dark' }, + { name: 'night', label: 'Night' }, + { name: 'forest', label: 'Forest' }, + { name: 'aqua', label: 'Aqua' }, + { name: 'aestheticLight', label: 'Aesthetic Light' }, + { name: 'aestheticDark', label: 'Aesthetic Dark' } +]; diff --git a/frontend/src/locales/de.json b/frontend/src/locales/de.json index 63897a7..f62a773 100644 --- a/frontend/src/locales/de.json +++ b/frontend/src/locales/de.json @@ -187,7 +187,8 @@ "day": "Tag", "add_a_tag": "Fügen Sie ein Tag hinzu", "tags": "Schlagworte", - "set_to_pin": "Auf „Anpinnen“ setzen" + "set_to_pin": "Auf „Anpinnen“ setzen", + "category_fetch_error": "Fehler beim Abrufen der Kategorien" }, "home": { "desc_1": "Entdecken, planen und erkunden Sie mit Leichtigkeit", @@ -219,19 +220,20 @@ "shared_with_me": "Mit mir geteilt", "theme_selection": "Themenauswahl", "themes": { - "aestetic-dark": "Ästhetisches Dunkel", - "aestetic-light": "Ästhetisches Licht", "aqua": "Aqua", "dark": "Dunkel", "forest": "Wald", "light": "Licht", - "night": "Nacht" + "night": "Nacht", + "aestheticDark": "Ästhetisches Dunkel", + "aestheticLight": "Ästhetisches Licht" }, "users": "Benutzer", "worldtravel": "Weltreisen", "my_tags": "Meine Tags", "tag": "Etikett", - "language_selection": "Sprache" + "language_selection": "Sprache", + "support": "Unterstützung" }, "auth": { "confirm_password": "Passwort bestätigen", @@ -399,5 +401,14 @@ "user_stats": "Benutzerstatistiken", "visited_countries": "Besuchte Länder", "visited_regions": "Besuchte Regionen" + }, + "categories": { + "category_name": "Kategoriename", + "edit_category": "Kategorie bearbeiten", + "icon": "Symbol", + "manage_categories": "Kategorien verwalten", + "no_categories_found": "Keine Kategorien gefunden.", + "select_category": "Kategorie auswählen", + "update_after_refresh": "Die Abenteuerkarten werden aktualisiert, sobald Sie die Seite aktualisieren." } } diff --git a/frontend/src/locales/en.json b/frontend/src/locales/en.json index d2ce0a5..0b00798 100644 --- a/frontend/src/locales/en.json +++ b/frontend/src/locales/en.json @@ -18,14 +18,15 @@ "documentation": "Documentation", "discord": "Discord", "language_selection": "Language", + "support": "Support", "theme_selection": "Theme Selection", "themes": { "light": "Light", "dark": "Dark", "night": "Night", "forest": "Forest", - "aestetic-dark": "Aestetic Dark", - "aestetic-light": "Aestetic Light", + "aestheticLight": "Aesthetic Light", + "aestheticDark": "Aesthetic Dark", "aqua": "Aqua" } }, @@ -400,5 +401,14 @@ "user_stats": "User Stats", "visited_countries": "Visited Countries", "visited_regions": "Visited Regions" + }, + "categories": { + "manage_categories": "Manage Categories", + "no_categories_found": "No categories found.", + "edit_category": "Edit Category", + "icon": "Icon", + "update_after_refresh": "The adventure cards will be updated once you refresh the page.", + "select_category": "Select Category", + "category_name": "Category Name" } } diff --git a/frontend/src/locales/es.json b/frontend/src/locales/es.json index a31f824..4079a13 100644 --- a/frontend/src/locales/es.json +++ b/frontend/src/locales/es.json @@ -21,13 +21,14 @@ "dark": "Oscuro", "night": "Noche", "forest": "Bosque", - "aestetic-dark": "Estético Oscuro", - "aestetic-light": "Estético Claro", - "aqua": "Aqua" + "aqua": "Aqua", + "aestheticDark": "Estética Oscura", + "aestheticLight": "Luz estetica" }, "my_tags": "Mis etiquetas", "tag": "Etiqueta", - "language_selection": "Idioma" + "language_selection": "Idioma", + "support": "Apoyo" }, "about": { "about": "Acerca de", @@ -231,7 +232,8 @@ "day": "Día", "add_a_tag": "Agregar una etiqueta", "tags": "Etiquetas", - "set_to_pin": "Establecer en Fijar" + "set_to_pin": "Establecer en Fijar", + "category_fetch_error": "Error al buscar categorías" }, "worldtravel": { "all": "Todo", @@ -399,5 +401,14 @@ "user_stats": "Estadísticas de usuario", "visited_countries": "Países visitados", "visited_regions": "Regiones visitadas" + }, + "categories": { + "category_name": "Nombre de categoría", + "edit_category": "Editar categoría", + "icon": "Icono", + "manage_categories": "Administrar categorías", + "no_categories_found": "No se encontraron categorías.", + "select_category": "Seleccionar categoría", + "update_after_refresh": "Las tarjetas de aventuras se actualizarán una vez que actualices la página." } } diff --git a/frontend/src/locales/fr.json b/frontend/src/locales/fr.json index c70e14c..8804d9b 100644 --- a/frontend/src/locales/fr.json +++ b/frontend/src/locales/fr.json @@ -187,7 +187,8 @@ "day": "Jour", "add_a_tag": "Ajouter une balise", "tags": "Balises", - "set_to_pin": "Définir sur Épingler" + "set_to_pin": "Définir sur Épingler", + "category_fetch_error": "Erreur lors de la récupération des catégories" }, "home": { "desc_1": "Découvrez, planifiez et explorez en toute simplicité", @@ -222,16 +223,17 @@ "forest": "Forêt", "light": "Lumière", "night": "Nuit", - "aestetic-dark": "Esthétique sombre", - "aestetic-light": "Lumière esthétique", "aqua": "Aqua", - "dark": "Sombre" + "dark": "Sombre", + "aestheticDark": "Esthétique sombre", + "aestheticLight": "Lumière esthétique" }, "users": "Utilisateurs", "worldtravel": "Voyage dans le monde", "my_tags": "Mes balises", "tag": "Étiqueter", - "language_selection": "Langue" + "language_selection": "Langue", + "support": "Soutien" }, "auth": { "confirm_password": "Confirmez le mot de passe", @@ -399,5 +401,14 @@ "user_stats": "Statistiques des utilisateurs", "visited_countries": "Pays visités", "visited_regions": "Régions visitées" + }, + "categories": { + "category_name": "Nom de la catégorie", + "edit_category": "Modifier la catégorie", + "icon": "Icône", + "manage_categories": "Gérer les catégories", + "no_categories_found": "Aucune catégorie trouvée.", + "select_category": "Sélectionnez une catégorie", + "update_after_refresh": "Les cartes d'aventure seront mises à jour une fois que vous aurez actualisé la page." } } diff --git a/frontend/src/locales/it.json b/frontend/src/locales/it.json index edb1a9b..c0444d1 100644 --- a/frontend/src/locales/it.json +++ b/frontend/src/locales/it.json @@ -187,7 +187,8 @@ "day": "Giorno", "add_a_tag": "Aggiungi un'etichetta", "tags": "Tag", - "set_to_pin": "Imposta su Blocca" + "set_to_pin": "Imposta su Blocca", + "category_fetch_error": "Errore durante il recupero delle categorie" }, "home": { "desc_1": "Scopri, pianifica ed esplora con facilità", @@ -219,19 +220,20 @@ "shared_with_me": "Condiviso con me", "theme_selection": "Selezione del tema", "themes": { - "aestetic-dark": "Oscuro estetico", - "aestetic-light": "Luce estetica", "aqua": "Acqua", "dark": "Buio", "forest": "Foresta", "light": "Leggero", - "night": "Notte" + "night": "Notte", + "aestheticDark": "Estetico scuro", + "aestheticLight": "Luce estetica" }, "users": "Utenti", "worldtravel": "Viaggio nel mondo", "my_tags": "I miei tag", "tag": "Etichetta", - "language_selection": "Lingua" + "language_selection": "Lingua", + "support": "Supporto" }, "auth": { "confirm_password": "Conferma password", @@ -399,5 +401,14 @@ "user_stats": "Statistiche utente", "visited_countries": "Paesi visitati", "visited_regions": "Regioni visitate" + }, + "categories": { + "category_name": "Nome della categoria", + "edit_category": "Modifica categoria", + "icon": "Icona", + "manage_categories": "Gestisci categorie", + "no_categories_found": "Nessuna categoria trovata.", + "select_category": "Seleziona Categoria", + "update_after_refresh": "Le carte avventura verranno aggiornate una volta aggiornata la pagina." } } diff --git a/frontend/src/locales/nl.json b/frontend/src/locales/nl.json index 203441b..bf004c1 100644 --- a/frontend/src/locales/nl.json +++ b/frontend/src/locales/nl.json @@ -187,7 +187,8 @@ "day": "Dag", "add_a_tag": "Voeg een label toe", "tags": "Labels", - "set_to_pin": "Stel in op Vastzetten" + "set_to_pin": "Stel in op Vastzetten", + "category_fetch_error": "Fout bij ophalen van categorieën" }, "home": { "desc_1": "Ontdek, plan en verken met gemak", @@ -219,19 +220,20 @@ "shared_with_me": "Gedeeld met mij", "theme_selection": "Thema Selectie", "themes": { - "aestetic-dark": "Esthetisch donker", - "aestetic-light": "Esthetisch licht", "aqua": "Aqua", "dark": "Donker", "forest": "Woud", "light": "Licht", - "night": "Nacht" + "night": "Nacht", + "aestheticDark": "Esthetisch donker", + "aestheticLight": "Esthetisch licht" }, "users": "Gebruikers", "worldtravel": "Wereldreizen", "my_tags": "Mijn tags", "tag": "Label", - "language_selection": "Taal" + "language_selection": "Taal", + "support": "Steun" }, "auth": { "confirm_password": "Bevestig wachtwoord", @@ -399,5 +401,14 @@ "user_stats": "Gebruikersstatistieken", "visited_countries": "Bezochte landen", "visited_regions": "Bezochte regio's" + }, + "categories": { + "category_name": "Categorienaam", + "edit_category": "Categorie bewerken", + "icon": "Icon", + "manage_categories": "Beheer categorieën", + "no_categories_found": "Geen categorieën gevonden.", + "select_category": "Selecteer Categorie", + "update_after_refresh": "De avonturenkaarten worden bijgewerkt zodra u de pagina vernieuwt." } } diff --git a/frontend/src/locales/sv.json b/frontend/src/locales/sv.json index a70ea6f..990b652 100644 --- a/frontend/src/locales/sv.json +++ b/frontend/src/locales/sv.json @@ -187,7 +187,8 @@ "day": "Dag", "add_a_tag": "Lägg till en tagg", "tags": "Taggar", - "set_to_pin": "Ställ in på Pin" + "set_to_pin": "Ställ in på Pin", + "category_fetch_error": "Det gick inte att hämta kategorier" }, "home": { "desc_1": "Upptäck, planera och utforska med lätthet", @@ -219,19 +220,20 @@ "shared_with_me": "Delade med mig", "theme_selection": "Temaval", "themes": { - "aestetic-dark": "Estetisk mörk", - "aestetic-light": "Estetiskt ljus", "aqua": "Aqua", "dark": "Mörk", "forest": "Skog", "light": "Ljus", - "night": "Natt" + "night": "Natt", + "aestheticDark": "Estetisk mörk", + "aestheticLight": "Estetiskt ljus" }, "users": "Användare", "worldtravel": "Världsresor", "my_tags": "Mina taggar", "tag": "Märka", - "language_selection": "Språk" + "language_selection": "Språk", + "support": "Stöd" }, "worldtravel": { "all": "Alla", @@ -399,5 +401,14 @@ "user_stats": "Användarstatistik", "visited_countries": "Besökta länder", "visited_regions": "Besökte regioner" + }, + "categories": { + "category_name": "Kategorinamn", + "edit_category": "Redigera kategori", + "icon": "Ikon", + "manage_categories": "Hantera kategorier", + "no_categories_found": "Inga kategorier hittades.", + "select_category": "Välj Kategori", + "update_after_refresh": "Äventyrskorten kommer att uppdateras när du uppdaterar sidan." } } diff --git a/frontend/src/locales/zh.json b/frontend/src/locales/zh.json index 13b5687..cd80e83 100644 --- a/frontend/src/locales/zh.json +++ b/frontend/src/locales/zh.json @@ -187,7 +187,8 @@ "day": "天", "add_a_tag": "添加标签", "tags": "标签", - "set_to_pin": "设置为固定" + "set_to_pin": "设置为固定", + "category_fetch_error": "获取类别时出错" }, "home": { "desc_1": "轻松发现、规划和探索", @@ -219,19 +220,20 @@ "shared_with_me": "与我分享", "theme_selection": "主题选择", "themes": { - "aestetic-dark": "审美黑暗", - "aestetic-light": "审美之光", "aqua": "阿夸", "dark": "黑暗的", "forest": "森林", "light": "光", - "night": "夜晚" + "night": "夜晚", + "aestheticDark": "审美黑暗", + "aestheticLight": "美学之光" }, "users": "用户", "worldtravel": "环球旅行", "my_tags": "我的标签", "tag": "标签", - "language_selection": "语言" + "language_selection": "语言", + "support": "支持" }, "auth": { "forgot_password": "忘记密码?", @@ -399,5 +401,14 @@ "user_stats": "用户统计", "visited_countries": "访问过的国家", "visited_regions": "访问地区" + }, + "categories": { + "category_name": "类别名称", + "edit_category": "编辑类别", + "icon": "图标", + "manage_categories": "管理类别", + "no_categories_found": "未找到类别。", + "select_category": "选择类别", + "update_after_refresh": "刷新页面后,冒险卡将更新。" } } diff --git a/frontend/src/routes/+page.server.ts b/frontend/src/routes/+page.server.ts index 7721524..93de50a 100644 --- a/frontend/src/routes/+page.server.ts +++ b/frontend/src/routes/+page.server.ts @@ -1,7 +1,6 @@ const PUBLIC_SERVER_URL = process.env['PUBLIC_SERVER_URL']; import { redirect, type Actions } from '@sveltejs/kit'; -import type { PageServerLoad } from './$types'; -import { getRandomBackground } from '$lib'; +import { themes } from '$lib'; const serverEndpoint = PUBLIC_SERVER_URL || 'http://localhost:8000'; @@ -9,21 +8,7 @@ export const actions: Actions = { setTheme: async ({ url, cookies }) => { const theme = url.searchParams.get('theme'); // change the theme only if it is one of the allowed themes - if ( - theme && - [ - 'light', - 'dark', - 'night', - 'retro', - 'forest', - 'aqua', - 'forest', - 'aestheticLight', - 'aestheticDark', - 'emerald' - ].includes(theme) - ) { + if (theme && themes.find((t) => t.name === theme)) { cookies.set('colortheme', theme, { path: '/', maxAge: 60 * 60 * 24 * 365