Prettier for Journals
This commit is contained in:
@@ -1,103 +1,108 @@
|
||||
<script lang="ts">
|
||||
/**
|
||||
* src/routes/journals/+page.svelte
|
||||
* Modernized Journals Index View
|
||||
* Focus: Simplicity for regular users, power tools for edit mode.
|
||||
*/
|
||||
// import { onMount } from 'svelte';
|
||||
import { goto } from '$app/navigation';
|
||||
/**
|
||||
* src/routes/journals/+page.svelte
|
||||
* Modernized Journals Index View
|
||||
* Focus: Simplicity for regular users, power tools for edit mode.
|
||||
*/
|
||||
// import { onMount } from 'svelte';
|
||||
import { goto } from '$app/navigation';
|
||||
|
||||
// *** Icons
|
||||
import { BookPlus, FileUp, LoaderCircle, Sparkles, SquareLibrary, Wrench } from '@lucide/svelte';
|
||||
// *** Libraries & Stores
|
||||
import { liveQuery } from 'dexie';
|
||||
import { Modal } from 'flowbite-svelte';
|
||||
import { db_core } from '$lib/ae_core/db_core';
|
||||
import { db_journals } from '$lib/ae_journals/db_journals';
|
||||
import { journals_func } from '$lib/ae_journals/ae_journals_functions';
|
||||
import { ae_loc, ae_api, slct } from '$lib/stores/ae_stores';
|
||||
import {
|
||||
journals_loc,
|
||||
journals_sess,
|
||||
journals_slct,
|
||||
journals_trig
|
||||
} from '$lib/ae_journals/ae_journals_stores';
|
||||
// *** Icons
|
||||
import {
|
||||
BookPlus,
|
||||
FileUp,
|
||||
LoaderCircle,
|
||||
Sparkles,
|
||||
SquareLibrary,
|
||||
Wrench
|
||||
} from '@lucide/svelte';
|
||||
// *** Libraries & Stores
|
||||
import { liveQuery } from 'dexie';
|
||||
import { Modal } from 'flowbite-svelte';
|
||||
import { db_core } from '$lib/ae_core/db_core';
|
||||
import { db_journals } from '$lib/ae_journals/db_journals';
|
||||
import { journals_func } from '$lib/ae_journals/ae_journals_functions';
|
||||
import { ae_loc, ae_api, slct } from '$lib/stores/ae_stores';
|
||||
import {
|
||||
journals_loc,
|
||||
journals_sess,
|
||||
journals_slct,
|
||||
journals_trig
|
||||
} from '$lib/ae_journals/ae_journals_stores';
|
||||
|
||||
// *** Components
|
||||
import AE_Comp_Modal_Journal_Config from './ae_comp__modal_journal_config.svelte';
|
||||
import Journal_obj_li from './ae_comp__journal_obj_li.svelte';
|
||||
import AE_Comp_Journal_Entry_Quick_Add from './ae_comp__journal_entry_quick_add.svelte';
|
||||
import AE_Comp_Modal_Journal_Import from './ae_comp__modal_journal_import.svelte';
|
||||
// *** Components
|
||||
import AE_Comp_Modal_Journal_Config from './ae_comp__modal_journal_config.svelte';
|
||||
import Journal_obj_li from './ae_comp__journal_obj_li.svelte';
|
||||
import AE_Comp_Journal_Entry_Quick_Add from './ae_comp__journal_entry_quick_add.svelte';
|
||||
import AE_Comp_Modal_Journal_Import from './ae_comp__modal_journal_import.svelte';
|
||||
|
||||
interface Props {
|
||||
data: any;
|
||||
}
|
||||
interface Props {
|
||||
data: any;
|
||||
}
|
||||
|
||||
let { data }: Props = $props();
|
||||
let { data }: Props = $props();
|
||||
|
||||
// *** State
|
||||
let show_import_modal = $state(false);
|
||||
let log_lvl = 0;
|
||||
// *** State
|
||||
let show_import_modal = $state(false);
|
||||
let log_lvl = 0;
|
||||
|
||||
// *** LiveQueries
|
||||
let lq__account = $derived(
|
||||
liveQuery(async () => {
|
||||
if (!$slct.account_id) return null;
|
||||
return await db_core.account.get($slct.account_id);
|
||||
})
|
||||
);
|
||||
// *** LiveQueries
|
||||
let lq__account = $derived(
|
||||
liveQuery(async () => {
|
||||
if (!$slct.account_id) return null;
|
||||
return await db_core.account.get($slct.account_id);
|
||||
})
|
||||
);
|
||||
|
||||
let lq__journal_obj_li = $derived(
|
||||
liveQuery(async () => {
|
||||
return await db_journals.journal
|
||||
.where('person_id')
|
||||
.equals($ae_loc.person_id)
|
||||
.reverse()
|
||||
.sortBy('tmp_sort_3');
|
||||
})
|
||||
);
|
||||
let lq__journal_obj_li = $derived(
|
||||
liveQuery(async () => {
|
||||
return await db_journals.journal
|
||||
.where('person_id')
|
||||
.equals($ae_loc.person_id)
|
||||
.reverse()
|
||||
.sortBy('tmp_sort_3');
|
||||
})
|
||||
);
|
||||
|
||||
async function create_journal() {
|
||||
if (!confirm('Create a new journal?')) return;
|
||||
async function create_journal() {
|
||||
if (!confirm('Create a new journal?')) return;
|
||||
|
||||
const name = $journals_sess.journal.new_journal_name;
|
||||
const type = $journals_sess.journal.new_journal_type_code;
|
||||
const name = $journals_sess.journal.new_journal_name;
|
||||
const type = $journals_sess.journal.new_journal_type_code;
|
||||
|
||||
if (name && type) {
|
||||
try {
|
||||
const results = await journals_func.create_ae_obj__journal({
|
||||
api_cfg: $ae_api,
|
||||
account_id: $slct.account_id,
|
||||
data_kv: {
|
||||
person_id: $ae_loc.person_id,
|
||||
name,
|
||||
type_code: type,
|
||||
cfg_json: {
|
||||
category_li: [{ code: '', name: 'Default' }]
|
||||
}
|
||||
if (name && type) {
|
||||
try {
|
||||
const results = await journals_func.create_ae_obj__journal({
|
||||
api_cfg: $ae_api,
|
||||
account_id: $slct.account_id,
|
||||
data_kv: {
|
||||
person_id: $ae_loc.person_id,
|
||||
name,
|
||||
type_code: type,
|
||||
cfg_json: {
|
||||
category_li: [{ code: '', name: 'Default' }]
|
||||
}
|
||||
});
|
||||
if (results?.journal_id) {
|
||||
$journals_sess.show__modal_new__journal_obj = false;
|
||||
goto(`/journals/${results.journal_id}`);
|
||||
}
|
||||
} catch (error) {
|
||||
alert('Failed to create journal.');
|
||||
});
|
||||
if (results?.journal_id) {
|
||||
$journals_sess.show__modal_new__journal_obj = false;
|
||||
goto(`/journals/${results.journal_id}`);
|
||||
}
|
||||
} else {
|
||||
alert('Please provide a name and type.');
|
||||
} catch (error) {
|
||||
alert('Failed to create journal.');
|
||||
}
|
||||
} else {
|
||||
alert('Please provide a name and type.');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="page_container flex flex-col gap-4 sm:gap-6 md:gap-8 items-center w-full min-h-screen p-3 sm:p-4 md:p-8"
|
||||
>
|
||||
class="page_container flex min-h-screen w-full flex-col items-center gap-4 p-3 sm:gap-6 sm:p-4 md:gap-8 md:p-8">
|
||||
<!-- Header Section -->
|
||||
<header class="text-center space-y-2 max-w-3xl">
|
||||
<header class="max-w-3xl space-y-2 text-center">
|
||||
<h1
|
||||
class="text-3xl sm:text-4xl md:text-5xl font-black tracking-tight text-surface-900 dark:text-surface-100"
|
||||
>
|
||||
class="text-surface-900 dark:text-surface-100 text-3xl font-black tracking-tight sm:text-4xl md:text-5xl">
|
||||
<SquareLibrary size="1em" class="text-primary-500 inline-block" />
|
||||
Journals
|
||||
</h1>
|
||||
@@ -105,7 +110,9 @@
|
||||
{#if $ae_loc.person.given_name || $ae_loc.person.family_name}
|
||||
<p class="text-surface-600 dark:text-surface-400 font-medium">
|
||||
<span class="text-primary-500 font-semibold">
|
||||
{[$ae_loc.person.given_name, $ae_loc.person.family_name].filter(Boolean).join(' ')}
|
||||
{[$ae_loc.person.given_name, $ae_loc.person.family_name]
|
||||
.filter(Boolean)
|
||||
.join(' ')}
|
||||
</span>
|
||||
</p>
|
||||
{/if}
|
||||
@@ -113,19 +120,17 @@
|
||||
|
||||
<!-- Quick Add Integrated Section -->
|
||||
<section class="w-full max-w-2xl">
|
||||
<div class="relative group">
|
||||
<div class="group relative">
|
||||
<!-- Glow ring: slightly brighter in dark mode where colors need more presence -->
|
||||
<div
|
||||
class="absolute -inset-1 bg-linear-to-r from-primary-500 to-secondary-500 rounded-2xl blur opacity-25 dark:opacity-40 group-hover:opacity-60 dark:group-hover:opacity-70 transition duration-1000 group-hover:duration-200"
|
||||
></div>
|
||||
class="from-primary-500 to-secondary-500 absolute -inset-1 rounded-2xl bg-linear-to-r opacity-25 blur transition duration-1000 group-hover:opacity-60 group-hover:duration-200 dark:opacity-40 dark:group-hover:opacity-70">
|
||||
</div>
|
||||
<AE_Comp_Journal_Entry_Quick_Add
|
||||
journals_li={$lq__journal_obj_li}
|
||||
class="relative shadow-2xl rounded-xl overflow-hidden border border-surface-500/10 bg-surface-50 dark:bg-surface-900"
|
||||
/>
|
||||
class="border-surface-500/10 bg-surface-50 dark:bg-surface-900 relative overflow-hidden rounded-xl border shadow-2xl" />
|
||||
</div>
|
||||
<div
|
||||
class="mt-2 flex items-center justify-center gap-2 text-xs opacity-50 font-bold uppercase tracking-widest"
|
||||
>
|
||||
class="mt-2 flex items-center justify-center gap-2 text-xs font-bold tracking-widest uppercase opacity-50">
|
||||
<Sparkles size="1em" />
|
||||
<span>Fast Input Mode Active</span>
|
||||
</div>
|
||||
@@ -134,33 +139,29 @@
|
||||
<!-- Administrative Action Bar (Edit Mode Only) -->
|
||||
{#if $ae_loc.edit_mode}
|
||||
<nav
|
||||
class="flex flex-row flex-wrap gap-3 items-center justify-center w-full py-4 border-y border-surface-500/10"
|
||||
>
|
||||
class="border-surface-500/10 flex w-full flex-row flex-wrap items-center justify-center gap-3 border-y py-4">
|
||||
<button
|
||||
type="button"
|
||||
class="btn preset-tonal-secondary shadow-lg hover:scale-105 transition-transform"
|
||||
class="btn preset-tonal-secondary shadow-lg transition-transform hover:scale-105"
|
||||
onclick={() =>
|
||||
($journals_sess.show__modal_new__journal_obj = true)}
|
||||
>
|
||||
($journals_sess.show__modal_new__journal_obj = true)}>
|
||||
<BookPlus size="1.2em" class="mr-2" />
|
||||
<span>New Journal</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
class="btn preset-tonal-surface shadow-lg hover:scale-105 transition-transform"
|
||||
onclick={() => (show_import_modal = true)}
|
||||
>
|
||||
class="btn preset-tonal-surface shadow-lg transition-transform hover:scale-105"
|
||||
onclick={() => (show_import_modal = true)}>
|
||||
<FileUp size="1.2em" class="mr-2" />
|
||||
<span>Import</span>
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
class="btn preset-tonal-surface shadow-lg hover:scale-105 transition-transform"
|
||||
class="btn preset-tonal-surface shadow-lg transition-transform hover:scale-105"
|
||||
onclick={() =>
|
||||
($journals_sess.show__modal__journals_config = true)}
|
||||
>
|
||||
($journals_sess.show__modal__journals_config = true)}>
|
||||
<Wrench size="1.2em" class="mr-2" />
|
||||
<span>Config</span>
|
||||
</button>
|
||||
@@ -168,11 +169,10 @@
|
||||
{/if}
|
||||
|
||||
<!-- Main List Section -->
|
||||
<main class="w-full flex justify-center">
|
||||
<main class="flex w-full justify-center">
|
||||
{#if $lq__journal_obj_li === undefined}
|
||||
<div
|
||||
class="flex flex-col items-center justify-center p-20 gap-4 opacity-50"
|
||||
>
|
||||
class="flex flex-col items-center justify-center gap-4 p-20 opacity-50">
|
||||
<LoaderCircle size="3em" class="animate-spin" />
|
||||
<p class="text-xl font-bold">Accessing Brain...</p>
|
||||
</div>
|
||||
@@ -180,11 +180,10 @@
|
||||
<Journal_obj_li {lq__journal_obj_li} />
|
||||
{:else}
|
||||
<div
|
||||
class="max-w-md text-center p-12 bg-surface-500/5 rounded-3xl border-2 border-dashed border-surface-500/20"
|
||||
>
|
||||
class="bg-surface-500/5 border-surface-500/20 max-w-md rounded-3xl border-2 border-dashed p-12 text-center">
|
||||
<SquareLibrary size="4em" class="mx-auto mb-4 opacity-20" />
|
||||
<h3 class="text-2xl font-bold mb-2">No Journals Found</h3>
|
||||
<p class="opacity-60 mb-6">
|
||||
<h3 class="mb-2 text-2xl font-bold">No Journals Found</h3>
|
||||
<p class="mb-6 opacity-60">
|
||||
You haven't created any journals yet. Start by creating one
|
||||
to begin your documentation journey.
|
||||
</p>
|
||||
@@ -192,8 +191,7 @@
|
||||
type="button"
|
||||
class="btn preset-filled-primary"
|
||||
onclick={() =>
|
||||
($journals_sess.show__modal_new__journal_obj = true)}
|
||||
>
|
||||
($journals_sess.show__modal_new__journal_obj = true)}>
|
||||
Create Your First Journal
|
||||
</button>
|
||||
</div>
|
||||
@@ -208,32 +206,27 @@
|
||||
bind:open={$journals_sess.show__modal_new__journal_obj}
|
||||
autoclose={false}
|
||||
size="md"
|
||||
class="bg-white dark:bg-surface-900 shadow-2xl rounded-2xl"
|
||||
>
|
||||
<div class="p-2 space-y-4">
|
||||
class="dark:bg-surface-900 rounded-2xl bg-white shadow-2xl">
|
||||
<div class="space-y-4 p-2">
|
||||
<div class="space-y-1">
|
||||
<!-- svelte-ignore a11y_label_has_associated_control -->
|
||||
<label class="label text-sm font-bold opacity-75"
|
||||
>Journal Name</label
|
||||
>
|
||||
>Journal Name</label>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="e.g. My Daily Logs"
|
||||
bind:value={$journals_sess.journal.new_journal_name}
|
||||
class="input"
|
||||
/>
|
||||
class="input" />
|
||||
</div>
|
||||
<div class="space-y-1">
|
||||
<!-- svelte-ignore a11y_label_has_associated_control -->
|
||||
<label class="label text-sm font-bold opacity-75"
|
||||
>Type Code</label
|
||||
>
|
||||
>Type Code</label>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="e.g. diary, log, notebook"
|
||||
bind:value={$journals_sess.journal.new_journal_type_code}
|
||||
class="input"
|
||||
/>
|
||||
class="input" />
|
||||
</div>
|
||||
<div class="flex justify-end gap-2 pt-4">
|
||||
<button
|
||||
@@ -241,13 +234,11 @@
|
||||
class="btn preset-tonal-surface"
|
||||
onclick={() =>
|
||||
($journals_sess.show__modal_new__journal_obj = false)}
|
||||
>Cancel</button
|
||||
>
|
||||
>Cancel</button>
|
||||
<button
|
||||
type="button"
|
||||
class="btn preset-filled-primary font-bold"
|
||||
onclick={create_journal}>Create Journal</button
|
||||
>
|
||||
onclick={create_journal}>Create Journal</button>
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
@@ -255,12 +246,10 @@
|
||||
|
||||
{#if $journals_sess.show__modal__journals_config}
|
||||
<AE_Comp_Modal_Journal_Config
|
||||
show={$journals_sess.show__modal__journals_config}
|
||||
/>
|
||||
show={$journals_sess.show__modal__journals_config} />
|
||||
{/if}
|
||||
|
||||
<AE_Comp_Modal_Journal_Import
|
||||
bind:open={show_import_modal}
|
||||
on_close={() => (show_import_modal = false)}
|
||||
on_import_complete={() => {}}
|
||||
/>
|
||||
on_import_complete={() => {}} />
|
||||
|
||||
Reference in New Issue
Block a user