feat(sys-bar): polish sign-in forms, fix passcode flow, dynamic section headers

Sign In/Out (e_app_sign_in_out.svelte):
- Remove redundant internal header (sr-only was broken by :global CSS override)
- Full-width form inputs and buttons with 'or' divider between the two methods
- Signed-in state shows centered username and full-width action buttons

Access/Passcode (e_app_access_type.svelte):
- Fix 'Locked' button: was running trigger=true (no-op permission reprocess);
  now correctly toggles show_passcode_input so the input shows/hides on click

System bar (e_app_sys_bar.svelte):
- Dynamic section headers: Sign In/Out shows username when signed in;
  Access/Passcode shows ShieldEllipsis/ShieldMinus/ShieldUser based on state
- Fix passcode input not showing on re-open via menu button:
  onDestroy resets show_element__passcode_input=false; toggle_expand now
  restores it to true for anonymous/no-access state (matches handle_shield_click)
- Broaden anonymous check from === 'anonymous' to !access_type || === 'anonymous'
- Remove dead getElementById focus call (DOM not ready at that point;
  focus_input binding in Element_access_type handles it correctly)
- Appearance section: mode/font buttons at top, dark mode gets amber tint
  in light mode for visual context, theme select uses text-sm

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Scott Idem
2026-03-13 16:59:04 -04:00
parent 50bfe2f64b
commit 0b9272e9f9
3 changed files with 108 additions and 183 deletions

View File

