285 lines
10 KiB
Svelte
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'}×)
|
|
{/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> |