Skip to content

Commit 4fb913d

Browse files
committed
feat: refactor PetPanel and Viewport to use right panel for confirmation and memorial views
1 parent ec6fc30 commit 4fb913d

File tree

3 files changed

+88
-49
lines changed

3 files changed

+88
-49
lines changed

src/lib/components/panels/PetPanel.svelte

Lines changed: 14 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
import { Upload, Terminal } from 'lucide-svelte';
44
import { petStore, selectedPetStore, petHelpers, selectedPetHelpers } from '$lib/stores/pets';
55
import type { PetPanelData } from '$lib/types/Pet.js';
6-
import Modal from '../ui/Modal.svelte';
7-
import MemorialModal from '../ui/MemorialModal.svelte';
6+
import { rightPanelView, uiHelpers } from '$lib/stores/ui';
87
98
let pets: PetPanelData[] = [];
109
// Derived lists
@@ -14,11 +13,8 @@
1413
let showCreateForm = false;
1514
let imageInput: HTMLInputElement;
1615
17-
// Archive workflow state
18-
let confirmArchiveOpen = false;
16+
// Right-panel driven workflows (no modals)
1917
let petToArchive: PetPanelData | null = null;
20-
let memorialOpen = false;
21-
let memorialPet: PetPanelData | null = null;
2218
2319
const speciesSuggestions = ['dog','cat','bird','reptile','fish','rabbit','hamster','other'] as const;
2420
const ageUnitSuggestions = ['years','months','weeks'] as const;
@@ -217,38 +213,26 @@
217213
}
218214
219215
function archivePet(petId: string) {
220-
const p = pets.find((x) => x.id === petId) || null;
221-
petToArchive = p;
222-
confirmArchiveOpen = true;
223-
}
224-
225-
function confirmArchive() {
226-
if (!petToArchive) return;
227-
petHelpers.archive(petToArchive.id);
228-
if (selectedPetId === petToArchive.id) {
229-
selectedPetHelpers.clear();
216+
const p = pets.find((x) => x.id === petId) || null;
217+
petToArchive = p;
218+
if (p) {
219+
selectedPetHelpers.select(p.id);
230220
}
231-
confirmArchiveOpen = false;
232-
petToArchive = null;
221+
uiHelpers.setView('confirmArchive');
233222
}
234223
235-
function cancelArchive() {
236-
confirmArchiveOpen = false;
237-
petToArchive = null;
238-
}
224+
// Confirmation is handled in the right panel now
239225
240226
function unarchivePet(petId: string) {
241227
petHelpers.unarchive(petId);
242228
}
243229
244230
function openMemorial(petId: string) {
245-
memorialPet = pets.find((p) => p.id === petId) || null;
246-
memorialOpen = true;
247-
}
248-
249-
function closeMemorial() {
250-
memorialOpen = false;
251-
memorialPet = null;
231+
const p = pets.find((p) => p.id === petId) || null;
232+
if (p) {
233+
selectedPetHelpers.select(p.id);
234+
}
235+
uiHelpers.setView('memorial');
252236
}
253237
</script>
254238

@@ -426,19 +410,7 @@
426410
</div>
427411
</div>
428412

429-
<!-- Archive confirmation modal -->
430-
<Modal isOpen={confirmArchiveOpen} title="Archive Pet" size="sm" onclose={cancelArchive}>
431-
<div class="space-y-4 font-mono">
432-
<p>Mark {petToArchive?.name} as passed away?</p>
433-
<div class="flex justify-end gap-2">
434-
<button class="button-secondary" onclick={cancelArchive}>Cancel</button>
435-
<button class="button" onclick={confirmArchive}>Confirm</button>
436-
</div>
437-
</div>
438-
</Modal>
439-
440-
<!-- Memorial modal for archived pet -->
441-
<MemorialModal isOpen={memorialOpen} pet={memorialPet} onclose={closeMemorial} />
413+
<!-- Right panel shows confirmation/memorial; no modals here -->
442414

443415
<style>
444416
.cli-row {

src/lib/components/panels/Viewport.svelte

Lines changed: 63 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,14 @@
66
import AIInsightsCard from '../ui/AIInsightsCard.svelte';
77
import EmptyState from '../ui/EmptyState.svelte';
88
import Skeleton from '../ui/Skeleton.svelte';
9+
import { rightPanelView, uiHelpers } from '$lib/stores/ui';
910
import type { PetPanelData } from '$lib/types/Pet';
1011
import type { JournalEntry } from '$lib/types/JournalEntry';
1112
1213
let selectedPet: PetPanelData | null = null;
1314
let selectedPetId: string | null = null;
1415
let pets: PetPanelData[] = [];
15-
let currentView = 'dashboard'; // dashboard, journal, history
16+
let currentView: 'dashboard' | 'journal' | 'history' | 'memorial' | 'confirmArchive' = 'dashboard';
1617
let journalInput = '';
1718
let selectedMood = '';
1819
let selectedActivity = '';
@@ -57,6 +58,9 @@
5758
selectedPet = petId ? pets.find((p) => p.id === petId) || null : null;
5859
});
5960
61+
// Drive view from shared UI store
62+
rightPanelView.subscribe((v) => (currentView = v));
63+
6064
// Load from storage (will trigger subscriptions above)
6165
petHelpers.load();
6266
selectedPetHelpers.load();
@@ -95,7 +99,7 @@
9599
journalInput = '';
96100
selectedMood = '';
97101
selectedActivity = '';
98-
currentView = 'dashboard';
102+
uiHelpers.setView('dashboard');
99103
100104
// Refresh selected pet data
101105
selectedPet = petHelpers.getPet(selectedPet.id);
@@ -127,7 +131,7 @@
127131
}}
128132
/>
129133
{:else}
130-
<div class="pet-viewport h-full flex flex-col">
134+
<div class="pet-viewport h-full flex flex-col">
131135
<!-- Header with pet info and navigation -->
132136
<div class="viewport-header p-4 border-b" style="border-color: var(--petalytics-border); background: var(--petalytics-overlay);">
133137
<div class="flex items-center justify-between">
@@ -145,21 +149,21 @@
145149

