|
13 | 13 | let selectedPet: PetPanelData | null = null; |
14 | 14 | let selectedPetId: string | null = null; |
15 | 15 | let pets: PetPanelData[] = []; |
16 | | - let currentView: 'dashboard' | 'journal' | 'history' | 'memorial' | 'confirmArchive' = 'dashboard'; |
| 16 | + let currentView: 'dashboard' | 'journal' | 'history' | 'memories' | 'confirmArchive' = 'dashboard'; |
17 | 17 | let journalInput = ''; |
18 | 18 | let selectedMood = ''; |
19 | 19 | let selectedActivity = ''; |
|
41 | 41 | return parts.join(' | '); |
42 | 42 | } |
43 | 43 |
|
| 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 | +
|
44 | 52 | onMount(() => { |
45 | 53 | // Subscribe first so incoming loads propagate into state |
46 | 54 | petStore.subscribe((list) => { |
47 | 55 | pets = list || []; |
48 | 56 | if (selectedPetId) { |
49 | 57 | selectedPet = pets.find((p) => p.id === selectedPetId) || null; |
50 | 58 | } 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 | + } |
53 | 69 | } |
54 | 70 | }); |
55 | 71 |
|
56 | 72 | selectedPetStore.subscribe((petId) => { |
57 | 73 | selectedPetId = petId; |
58 | 74 | 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. |
59 | 77 | }); |
60 | 78 |
|
61 | 79 | // Drive view from shared UI store |
|
136 | 154 | <div class="viewport-header p-4 border-b" style="border-color: var(--petalytics-border); background: var(--petalytics-overlay);"> |
137 | 155 | <div class="flex items-center justify-between"> |
138 | 156 | <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} |
144 | 164 | <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> |
147 | 167 | </div> |
148 | 168 | </div> |
149 | 169 |
|
|
152 | 172 | on:click={() => uiHelpers.setView('dashboard')} |
153 | 173 | class="nav-button px-3 py-1 rounded-md text-sm" |
154 | 174 | class:active={currentView === 'dashboard'} |
| 175 | + disabled={isArchived(selectedPet)} |
155 | 176 | > |
156 | 177 | Dashboard |
157 | 178 | </button> |
158 | 179 | <button |
159 | 180 | on:click={() => uiHelpers.setView('journal')} |
160 | 181 | class="nav-button px-3 py-1 rounded-md text-sm" |
161 | 182 | class:active={currentView === 'journal'} |
| 183 | + disabled={isArchived(selectedPet)} |
162 | 184 | > |
163 | 185 | New Entry |
164 | 186 | </button> |
165 | 187 | <button |
166 | 188 | on:click={() => uiHelpers.setView('history')} |
167 | 189 | class="nav-button px-3 py-1 rounded-md text-sm" |
168 | 190 | class:active={currentView === 'history'} |
| 191 | + disabled={isArchived(selectedPet)} |
169 | 192 | > |
170 | 193 | History |
171 | 194 | </button> |
|
193 | 216 | }}>Confirm</button> |
194 | 217 | </div> |
195 | 218 | </div> |
196 | | - {:else if currentView === 'memorial'} |
197 | | - <!-- Memorial View (inline, no modal) --> |
| 219 | + {:else if currentView === 'memories'} |
| 220 | + <!-- Centralized archived memories view --> |
198 | 221 | <div class="space-y-4 font-mono"> |
199 | 222 | <div class="rounded p-3" style="background: color-mix(in oklab, var(--petalytics-overlay) 60%, transparent); border: 1px solid var(--petalytics-border);"> |
200 | 223 | <div class="flex items-center justify-between"> |
201 | 224 | <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> |
206 | 227 | </div> |
207 | 228 | <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 |
209 | 230 | </div> |
210 | 231 | </div> |
211 | 232 | </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> |
214 | 236 | {: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> |
225 | 242 | </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} |
228 | 262 | {/if} |
229 | 263 | </div> |
230 | 264 | {:else if currentView === 'dashboard'} |
|
0 commit comments