Files
OSIT-AE-App-Svelte/src/routes/journals/ae_comp__journal_obj_li.svelte
Scott Idem b543c8a930 chore: migrate all FA icons to Lucide (@lucide/svelte)
- Replaced all active FontAwesome <span class="fas fa-*"> icons with
  Lucide components across 145 files (excluding /idaa/ which is intentional)
- Fixed merge script bug: consolidated lucide-svelte imports into @lucide/svelte
- Replaced dynamic toggle patterns (fa-toggle-on/off) with ToggleRight/ToggleLeft
- Replaced fa-eye/fa-eye-slash with Eye/EyeOff
- Replaced fa-bug/fa-bug-slash with Bug/BugOff
- Replaced fa-sync fa-spin with RefreshCw + animate-spin
- Replaced fa-microchip with Cpu
- Fixed {@const} placement in element_manage_event_file_li.svelte
- Removed obsolete CSS hover rules for .unlock_icon/.lock_icon
- svelte-check: 0 errors, 0 warnings
2026-03-16 18:07:43 -04:00

134 lines
6.8 KiB
Svelte

<script lang="ts">
/**
* 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, Calendar, Clock, Hash } from '@lucide/svelte';
import { ae_util } from '$lib/ae_utils/ae_utils';
import { ae_loc } from '$lib/stores/ae_stores';
interface Props {
lq__journal_obj_li: any;
}
let { lq__journal_obj_li }: Props = $props();
</script>
<!--
Compact mobile-first list — the entire row is the tap target.
Glow effect mirrors the Quick Add section above it.
Uses plain Tailwind gray scale with explicit dark: variants — no Skeleton paired utilities —
so behavior is predictable regardless of which Skeleton theme is active.
-->
<div class="w-full max-w-2xl relative group/list">
<!-- Glow ring behind the list, same technique as Quick Add -->
<div
class="absolute -inset-1 bg-linear-to-r from-primary-500 to-secondary-500
rounded-2xl blur opacity-10 dark:opacity-20
group-hover/list:opacity-25 dark:group-hover/list:opacity-35
transition duration-700 pointer-events-none"
></div>
<section class="journal_list relative w-full space-y-1.5 p-2 sm:p-3
bg-white dark:bg-gray-900
border border-gray-200 dark:border-gray-700
rounded-2xl shadow-xl">
{#if $lq__journal_obj_li && $lq__journal_obj_li.length}
{#each $lq__journal_obj_li as journal (journal.journal_id)}
<a
href="/journals/{journal?.journal_id}"
class="journal_card group relative
flex items-center gap-3 px-4 py-3
bg-gray-50 dark:bg-gray-800
border border-gray-200 dark:border-gray-700
border-l-4 border-l-primary-500/60
rounded-xl shadow-sm
hover:shadow-md hover:border-l-primary-500
hover:bg-gray-100 dark:hover:bg-gray-700
active:scale-[0.99]
transition-all duration-150 ease-in-out"
class:hidden={(journal?.hide || !journal?.enable) && !$ae_loc.trusted_access}
class:opacity-60={journal.hide}
class:!border-l-warning-500={!journal?.enable}
>
<!-- Icon: fixed size, never squashed -->
<div class="shrink-0 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.3em" />
</div>
<!-- Name + badge: min-w-0 flex-1 lets text shrink and wrap -->
<div class="min-w-0 flex-1">
<div class="text-sm sm:text-base font-bold
text-gray-900 dark:text-gray-100
leading-snug break-words">
{journal.name}
</div>
<div class="flex flex-wrap items-center gap-2 mt-0.5">
{#if journal.type_code}
<span class="badge preset-tonal-warning text-[10px] uppercase tracking-wider font-bold">
{journal.type_code}
</span>
{/if}
<!-- Description snippet: edit mode only -->
{#if journal.description && $ae_loc.edit_mode}
<span class="text-[11px] text-gray-500 dark:text-gray-400 font-mono truncate max-w-[16rem]">
{ae_util.strip_html ? ae_util.strip_html(journal.description).slice(0, 60) : journal.description.slice(0, 60)}&hellip;
</span>
{/if}
</div>
</div>
<!-- Stats: right-aligned, compact -->
<div class="shrink-0 flex flex-col items-end gap-0.5
text-xs text-gray-500 dark:text-gray-400">
<div class="flex items-center gap-1" title="Entry Count">
<Hash size="0.85em" />
<span class="font-bold tabular-nums">{journal.journal_entry_count ?? 0}&times;</span>
</div>
<div class="flex items-center gap-1" title="Last Updated">
<Clock size="0.85em" />
<span class="tabular-nums">{ae_util.iso_datetime_formatter(
journal.updated_on || journal.created_on,
'date_short'
)}</span>
</div>
{#if $ae_loc.edit_mode && $ae_loc.administrator_access}
<div class="flex items-center gap-1 opacity-40" title="Created">
<Calendar size="0.85em" />
<span class="font-mono text-[10px] tabular-nums">{ae_util.iso_datetime_formatter(
journal.created_on,
'date_short'
)}</span>
</div>
{/if}
</div>
<!-- Chevron hint: desktop only -->
<BookOpenText size="0.95em"
class="shrink-0 opacity-0 group-hover:opacity-30 transition-opacity hidden sm:block" />
<!-- Status overlays: edit mode only -->
{#if $ae_loc.edit_mode}
<div class="absolute -top-1.5 -right-1.5 flex gap-1">
{#if journal.hide}
<span class="badge-icon preset-tonal-surface shadow-sm" title="Hidden">🚫</span>
{/if}
{#if !journal.enable}
<span class="badge-icon preset-tonal-warning shadow-sm" title="Disabled">⚠️</span>
{/if}
</div>
{/if}
</a>
{/each}
{:else}
<div class="p-20 text-center text-gray-400 dark:text-gray-500 flex flex-col items-center gap-4">
<BookType size="4em" />
<p class="text-xl">No journals found in this view.</p>
</div>
{/if}
</section>
</div>