Working on new Aether App Menu.
This commit is contained in:
@@ -23,6 +23,7 @@ import {
|
|||||||
auth_ae_obj__user_id_user_auth_key,
|
auth_ae_obj__user_id_user_auth_key,
|
||||||
send_email_auth_ae_obj__user_id,
|
send_email_auth_ae_obj__user_id,
|
||||||
qry_ae_obj_li__user_email,
|
qry_ae_obj_li__user_email,
|
||||||
|
auth_ae_obj__user_id_change_password,
|
||||||
// handle_load_ae_obj_id__user,
|
// handle_load_ae_obj_id__user,
|
||||||
// handle_load_ae_obj_li__user,
|
// handle_load_ae_obj_li__user,
|
||||||
// handle_create_ae_obj__user,
|
// handle_create_ae_obj__user,
|
||||||
@@ -446,6 +447,7 @@ let export_obj = {
|
|||||||
auth_ae_obj__user_id_user_auth_key: auth_ae_obj__user_id_user_auth_key,
|
auth_ae_obj__user_id_user_auth_key: auth_ae_obj__user_id_user_auth_key,
|
||||||
send_email_auth_ae_obj__user_id: send_email_auth_ae_obj__user_id,
|
send_email_auth_ae_obj__user_id: send_email_auth_ae_obj__user_id,
|
||||||
qry_ae_obj_li__user_email: qry_ae_obj_li__user_email,
|
qry_ae_obj_li__user_email: qry_ae_obj_li__user_email,
|
||||||
|
auth_ae_obj__user_id_change_password: auth_ae_obj__user_id_change_password,
|
||||||
handle_update_ae_obj_id_crud: handle_update_ae_obj_id_crud,
|
handle_update_ae_obj_id_crud: handle_update_ae_obj_id_crud,
|
||||||
handle_download_export__obj_type: handle_download_export__obj_type,
|
handle_download_export__obj_type: handle_download_export__obj_type,
|
||||||
generate_qr_code: generate_qr_code
|
generate_qr_code: generate_qr_code
|
||||||
|
|||||||
@@ -146,6 +146,11 @@ export let ae_app_local_data_struct: key_val = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
app_cfg: {
|
app_cfg: {
|
||||||
|
show_element__header: false,
|
||||||
|
show_element__footer: false,
|
||||||
|
show_element__menu: false,
|
||||||
|
show_element__menu_btn: false,
|
||||||
|
|
||||||
show_element__access_type: true,
|
show_element__access_type: true,
|
||||||
show_element__cfg: true,
|
show_element__cfg: true,
|
||||||
show_element__cfg_detail: false,
|
show_element__cfg_detail: false,
|
||||||
|
|||||||
@@ -215,9 +215,17 @@ function handle_clear_access() {
|
|||||||
|
|
||||||
|
|
||||||
<section
|
<section
|
||||||
id="AE-Quick-Access-Type"
|
id="xAE-Quick-Access-Type"
|
||||||
class="
|
class="
|
||||||
ae_access_type bg-surface-100 text-surface-800 duration-300 delay-150 hover:delay-1000 hover:ease-out transition-all hover:transition-all hidden-print flex flex-col items-end gap-1
|
ae_access_type
|
||||||
|
hidden-print
|
||||||
|
bg-surface-100 text-surface-800
|
||||||
|
duration-300 delay-150 hover:delay-1000 hover:ease-out
|
||||||
|
transition-all hover:transition-all
|
||||||
|
flex flex-col flex-wrap gap-1
|
||||||
|
items-end justify-center
|
||||||
|
max-w-64
|
||||||
|
|
||||||
"
|
"
|
||||||
class:hidden={hidden}
|
class:hidden={hidden}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -91,7 +91,19 @@ function handle_clear_storage(item: null|string) {
|
|||||||
|
|
||||||
|
|
||||||
<!-- transition duration-500 delay-1000 hover:duration-500 hover:delay-1000 hover:transition-all -->
|
<!-- transition duration-500 delay-1000 hover:duration-500 hover:delay-1000 hover:transition-all -->
|
||||||
<section id="AE-App-Cfg" class="ae_app_cfg bg-surface-100 text-surface-800 transition hover:transition-all hidden-print">
|
<section
|
||||||
|
id="xAE-App-Cfg"
|
||||||
|
class="
|
||||||
|
ae_app_cfg
|
||||||
|
hidden-print
|
||||||
|
bg-surface-100 text-surface-800
|
||||||
|
transition hover:transition-all
|
||||||
|
flex flex-col flex-wrap gap-1
|
||||||
|
items-center justify-center
|
||||||
|
max-w-72
|
||||||
|
|
||||||
|
"
|
||||||
|
>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="ae_cfg_content text-xs space-y-4 my-4"
|
class="ae_cfg_content text-xs space-y-4 my-4"
|
||||||
|
|||||||
@@ -3,10 +3,13 @@
|
|||||||
// *** Import Svelte specific
|
// *** Import Svelte specific
|
||||||
import { browser } from '$app/environment';
|
import { browser } from '$app/environment';
|
||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
|
import { Modal } from 'flowbite-svelte';
|
||||||
|
|
||||||
// *** Import other supporting libraries
|
// *** Import other supporting libraries
|
||||||
import {
|
import {
|
||||||
CircleX,
|
CircleX,
|
||||||
|
Eye, EyeOff,
|
||||||
|
Key,
|
||||||
LogIn, LogOut, LockKeyhole,
|
LogIn, LogOut, LockKeyhole,
|
||||||
Mail, MailCheck,
|
Mail, MailCheck,
|
||||||
User, UserCheck
|
User, UserCheck
|
||||||
@@ -52,7 +55,6 @@ let user_obj: key_val = $state({}); // Use $state to ensure reactivity
|
|||||||
let person_id = $state(null); // Use $state to ensure reactivity
|
let person_id = $state(null); // Use $state to ensure reactivity
|
||||||
let person_obj: key_val = $state({}); // Use $state to ensure reactivity
|
let person_obj: key_val = $state({}); // Use $state to ensure reactivity
|
||||||
|
|
||||||
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
if (user_id && person_id && trigger) {
|
if (user_id && person_id && trigger) {
|
||||||
// alert(`Ready to sign in person! \n\nuser_id: ${user_id}\nperson_id: ${person_id}\n\nThis is a test alert to confirm the values are set.`);
|
// alert(`Ready to sign in person! \n\nuser_id: ${user_id}\nperson_id: ${person_id}\n\nThis is a test alert to confirm the values are set.`);
|
||||||
@@ -62,6 +64,12 @@ $effect(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
let new_password = '';
|
||||||
|
let confirm_password = '';
|
||||||
|
let is_changing_password = false;
|
||||||
|
let show_password_text = $state('password'); // password or text
|
||||||
|
|
||||||
|
|
||||||
function sign_in() {
|
function sign_in() {
|
||||||
$ae_loc.person_id = person_id; // Set the person_id in the ae_loc store
|
$ae_loc.person_id = person_id; // Set the person_id in the ae_loc store
|
||||||
$ae_loc.person = person_obj; // Store the full person object for reference
|
$ae_loc.person = person_obj; // Store the full person object for reference
|
||||||
@@ -201,19 +209,54 @@ function handle_lookup_user_email({email}: {email: string}) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async function handle_change_password() {
|
||||||
|
if (new_password !== confirm_password) {
|
||||||
|
alert('Passwords do not match.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!new_password) {
|
||||||
|
alert('Password cannot be empty.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
is_changing_password = true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
await core_func.auth_ae_obj__user_id_change_password({
|
||||||
|
api_cfg: $ae_api,
|
||||||
|
account_id: $ae_loc.account_id,
|
||||||
|
user_id: $ae_loc.user_id,
|
||||||
|
password: new_password,
|
||||||
|
log_lvl: 1
|
||||||
|
});
|
||||||
|
alert('Password changed successfully.');
|
||||||
|
$ae_sess.show__modal_change_password = false;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error changing password:', error);
|
||||||
|
alert('Failed to change password.');
|
||||||
|
} finally {
|
||||||
|
is_changing_password = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
<!-- It is important to keep in mind that a Person can only fully sign in if they have a linked User record. -->
|
<!-- It is important to keep in mind that a Person can only fully sign in if they have a linked User record. -->
|
||||||
<!-- *:hover:inline -->
|
<!-- *:hover:inline -->
|
||||||
<section
|
<section
|
||||||
id="AE-Sign-In-Out"
|
id="xAE-Sign-In-Out"
|
||||||
class="
|
class="
|
||||||
ae_sign_in_out
|
ae_sign_in_out
|
||||||
hidden-print
|
hidden-print
|
||||||
bg-surface-100 text-surface-800
|
bg-surface-100 text-surface-800
|
||||||
transition-all duration-300 delay-150 hover:delay-1000 hover:ease-out hover:transition-all
|
transition-all duration-300 delay-150 hover:delay-1000 hover:ease-out hover:transition-all
|
||||||
flex flex-col flex-wrap items-start gap-1
|
flex flex-col flex-wrap gap-1
|
||||||
|
items-center justify-center
|
||||||
|
max-w-64
|
||||||
|
|
||||||
"
|
"
|
||||||
class:hidden={hidden}
|
class:hidden={hidden}
|
||||||
>
|
>
|
||||||
@@ -290,8 +333,7 @@ function handle_lookup_user_email({email}: {email: string}) {
|
|||||||
<form
|
<form
|
||||||
class="
|
class="
|
||||||
ae_sign_in_form
|
ae_sign_in_form
|
||||||
flex flex-col items-start gap-1
|
flex flex-col gap-1 items-center justify-center
|
||||||
p-1
|
|
||||||
p-1 my-1
|
p-1 my-1
|
||||||
border-2 border-gray-200
|
border-2 border-gray-200
|
||||||
"
|
"
|
||||||
@@ -330,7 +372,7 @@ function handle_lookup_user_email({email}: {email: string}) {
|
|||||||
<form
|
<form
|
||||||
class="
|
class="
|
||||||
ae_sign_in_form
|
ae_sign_in_form
|
||||||
flex flex-col items-start gap-1
|
flex flex-col gap-1 items-center
|
||||||
p-1 my-1
|
p-1 my-1
|
||||||
border-2 border-gray-200
|
border-2 border-gray-200
|
||||||
"
|
"
|
||||||
@@ -564,7 +606,7 @@ function handle_lookup_user_email({email}: {email: string}) {
|
|||||||
|
|
||||||
{:else}
|
{:else}
|
||||||
|
|
||||||
<div class="flex flex-col items-start gap-1">
|
<div class="flex flex-col gap-1 items-center justify-center">
|
||||||
<span class="text-sm text-gray-500">
|
<span class="text-sm text-gray-500">
|
||||||
{$ae_loc?.user.username ?? '-- not set --'}
|
{$ae_loc?.user.username ?? '-- not set --'}
|
||||||
</span>
|
</span>
|
||||||
@@ -610,14 +652,101 @@ function handle_lookup_user_email({email}: {email: string}) {
|
|||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<!-- Change Password Modal -->
|
||||||
|
<!-- They should be able to see their password (text) -->
|
||||||
|
<!-- autocomplete="off" -->
|
||||||
|
{#if $ae_sess.show__modal_change_password}
|
||||||
|
<Modal
|
||||||
|
title="Change Password"
|
||||||
|
bind:open={$ae_sess.show__modal_change_password}
|
||||||
|
autoclose={false}
|
||||||
|
placement="top-center"
|
||||||
|
size="md"
|
||||||
|
class="top-center bg-white dark:bg-gray-800 text-gray-800 dark:text-gray-200 rounded-lg border-gray-200 dark:border-gray-700 divide-gray-200 dark:divide-gray-700 shadow-md relative mx-auto w-full divide-y"
|
||||||
|
>
|
||||||
|
<div class="modal-box flex flex-col gap-2 items-center justify-center">
|
||||||
|
<div class="flex flex-row flex-wrap gap-2">
|
||||||
|
<span class="flex flex-row flex-wrap gap-1">
|
||||||
|
<input
|
||||||
|
type={show_password_text}
|
||||||
|
autocomplete="new-password"
|
||||||
|
name="new_password"
|
||||||
|
placeholder="New Password"
|
||||||
|
bind:value={new_password}
|
||||||
|
class="input input-bordered w-48 max-w-full"
|
||||||
|
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
type={show_password_text}
|
||||||
|
autocomplete="off"
|
||||||
|
name="confirm_password"
|
||||||
|
placeholder="Confirm Password"
|
||||||
|
bind:value={confirm_password}
|
||||||
|
class="input input-bordered w-48 max-w-full"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<!-- Show/Hide Password Text -->
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="btn btn-icon variant-soft-secondary"
|
||||||
|
onclick={() => {
|
||||||
|
// const inputs = document.querySelectorAll('.modal-box input[type="password"]');
|
||||||
|
// inputs.forEach((input) => {
|
||||||
|
// input.type = input.type === 'password' ? 'text' : 'password';
|
||||||
|
// });
|
||||||
|
if (show_password_text === 'password') {
|
||||||
|
show_password_text = 'text';
|
||||||
|
} else {
|
||||||
|
show_password_text = 'password';
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
title="Show/Hide Password Text"
|
||||||
|
>
|
||||||
|
{#if show_password_text === 'password'}
|
||||||
|
<EyeOff class="mx-1"/>
|
||||||
|
{:else}
|
||||||
|
<Eye class="mx-1"/>
|
||||||
|
{/if}
|
||||||
|
<!-- <Eye class="mx-1"/> -->
|
||||||
|
<!-- <span class="hidden sm:inline">
|
||||||
|
Show/Hide
|
||||||
|
</span> -->
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex flex-row flex-wrap gap-2">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="btn variant-filled-warning"
|
||||||
|
onclick={handle_change_password}
|
||||||
|
disabled={is_changing_password}
|
||||||
|
>
|
||||||
|
<Key class="mx-1" />
|
||||||
|
Change Password
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="btn variant-glass-secondary"
|
||||||
|
onclick={() => ($ae_sess.show__modal_change_password = false)}
|
||||||
|
>
|
||||||
|
<CircleX class="mx-1" />
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
{/if}
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
/* BEGIN: AE's Svelte Quick Access Type component */
|
/* BEGIN: AE's Svelte Quick Access Type component */
|
||||||
#AE-Sign-In-Out {
|
#AE-Sign-In-Out {
|
||||||
/* position: absolute; */
|
// outline: red solid thin;
|
||||||
|
// position: absolute;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
/* position: relative; */
|
// position: relative;
|
||||||
/* position: static; */
|
// position: static;
|
||||||
/* position: sticky; */
|
// position: sticky;
|
||||||
/* top: 1em; */
|
/* top: 1em; */
|
||||||
bottom: 1.5rem;
|
bottom: 1.5rem;
|
||||||
left: 0rem;
|
left: 0rem;
|
||||||
@@ -644,7 +773,7 @@ function handle_lookup_user_email({email}: {email: string}) {
|
|||||||
|
|
||||||
/* NOTE: transition when no longer hovering */
|
/* NOTE: transition when no longer hovering */
|
||||||
transition-property: opacity, background-color;
|
transition-property: opacity, background-color;
|
||||||
transition-delay: 1.25s;
|
transition-delay: 3.25s;
|
||||||
transition-duration: .75s;
|
transition-duration: .75s;
|
||||||
transition-timing-function: ease-out;
|
transition-timing-function: ease-out;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -444,6 +444,38 @@ $effect(() => {
|
|||||||
|
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
<!-- min-h-full
|
||||||
|
max-h-max
|
||||||
|
min-w-full
|
||||||
|
max-w-max -->
|
||||||
|
<!-- Show menu on right side of page -->
|
||||||
|
<section
|
||||||
|
class="
|
||||||
|
ae_app__menu
|
||||||
|
hidden-print
|
||||||
|
flex flex-col
|
||||||
|
items-end justify-center
|
||||||
|
gap-4
|
||||||
|
min-h-96
|
||||||
|
min-w-48
|
||||||
|
absolute right-0 bottom-10
|
||||||
|
bg-white dark:bg-gray-800
|
||||||
|
border border-gray-200 dark:border-gray-700
|
||||||
|
rounded-lg
|
||||||
|
p-4
|
||||||
|
"
|
||||||
|
>
|
||||||
|
|
||||||
|
<!-- {#if $ae_loc?.app_cfg?.show_element__cfg} -->
|
||||||
|
<span
|
||||||
|
class:hidden={!$ae_loc?.app_cfg?.show_element__cfg || !$ae_loc.edit_mode}
|
||||||
|
>
|
||||||
|
<Element_app_cfg
|
||||||
|
set_theme_mode={true}
|
||||||
|
set_theme_name={true}
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
<!-- {/if} -->
|
||||||
|
|
||||||
{#if $ae_loc.app_cfg?.show_element__sign_in_out}
|
{#if $ae_loc.app_cfg?.show_element__sign_in_out}
|
||||||
<Element_sign_in_out
|
<Element_sign_in_out
|
||||||
@@ -460,23 +492,20 @@ $effect(() => {
|
|||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
|
||||||
<!-- {#if $ae_loc?.app_cfg?.show_element__cfg} -->
|
</section>
|
||||||
<span
|
|
||||||
class:hidden={!$ae_loc?.app_cfg?.show_element__cfg || !$ae_loc.edit_mode}
|
|
||||||
>
|
|
||||||
<Element_app_cfg
|
|
||||||
set_theme_mode={true}
|
|
||||||
set_theme_name={true}
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
<!-- {/if} -->
|
|
||||||
|
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="flex text-sm sm:text-sm md:text-md lg:text-md xl:text-md 2xl:text-lg text-slate-400 hover:text-slate-800 transition px-1 hidden"
|
class="absolute bottom-0 left-0 flex text-sm sm:text-sm md:text-md lg:text-md xl:text-md 2xl:text-lg text-slate-400 hover:text-slate-800 transition px-1 w-full outline"
|
||||||
class:ae_debug={$ae_loc.debug}
|
class:ae_debug={$ae_loc.debug}
|
||||||
>
|
>
|
||||||
<button
|
<!-- {#if $ae_loc.app_cfg?.show_element__sign_in_out}
|
||||||
|
<Element_sign_in_out
|
||||||
|
data={data}
|
||||||
|
hidden={$ae_loc.iframe || !$ae_loc.app_cfg?.show_element__sign_in_out}
|
||||||
|
/>
|
||||||
|
{/if} -->
|
||||||
|
|
||||||
|
<!-- <button
|
||||||
type="button"
|
type="button"
|
||||||
onclick={() => {
|
onclick={() => {
|
||||||
console.log('Debug ae_loc:', $ae_loc);
|
console.log('Debug ae_loc:', $ae_loc);
|
||||||
@@ -487,7 +516,13 @@ $effect(() => {
|
|||||||
title="Turn debug content and styles off and on"
|
title="Turn debug content and styles off and on"
|
||||||
>
|
>
|
||||||
π
|
π
|
||||||
</button>
|
</button> -->
|
||||||
|
|
||||||
|
<!-- {#if $ae_loc.app_cfg?.show_element__access_type}
|
||||||
|
<Element_access_type
|
||||||
|
hidden={$ae_loc.iframe && !$ae_loc.trusted_access}
|
||||||
|
/>
|
||||||
|
{/if} -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user