refactor(worldtravel): remove insert_id fields from city, country, and region models; update related migration

feat(search): enhance search results display with total results count and improved layout
fix(profile): update achievement levels based on adventure count; remove unused quick actions
refactor(shared): delete unused shared collections route and related components
feat(worldtravel): improve interactive map functionality and layout in world travel detail view
This commit is contained in:
Sean Morley
2025-06-14 14:05:30 -04:00
parent 151c76dbd1
commit b5931c6c23
10 changed files with 275 additions and 228 deletions

View File

@@ -18,6 +18,7 @@
VisitedRegion,
VisitedCity
} from '$lib/types';
import SearchIcon from '~icons/mdi/magnify';
export let data: PageData;
@@ -34,71 +35,171 @@
$: cities = data.cities as City[];
$: visited_regions = data.visited_regions as VisitedRegion[];
$: visited_cities = data.visited_cities as VisitedCity[];
// new stats
$: totalResults =
adventures.length +
collections.length +
users.length +
countries.length +
regions.length +
cities.length;
$: hasResults = totalResults > 0;
</script>
<h1 class="text-4xl font-bold text-center m-4">Search{query ? `: ${query}` : ''}</h1>
{#if adventures.length > 0}
<h2 class="text-3xl font-bold text-center m-4">Adventures</h2>
<div class="flex flex-wrap gap-4 mr-4 ml-4 justify-center content-center">
{#each adventures as adventure}
<AdventureCard {adventure} user={null} />
{/each}
</div>
{/if}
{#if collections.length > 0}
<h2 class="text-3xl font-bold text-center m-4">Collections</h2>
<div class="flex flex-wrap gap-4 mr-4 ml-4 justify-center content-center">
{#each collections as collection}
<CollectionCard {collection} type="" />
{/each}
</div>
{/if}
{#if countries.length > 0}
<h2 class="text-3xl font-bold text-center m-4">Countries</h2>
<div class="flex flex-wrap gap-4 mr-4 ml-4 justify-center content-center">
{#each countries as country}
<CountryCard {country} />
{/each}
</div>
{/if}
{#if regions.length > 0}
<h2 class="text-3xl font-bold text-center m-4">Regions</h2>
<div class="flex flex-wrap gap-4 mr-4 ml-4 justify-center content-center">
{#each regions as region}
<RegionCard {region} visited={visited_regions.some((vr) => vr.region === region.id)} />
{/each}
</div>
{/if}
{#if cities.length > 0}
<h2 class="text-3xl font-bold text-center m-4">Cities</h2>
<div class="flex flex-wrap gap-4 mr-4 ml-4 justify-center content-center">
{#each cities as city}
<CityCard {city} visited={visited_cities.some((vc) => vc.city === city.id)} />
{/each}
</div>
{/if}
{#if users.length > 0}
<h2 class="text-3xl font-bold text-center m-4">Users</h2>
<div class="flex flex-wrap gap-4 mr-4 ml-4 justify-center content-center">
{#each users as user}
<UserCard {user} />
{/each}
</div>
{/if}
{#if adventures.length === 0 && regions.length === 0 && cities.length === 0 && countries.length === 0 && collections.length === 0 && users.length === 0}
<p class="text-center text-lg m-4">
{$t('adventures.no_results')}
</p>
{/if}
<svelte:head>
<title>Search: {query}</title>
<meta name="description" content="AdventureLog global search results for {query}" />
</svelte:head>
<div class="min-h-screen bg-gradient-to-br from-base-200 via-base-100 to-base-200">
<!-- Header -->
<div class="sticky top-0 z-40 bg-base-100/80 backdrop-blur-lg border-b border-base-300">
<div class="container mx-auto px-6 py-4 flex items-center">
<div class="flex items-center gap-3">
<div class="p-2 bg-primary/10 rounded-xl">
<SearchIcon class="w-8 h-8 text-primary" />
</div>
<div>
<h1
class="text-3xl font-bold bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent"
>
Search{query ? `: ${query}` : ''}
</h1>
{#if hasResults}
<p class="text-sm text-base-content/60">
{totalResults} result{totalResults !== 1 ? 's' : ''} found
</p>
{/if}
</div>
</div>
</div>
</div>
<!-- Main content -->
<div class="container mx-auto px-6 py-8">
{#if !hasResults}
<div class="flex flex-col items-center justify-center py-16">
<div class="p-6 bg-base-200/50 rounded-2xl mb-6">
<SearchIcon class="w-16 h-16 text-base-content/30" />
</div>
<h3 class="text-xl font-semibold text-base-content/70 mb-2">
{$t('adventures.no_results')}
</h3>
<p class="text-base-content/50 text-center max-w-md">
Try searching for adventures, collections, countries, regions, cities, or users.
</p>
</div>
{:else}
{#if adventures.length > 0}
<div class="mb-12">
<div class="flex items-center gap-3 mb-6">
<div class="p-2 bg-primary/10 rounded-lg">
<SearchIcon class="w-6 h-6 text-primary" />
</div>
<h2 class="text-2xl font-bold">Adventures</h2>
<div class="badge badge-primary">{adventures.length}</div>
</div>
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6">
{#each adventures as adventure}
<AdventureCard {adventure} user={null} />
{/each}
</div>
</div>
{/if}
{#if collections.length > 0}
<div class="mb-12">
<div class="flex items-center gap-3 mb-6">
<div class="p-2 bg-secondary/10 rounded-lg">
<!-- you can replace with a CollectionIcon -->
<SearchIcon class="w-6 h-6 text-secondary" />
</div>
<h2 class="text-2xl font-bold">Collections</h2>
<div class="badge badge-secondary">{collections.length}</div>
</div>
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6">
{#each collections as collection}
<CollectionCard {collection} type="" user={null} />
{/each}
</div>
</div>
{/if}
{#if countries.length > 0}
<div class="mb-12">
<div class="flex items-center gap-3 mb-6">
<div class="p-2 bg-accent/10 rounded-lg">
<!-- you can replace with a GlobeIcon -->
<SearchIcon class="w-6 h-6 text-accent" />
</div>
<h2 class="text-2xl font-bold">Countries</h2>
<div class="badge badge-accent">{countries.length}</div>
</div>
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6">
{#each countries as country}
<CountryCard {country} />
{/each}
</div>
</div>
{/if}
{#if regions.length > 0}
<div class="mb-12">
<div class="flex items-center gap-3 mb-6">
<div class="p-2 bg-info/10 rounded-lg">
<!-- MapIcon -->
<SearchIcon class="w-6 h-6 text-info" />
</div>
<h2 class="text-2xl font-bold">Regions</h2>
<div class="badge badge-info">{regions.length}</div>
</div>
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6">
{#each regions as region}
<RegionCard
{region}
visited={visited_regions.some((vr) => vr.region === region.id)}
/>
{/each}
</div>
</div>
{/if}
{#if cities.length > 0}
<div class="mb-12">
<div class="flex items-center gap-3 mb-6">
<div class="p-2 bg-warning/10 rounded-lg">
<!-- CityIcon -->
<SearchIcon class="w-6 h-6 text-warning" />
</div>
<h2 class="text-2xl font-bold">Cities</h2>
<div class="badge badge-warning">{cities.length}</div>
</div>
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6">
{#each cities as city}
<CityCard {city} visited={visited_cities.some((vc) => vc.city === city.id)} />
{/each}
</div>
</div>
{/if}
{#if users.length > 0}
<div class="mb-12">
<div class="flex items-center gap-3 mb-6">
<div class="p-2 bg-success/10 rounded-lg">
<!-- UserIcon -->
<SearchIcon class="w-6 h-6 text-success" />
</div>
<h2 class="text-2xl font-bold">Users</h2>
<div class="badge badge-success">{users.length}</div>
</div>
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6">
{#each users as user}
<UserCard {user} />
{/each}
</div>
</div>
{/if}
{/if}
</div>
</div>