remove trash and archive pages for notes in favor of tabs on note page
This commit is contained in:
@@ -1,78 +0,0 @@
|
|||||||
<script lang="ts">
|
|
||||||
import { goto } from '$app/navigation';
|
|
||||||
import { getNoteService } from '$lib/context/notes.svelte';
|
|
||||||
import { Button } from '$lib/components/ui/button/index.js';
|
|
||||||
import { Separator } from '$lib/components/ui/separator/index.js';
|
|
||||||
import { ArrowLeft, LayoutGrid, List } from '@lucide/svelte';
|
|
||||||
import NotesGrid from '../NotesGrid.svelte';
|
|
||||||
import NoteSearchBar from '../NoteSearchBar.svelte';
|
|
||||||
|
|
||||||
const noteService = getNoteService();
|
|
||||||
|
|
||||||
let searchQuery = $state('');
|
|
||||||
let view = $state<'grid' | 'list'>('grid');
|
|
||||||
|
|
||||||
const filteredNotes = $derived(() => {
|
|
||||||
if (searchQuery.trim()) {
|
|
||||||
return noteService.searchNotes(searchQuery, noteService.archivedNotes);
|
|
||||||
}
|
|
||||||
return noteService.archivedNotes;
|
|
||||||
});
|
|
||||||
|
|
||||||
function openNote(noteId: string) {
|
|
||||||
goto(`/notes/${noteId}`);
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div class="w-full container mx-auto p-6 space-y-6">
|
|
||||||
<!-- Page Header -->
|
|
||||||
<div class="flex items-center justify-between">
|
|
||||||
<div class="flex items-center gap-4">
|
|
||||||
<Button variant="ghost" size="icon-sm" onclick={() => goto('/notes')}>
|
|
||||||
<ArrowLeft class="h-4 w-4" />
|
|
||||||
<span class="sr-only">Back to notes</span>
|
|
||||||
</Button>
|
|
||||||
<div>
|
|
||||||
<h1 class="text-3xl font-bold tracking-tight text-foreground">Archived Notes</h1>
|
|
||||||
<p class="text-muted-foreground">
|
|
||||||
{noteService.archivedNotes.length}
|
|
||||||
{noteService.archivedNotes.length === 1 ? 'note' : 'notes'} archived
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- View Toggle -->
|
|
||||||
<div class="flex items-center border rounded-md">
|
|
||||||
<Button
|
|
||||||
variant={view === 'grid' ? 'secondary' : 'ghost'}
|
|
||||||
size="icon-sm"
|
|
||||||
onclick={() => (view = 'grid')}
|
|
||||||
aria-label="Grid view"
|
|
||||||
>
|
|
||||||
<LayoutGrid class="h-4 w-4" />
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant={view === 'list' ? 'secondary' : 'ghost'}
|
|
||||||
size="icon-sm"
|
|
||||||
onclick={() => (view = 'list')}
|
|
||||||
aria-label="List view"
|
|
||||||
>
|
|
||||||
<List class="h-4 w-4" />
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Separator />
|
|
||||||
|
|
||||||
<!-- Search -->
|
|
||||||
<NoteSearchBar bind:value={searchQuery} placeholder="Search archived notes..." />
|
|
||||||
|
|
||||||
<!-- Notes Grid -->
|
|
||||||
<NotesGrid
|
|
||||||
notes={filteredNotes()}
|
|
||||||
{view}
|
|
||||||
loading={noteService.loading}
|
|
||||||
emptyMessage={searchQuery ? 'No archived notes match your search' : 'No archived notes'}
|
|
||||||
onNoteClick={(note) => openNote(note.id)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
@@ -1,112 +0,0 @@
|
|||||||
<script lang="ts">
|
|
||||||
import { goto } from '$app/navigation';
|
|
||||||
import { getNoteService } from '$lib/context/notes.svelte';
|
|
||||||
import { Button } from '$lib/components/ui/button/index.js';
|
|
||||||
import * as AlertDialog from '$lib/components/ui/alert-dialog/index.js';
|
|
||||||
import { Separator } from '$lib/components/ui/separator/index.js';
|
|
||||||
import { ArrowLeft, LayoutGrid, List, Trash2 } from '@lucide/svelte';
|
|
||||||
import NotesGrid from '../NotesGrid.svelte';
|
|
||||||
import NoteSearchBar from '../NoteSearchBar.svelte';
|
|
||||||
|
|
||||||
const noteService = getNoteService();
|
|
||||||
|
|
||||||
let searchQuery = $state('');
|
|
||||||
let view = $state<'grid' | 'list'>('grid');
|
|
||||||
let emptyTrashDialog = $state(false);
|
|
||||||
|
|
||||||
const filteredNotes = $derived(() => {
|
|
||||||
if (searchQuery.trim()) {
|
|
||||||
return noteService.searchNotes(searchQuery, noteService.trashedNotes);
|
|
||||||
}
|
|
||||||
return noteService.trashedNotes;
|
|
||||||
});
|
|
||||||
|
|
||||||
async function handleEmptyTrash() {
|
|
||||||
await noteService.emptyTrash();
|
|
||||||
emptyTrashDialog = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function openNote(noteId: string) {
|
|
||||||
goto(`/notes/${noteId}`);
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div class="w-full container mx-auto p-6 space-y-6">
|
|
||||||
<!-- Page Header -->
|
|
||||||
<div class="flex items-center justify-between">
|
|
||||||
<div class="flex items-center gap-4">
|
|
||||||
<Button variant="ghost" size="icon-sm" onclick={() => goto('/notes')}>
|
|
||||||
<ArrowLeft class="h-4 w-4" />
|
|
||||||
<span class="sr-only">Back to notes</span>
|
|
||||||
</Button>
|
|
||||||
<div>
|
|
||||||
<h1 class="text-3xl font-bold tracking-tight text-foreground">Trash</h1>
|
|
||||||
<p class="text-muted-foreground">
|
|
||||||
{noteService.trashedNotes.length}
|
|
||||||
{noteService.trashedNotes.length === 1 ? 'note' : 'notes'} in trash • Auto-delete after
|
|
||||||
30 days
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="flex items-center gap-3">
|
|
||||||
<!-- View Toggle -->
|
|
||||||
<div class="flex items-center border rounded-md">
|
|
||||||
<Button
|
|
||||||
variant={view === 'grid' ? 'secondary' : 'ghost'}
|
|
||||||
size="icon-sm"
|
|
||||||
onclick={() => (view = 'grid')}
|
|
||||||
aria-label="Grid view"
|
|
||||||
>
|
|
||||||
<LayoutGrid class="h-4 w-4" />
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant={view === 'list' ? 'secondary' : 'ghost'}
|
|
||||||
size="icon-sm"
|
|
||||||
onclick={() => (view = 'list')}
|
|
||||||
aria-label="List view"
|
|
||||||
>
|
|
||||||
<List class="h-4 w-4" />
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Empty Trash Button -->
|
|
||||||
{#if noteService.trashedNotes.length > 0}
|
|
||||||
<Button variant="destructive" onclick={() => (emptyTrashDialog = true)} class="gap-2">
|
|
||||||
<Trash2 class="h-4 w-4" />
|
|
||||||
Empty Trash
|
|
||||||
</Button>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Separator />
|
|
||||||
|
|
||||||
<!-- Search -->
|
|
||||||
<NoteSearchBar bind:value={searchQuery} placeholder="Search trash..." />
|
|
||||||
|
|
||||||
<!-- Notes Grid -->
|
|
||||||
<NotesGrid
|
|
||||||
notes={filteredNotes()}
|
|
||||||
{view}
|
|
||||||
loading={noteService.loading}
|
|
||||||
emptyMessage={searchQuery ? 'No trashed notes match your search' : 'Trash is empty'}
|
|
||||||
onNoteClick={(note) => openNote(note.id)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Empty Trash Confirmation Dialog -->
|
|
||||||
<AlertDialog.Root bind:open={emptyTrashDialog}>
|
|
||||||
<AlertDialog.Content>
|
|
||||||
<AlertDialog.Header>
|
|
||||||
<AlertDialog.Title>Empty trash?</AlertDialog.Title>
|
|
||||||
<AlertDialog.Description>
|
|
||||||
This will permanently delete all notes in the trash. This action cannot be undone.
|
|
||||||
</AlertDialog.Description>
|
|
||||||
</AlertDialog.Header>
|
|
||||||
<AlertDialog.Footer>
|
|
||||||
<AlertDialog.Cancel>Cancel</AlertDialog.Cancel>
|
|
||||||
<Button onclick={handleEmptyTrash} variant="destructive">Empty trash</Button>
|
|
||||||
</AlertDialog.Footer>
|
|
||||||
</AlertDialog.Content>
|
|
||||||
</AlertDialog.Root>
|
|
||||||
Reference in New Issue
Block a user