146150
<div class="flex space-x-2">
147151
<button
148-
on:click={() => (currentView = 'dashboard')}
152+
on:click={() => uiHelpers.setView('dashboard')}
149153
class="nav-button px-3 py-1 rounded-md text-sm"
150154
class:active={currentView === 'dashboard'}
151155
>
152156
Dashboard
153157
</button>
154158
<button
155-
on:click={() => (currentView = 'journal')}
159+
on:click={() => uiHelpers.setView('journal')}
156160
class="nav-button px-3 py-1 rounded-md text-sm"
157161
class:active={currentView === 'journal'}
158162
>
159163
New Entry
160164
</button>
161165
<button
162-
on:click={() => (currentView = 'history')}
166+
on:click={() => uiHelpers.setView('history')}
163167
class="nav-button px-3 py-1 rounded-md text-sm"
164168
class:active={currentView === 'history'}
165169
>
@@ -171,7 +175,59 @@
171175

172176
<!-- Content Area -->
173177
<div class="viewport-content flex-1 p-4 overflow-y-auto">
174-
{#if currentView === 'dashboard'}
178+
{#if currentView === 'confirmArchive'}
179+
<!-- Confirm Archive View -->
180+
<div class="space-y-4 font-mono">
181+
<h3 class="text-lg font-semibold" style="color: var(--petalytics-text);">Archive Pet</h3>
182+
<p>Mark {selectedPet?.name} as passed away?</p>
183+
<div class="flex justify-end gap-2">
184+
<button class="button-secondary" on:click={() => uiHelpers.setView('dashboard')}>Cancel</button>
185+
<button class="button" on:click={() => {
186+
if (selectedPet) {
187+
petHelpers.archive(selectedPet.id);
188+
if (selectedPetId === selectedPet.id) {
189+
selectedPetHelpers.clear();
190+
}
191+
}
192+
uiHelpers.setView('dashboard');
193+
}}>Confirm</button>
194+
</div>
195+
</div>
196+
{:else if currentView === 'memorial'}
197+
<!-- Memorial View (inline, no modal) -->
198+
<div class="space-y-4 font-mono">
199+
<div class="rounded p-3" style="background: color-mix(in oklab, var(--petalytics-overlay) 60%, transparent); border: 1px solid var(--petalytics-border);">
200+
<div class="flex items-center justify-between">
201+
<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>
206+
</div>
207+
<div class="text-xs px-2 py-1 rounded" style="background: var(--petalytics-surface); color: var(--petalytics-subtle);">
208+
{selectedPet?.journalEntries.length || 0} memories
209+
</div>
210+
</div>
211+
</div>
212+
{#if (selectedPet?.journalEntries.length || 0) === 0}
213+
<div class="text-sm" style="color: var(--petalytics-subtle);">No journal entries yet.</div>
214+
{: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>
225+
</div>
226+
{/each}
227+
</div>
228+
{/if}
229+
</div>
230+
{:else if currentView === 'dashboard'}
175231
<!-- Dashboard View -->
176232
<div class="dashboard-grid space-y-4">
177233
<!-- Stats Cards -->

src/lib/stores/ui.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { writable } from 'svelte/store';
2+
3+
export type RightPanelView = 'dashboard' | 'journal' | 'history' | 'memorial' | 'confirmArchive';
4+
5+
export const rightPanelView = writable<RightPanelView>('dashboard');
6+
7+
export const uiHelpers = {
8+
setView(view: RightPanelView) {
9+
rightPanelView.set(view);
10+
}
11+
};

0 commit comments

Comments
 (0)