feat: show search duration and result count feedback

This commit is contained in:
2026-01-29 13:15:25 -06:00
parent a007ccb6a2
commit e008ee5a12
2 changed files with 47 additions and 1 deletions
@@ -0,0 +1,34 @@
<script lang="ts">
export interface SearchMeta {
totalCount: number;
durationMs: number;
timestamp: Date;
}
let { meta }: { meta: SearchMeta | null } = $props();
let formattedTime = $derived(
meta
? meta.timestamp.toLocaleTimeString(undefined, {
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
})
: ""
);
let countLabel = $derived(meta ? meta.totalCount.toLocaleString() : "");
let resultNoun = $derived(meta ? (meta.totalCount !== 1 ? "results" : "result") : "");
let durationLabel = $derived(meta ? `${Math.round(meta.durationMs)}ms` : "");
</script>
{#if meta}
<p
class="pl-1 text-xs"
title="Last searched at {formattedTime}"
>
<span class="text-muted-foreground/70">{countLabel}</span>
<span class="text-muted-foreground/35">{resultNoun} in</span>
<span class="text-muted-foreground/70">{durationLabel}</span>
</p>
{/if}
+13 -1
View File
@@ -10,6 +10,7 @@ import {
} from "$lib/api";
import type { SortingState } from "@tanstack/table-core";
import SearchFilters from "$lib/components/SearchFilters.svelte";
import SearchStatus, { type SearchMeta } from "$lib/components/SearchStatus.svelte";
import CourseTable from "$lib/components/CourseTable.svelte";
import Pagination from "$lib/components/Pagination.svelte";
import Footer from "$lib/components/Footer.svelte";
@@ -56,6 +57,7 @@ let subjectMap: Record<string, string> = $derived(
Object.fromEntries(subjects.map((s) => [s.code, s.description]))
);
let searchResult: SearchResponse | null = $state(null);
let searchMeta: SearchMeta | null = $state(null);
let loading = $state(false);
let error = $state<string | null>(null);
@@ -169,6 +171,7 @@ async function performSearch(
if (sortDir && sortBy) params.set("sort_dir", sortDir);
goto(`?${params.toString()}`, { replaceState: true, noScroll: true, keepFocus: true });
const t0 = performance.now();
try {
searchResult = await client.searchCourses({
term,
@@ -180,6 +183,11 @@ async function performSearch(
sort_by: sortBy,
sort_dir: sortDir,
});
searchMeta = {
totalCount: searchResult.totalCount,
durationMs: performance.now() - t0,
timestamp: new Date(),
};
} catch (e) {
error = e instanceof Error ? e.message : "Search failed";
} finally {
@@ -199,7 +207,10 @@ function handlePageChange(newOffset: number) {
<h1 class="text-2xl font-semibold text-foreground">UTSA Course Search</h1>
</div>
<!-- Filters -->
<!-- Search status + Filters -->
<div class="flex flex-col gap-1.5">
<SearchStatus meta={searchMeta} />
<!-- Filters -->
<SearchFilters
terms={data.terms}
{subjects}
@@ -208,6 +219,7 @@ function handlePageChange(newOffset: number) {
bind:query
bind:openOnly
/>
</div>
<!-- Results -->
{#if error}