feat(journals): modernize UI with responsive grid and fix Quick Add integration
This commit is contained in:
@@ -1,31 +1,14 @@
|
||||
<script lang="ts">
|
||||
// let log_lvl: number = 0;
|
||||
|
||||
// *** Import Svelte specific
|
||||
// import { goto } from '$app/navigation';
|
||||
|
||||
// *** Import other supporting libraries
|
||||
// import { Spinner } from 'flowbite-svelte';
|
||||
import { BookOpenText, BookType } from '@lucide/svelte';
|
||||
|
||||
// *** Import Aether specific variables and functions
|
||||
/**
|
||||
* ae_comp__journal_obj_li.svelte
|
||||
* Modernized Journal List Component
|
||||
* Layout: Responsive Grid (1 col mobile, 2 col tablet, 3 col desktop)
|
||||
* Style: Tailwind 4 + Skeleton UI Reference Standard
|
||||
*/
|
||||
import { BookOpenText, BookType, Hash, Calendar, Clock } from '@lucide/svelte';
|
||||
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
|
||||
} from '$lib/ae_journals/ae_journals_stores';
|
||||
import { ae_loc } from '$lib/stores/ae_stores';
|
||||
|
||||
// *** Setup Svelte properties
|
||||
interface Props {
|
||||
lq__journal_obj_li: any;
|
||||
}
|
||||
@@ -33,128 +16,99 @@
|
||||
let { lq__journal_obj_li }: Props = $props();
|
||||
</script>
|
||||
|
||||
<section class="journal_list flex flex-col gap-2 items-center justify-center w-full">
|
||||
<!-- Responsive Grid Container -->
|
||||
<section class="journal_list grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 w-full max-w-7xl px-4">
|
||||
{#if $lq__journal_obj_li && $lq__journal_obj_li.length}
|
||||
{#each $lq__journal_obj_li as journals_journal_obj, index}
|
||||
{#each $lq__journal_obj_li as journal, index}
|
||||
<div
|
||||
class="
|
||||
container journal journal_obj
|
||||
border border-surface-500/30 rounded-lg p-3 mb-4 space-y-3
|
||||
w-full max-w-2xl
|
||||
flex flex-col items-center justify-center
|
||||
bg-surface-50 dark:bg-surface-900
|
||||
shadow-sm hover:shadow-md transition-shadow
|
||||
"
|
||||
class:hidden={(journals_journal_obj?.hide || !journals_journal_obj?.enable) &&
|
||||
!$ae_loc.trusted_access}
|
||||
class:opacity-50={journals_journal_obj.hide}
|
||||
class:preset-filled-warning-100-900={!journals_journal_obj?.enable}
|
||||
journal_card
|
||||
group relative
|
||||
flex flex-col justify-between
|
||||
bg-surface-50 dark:bg-surface-900
|
||||
border border-surface-500/20 rounded-xl
|
||||
p-5 shadow-sm hover:shadow-xl hover:border-primary-500/50
|
||||
transition-all duration-200 ease-in-out
|
||||
"
|
||||
class:hidden={(journal?.hide || !journal?.enable) && !$ae_loc.trusted_access}
|
||||
class:opacity-60={journal.hide}
|
||||
class:border-warning-500={!journal?.enable}
|
||||
>
|
||||
<header
|
||||
class="
|
||||
ae_header
|
||||
flex flex-row gap-2 items-center justify-between
|
||||
w-full
|
||||
"
|
||||
>
|
||||
<h3 class="journal__name text-xl md:text-2xl font-bold flex items-center gap-2 text-surface-900 dark:text-surface-100">
|
||||
<BookType size="1.25em" class="text-primary-500" />
|
||||
<span class="journal__name truncate">{journals_journal_obj.name}</span>
|
||||
</h3>
|
||||
|
||||
<!-- Show a label if the type code is set -->
|
||||
{#if journals_journal_obj.type_code}
|
||||
<span
|
||||
class="
|
||||
preset-tonal-warning
|
||||
text-xs font-semibold
|
||||
mr-2 px-2.5 py-0.5
|
||||
rounded
|
||||
|
||||
"
|
||||
>
|
||||
<!-- <span class="ae_label">Type:</span> -->
|
||||
<span class="ae_value">{journals_journal_obj.type_code}</span>
|
||||
</span>
|
||||
{/if}
|
||||
</header>
|
||||
|
||||
<!-- {journals_journal_obj?.tmp_sort_3} -->
|
||||
|
||||
{#if journals_journal_obj.description && $ae_loc.edit_mode}
|
||||
<div
|
||||
class="
|
||||
prose
|
||||
space-y-1
|
||||
journal__description
|
||||
p-2
|
||||
w-full max-w-(--breakpoint-sm) md:max-w-(--breakpoint-md)
|
||||
font-mono
|
||||
text-gray-900
|
||||
dark:bg-blue-900 dark:text-gray-100
|
||||
shadow-md rounded-lg
|
||||
text-sm font-normal text-wrap word-break
|
||||
|
||||
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 journals_journal_obj.description_md_html}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="ae_options flex flex-row flex-wrap gap-3 items-center justify-center">
|
||||
<a
|
||||
href="/journals/{journals_journal_obj?.journal_id}"
|
||||
class="btn variant-filled-primary md:btn-lg font-bold shadow-lg hover:scale-105 transition-transform"
|
||||
title={`View: ${journals_journal_obj?.name}`}
|
||||
>
|
||||
<BookOpenText size="1.25em" />
|
||||
<span>Open Journal</span>
|
||||
|
||||
{#if journals_journal_obj?.journal_entry_count}
|
||||
<span class="badge variant-filled-secondary ml-2">
|
||||
{journals_journal_obj?.journal_entry_count} {journals_journal_obj?.journal_entry_count === 1 ? 'entry' : 'entries'}
|
||||
<!-- Top Section: Title & Badge -->
|
||||
<div class="space-y-3">
|
||||
<header class="flex justify-between items-start gap-2">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="p-2 bg-primary-500/10 rounded-lg text-primary-500 group-hover:bg-primary-500 group-hover:text-white transition-colors">
|
||||
<BookType size="1.5em" />
|
||||
</div>
|
||||
<h3 class="text-xl font-bold text-surface-900 dark:text-surface-100 line-clamp-1">
|
||||
{journal.name}
|
||||
</h3>
|
||||
</div>
|
||||
|
||||
{#if journal.type_code}
|
||||
<span class="badge preset-tonal-warning text-[10px] uppercase tracking-wider font-bold">
|
||||
{journal.type_code}
|
||||
</span>
|
||||
{/if}
|
||||
</a>
|
||||
</header>
|
||||
|
||||
<!-- Description (Power User / Edit Mode Only) -->
|
||||
{#if journal.description && $ae_loc.edit_mode}
|
||||
<div class="prose prose-sm dark:prose-invert max-h-24 overflow-y-auto bg-surface-100/50 dark:bg-surface-800/50 p-3 rounded-lg text-xs font-mono">
|
||||
{@html journal.description_md_html}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- Quick Stats (Clean View) -->
|
||||
<div class="flex items-center gap-4 text-xs text-surface-600 dark:text-surface-400">
|
||||
<div class="flex items-center gap-1" title="Entry Count">
|
||||
<Hash size="1.2em" />
|
||||
<span class="font-bold">{journal.journal_entry_count ?? 0}</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-1" title="Last Updated">
|
||||
<Clock size="1.2em" />
|
||||
<span>{ae_util.iso_datetime_formatter(journal.updated_on || journal.created_on, 'date_short')}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section
|
||||
class="ae_section ae_footer ae_meta journal__meta mt-2 flex flex-col sm:flex-row gap-1 items-center justify-center text-sm text-gray-500"
|
||||
class:hidden={!$ae_loc.administrator_access || !$ae_loc.edit_mode}
|
||||
>
|
||||
<div class="ae_group">
|
||||
{#if !journals_journal_obj.updated_on}
|
||||
<span class="journal__created_on">
|
||||
<span class="ae_label">Created on:</span>
|
||||
<span class="ae_value"
|
||||
>{ae_util.iso_datetime_formatter(
|
||||
journals_journal_obj.created_on,
|
||||
'datetime_12_long'
|
||||
)}</span
|
||||
>
|
||||
</span>
|
||||
{:else}
|
||||
<span class="journal__updated_on">
|
||||
<span class="ae_label">Updated on:</span>
|
||||
<span class="ae_value"
|
||||
>{ae_util.iso_datetime_formatter(
|
||||
journals_journal_obj.updated_on,
|
||||
'datetime_12_long'
|
||||
)}</span
|
||||
>
|
||||
</span>
|
||||
<!-- Bottom Section: Actions -->
|
||||
<div class="mt-6 pt-4 border-t border-surface-500/10 flex flex-col gap-3">
|
||||
<a
|
||||
href="/journals/{journal?.journal_id}"
|
||||
class="btn variant-filled-primary w-full font-bold shadow-md hover:scale-[1.02] active:scale-95 transition-all"
|
||||
>
|
||||
<BookOpenText size="1.2em" class="mr-2" />
|
||||
<span>Open Journal</span>
|
||||
</a>
|
||||
|
||||
<!-- Admin Metadata (Edit Mode Only) -->
|
||||
{#if $ae_loc.edit_mode && $ae_loc.administrator_access}
|
||||
<div class="flex items-center justify-center gap-2 text-[10px] opacity-50 font-mono">
|
||||
<Calendar size="1em" />
|
||||
<span>Created: {ae_util.iso_datetime_formatter(journal.created_on, 'datetime_iso_12_no_seconds')}</span>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<!-- Status Indicators (Edit Mode Only) -->
|
||||
{#if $ae_loc.edit_mode}
|
||||
<div class="absolute -top-2 -right-2 flex gap-1">
|
||||
{#if journal.hide}
|
||||
<span class="badge-icon variant-filled-surface shadow-sm" title="Hidden">🚫</span>
|
||||
{/if}
|
||||
{#if !journal.enable}
|
||||
<span class="badge-icon variant-filled-warning shadow-sm" title="Disabled">⚠️</span>
|
||||
{/if}
|
||||
</div>
|
||||
</section>
|
||||
{/if}
|
||||
</div>
|
||||
{/each}
|
||||
{:else}
|
||||
No journals found at this time
|
||||
<div class="col-span-full p-20 text-center opacity-50 flex flex-col items-center gap-4">
|
||||
<BookType size="4em" />
|
||||
<p class="text-xl">No journals found in this view.</p>
|
||||
</div>
|
||||
{/if}
|
||||
</section>
|
||||
<!-- {/if} -->
|
||||
</section>
|
||||
Reference in New Issue
Block a user