Add geographic coordinates to Transportation model and update related components

This commit is contained in:
Sean Morley
2024-12-19 18:46:52 -05:00
parent 57f2bdb8ba
commit 7c68dc839a
11 changed files with 1025 additions and 289 deletions

View File

@@ -7,6 +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';
export let data;
let user: User;
@@ -154,195 +155,220 @@
/>
{/if}
<h1 class="text-center font-extrabold text-4xl mb-6">{$t('settings.settings_page')}</h1>
<h1 class="text-center font-extrabold text-xl">{$t('settings.account_settings')}</h1>
<div class="flex justify-center">
<form
method="post"
action="?/changeDetails"
use:enhance
class="w-full max-w-xs"
enctype="multipart/form-data"
>
<label for="username">{$t('auth.username')}</label>
<input
bind:value={user.username}
name="username"
id="username"
class="block mb-2 input input-bordered w-full max-w-xs"
/><br />
<label for="first_name">{$t('auth.first_name')}</label>
<input
type="text"
bind:value={user.first_name}
name="first_name"
id="first_name"
class="block mb-2 input input-bordered w-full max-w-xs"
/><br />
<label for="last_name">{$t('auth.last_name')}</label>
<input
type="text"
bind:value={user.last_name}
name="last_name"
id="last_name"
class="block mb-2 input input-bordered w-full max-w-xs"
/><br />
<label for="profilePicture">{$t('auth.profile_picture')}</label>
<input
type="file"
name="profile_pic"
id="profile_pic"
class="file-input file-input-bordered w-full max-w-xs mb-2"
/><br />
<div class="form-control">
<div class="tooltip tooltip-info" data-tip={$t('auth.public_tooltip')}>
<label class="label cursor-pointer">
<span class="label-text">{$t('auth.public_profile')}</span>
<div class="container mx-auto p-6 max-w-4xl">
<h1 class="text-3xl font-extrabold text-center mb-6">
{$t('settings.settings_page')}
</h1>
<!-- Account Settings Section -->
<section class="space-y-8">
<h2 class="text-2xl font-semibold text-center">
{$t('settings.account_settings')}
</h2>
<div class=" bg-neutral p-6 rounded-lg shadow-md">
<form
method="post"
action="?/changeDetails"
use:enhance
enctype="multipart/form-data"
class="space-y-6"
>
<div>
<label for="username" class="text-sm font-medium">{$t('auth.username')}</label>
<input
type="text"
id="username"
name="username"
bind:value={user.username}
class="block w-full mt-1 input input-bordered input-primary"
/>
</div>
<div>
<label for="first_name" class="text-sm font-medium">{$t('auth.first_name')}</label>
<input
type="text"
id="first_name"
name="first_name"
bind:value={user.first_name}
class="block w-full mt-1 input input-bordered input-primary"
/>
</div>
<div>
<label for="last_name" class="text-sm font-medium">{$t('auth.last_name')}</label>
<input
type="text"
id="last_name"
name="last_name"
bind:value={user.last_name}
class="block w-full mt-1 input input-bordered input-primary"
/>
</div>
<div>
<label for="profile_pic" class="text-sm font-medium">{$t('auth.profile_picture')}</label>
<input
type="file"
id="profile_pic"
name="profile_pic"
class="file-input file-input-bordered file-input-primary mt-1 w-full"
/>
</div>
<div class="flex items-center">
<input
type="checkbox"
id="public_profile"
name="public_profile"
type="checkbox"
class="toggle"
checked={user.public_profile}
bind:checked={user.public_profile}
class="toggle toggle-primary"
/>
</label>
</div>
<label for="public_profile" class="ml-2 text-sm">{$t('auth.public_profile')}</label>
</div>
<button class="w-full mt-4 btn btn-primary py-2">{$t('settings.update')}</button>
</form>
</div>
<button class="py-2 mt-2 px-4 btn btn-primary">{$t('settings.update')}</button>
</form>
</div>
</section>
{#if $page.form?.message}
<div class="text-center text-error mt-4">
{$t($page.form.message)}
</div>
{/if}
<h1 class="text-center font-extrabold text-xl mt-4 mb-2">{$t('settings.password_change')}</h1>
<div class="flex justify-center">
<form action="?/changePassword" method="post" class="w-full max-w-xs" use:enhance>
<input
type="password"
name="current_password"
placeholder={$t('settings.current_password')}
id="current_password"
class="block mb-2 input input-bordered w-full max-w-xs"
/>
<br />
<input
type="password"
name="password1"
placeholder={$t('settings.new_password')}
id="password1"
class="block mb-2 input input-bordered w-full max-w-xs"
/>
<br />
<input
type="password"
name="password2"
id="password2"
placeholder={$t('settings.confirm_new_password')}
class="block mb-2 input input-bordered w-full max-w-xs"
/>
<div class="tooltip tooltip-warning" data-tip={$t('settings.password_change_lopout_warning')}>
<button class="py-2 px-4 btn btn-primary mt-2">{$t('settings.password_change')}</button>
</div>
<br />
</form>
</div>
<h1 class="text-center font-extrabold text-xl mt-4 mb-2">{$t('settings.email_change')}</h1>
<div class="flex justify-center mb-4">
<div>
{#each emails as email}
<p class="mb-2">
{email.email}
{#if email.verified}
<div class="badge badge-success">{$t('settings.verified')}</div>
{:else}
<div class="badge badge-error">{$t('settings.not_verified')}</div>
{/if}
{#if email.primary}
<div class="badge badge-primary">{$t('settings.primary')}</div>
{/if}
{#if !email.verified}
<button class="btn btn-sm btn-secondary ml-2" on:click={() => verifyEmail(email)}
>{$t('settings.verify')}</button
<!-- Password Change Section -->
<section class="space-y-8">
<h2 class="text-2xl font-semibold text-center mt-8">
{$t('settings.password_change')}
</h2>
<div class="bg-neutral p-6 rounded-lg shadow-md">
<form method="post" action="?/changePassword" use:enhance class="space-y-6">
<div>
<label for="current_password" class="text-sm font-medium"
>{$t('settings.current_password')}</label
>
{/if}
{#if !email.primary}
<button class="btn btn-sm btn-secondary ml-2" on:click={() => primaryEmail(email)}
>{$t('settings.make_primary')}</button
<input
type="password"
id="current_password"
name="current_password"
class="block w-full mt-1 input input-bordered input-primary"
/>
</div>
<div>
<label for="password1" class="text-sm font-medium">{$t('settings.new_password')}</label>
<input
type="password"
id="password1"
name="password1"
class="block w-full mt-1 input input-bordered input-primary"
/>
</div>
<div>
<label for="password2" class="text-sm font-medium"
>{$t('settings.confirm_new_password')}</label
>
{/if}
<button class="btn btn-sm btn-warning ml-2" on:click={() => removeEmail(email)}
>{$t('adventures.remove')}</button
<input
type="password"
id="password2"
name="password2"
class="block w-full mt-1 input input-bordered input-primary"
/>
</div>
<div
class="tooltip tooltip-warning"
data-tip={$t('settings.password_change_lopout_warning')}
>
</p>
{/each}
{#if emails.length === 0}
<p>{$t('settings.no_emai_set')}</p>
{/if}
</div>
</div>
<div class="flex justify-center mt-4">
<form class="w-full max-w-xs" on:submit={addEmail}>
<div class="mb-4">
<input
type="email"
name="new_email"
placeholder={$t('settings.new_email')}
bind:value={new_email}
id="new_email"
class="block mb-2 input input-bordered w-full max-w-xs"
/>
<button class="w-full btn btn-primary py-2 mt-4">{$t('settings.password_change')}</button>
</div>
</form>
</div>
<div>
<button class="py-2 px-4 mb-4 btn btn-primary">{$t('settings.email_change')}</button>
</section>
<!-- Email Change Section -->
<section class="space-y-8">
<h2 class="text-2xl font-semibold text-center mt-8">
{$t('settings.email_change')}
</h2>
<div class="bg-neutral p-6 rounded-lg shadow-md">
<div>
{#each emails as email}
<div class="flex items-center space-x-2 mb-2">
<span>{email.email}</span>
{#if email.verified}
<div class="badge badge-success">{$t('settings.verified')}</div>
{:else}
<div class="badge badge-error">{$t('settings.not_verified')}</div>
{/if}
{#if email.primary}
<div class="badge badge-primary">{$t('settings.primary')}</div>
{/if}
{#if !email.verified}
<button class="btn btn-sm btn-secondary" on:click={() => verifyEmail(email)}
>{$t('settings.verify')}</button
>
{/if}
{#if !email.primary}
<button class="btn btn-sm btn-secondary" on:click={() => primaryEmail(email)}
>{$t('settings.make_primary')}</button
>
{/if}
<button class="btn btn-sm btn-warning" on:click={() => removeEmail(email)}
>{$t('adventures.remove')}</button
>
</div>
{/each}
{#if emails.length === 0}
<p class="text-center">{$t('settings.no_email_set')}</p>
{/if}
</div>
<form class="mt-4" on:submit={addEmail}>
<input
type="email"
id="new_email"
name="new_email"
bind:value={new_email}
placeholder={$t('settings.new_email')}
class="block w-full input input-bordered input-primary"
/>
<button class="w-full mt-4 btn btn-primary py-2">{$t('settings.email_change')}</button>
</form>
</div>
</form>
</section>
<!-- MFA Section -->
<section class="space-y-8">
<h2 class="text-2xl font-semibold text-center mt-8">
{$t('settings.mfa_page_title')}
</h2>
<div class="bg-neutral p-6 rounded-lg shadow-md text-center">
{#if !data.props.authenticators}
<p>{$t('settings.mfa_not_enabled')}</p>
<button class="btn btn-primary mt-4" on:click={() => (isMFAModalOpen = true)}
>{$t('settings.enable_mfa')}</button
>
{:else}
<button class="btn btn-warning mt-4" on:click={disableMfa}
>{$t('settings.disable_mfa')}</button
>
{/if}
</div>
</section>
<!-- Visited Region Check Section -->
<section class="text-center mt-8">
<h2 class="text-2xl font-semibold">{$t('adventures.visited_region_check')}</h2>
<p>{$t('adventures.visited_region_check_desc')}</p>
<button class="btn btn-neutral mt-4" on:click={checkVisitedRegions}
>{$t('adventures.update_visited_regions')}</button
>
</section>
<small class="text-center block mt-8">
<b>For Debug Use:</b> UUID={user.uuid} | Staff user: {user.is_staff} | {appTitle}
{appVersion}
</small>
</div>
<h1 class="text-center font-extrabold text-xl mt-4 mb-2">{$t('settings.mfa_page_title')}</h1>
<div class="flex justify-center mb-4">
<div>
{#if !data.props.authenticators}
<p>{$t('settings.mfa_not_enabled')}</p>
<button class="btn btn-primary mt-2" on:click={() => (isMFAModalOpen = true)}
>{$t('settings.enable_mfa')}</button
>
{:else}
<button class="btn btn-warning mt-2" on:click={disableMfa}
>{$t('settings.disable_mfa')}</button
>
{/if}
</div>
</div>
<div class="flex flex-col items-center mt-4">
<h1 class="text-center font-extrabold text-xl mt-4 mb-2">
{$t('adventures.visited_region_check')}
</h1>
<p>
{$t('adventures.visited_region_check_desc')}
</p>
<p>{$t('adventures.update_visited_regions_disclaimer')}</p>
<button class="btn btn-neutral mt-2 mb-2" on:click={checkVisitedRegions}
>{$t('adventures.update_visited_regions')}</button
>
</div>
<small class="text-center"
><b>For Debug Use:</b> UUID={user.uuid} | Staff user: {user.is_staff}</small
>
<svelte:head>
<title>User Settings | AdventureLog</title>
<meta