clean up folders, created sub-components
This commit is contained in:
94
src/lib/timeline/TimelineView.svelte
Normal file
94
src/lib/timeline/TimelineView.svelte
Normal file
@@ -0,0 +1,94 @@
|
||||
<script>
|
||||
import { get } from 'svelte/store';
|
||||
import { journals } from '../stores/journalStore.js';
|
||||
import TimelineToolbar from './TimelineToolbar.svelte';
|
||||
import TimelineCard from './TimelineCard.svelte';
|
||||
import JournalDetail from './JournalDetail.svelte';
|
||||
|
||||
/** @type {import('../stores/journalStore.js').JournalEntry|null} */
|
||||
let selected = $state(null);
|
||||
|
||||
let entries = $state(get(journals));
|
||||
$effect(() => {
|
||||
const unsub = journals.subscribe((v) => { entries = v; });
|
||||
return unsub;
|
||||
});
|
||||
|
||||
let sortKey = $state('date-desc');
|
||||
|
||||
let sortedEntries = $state(/** @type {typeof entries} */([]));
|
||||
$effect(() => {
|
||||
const key = sortKey;
|
||||
sortedEntries = [...entries].sort((a, b) => {
|
||||
if (key === 'date-asc') return a.date.localeCompare(b.date);
|
||||
if (key === 'date-desc') return b.date.localeCompare(a.date);
|
||||
if (key === 'country-asc') return a.location.country.localeCompare(b.location.country) || b.date.localeCompare(a.date);
|
||||
if (key === 'country-desc') return b.location.country.localeCompare(a.location.country) || b.date.localeCompare(a.date);
|
||||
return 0;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
{#if selected}
|
||||
<JournalDetail entry={selected} onBack={() => (selected = null)} />
|
||||
{:else}
|
||||
<section class="timeline-view">
|
||||
<TimelineToolbar {sortKey} onSort={(k) => (sortKey = k)} />
|
||||
|
||||
{#if sortedEntries.length === 0}
|
||||
<p class="empty">No journal entries yet.</p>
|
||||
{:else}
|
||||
<ol class="v-list">
|
||||
{#each sortedEntries as entry (entry.id)}
|
||||
<TimelineCard {entry} onClick={() => (selected = entry)} />
|
||||
{/each}
|
||||
</ol>
|
||||
{/if}
|
||||
|
||||
<footer class="page-footer">
|
||||
{sortedEntries.length} {sortedEntries.length === 1 ? 'entry' : 'entries'}
|
||||
</footer>
|
||||
</section>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
.timeline-view {
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
padding: 48px 24px 64px;
|
||||
font-family: var(--sans, system-ui, sans-serif);
|
||||
}
|
||||
|
||||
.v-list {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
position: relative;
|
||||
}
|
||||
.v-list::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
top: 6px;
|
||||
bottom: 6px;
|
||||
width: 2px;
|
||||
background: var(--border, #e5e4e7);
|
||||
border-radius: 1px;
|
||||
}
|
||||
|
||||
.page-footer {
|
||||
margin-top: 40px;
|
||||
text-align: center;
|
||||
font-size: 13px;
|
||||
color: var(--text, #6b6375);
|
||||
padding-top: 24px;
|
||||
border-top: 1px solid var(--border, #e5e4e7);
|
||||
}
|
||||
|
||||
.empty { text-align: center; color: var(--text, #6b6375); padding: 80px 0; }
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.timeline-view { padding: 32px 16px 48px; }
|
||||
.v-list::before { left: 8px; }
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user