Files
OSIT-AE-App-Svelte/src/routes/journals/ae_comp__journal_obj_id_view.svelte
2025-05-15 13:03:43 -04:00

285 lines
10 KiB
Svelte

<script lang="ts">
// *** Import Svelte specific
// *** 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/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) {
log_lvl = 1;
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 = '';
$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" />
{@html $lq__journal_obj?.name ?? 'Loading...'}
{#if $ae_loc.trusted_access && $ae_loc.edit_mode}
({$lq__journal_entry_obj_li?.length ?? '0'}&times;)
{/if}
{#await $journals_prom.load__journal_entry_obj_li}
<span class="fas fa-spinner fa-spin"></span>
{:then}
<!-- done -->
{/await}
</h2>
<section class="relative">
<!-- Menu Button -->
<button
type="button"
onclick={() => (show_menu = !show_menu)}
class="btn variant-outline-secondary hover:variant-filled-secondary transition py-1 px-2 w-24 *:hover:inline"
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 bg-white dark:bg-gray-800 shadow-xl rounded-lg p-4 z-50 w-80 space-y-0.5 border border-gray-500"
>
<div class="flex flex-row flex-wrap gap-1 items-center justify-between">
<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;
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
variant-ghost-secondary
hover:variant-filled-secondary
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
variant-ghost-warning
hover:variant-filled-warning
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>
</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}
<div
class="
prose
space-y-1
m-4
p-2
w-full max-w-screen-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>