diff --git a/backend/server/adventures/views/reverse_geocode_view.py b/backend/server/adventures/views/reverse_geocode_view.py index e7c4562..d876787 100644 --- a/backend/server/adventures/views/reverse_geocode_view.py +++ b/backend/server/adventures/views/reverse_geocode_view.py @@ -7,6 +7,7 @@ from adventures.models import Adventure from adventures.serializers import AdventureSerializer import requests from adventures.geocoding import reverse_geocode +from adventures.geocoding import extractIsoCode class ReverseGeocodeViewSet(viewsets.ViewSet): permission_classes = [IsAuthenticated] @@ -49,7 +50,7 @@ class ReverseGeocodeViewSet(viewsets.ViewSet): data = response.json() except requests.exceptions.JSONDecodeError: return Response({"error": "Invalid response from geocoding service"}, status=400) - extracted_region = self.extractIsoCode(data) + extracted_region = extractIsoCode(self.request.user,data) if 'error' not in extracted_region: region = Region.objects.filter(id=extracted_region['region_id']).first() visited_region = VisitedRegion.objects.filter(region=region, user_id=self.request.user).first() diff --git a/frontend/src/routes/settings/+page.svelte b/frontend/src/routes/settings/+page.svelte index 1ca20db..2063a36 100644 --- a/frontend/src/routes/settings/+page.svelte +++ b/frontend/src/routes/settings/+page.svelte @@ -7,7 +7,7 @@ import { browser } from '$app/environment'; import { t } from 'svelte-i18n'; import TotpModal from '$lib/components/TOTPModal.svelte'; - import { appTitle, appVersion } from '$lib/config.js'; + import { appTitle, appVersion, copyrightYear } from '$lib/config.js'; import ImmichLogo from '$lib/assets/immich.svg'; export let data; @@ -20,10 +20,10 @@ } let new_password_disable_setting: boolean = false; - let new_email: string = ''; let public_url: string = data.props.publicUrl; let immichIntegration = data.props.immichIntegration; + let activeSection: string = 'profile'; let newImmichIntegration: ImmichIntegration = { server_url: '', @@ -33,6 +33,15 @@ let isMFAModalOpen: boolean = false; + const sections = [ + { id: 'profile', icon: '👤', label: 'Profile' }, + { id: 'security', icon: '🔒', label: 'Security' }, + { id: 'emails', icon: '📧', label: 'Emails' }, + { id: 'integrations', icon: '🔗', label: 'Integrations' }, + { id: 'admin', icon: '⚙️', label: 'Admin' }, + { id: 'advanced', icon: '🛠️', label: 'Advanced' } + ]; + onMount(async () => { if (browser) { const queryParams = new URLSearchParams($page.url.search); @@ -162,7 +171,6 @@ }); if (res.ok) { addToast('success', $t('settings.email_set_primary')); - // remove primary from all other emails and set this one as primary emails = emails.map((e) => { if (e.email === email.email) { e.primary = true; @@ -248,415 +256,777 @@ /> {/if} -
-

- {$t('settings.settings_page')} -

- - -
-

- {$t('settings.account_settings')} -

-
-
+
+ +
+
+
- - + {$t('settings.settings_page')} + +

Manage your account preferences and integrations

- -
- - -
- -
- - -
- -
- - -
- -
- - -
- - - +
-
+
- -
-

- {$t('settings.password_change')} -

-
-
- {#if user.has_password} -
- - -
- {/if} - -
- - +
+
+ +
+
+

Settings Menu

+
- -
- - -
- {#if $page.form?.message} -
- {$t($page.form?.message)} -
- {/if} - -
- -
- -
-
- - -
-

- {$t('settings.email_change')} -

-
-
- {#each emails as email} -
- {email.email} - {#if email.verified} -
{$t('settings.verified')}
- {:else} -
{$t('settings.not_verified')}
- {/if} - {#if email.primary} -
{$t('settings.primary')}
- {/if} - {#if !email.verified} - - {/if} - {#if !email.primary} - - {/if} - -
- {/each} - {#if emails.length === 0} -

{$t('settings.no_email_set')}

- {/if}
-
- - -
-
-
- - -
-

- {$t('settings.mfa_page_title')} -

-
- {#if !data.props.authenticators} -

{$t('settings.mfa_not_enabled')}

- {#if !emails.some((e) => e.verified)} -
- {$t('settings.no_verified_email_warning')} -
- {:else} - - {/if} - {:else} - - {/if} -
-
- - - {#if user.is_staff} -
-

- {$t('settings.administration_settings')} -

-
- {$t('settings.launch_administration_panel')} -
-
- {/if} - - -
-

{$t('settings.social_oidc_auth')}

-
-

- {$t('settings.social_auth_desc')} -

- - {$t('settings.launch_account_connections')} - - {#if data.props.socialProviders && data.props.socialProviders.length > 0} -
-

{$t('settings.password_disable')}

-

{$t('settings.password_disable_desc')}

- -
- - - - {#if user.disable_password} -
{$t('settings.password_disabled')}
- {/if} - {#if !user.disable_password} -
{$t('settings.password_enabled')}
- {/if} - {#if user.disable_password} -
- {$t('settings.password_disable_warning')} + +
+
+ + {#if activeSection === 'profile'} +
+
+
+ 👤 +
+
+

Profile Information

+

+ Update your personal details and profile picture +

+
- {/if} -
-
- {/if} -
-
- -
-

- {$t('immich.immich_integration')} - Immich -

-
-

- {$t('immich.immich_desc')} - {$t('immich.documentation')} -

- {#if immichIntegration} -
-
{$t('immich.integration_enabled')}
-
- - -
-
- {/if} - {#if !immichIntegration || newImmichIntegration.id} -
-
- - - {#if newImmichIntegration.server_url && !newImmichIntegration.server_url.endsWith('api')} -

- {$t('immich.api_note')} +

+
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+
+ +
+ +
+ + +
+
+ {/if} + + + {#if activeSection === 'security'} +
+ +
+
+
+ 🔐 +
+
+

Change Password

+

+ Update your account password for better security +

+
+
+ +
+ {#if user.has_password} +
+ + +
+ {/if} + +
+
+ + +
+ +
+ + +
+
+ + {#if $page.form?.message} +
+ + + + {$t($page.form?.message)} +
+ {/if} + +
+ +
+
+
+ + +
+
+
+ 🛡️ +
+
+

Two-Factor Authentication

+

+ Add an extra layer of security to your account +

+
+
+ +
+
+
+ {#if data.props.authenticators} + ✅ Enabled + {:else} + ❌ Disabled + {/if} +
+ + {data.props.authenticators + ? 'MFA is currently enabled' + : 'MFA is not enabled'} + +
+ + {#if !data.props.authenticators} + {#if !emails.some((e) => e.verified)} +
+ +
+ {:else} + + {/if} + {:else} + + {/if} +
+ + {#if !emails.some((e) => e.verified)} +
+ + + + {$t('settings.no_verified_email_warning')} +
+ {/if} +
+ + + {#if data.props.socialProviders && data.props.socialProviders.length > 0} +
+
+
+ 🔗 +
+
+

Social Authentication

+

+ Manage social login options and password settings +

+
+
+ +
+
+
+
+

Password Authentication

+

+ {user.disable_password + ? 'Password login is disabled' + : 'Password login is enabled'} +

+
+
+
+ {user.disable_password ? 'Disabled' : 'Enabled'} +
+ +
+
+ {#if user.disable_password} +
+ + + + {$t('settings.password_disable_warning')} +
+ {/if} +
+ + + 🔗 {$t('settings.launch_account_connections')} + +
+
+ {/if} +
+ {/if} + + + {#if activeSection === 'emails'} +
+
+
+ 📧 +
+
+

Email Management

+

+ Manage your email addresses and verification status +

+
+
+ + + {#if emails.length > 0} +
+ {#each emails as email} +
+
+
+ {email.email} +
+ {#if email.verified} +
✅ Verified
+ {:else} +
❌ Not Verified
+ {/if} + {#if email.primary} +
⭐ Primary
+ {/if} +
+
+
+ {#if !email.verified} + + {/if} + {#if !email.primary && email.verified} + + {/if} + +
+
+
+ {/each} +
+ {:else} +
+
📧
+

{$t('settings.no_email_set')}

+
+ {/if} + + +
Add New Email
+
+
+ + +
+ +
+
+ {/if} + + + {#if activeSection === 'integrations'} +
+
+
+ 🔗 +
+
+

Integrations

+

+ Connect external services to enhance your experience +

+
+
+ + +
+
+ Immich +
+

Immich Integration

+

+ Connect your Immich photo management server +

+
+ {#if immichIntegration} +
Connected
+ {:else} +
Disconnected
+ {/if} +
+ + {#if immichIntegration && !newImmichIntegration.id} +
+ + +
+ {/if} + + {#if !immichIntegration || newImmichIntegration.id} +
+
+ + + {#if newImmichIntegration.server_url && !newImmichIntegration.server_url.endsWith('api')} +
+ {$t('immich.api_note')} +
+ {/if} + {#if newImmichIntegration.server_url && (newImmichIntegration.server_url.indexOf('localhost') !== -1 || newImmichIntegration.server_url.indexOf('127.0.0.1') !== -1)} +
+ {$t('immich.localhost_note')} +
+ {/if} +
+ +
+ + +
+ + +
+ {/if} + +
+

+ 📖 Need help setting this up? Check out the + documentation +

+
+
+
+ {/if} + + + {#if activeSection === 'admin' && user.is_staff} +
+
+
+ ⚙️ +
+
+

Administration

+

Administrative tools and settings

+
+
+ +
+
+
+
🛠️
+

Admin Panel

+

+ Access the full administration interface +

+ + Launch Admin Panel + +
+
+ +
+
+
📍
+

Region Updates

+

+ Update visited regions and cities +

+ +
+
+
+
+ {:else if activeSection === 'admin' && !user.is_staff} +
+
🔒
+

Access Restricted

+

+ Administrative features are only available to staff members.

- {/if} - {#if newImmichIntegration.server_url && (newImmichIntegration.server_url.indexOf('localhost') !== -1 || newImmichIntegration.server_url.indexOf('127.0.0.1') !== -1)} -

- {$t('immich.localhost_note')} -

- {/if} -
-
- - -
- +
+ {/if} + + + {#if activeSection === 'advanced'} +
+ +
+
+
+ 🛠️ +
+
+

Advanced Settings

+

Advanced configuration and development tools

+
+
+ +
+ +
+

Social Authentication Setup

+

{$t('settings.social_auth_desc')}

+ +
+ + + +
+ {$t('settings.social_auth_desc_2')} + {$t('settings.documentation_link')} +
+
+
+ + +
+

Debug Information

+
+
+ User UUID: +
+ {user.uuid} +
+
+ Staff Status: +
+ + {user.is_staff ? 'Staff User' : 'Regular User'} + +
+
+ App Version: +
+ {appTitle} {appVersion} +
+
+ Profile Type: +
+ + {user.public_profile ? 'Public' : 'Private'} + +
+
+
+ + +
+

Quick Actions

+
+ + {#if user.is_staff} + + ⚙️ Open Admin Panel + + {/if} +
+
+ + +
+
+

About AdventureLog

+

+ AdventureLog is open-source software released under the GPL-3.0 License. +

+

+ © {copyrightYear} + Sean Morley. All rights reserved. +

+ +
+
+
+
+
+ {/if}
- {/if} + -
- - -
-

{$t('adventures.visited_region_check')}

-

{$t('adventures.visited_region_check_desc')}

- -
- - - For Debug Use: UUID={user.uuid} | Staff user: {user.is_staff} | {appTitle} - {appVersion} - + User Settings | AdventureLog