Files
OSIT-AE-App-Svelte/src/routes/journals/ae_comp__journal_obj_id_view.svelte
Scott Idem 0987cd6ad9 style: Apply Prettier formatting with 4-space indentation
Applied consistent code formatting across the project using Prettier, now configured to use 4-space indentation instead of tabs.
2025-11-18 18:40:50 -05:00

333 lines
14 KiB
Svelte
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script lang="ts">
// *** Import Svelte specific
import { goto } from '$app/navigation';
// *** Import other supporting libraries
import { BookPlus, BookOpenText, FilePlus, Menu, Pencil } from '@lucide/svelte';
// *** Import Aether specific variables and functions
import { ae_util } from '$lib/ae_utils/ae_utils';
import {
ae_snip,
ae_loc,
ae_sess,
ae_api,
ae_trig,
slct,
slct_trigger
} from '$lib/stores/ae_stores';
import {
journals_loc,
journals_sess,
journals_slct,
journals_trig,
journals_prom
} from '$lib/ae_journals/ae_journals_stores';
import { journals_func } from '$lib/ae_journals/ae_journals_functions';
interface Props {
log_lvl?: number;
lq__journal_obj: any;
lq__journal_entry_obj_li: any;
}
let { log_lvl = 0, lq__journal_obj, lq__journal_entry_obj_li }: Props = $props();
// let ae_promises: key_val = {};
// let ae_tmp: key_val = {};
// let ae_trigger: any = null;
// let ae_triggers: key_val = {};
let show_menu: boolean = $state(false);
let typed_journal_passcode: string = $state('');
let passcode_timer: any = $state(null);
$effect(() => {
if (typed_journal_passcode?.length > 4) {
if (!$journals_sess?.journal_kv) {
$journals_sess.journal_kv = {};
}
if (!$journals_sess.journal_kv[$lq__journal_obj?.id]) {
$journals_sess.journal_kv[$lq__journal_obj?.id] = {};
}
verify_journal_passcode();
}
// We need to set a timeout to force the user to re-enter their private passcode
if (
$lq__journal_obj?.id &&
$journals_sess?.journal_kv[$lq__journal_obj?.id] &&
$journals_sess?.journal_kv[$lq__journal_obj?.id]?.journal_passcode_verified
) {
if (passcode_timer) {
if (log_lvl) {
console.log('Passcode timer already set');
}
return;
}
console.log('Setting passcode timer');
passcode_timer = setTimeout(
() => {
if (log_lvl) {
console.log('Passcode timer expired');
}
typed_journal_passcode = '';
if (!$journals_sess?.journal_kv[$lq__journal_obj?.id]) {
$journals_sess.journal_kv[$lq__journal_obj?.id] = {};
}
$journals_sess.journal_kv[$lq__journal_obj?.id].journal_passcode_verified =
false;
},
1000 * 60 * 1
); // 1 minutes
// }, 1000 * $lq__journal_obj?.passcode_timeout); // 5 minutes
}
});
function verify_journal_passcode() {
if (log_lvl) {
console.log(
`verify_journal_passcode: typed_journal_passcode = ${typed_journal_passcode} journal private passcode = ${$lq__journal_obj?.private_passcode}`
);
}
if (typed_journal_passcode === $lq__journal_obj?.private_passcode) {
console.log('Matched journal private passcode');
if (!$journals_sess?.journal_kv[$lq__journal_obj?.id]) {
$journals_sess.journal_kv[$lq__journal_obj?.id] = {};
}
$journals_sess.journal_kv[$lq__journal_obj?.id] = {
typed_journal_passcode: typed_journal_passcode,
journal_passcode_verified: true
};
typed_journal_passcode = '';
} else {
}
}
</script>
<section
class="
rounded-lg p-2 m-2 w-full
flex flex-col flex-wrap items-center justify-center
bg-{$lq__journal_obj?.cfg_json.color_scheme}-100
text-gray-900 dark:text-gray-900
"
bind:clientHeight={$ae_loc.iframe_height_modal_body}
>
<header
class="ae_header journal__header flex flex-row flex-wrap gap-2 items-center justify-between w-full"
>
<h2 class="journal__name h3 text-center">
<BookOpenText class="inline-block text-neutral-800/60" />
{@html $lq__journal_obj?.name ?? 'Loading...'}
{#if $ae_loc.trusted_access && $ae_loc.edit_mode}
({$lq__journal_entry_obj_li?.length ?? '0'}×)
{/if}
{#await $journals_prom.load__journal_entry_obj_li}
<span class="fas fa-spinner fa-spin"></span>
{:then}
<!-- done -->
{/await}
</h2>
<div class="grow flex flex-row flex-wrap gap-2 items-center justify-end">
<section class="relative transition-all">
<!-- Menu Button -->
<button
type="button"
onclick={() => (show_menu = !show_menu)}
class="
btn
variant-outline-secondary hover:preset-filled-secondary-400-600
py-1 px-2 w-24
transition-all
"
title="Toggle menu"
>
<Menu size="1.5em" class="inline-block" />
<span class="hidden md:inline">Menu</span>
</button>
<!-- Menu -->
<!-- {#if show_menu} -->
<div
class="
absolute top-12 right-0
p-4 z-50 w-80
space-y-0.5
bg-white dark:bg-gray-800
border border-gray-500
shadow-xl rounded-lg
min-w-72
max-w-fit
"
class:hidden={!show_menu}
>
<div
class="
flex flex-row flex-wrap items-center justify-evenly gap-2 w-full
"
>
<span class="text-sm text-gray-500">
<span class="fas fa-info-circle text-blue-500"></span>
Journal ID: {$lq__journal_obj?.id}
</span>
<button
type="button"
onclick={() => {
// $journals_sess.show__modal_new__journal_entry_obj = true
// log_lvl = 3;
let data_kv = {
category_code: null
};
if ($journals_loc.qry__category_code) {
data_kv.category_code = $journals_loc.qry__category_code;
}
if (log_lvl) {
console.log(
'Creating new journal entry with data_kv:',
data_kv
);
}
journals_func
.create_ae_obj__journal_entry({
api_cfg: $ae_api,
journal_id: $lq__journal_obj?.journal_id,
data_kv: data_kv,
log_lvl: log_lvl
})
.then((results) => {
if (log_lvl) {
console.log('New journal entry created:', results);
}
$journals_slct.journal_entry_id =
results?.journal_entry_id_random;
// $journals_loc.entry.edit = true;
$journals_loc.entry.edit_kv[
$journals_slct.journal_entry_id
] = 'current';
// alert(`Journal entry created successfully! ${$journals_slct.journal_entry_id}`);
})
.catch((error) => {
console.error('Error updating journal entry:', error);
alert('Failed to update journal entry.');
})
.finally(() => {
if ($journals_slct.journal_entry_id) {
goto(
`/journals/${$lq__journal_obj?.journal_id}/entry/${$journals_slct.journal_entry_id}`
);
} else {
alert('Failed to create new journal entry.');
}
});
}}
class="
btn btn-sm
preset-tonal-secondary border border-secondary-500
hover:preset-filled-secondary-500
transition
"
title="Create a new journal entry for this journal: {$lq__journal_obj?.name}"
>
<FilePlus />
<!-- <span class="fas fa-plus m-1"></span> -->
<span class="hidden sm:inline"> New Journal Entry </span>
</button>
<button
type="button"
onclick={() => {
$journals_slct.tmp_journal_obj = {
name: $lq__journal_obj?.name,
description: $lq__journal_obj?.description,
type_code: $lq__journal_obj?.type_code,
passcode: $lq__journal_obj?.passcode,
passcode_timeout: $lq__journal_obj?.passcode_timeout,
auth_key: $lq__journal_obj?.auth_key,
cfg_json: $lq__journal_obj?.cfg_json
};
$journals_sess.show__modal_edit__journal_obj = true;
}}
class:hidden={!$ae_loc.edit_mode}
class="
btn btn-sm
preset-tonal-warning border border-warning-500
hover:preset-filled-warning-500
transition
"
title="Edit Journal meta and configuration (name, type, passcode, categories, etc.: {$lq__journal_obj?.name})"
>
<Pencil />
<span class="hidden md:inline"> Edit Journal </span>
</button>
</div>
<!-- Set Journal private_passcode (string) -->
<!-- The Journal private_passcode will be used along with the Journal passcode to encrypt the journal entries. -->
<input
type="text"
bind:value={typed_journal_passcode}
placeholder="Journal passcode"
onchange={() => {
// console.log('HERE');
// verify_journal_passcode();
}}
class="input input-sm input-bordered w-full mb-2"
title="Enter private passcode of this journal"
/>
{#if $journals_sess?.journal_kv[$lq__journal_obj?.id]?.journal_passcode_verified}
<div class="text-sm text-gray-500">
<span class="fas fa-check-circle text-green-500"></span>
Journal passcode verified
</div>
{:else}
<div class="text-sm text-gray-500">
<span class="fas fa-exclamation-circle text-red-500"></span>
Journal passcode not verified {$lq__journal_obj?.private_passcode ??
'??'}
</div>
{/if}
</div>
<!-- {/if} -->
</section>
</div>
</header>
<!-- Show Journal description -->
<!-- class:bg-green-100={$lq__journal_obj?.cfg_json.color_scheme ?? 'green'} -->
<!-- prose-h1:text-gray-100 dark:prose-h1:text-gray-900 -->
<!-- <div> -->
{#if $lq__journal_obj?.description && $ae_loc.edit_mode}
<div
class="
prose
space-y-1
p-2
w-full max-w-(--breakpoint-sm) md:max-w-(--breakpoint-md)
font-mono
text-gray-900
dark:bg-blue-900/40 dark:text-gray-100
shadow-md rounded-lg
text-sm font-normal text-wrap word-break
prose-p:m-0 prose-p:p-0
prose-h1:underline prose-h1:decoration-double
prose-h2:underline
prose-h1:text-2xl prose-h2:text-xl prose-h3:text-lg
prose-h1:m-0 prose-h2:m-0 prose-h3:m-0 prose-h4:m-0 prose-h5:m-0 prose-h6:m-0
prose-li:m-0 prose-li:p-0 prose-li:line-height-none
"
>
{@html $lq__journal_obj.description_md_html}
</div>
{/if}
<!-- </div> -->
</section>