1
0
Fork 0
mirror of https://github.com/seanmorley15/AdventureLog.git synced 2025-07-23 14:59:36 +02:00

feat: Enhance City and Lodging components with region and country names, and improve password disable functionality

This commit is contained in:
Sean Morley 2025-03-17 10:38:41 -04:00
parent eb541225bd
commit 4e543fad55
6 changed files with 64 additions and 33 deletions

View file

@ -43,10 +43,13 @@ class RegionSerializer(serializers.ModelSerializer):
return City.objects.filter(region=obj).count() return City.objects.filter(region=obj).count()
class CitySerializer(serializers.ModelSerializer): class CitySerializer(serializers.ModelSerializer):
region_name = serializers.CharField(source='region.name', read_only=True)
country_name = serializers.CharField(source='region.country.name', read_only=True
)
class Meta: class Meta:
model = City model = City
fields = '__all__' fields = '__all__'
read_only_fields = ['id', 'name', 'region', 'longitude', 'latitude'] read_only_fields = ['id', 'name', 'region', 'longitude', 'latitude', 'region_name', 'country_name']
class VisitedRegionSerializer(CustomModelSerializer): class VisitedRegionSerializer(CustomModelSerializer):
longitude = serializers.DecimalField(source='region.longitude', max_digits=9, decimal_places=6, read_only=True) longitude = serializers.DecimalField(source='region.longitude', max_digits=9, decimal_places=6, read_only=True)

View file

@ -1,4 +1,5 @@
<script lang="ts"> <script lang="ts">
import { goto } from '$app/navigation';
import { addToast } from '$lib/toasts'; import { addToast } from '$lib/toasts';
import type { City } from '$lib/types'; import type { City } from '$lib/types';
import { createEventDispatcher } from 'svelte'; import { createEventDispatcher } from 'svelte';
@ -45,7 +46,10 @@
<div class="card-body"> <div class="card-body">
<h2 class="card-title overflow-ellipsis">{city.name}</h2> <h2 class="card-title overflow-ellipsis">{city.name}</h2>
<div class="flex flex-wrap gap-2"> <div class="flex flex-wrap gap-2">
<div class="badge badge-neutral-300">{city.id}</div> <div class="badge badge-neutral-300">
{city.region_name}, {city.country_name}
</div>
<div class="badge badge-neutral-300">{city.region}</div>
</div> </div>
<div class="card-actions justify-end"> <div class="card-actions justify-end">
{#if !visited} {#if !visited}

View file

@ -6,9 +6,18 @@
import { addToast } from '$lib/toasts'; import { addToast } from '$lib/toasts';
import { t } from 'svelte-i18n'; import { t } from 'svelte-i18n';
import DeleteWarning from './DeleteWarning.svelte'; import DeleteWarning from './DeleteWarning.svelte';
import { LODGING_TYPES_ICONS } from '$lib';
const dispatch = createEventDispatcher(); const dispatch = createEventDispatcher();
function getLodgingIcon(type: string) {
if (type in LODGING_TYPES_ICONS) {
return LODGING_TYPES_ICONS[type as keyof typeof LODGING_TYPES_ICONS];
} else {
return '🏨';
}
}
export let lodging: Lodging; export let lodging: Lodging;
export let user: User | null = null; export let user: User | null = null;
export let collection: Collection | null = null; export let collection: Collection | null = null;
@ -91,7 +100,7 @@
<h2 class="card-title text-lg font-semibold truncate">{lodging.name}</h2> <h2 class="card-title text-lg font-semibold truncate">{lodging.name}</h2>
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
<div class="badge badge-secondary"> <div class="badge badge-secondary">
{$t(`lodging.${lodging.type}`)} {$t(`lodging.${lodging.type}`) + ' ' + getLodgingIcon(lodging.type)}
</div> </div>
<!-- {#if hotel.type == 'plane' && hotel.flight_number} <!-- {#if hotel.type == 'plane' && hotel.flight_number}
<div class="badge badge-neutral-200">{hotel.flight_number}</div> <div class="badge badge-neutral-200">{hotel.flight_number}</div>

View file

@ -72,6 +72,8 @@ export type City = {
latitude: number | null; latitude: number | null;
longitude: number | null; longitude: number | null;
region: string; region: string;
region_name: string;
country_name: string;
}; };
export type VisitedRegion = { export type VisitedRegion = {

View file

@ -63,6 +63,13 @@ export const load: PageServerLoad = async (event) => {
immichIntegration = await immichIntegrationsFetch.json(); immichIntegration = await immichIntegrationsFetch.json();
} }
let socialProvidersFetch = await fetch(`${endpoint}/auth/social-providers`, {
headers: {
Cookie: `sessionid=${sessionId}`
}
});
let socialProviders = await socialProvidersFetch.json();
let publicUrlFetch = await fetch(`${endpoint}/public-url/`); let publicUrlFetch = await fetch(`${endpoint}/public-url/`);
let publicUrl = ''; let publicUrl = '';
if (!publicUrlFetch.ok) { if (!publicUrlFetch.ok) {
@ -78,7 +85,8 @@ export const load: PageServerLoad = async (event) => {
emails, emails,
authenticators, authenticators,
immichIntegration, immichIntegration,
publicUrl publicUrl,
socialProviders
} }
}; };
}; };

