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:
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user