feat(05-03): add highlighting to EntryCard and integrate search UI
- Add searchQuery prop to EntryCard for text highlighting
- Use {@html highlightText()} for title and content in collapsed view
- Integrate SearchBar and FilterBar in +page.svelte
- Add search/filter state with reactive sync to filters.query
- Pass recentSearches store to SearchBar
- Update filterEntries to use generics for type preservation
This commit is contained in:
@@ -1,14 +1,29 @@
|
||||
<script lang="ts">
|
||||
import { goto } from '$app/navigation';
|
||||
import { page } from '$app/state';
|
||||
import { get } from 'svelte/store';
|
||||
import EntryList from '$lib/components/EntryList.svelte';
|
||||
import QuickCapture from '$lib/components/QuickCapture.svelte';
|
||||
import CompletedToggle from '$lib/components/CompletedToggle.svelte';
|
||||
import SearchBar from '$lib/components/SearchBar.svelte';
|
||||
import FilterBar from '$lib/components/FilterBar.svelte';
|
||||
import { preferences } from '$lib/stores/preferences.svelte';
|
||||
import { get } from 'svelte/store';
|
||||
import { recentSearches, addRecentSearch } from '$lib/stores/recentSearches';
|
||||
import { type SearchFilters, defaultFilters } from '$lib/types/search';
|
||||
|
||||
let { data } = $props();
|
||||
|
||||
// Search and filter state
|
||||
let searchQuery = $state('');
|
||||
let filters = $state<SearchFilters>({ ...defaultFilters });
|
||||
|
||||
// Sync filters.query with searchQuery
|
||||
$effect(() => {
|
||||
if (filters.query !== searchQuery) {
|
||||
filters = { ...filters, query: searchQuery };
|
||||
}
|
||||
});
|
||||
|
||||
// Sync URL with preference on mount (client-side only)
|
||||
$effect(() => {
|
||||
if (typeof window !== 'undefined') {
|
||||
@@ -27,6 +42,14 @@
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function handleFilterChange(newFilters: SearchFilters) {
|
||||
filters = newFilters;
|
||||
// Sync query back to searchQuery
|
||||
if (newFilters.query !== searchQuery) {
|
||||
searchQuery = newFilters.query;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
@@ -35,14 +58,21 @@
|
||||
|
||||
<main class="min-h-screen bg-gray-50 pb-40">
|
||||
<header class="bg-white border-b border-gray-200 sticky top-0 z-10">
|
||||
<div class="max-w-2xl mx-auto px-4 py-4 flex items-center justify-between">
|
||||
<h1 class="text-xl font-bold text-gray-900">TaskPlaner</h1>
|
||||
<CompletedToggle />
|
||||
<div class="max-w-2xl mx-auto px-4 py-4">
|
||||
<div class="flex items-center justify-between mb-3">
|
||||
<h1 class="text-xl font-bold text-gray-900">TaskPlaner</h1>
|
||||
<CompletedToggle />
|
||||
</div>
|
||||
<SearchBar bind:value={searchQuery} recentSearches={$recentSearches} />
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="max-w-2xl mx-auto px-4 py-3">
|
||||
<FilterBar {filters} availableTags={data.allTags} onchange={handleFilterChange} />
|
||||
</div>
|
||||
|
||||
<div class="max-w-2xl mx-auto px-4 py-4">
|
||||
<EntryList entries={data.entries} availableTags={data.allTags} />
|
||||
<EntryList entries={data.entries} availableTags={data.allTags} {filters} {searchQuery} />
|
||||
</div>
|
||||
|
||||
<QuickCapture />
|
||||
|
||||
Reference in New Issue
Block a user