@@ -16,10 +16,7 @@
LockKeyhole,
Mail,
MailCheck,
ShieldUser,
User,
UserCheck,
UserLock
UserCheck
} from '@lucide/svelte';
// *** Import Aether specific variables and functions
@@ -373,44 +370,11 @@
"
class:hidden
>
<header class:hidden={!$ae_sess.show__sign_in_out__fields} class="ae_header w-full">
<h2 class="text-sm text-center font-semibold">
{#if $ae_loc?.person_id && $ae_loc?.user_id}
<!-- <button
type="button"
class="btn btn-sm variant-outline-surface hover:variant-filled-surface"
title="Show/Hide Sign-In/Out Options"
onclick={() => {
$ae_sess.show__sign_in_out__fields = !$ae_sess.show__sign_in_out__fields; // Toggle the visibility of the sign-in form
}}
> -->
{$ae_loc?.person?.full_name_override ?? $ae_loc?.person?.full_name}
<!-- <span class="text-sm text-gray-500">
{$ae_loc?.user.username ?? '-- not set --'}
</span> -->
<!-- {#if log_lvl > 1}
<span class="text-xs text-gray-500">({$ae_loc.person_id} / {$ae_loc.user_id})</span>
{/if} -->
<!-- </button> -->
{:else}
<!-- <LogIn class="mx-1" /> -->
User Sign In
{/if}
</h2>
</header>
<span
class:hidden={!$ae_sess.show__sign_in_out__fields}
class="flex flex-col gap-1 transition-all w-full"
>
<span class="flex flex-col gap-2 w-full">
{#if !$ae_loc?.person_id && !$ae_loc?.user_id}
<!-- Form for user look up based on email address -->
<form
class="
ae_sign_in_form
flex flex-col gap-1 items-end justify-center
p-1 my-1
"
class="ae_sign_in_form flex flex-col gap-2 w-full"
onsubmit={async (e) => {
e.preventDefault();
if ($ae_sess.auth__entered_email) {
@@ -423,32 +387,34 @@
}
}}
>
<div class="text-xs text-gray-400 dark:text-gray-500 font-medium">Email magic link</div>
<input
type="text"
class="input max-w-48"
class="input w-full text-sm"
placeholder="Email Address"
value={$ae_sess.auth__entered_email ?? ''}
oninput={(e) => ($ae_sess.auth__entered_email = (e.target as HTMLInputElement).value)}
/>
<button
type="submit"
class="btn btn-sm preset-tonal-secondary border border-secondary-500 hover:preset-filled-secondary-500"
class="btn btn-sm preset-tonal-secondary border border-secondary-500 hover:preset-filled-secondary-500 w-full justify-center"
title="Look up user by email and send sign in email"
>
<!-- <User class="mx-1" /> -->
<!-- <Mail class="mx-1" /> -->
<MailCheck class="mx-1" />
Email Sign In
<MailCheck size="1em" class="shrink-0" />
<span class="ml-1">Send Sign In Email</span>
</button>
</form>
<!-- Divider between the two sign-in methods -->
<div class="flex items-center gap-2 text-xs text-gray-400 dark:text-gray-600">
<div class="flex-1 border-t border-gray-200/60 dark:border-gray-700/60"></div>
<span>or</span>
<div class="flex-1 border-t border-gray-200/60 dark:border-gray-700/60"></div>
</div>
<!-- We need to get the person's linked User ID and auth_key or User username and password to sign in. -->
<form
class="
ae_sign_in_form
flex flex-col gap-1 items-end
p-1 my-1
"
class="ae_sign_in_form flex flex-col gap-2 w-full"
onsubmit={async (e) => {
e.preventDefault();
@@ -657,17 +623,24 @@
}
}}
>
<div class="text-xs text-gray-400 dark:text-gray-500 font-medium">
{#if $ae_sess.auth__entered_user_id}
User ID &amp; Auth Key
{:else}
Username &amp; password
{/if}
</div>
{#if $ae_sess.auth__entered_user_id}
<input
type="text"
class="input max-w-36"
class="input w-full text-sm"
placeholder="User ID"
value={$ae_sess.auth__entered_user_id ?? ''}
oninput={(e) => ($ae_sess.auth__entered_user_id = (e.target as HTMLInputElement).value)}
/>
<input
type="text"
class="input max-w-36"
class="input w-full text-sm"
placeholder="Auth Key"
value={$ae_sess.auth__entered_user_key ?? ''}
oninput={(e) => ($ae_sess.auth__entered_user_key = (e.target as HTMLInputElement).value)}
@@ -675,14 +648,14 @@
{:else}
<input
type="text"
class="input max-w-48"
class="input w-full text-sm"
placeholder="Username"
value={$ae_sess.auth__entered_username ?? ''}
oninput={(e) => ($ae_sess.auth__entered_username = (e.target as HTMLInputElement).value)}
/>
<input
type="password"
class="input max-w-48"
class="input w-full text-sm"
placeholder="Password"
value={$ae_sess.auth__entered_password ?? ''}
oninput={(e) => ($ae_sess.auth__entered_password = (e.target as HTMLInputElement).value)}
@@ -691,44 +664,42 @@
<button
type="submit"
class="btn btn-sm preset-tonal-secondary border border-secondary-500 hover:preset-filled-secondary-500"
class="btn btn-sm preset-tonal-secondary border border-secondary-500 hover:preset-filled-secondary-500 w-full justify-center"
title="Sign in with username and password"
>
<!-- <LogIn class="mx-1" /> -->
<UserCheck class="mx-1" />
{#if $ae_sess.auth__entered_user_id}
User ID
{:else}
Username
{/if}
Sign In
<UserCheck size="1em" class="shrink-0" />
<span class="ml-1">
{#if $ae_sess.auth__entered_user_id}User ID{:else}Username{/if}
Sign In
</span>
</button>
</form>
{:else}
<div class="flex flex-col gap-1 items-center justify-center">
<span class="text-sm text-gray-500">
<!-- Signed in: show username, optional change password, sign out -->
<div class="flex flex-col gap-2 items-stretch w-full">
<div class="text-sm text-center text-gray-500 dark:text-gray-400 py-1 font-medium">
{$ae_loc?.user?.username ?? '-- not set --'}
</span>
</div>
<!-- Display change password option if the user is signed in and in Edit Mode -->
<!-- Change password — edit mode only -->
{#if $ae_loc.edit_mode}
<button
type="button"
class="btn btn-sm preset-tonal-warning border border-warning-500 hover:preset-filled-warning-500"
class="btn btn-sm preset-tonal-warning border border-warning-500 hover:preset-filled-warning-500 w-full justify-center"
title="Change Password"
onclick={() => {
$ae_sess.show__modal_change_password = true;
}}
>
<LockKeyhole class="mx-1" />
<span class="hidden sm:inline"> Change Password </span>
<LockKeyhole size="1em" class="shrink-0" />
<span class="ml-1">Change Password</span>
</button>
{/if}
<!-- Display sign out option if the user is signed in -->
<!-- Sign out -->
<button
type="button"
class="btn btn-sm preset-tonal-warning border border-warning-500 hover:preset-filled-warning-500"
class="btn btn-sm preset-tonal-warning border border-warning-500 hover:preset-filled-warning-500 w-full justify-center"
title="Sign Out"
onclick={async () => {
if (confirm('Are you sure you want to sign out?')) {
@@ -736,83 +707,13 @@
}
}}
>
<LogOut class="mx-1" />
<span class="hidden sm:inline"> Sign Out </span>
<LogOut size="1em" class="shrink-0" />
<span class="ml-1">Sign Out</span>
</button>
</div>
{/if}
</span>
<div class="flex flex-row gap-1 items-center justify-between w-full transition-all">
<span>
{#if $ae_loc?.person_id && $ae_loc?.user_id}
<span class="fas fa-user mx-1 text-gray-500"></span>
{$ae_loc?.person?.full_name_override ?? $ae_loc?.person?.full_name}
{:else}
<!-- <span class="fas fa-user-x mx-1 text-gray-500"></span> -->
<ShieldUser class="inline-block text-gray-500" />
User sign in:
{/if}
</span>
<button
type="button"
class="
btn btn-sm text-xs
variant-outline-warning hover:preset-tonal-warning
border border-warning-500 group
"
title="Sign In"
onclick={() => {
$ae_sess.show__sign_in_out__fields = !$ae_sess.show__sign_in_out__fields; // Toggle the visibility of the sign-in form
if (!$ae_sess.show__sign_in_out__fields) {
$ae_sess.app_cfg.show_element__passcode_input = true;
}
}}
>
{#if $ae_loc?.person_id && $ae_loc?.user_id}
{#if $ae_sess.show__sign_in_out__fields}
<CircleX class="m-1" />
<span
class="
cfg_text
hidden
group-hover:inline
"
>
Hide Sign-In
</span>
{:else}
<User class="mx-1 inline-block text-gray-500" />
{$ae_loc?.person?.full_name_override ?? $ae_loc?.person?.full_name}
{/if}
{:else if $ae_sess.show__sign_in_out__fields}
<CircleX class="mx-1" />
<span
class="
cfg_text
hidden
group-hover:inline
"
>
Hide Sign-In
</span>
{:else}
<!-- <LockKeyhole size="1.25em" class="mx-1 inline-block text-gray-500" /> -->
<UserLock size="1.25em" class="m-1 inline-block text-gray-500" />
<!-- <User class="mx-1 inline-block text-gray-500" /> -->
<span
class="
cfg_text
hidden
group-hover:inline
"
>
User Sign-In
</span>
{/if}
</button>
</div>
</section>
<!-- Change Password Modal -->