Skip to content

Commit 14da99f

Browse files
committed
feat: update PetPanel and Viewport to auto-select first active pet and rename memorial view to memories
1 parent 4fb913d commit 14da99f

File tree

3 files changed

+80
-44
lines changed

3 files changed

+80
-44
lines changed

src/lib/components/panels/PetPanel.svelte

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,14 @@
9494
onMount(() => {
9595
petStore.subscribe((value) => {
9696
pets = value;
97-
// If no selected pet and we have pets, auto-select the first one
97+
// If no selected pet and we have pets, auto-select the first ACTIVE one
9898
if (!selectedPetId && pets.length > 0) {
99-
selectedPetHelpers.select(pets[0].id);
99+
const firstActive = pets.find((p) => !p.archived) || null;
100+
if (firstActive) {
101+
selectedPetHelpers.select(firstActive.id);
102+
} else {
103+
selectedPetHelpers.clear();
104+
}
100105
}
101106
});
102107
selectedPetStore.subscribe((value) => {
@@ -227,12 +232,10 @@
227232
petHelpers.unarchive(petId);
228233
}
229234
230-
function openMemorial(petId: string) {
231-
const p = pets.find((p) => p.id === petId) || null;
232-
if (p) {
233-
selectedPetHelpers.select(p.id);
234-
}
235-
uiHelpers.setView('memorial');
235+
function openMemorial(_petId: string) {
236+
// Centralized memories view; no per-pet selection needed
237+
selectedPetHelpers.clear();
238+
uiHelpers.setView('memories');
236239
}
237240
</script>
238241

@@ -388,9 +391,11 @@
388391

389392
<!-- Archived list -->
390393
<div class="my-3"><div class="border-t" style="border-color: var(--petalytics-border);"></div></div>
391-
<div class="cli-row px-2 py-1" style="background: color-mix(in oklab, var(--petalytics-overlay) 60%, transparent);">
394+
<div class="cli-row px-2 py-1 items-center" style="background: color-mix(in oklab, var(--petalytics-overlay) 60%, transparent);">
392395
<span style="color: var(--petalytics-subtle);">#</span>
393396
<span class="ml-2" style="color: var(--petalytics-gold);">archived_pets</span>
397+
<span class="ml-auto"></span>
398+
<button class="arrow-btn" onclick={() => openMemorial('all')} disabled={archivedPets.length === 0}>view_memories</button>
394399
</div>
395400
{#if archivedPets.length === 0}
396401
<div class="px-2 py-2" style="color: var(--petalytics-subtle);">none</div>
@@ -402,9 +407,6 @@
402407
{pet.species || 'pet'} | {pet.breed || ''} | {pet.age}{pet.ageUnit === 'months' ? 'm' : pet.ageUnit === 'weeks' ? 'w' : 'y'}
403408
</span>
404409
</div>
405-
<div class="px-2 pb-2 flex justify-end">
406-
<button class="arrow-btn" onclick={() => openMemorial(pet.id)}>view_memories</button>
407-
</div>
408410
{/each}
409411
{/if}
410412
</div>

src/lib/components/panels/Viewport.svelte

Lines changed: 65 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
let selectedPet: PetPanelData | null = null;
1414
let selectedPetId: string | null = null;
1515
let pets: PetPanelData[] = [];
16-
let currentView: 'dashboard' | 'journal' | 'history' | 'memorial' | 'confirmArchive' = 'dashboard';
16+
let currentView: 'dashboard' | 'journal' | 'history' | 'memories' | 'confirmArchive' = 'dashboard';
1717
let journalInput = '';
1818
let selectedMood = '';
1919
let selectedActivity = '';
@@ -41,21 +41,39 @@
4141
return parts.join(' | ');
4242
}
4343
44+
function isArchived(p: PetPanelData | null): boolean {
45+
return !!(p && p.archived);
46+
}
47+
48+
function archivedPetsList(): PetPanelData[] {
49+
return (pets || []).filter((p) => p.archived);
50+
}
51+
4452
onMount(() => {
4553
// Subscribe first so incoming loads propagate into state
4654
petStore.subscribe((list) => {
4755
pets = list || [];
4856
if (selectedPetId) {
4957
selectedPet = pets.find((p) => p.id === selectedPetId) || null;
5058
} else if (!selectedPetId && pets.length > 0) {
51-
// Auto-select the first pet to show a summary by default
52-
selectedPetHelpers.select(pets[0].id);
59+
// Auto-select the first ACTIVE pet to show a summary by default
60+
const firstActive = pets.find((p) => !p.archived) || null;
61+
if (firstActive) {
62+
selectedPetHelpers.select(firstActive.id);
63+
uiHelpers.setView('dashboard');
64+
} else {
65+
// No active pets: keep selection cleared and default view dashboard
66+
selectedPetHelpers.clear();
67+
uiHelpers.setView('dashboard');
68+
}
5369
}
5470
});
5571
5672
selectedPetStore.subscribe((petId) => {
5773
selectedPetId = petId;
5874
selectedPet = petId ? pets.find((p) => p.id === petId) || null : null;
75+
// Keep current view unless user explicitly opened memories.
76+
// Disable actions via disabled buttons when archived is selected.
5977
});
6078
6179
// Drive view from shared UI store
@@ -136,14 +154,16 @@
136154
<div class="viewport-header p-4 border-b" style="border-color: var(--petalytics-border); background: var(--petalytics-overlay);">
137155
<div class="flex items-center justify-between">
138156
<div class="flex items-center space-x-3">
139-
<img
140-
src={selectedPet.profileImageUrl || '/images/default-pet.png'}
141-
alt={selectedPet.name}
142-
class="w-12 h-12 rounded-full object-cover"
143-
/>
157+
{#if selectedPet}
158+
<img
159+
src={selectedPet.profileImageUrl || '/images/default-pet.png'}
160+
alt={selectedPet.name}
161+
class="w-12 h-12 rounded-full object-cover"
162+
/>
163+
{/if}
144164
<div>
145-
<h2 class="text-xl font-bold" style="color: var(--petalytics-text);">{selectedPet.name}</h2>
146-
<p class="text-xs" style="color: var(--petalytics-subtle);">{petSubtitle(selectedPet)}</p>
165+
<h2 class="text-xl font-bold" style="color: var(--petalytics-text);">{selectedPet ? selectedPet.name : 'Memories'}</h2>
166+
<p class="text-xs" style="color: var(--petalytics-subtle);">{selectedPet ? petSubtitle(selectedPet) : 'Archived memories'}</p>
147167
</div>
148168
</div>
149169

@@ -152,20 +172,23 @@
152172
on:click={() => uiHelpers.setView('dashboard')}
153173
class="nav-button px-3 py-1 rounded-md text-sm"
154174
class:active={currentView === 'dashboard'}
175+
disabled={isArchived(selectedPet)}
155176
>
156177
Dashboard
157178
</button>
158179
<button
159180
on:click={() => uiHelpers.setView('journal')}
160181
class="nav-button px-3 py-1 rounded-md text-sm"
161182
class:active={currentView === 'journal'}
183+
disabled={isArchived(selectedPet)}
162184
>
163185
New Entry
164186
</button>
165187
<button
166188
on:click={() => uiHelpers.setView('history')}
167189
class="nav-button px-3 py-1 rounded-md text-sm"
168190
class:active={currentView === 'history'}
191+
disabled={isArchived(selectedPet)}
169192
>
170193
History
171194
</button>
@@ -193,38 +216,49 @@
193216
}}>Confirm</button>
194217
</div>
195218
</div>
196-
{:else if currentView === 'memorial'}
197-
<!-- Memorial View (inline, no modal) -->
219+
{:else if currentView === 'memories'}
220+
<!-- Centralized archived memories view -->
198221
<div class="space-y-4 font-mono">
199222
<div class="rounded p-3" style="background: color-mix(in oklab, var(--petalytics-overlay) 60%, transparent); border: 1px solid var(--petalytics-border);">
200223
<div class="flex items-center justify-between">
201224
<div>
202-
<div class="text-sm" style="color: var(--petalytics-subtle);">{petSubtitle(selectedPet!)}</div>
203-
<div class="text-base font-semibold" style="color: var(--petalytics-text);">
204-
In loving memory of {selectedPet?.name}
205-
</div>
225+
<div class="text-base font-semibold" style="color: var(--petalytics-text);">Memories</div>
226+
<div class="text-xs" style="color: var(--petalytics-subtle);">All archived pets</div>
206227
</div>
207228
<div class="text-xs px-2 py-1 rounded" style="background: var(--petalytics-surface); color: var(--petalytics-subtle);">
208-
{selectedPet?.journalEntries.length || 0} memories
229+
{archivedPetsList().length} pets
209230
</div>
210231
</div>
211232
</div>
212-
{#if (selectedPet?.journalEntries.length || 0) === 0}
213-
<div class="text-sm" style="color: var(--petalytics-subtle);">No journal entries yet.</div>
233+
234+
{#if archivedPetsList().length === 0}
235+
<div class="text-sm" style="color: var(--petalytics-subtle);">No archived pets yet.</div>
214236
{:else}
215-
<div class="space-y-3">
216-
{#each [...(selectedPet?.journalEntries || [])].slice().reverse() as entry}
217-
<div class="rounded border p-3" style="background: var(--petalytics-surface); border-color: var(--petalytics-border);">
218-
<div class="flex items-center justify-between mb-2">
219-
<div class="text-xs" style="color: var(--petalytics-subtle);">
220-
{new Date(entry.date as any).toLocaleDateString()}
221-
</div>
222-
<div class="text-sm" style="color: var(--petalytics-text);">{entry.mood || '🐾'}</div>
223-
</div>
224-
<div class="text-sm" style="color: var(--petalytics-text);">{entry.content}</div>
237+
{#each archivedPetsList() as ap}
238+
<div class="rounded border p-3 space-y-2" style="background: var(--petalytics-surface); border-color: var(--petalytics-border);">
239+
<div class="flex items-center justify-between">
240+
<div class="font-semibold" style="color: var(--petalytics-text);">In loving memory of {ap.name}</div>
241+
<div class="text-xs" style="color: var(--petalytics-subtle);">{(ap.journalEntries?.length || 0)} memories</div>
225242
</div>
226-
{/each}
227-
</div>
243+
{#if (ap.journalEntries?.length || 0) === 0}
244+
<div class="text-sm" style="color: var(--petalytics-subtle);">No journal entries.</div>
245+
{:else}
246+
<div class="space-y-2">
247+
{#each [...(ap.journalEntries || [])].slice().reverse() as entry}
248+
<div class="rounded border p-3" style="background: var(--petalytics-surface); border-color: var(--petalytics-border);">
249+
<div class="flex items-center justify-between mb-2">
250+
<div class="text-xs" style="color: var(--petalytics-subtle);">
251+
{new Date(entry.date as any).toLocaleDateString()} — {ap.name}
252+
</div>
253+
<div class="text-sm" style="color: var(--petalytics-text);">{entry.mood || '🐾'}</div>
254+
</div>
255+
<div class="text-sm" style="color: var(--petalytics-text);">{entry.content}</div>
256+
</div>
257+
{/each}
258+
</div>
259+
{/if}
260+
</div>
261+
{/each}
228262
{/if}
229263
</div>
230264
{:else if currentView === 'dashboard'}

src/lib/stores/ui.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { writable } from 'svelte/store';
22

3-
export type RightPanelView = 'dashboard' | 'journal' | 'history' | 'memorial' | 'confirmArchive';
3+
export type RightPanelView = 'dashboard' | 'journal' | 'history' | 'memories' | 'confirmArchive';
44

55
export const rightPanelView = writable<RightPanelView>('dashboard');
66

0 commit comments

Comments
 (0)