View file

@ -100,6 +100,7 @@
addToast('success', $t('settings.password_disabled')); addToast('success', $t('settings.password_disabled'));
} else { } else {
addToast('error', $t('settings.password_disabled_error')); addToast('error', $t('settings.password_disabled_error'));
user.disable_password = false;
} }
} else { } else {
let res = await fetch('/auth/disable-password/', { let res = await fetch('/auth/disable-password/', {
@ -112,6 +113,7 @@
addToast('success', $t('settings.password_enabled')); addToast('success', $t('settings.password_enabled'));
} else { } else {
addToast('error', $t('settings.password_enabled_error')); addToast('error', $t('settings.password_enabled_error'));
user.disable_password = true;
} }
} }
} }
@ -520,37 +522,40 @@
target="_blank">{$t('settings.launch_account_connections')}</a target="_blank">{$t('settings.launch_account_connections')}</a
> >
<div class="mt-8"> {#if data.props.socialProviders && data.props.socialProviders.length > 0}
<h2 class="text-2xl font-semibold text-center">{$t('settings.password_disable')}</h2> <div class="mt-8">
<p>{$t('settings.password_disable_desc')}</p> <h2 class="text-2xl font-semibold text-center">{$t('settings.password_disable')}</h2>
<p>{$t('settings.password_disable_desc')}</p>
<div class="flex flex-col items-center mt-4"> <div class="flex flex-col items-center mt-4">
<input <input
type="checkbox" type="checkbox"
id="disable_password" id="disable_password"
name="disable_password" name="disable_password"
bind:checked={user.disable_password} bind:checked={user.disable_password}
class="checkbox checkbox-primary" class="toggle toggle-primary"
/> on:change={disablePassword}
<label for="disable_password" class="ml-2 text-sm text-neutral-content" />
>{$t('settings.disable_password')}</label <label for="disable_password" class="ml-2 text-sm text-neutral-content"
> >{$t('settings.disable_password')}</label
<button class="btn btn-primary mt-4" on:click={disablePassword} >
>{$t('settings.update')}</button <!-- <button class="btn btn-primary mt-4" on:click={disablePassword}
> >{$t('settings.update')}</button
{#if user.disable_password} > -->
<div class="badge badge-error mt-2">{$t('settings.password_disabled')}</div> {#if user.disable_password}
{/if} <div class="badge badge-error mt-2">{$t('settings.password_disabled')}</div>
{#if !user.disable_password} {/if}
<div class="badge badge-success mt-2">{$t('settings.password_enabled')}</div> {#if !user.disable_password}
{/if} <div class="badge badge-success mt-2">{$t('settings.password_enabled')}</div>
{#if user.disable_password} {/if}
<div class="alert alert-warning mt-4"> {#if user.disable_password}
{$t('settings.password_disable_warning')} <div class="alert alert-warning mt-4">
</div> {$t('settings.password_disable_warning')}
{/if} </div>
{/if}
</div>
</div> </div>
</div> {/if}
</div> </div>
</section> </section>