Refactor UI components for improved localization and styling
- Updated various headings and text elements to utilize localization functions for better internationalization support. - Simplified gradient styles in headings to enhance readability. - Adjusted adventure and travel statistics sections to reflect localized titles and descriptions. - Enhanced filter options and buttons with localized text for clarity. - Modified Tailwind CSS configuration to include a new color 'dim' for future styling needs.
This commit is contained in:
@@ -78,61 +78,21 @@
|
||||
<div class="grid lg:grid-cols-2 gap-12 items-center">
|
||||
<!-- Left Content -->
|
||||
<div class="space-y-8 {isVisible ? 'animate-fade-in-up' : 'opacity-0'}">
|
||||
{#if data.user}
|
||||
{#if data.user.first_name && data.user.first_name !== null}
|
||||
<div class="space-y-4">
|
||||
<div
|
||||
class="inline-flex items-center gap-2 px-4 py-2 bg-primary/10 text-primary rounded-full border border-primary/20"
|
||||
>
|
||||
<LightningIcon class="w-4 h-4" />
|
||||
<span class="text-sm font-medium">Welcome back!</span>
|
||||
</div>
|
||||
<h1 class="text-5xl lg:text-7xl font-black leading-tight">
|
||||
<span
|
||||
class="bg-gradient-to-r from-primary via-secondary to-accent bg-clip-text text-transparent"
|
||||
>
|
||||
{data.user.first_name.charAt(0).toUpperCase() + data.user.first_name.slice(1)},
|
||||
</span>
|
||||
<br />
|
||||
<span class="text-base-content/90">
|
||||
{$t('home.hero_1')}
|
||||
</span>
|
||||
</h1>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="space-y-4">
|
||||
<div
|
||||
class="inline-flex items-center gap-2 px-4 py-2 bg-primary/10 text-primary rounded-full border border-primary/20"
|
||||
>
|
||||
<LightningIcon class="w-4 h-4" />
|
||||
<span class="text-sm font-medium">Ready to explore?</span>
|
||||
</div>
|
||||
<h1 class="text-5xl lg:text-7xl font-black leading-tight">
|
||||
<span
|
||||
class="bg-gradient-to-r from-primary via-secondary to-accent bg-clip-text text-transparent"
|
||||
>
|
||||
{$t('home.hero_1')}
|
||||
</span>
|
||||
</h1>
|
||||
</div>
|
||||
{/if}
|
||||
{:else}
|
||||
<div class="space-y-4">
|
||||
<div
|
||||
class="inline-flex items-center gap-2 px-4 py-2 bg-primary/10 text-primary rounded-full border border-primary/20"
|
||||
>
|
||||
<LightningIcon class="w-4 h-4" />
|
||||
<span class="text-sm font-medium">Start your journey</span>
|
||||
</div>
|
||||
<h1 class="text-5xl lg:text-7xl font-black leading-tight">
|
||||
<span
|
||||
class="bg-gradient-to-r from-primary via-secondary to-accent bg-clip-text text-transparent"
|
||||
>
|
||||
{$t('home.hero_1')}
|
||||
</span>
|
||||
</h1>
|
||||
<div class="space-y-4">
|
||||
<div
|
||||
class="inline-flex items-center gap-2 px-4 py-2 bg-primary/10 text-primary rounded-full border border-primary/20"
|
||||
>
|
||||
<LightningIcon class="w-4 h-4" />
|
||||
<span class="text-sm font-medium">{$t('home.start_your_journey')}</span>
|
||||
</div>
|
||||
{/if}
|
||||
<h1 class="text-5xl lg:text-7xl font-black leading-tight">
|
||||
<span
|
||||
class="bg-gradient-to-r from-primary via-secondary to-accent bg-clip-text text-transparent"
|
||||
>
|
||||
{$t('home.hero_1')}
|
||||
</span>
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<p class="text-xl lg:text-2xl text-base-content/70 leading-relaxed font-light max-w-2xl">
|
||||
{$t('home.hero_2')}
|
||||
@@ -165,21 +125,6 @@
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<!-- Stats -->
|
||||
<!-- <div class="grid grid-cols-3 gap-6 pt-8 border-t border-base-300">
|
||||
{#each stats as stat}
|
||||
<div class="text-center">
|
||||
<div class="flex justify-center mb-2">
|
||||
<div class="p-2 bg-primary/10 rounded-lg">
|
||||
<svelte:component this={stat.icon} class="w-5 h-5 text-primary" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-2xl font-bold text-base-content">{stat.value}</div>
|
||||
<div class="text-sm text-base-content/60">{stat.label}</div>
|
||||
</div>
|
||||
{/each}
|
||||
</div> -->
|
||||
</div>
|
||||
|
||||
<!-- Right Content - Hero Image -->
|
||||
@@ -230,7 +175,7 @@
|
||||
<!-- Section Header -->
|
||||
<div class="text-center mb-16 space-y-4">
|
||||
<div
|
||||
class="inline-flex items-center gap-2 px-4 py-2 bg-neutral/10 text-neutral rounded-full border border-neutral/20"
|
||||
class="inline-flex items-center gap-2 px-4 py-2 bg-neutral text-neutral-300 rounded-full border border-neutral"
|
||||
>
|
||||
<StarIcon class="w-4 h-4" />
|
||||
<span class="text-sm font-medium">{$t('home.key_features')}</span>
|
||||
@@ -279,58 +224,11 @@
|
||||
alt="World map with pins"
|
||||
class="rounded-2xl shadow-2xl object-cover w-full"
|
||||
/>
|
||||
|
||||
<!-- Floating Elements -->
|
||||
<div class="absolute top-4 right-4 bg-base-100 p-3 rounded-xl shadow-lg animate-float">
|
||||
<div class="flex items-center gap-2">
|
||||
<CheckIcon class="w-4 h-4 text-success" />
|
||||
<span class="text-sm font-medium">25 Countries</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="absolute bottom-4 left-4 bg-base-100 p-3 rounded-xl shadow-lg animate-float-delayed"
|
||||
>
|
||||
<div class="flex items-center gap-2">
|
||||
<TrophyIcon class="w-4 h-4 text-warning" />
|
||||
<span class="text-sm font-medium">Explorer Level</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Call to Action Section -->
|
||||
{#if !data.user}
|
||||
<section class="py-24 bg-gradient-to-r from-primary to-secondary">
|
||||
<div class="container mx-auto px-6 text-center">
|
||||
<div class="max-w-3xl mx-auto space-y-8">
|
||||
<h2 class="text-4xl lg:text-5xl font-bold text-white">Ready to Start Your Adventure?</h2>
|
||||
<p class="text-xl text-white/90 leading-relaxed">
|
||||
Join thousands of travelers already using AdventureLog to document their journeys and
|
||||
discover new destinations.
|
||||
</p>
|
||||
<div class="flex flex-col sm:flex-row gap-4 justify-center pt-4">
|
||||
<button
|
||||
on:click={() => goto('/signup')}
|
||||
class="btn btn-lg bg-white text-primary hover:bg-white/90 gap-3 shadow-lg group"
|
||||
>
|
||||
Get Started
|
||||
<ChevronRight class="w-4 h-4 group-hover:translate-x-1 transition-transform" />
|
||||
</button>
|
||||
<button
|
||||
on:click={() => goto('/login')}
|
||||
class="btn btn-lg btn-outline text-white border-white hover:bg-white hover:text-primary gap-3"
|
||||
>
|
||||
Sign In
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<svelte:head>
|
||||
|
||||
@@ -197,13 +197,14 @@
|
||||
<Compass 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"
|
||||
>
|
||||
<h1 class="text-3xl font-bold bg-clip-text text-primary">
|
||||
{$t('navbar.my_adventures')}
|
||||
</h1>
|
||||
<p class="text-sm text-base-content/60">
|
||||
{count} adventures • {getVisitedCount()} visited • {getPlannedCount()} planned
|
||||
{count}
|
||||
{$t('navbar.adventures')} • {getVisitedCount()}
|
||||
{$t('adventures.visited')} • {getPlannedCount()}
|
||||
{$t('adventures.planned')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -216,14 +217,14 @@
|
||||
<div class="stat-figure text-primary">
|
||||
<Eye class="w-5 h-5" />
|
||||
</div>
|
||||
<div class="stat-title text-xs">Visited</div>
|
||||
<div class="stat-title text-xs">{$t('adventures.visited')}</div>
|
||||
<div class="stat-value text-lg">{getVisitedCount()}</div>
|
||||
</div>
|
||||
<div class="stat py-2 px-4">
|
||||
<div class="stat-figure text-secondary">
|
||||
<Calendar class="w-5 h-5" />
|
||||
</div>
|
||||
<div class="stat-title text-xs">Planned</div>
|
||||
<div class="stat-title text-xs">{$t('adventures.planned')}</div>
|
||||
<div class="stat-value text-lg">{getPlannedCount()}</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -239,10 +240,11 @@
|
||||
<div class="p-6 bg-base-200/50 rounded-2xl mb-6">
|
||||
<Compass class="w-16 h-16 text-base-content/30" />
|
||||
</div>
|
||||
<h3 class="text-xl font-semibold text-base-content/70 mb-2">No adventures yet</h3>
|
||||
<h3 class="text-xl font-semibold text-base-content/70 mb-2">
|
||||
{$t('adventures.no_adventures_found')}
|
||||
</h3>
|
||||
<p class="text-base-content/50 text-center max-w-md">
|
||||
Start documenting your adventures and planning new ones. Every journey has a story
|
||||
worth telling.
|
||||
{$t('adventures.no_adventures_message')}
|
||||
</p>
|
||||
<button
|
||||
class="btn btn-primary btn-wide mt-6 gap-2"
|
||||
@@ -252,7 +254,7 @@
|
||||
}}
|
||||
>
|
||||
<Plus class="w-5 h-5" />
|
||||
Create Adventure
|
||||
{$t('adventures.create_adventure')}
|
||||
</button>
|
||||
</div>
|
||||
{:else}
|
||||
@@ -301,7 +303,7 @@
|
||||
<div class="p-2 bg-primary/10 rounded-lg">
|
||||
<Filter class="w-6 h-6 text-primary" />
|
||||
</div>
|
||||
<h2 class="text-xl font-bold">Filters & Sort</h2>
|
||||
<h2 class="text-xl font-bold">{$t('adventures.filters_and_sort')}</h2>
|
||||
</div>
|
||||
|
||||
<!-- Filters Form -->
|
||||
@@ -332,6 +334,7 @@
|
||||
|
||||
<div class="space-y-4">
|
||||
<div>
|
||||
<!-- svelte-ignore a11y-label-has-associated-control -->
|
||||
<label class="label">
|
||||
<span class="label-text font-medium">{$t('adventures.order_direction')}</span>
|
||||
</label>
|
||||
@@ -358,6 +361,7 @@
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<!-- svelte-ignore a11y-label-has-associated-control -->
|
||||
<label class="label">
|
||||
<span class="label-text font-medium">{$t('adventures.order_by')}</span>
|
||||
</label>
|
||||
@@ -491,12 +495,10 @@
|
||||
<Plus class="w-8 h-8" />
|
||||
</div>
|
||||
<ul
|
||||
tabindex="0"
|
||||
class="dropdown-content z-[40] menu p-4 shadow-2xl bg-base-100 rounded-2xl w-64 border border-base-300"
|
||||
>
|
||||
<div class="text-center mb-4">
|
||||
<h3 class="font-bold text-lg">{$t('adventures.create_new')}</h3>
|
||||
<p class="text-sm text-base-content/60">Document your journey</p>
|
||||
</div>
|
||||
<button
|
||||
class="btn btn-primary gap-2 w-full"
|
||||
|
||||
@@ -201,18 +201,16 @@
|
||||
<CollectionIcon 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"
|
||||
>
|
||||
<h1 class="text-3xl font-bold bg-clip-text text-primary">
|
||||
{$t(`adventures.my_collections`)}
|
||||
</h1>
|
||||
<p class="text-sm text-base-content/60">
|
||||
{currentCount}
|
||||
{activeView === 'owned'
|
||||
? 'collections'
|
||||
? $t('navbar.collections')
|
||||
: activeView === 'shared'
|
||||
? 'shared collections'
|
||||
: 'archived collections'}
|
||||
? $t('collection.shared_collections')
|
||||
: $t('adventures.archived_collections')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -225,7 +223,7 @@
|
||||
on:click={() => switchView('owned')}
|
||||
>
|
||||
<CollectionIcon class="w-4 h-4" />
|
||||
<span class="hidden sm:inline">My Collections</span>
|
||||
<span class="hidden sm:inline">{$t('adventures.my_collections')}</span>
|
||||
<div
|
||||
class="badge badge-sm {activeView === 'owned' ? 'badge-primary' : 'badge-ghost'}"
|
||||
>
|
||||
@@ -237,7 +235,7 @@
|
||||
on:click={() => switchView('shared')}
|
||||
>
|
||||
<Share class="w-4 h-4" />
|
||||
<span class="hidden sm:inline">Shared</span>
|
||||
<span class="hidden sm:inline">{$t('share.shared')}</span>
|
||||
<div
|
||||
class="badge badge-sm {activeView === 'shared' ? 'badge-primary' : 'badge-ghost'}"
|
||||
>
|
||||
@@ -249,7 +247,7 @@
|
||||
on:click={() => switchView('archived')}
|
||||
>
|
||||
<Archive class="w-4 h-4" />
|
||||
<span class="hidden sm:inline">Archived</span>
|
||||
<span class="hidden sm:inline">{$t('adventures.archived')}</span>
|
||||
<div
|
||||
class="badge badge-sm {activeView === 'archived'
|
||||
? 'badge-primary'
|
||||
@@ -278,17 +276,17 @@
|
||||
</div>
|
||||
<h3 class="text-xl font-semibold text-base-content/70 mb-2">
|
||||
{activeView === 'owned'
|
||||
? 'No collections yet'
|
||||
? $t('collection.no_collections_yet')
|
||||
: activeView === 'shared'
|
||||
? 'No shared collections.'
|
||||
: 'No archived collections'}
|
||||
? $t('collection.no_shared_collections')
|
||||
: $t('collection.no_archived_collections')}
|
||||
</h3>
|
||||
<p class="text-base-content/50 text-center max-w-md">
|
||||
{activeView === 'owned'
|
||||
? 'Create your first collection to organize your adventures and memories.'
|
||||
? $t('collection.create_first')
|
||||
: activeView === 'shared'
|
||||
? 'Make sure your profile is public so others can share with you.'
|
||||
: 'Archived collections will appear here.'}
|
||||
? $t('collection.make_sure_public')
|
||||
: $t('collection.archived_appear_here')}
|
||||
</p>
|
||||
{#if activeView === 'owned'}
|
||||
<button
|
||||
@@ -300,7 +298,7 @@
|
||||
}}
|
||||
>
|
||||
<Plus class="w-5 h-5" />
|
||||
Create Collection
|
||||
{$t('collection.create')}
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
@@ -353,7 +351,7 @@
|
||||
<div class="p-2 bg-primary/10 rounded-lg">
|
||||
<Sort class="w-6 h-6 text-primary" />
|
||||
</div>
|
||||
<h2 class="text-xl font-bold">Filters & Sort</h2>
|
||||
<h2 class="text-xl font-bold">{$t('adventures.filters_and_sort')}</h2>
|
||||
</div>
|
||||
|
||||
<!-- Sort Form - Updated to use URL navigation -->
|
||||
@@ -365,6 +363,7 @@
|
||||
|
||||
<div class="space-y-4">
|
||||
<div>
|
||||
<!-- svelte-ignore a11y-label-has-associated-control -->
|
||||
<label class="label">
|
||||
<span class="label-text font-medium">{$t(`adventures.order_direction`)}</span>
|
||||
</label>
|
||||
@@ -389,6 +388,7 @@
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<!-- svelte-ignore a11y-label-has-associated-control -->
|
||||
<label class="label">
|
||||
<span class="label-text font-medium">{$t('adventures.order_by')}</span>
|
||||
</label>
|
||||
@@ -427,18 +427,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Quick Actions -->
|
||||
<!-- <div class="space-y-3 mt-6">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-outline w-full gap-2"
|
||||
on:click={() => switchView('archived')}
|
||||
>
|
||||
<Archive class="w-4 h-4" />
|
||||
{$t(`adventures.archived_collections`)}
|
||||
</button>
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -456,12 +444,10 @@
|
||||
<Plus class="w-8 h-8" />
|
||||
</div>
|
||||
<ul
|
||||
tabindex="0"
|
||||
class="dropdown-content z-[1] menu p-4 shadow-2xl bg-base-100 rounded-2xl w-64 border border-base-300"
|
||||
>
|
||||
<div class="text-center mb-4">
|
||||
<h3 class="font-bold text-lg">{$t(`adventures.create_new`)}</h3>
|
||||
<p class="text-sm text-base-content/60">Choose what to create</p>
|
||||
</div>
|
||||
<button
|
||||
class="btn btn-primary gap-2 w-full"
|
||||
|
||||
@@ -37,28 +37,26 @@
|
||||
<div class="flex flex-col lg:flex-row lg:items-center lg:justify-between gap-6">
|
||||
<div>
|
||||
<div class="flex items-center gap-4 mb-4">
|
||||
<div class="avatar placeholder">
|
||||
<!-- <div class="avatar placeholder">
|
||||
<div class="bg-primary text-primary-content rounded-full w-16 h-16">
|
||||
<span class="text-xl font-bold">
|
||||
{user?.first_name?.charAt(0) || user?.username?.charAt(0) || 'A'}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
<div>
|
||||
<h1
|
||||
class="text-4xl lg:text-5xl font-bold bg-gradient-to-r from-primary via-secondary to-accent bg-clip-text text-transparent"
|
||||
>
|
||||
<h1 class="text-4xl lg:text-5xl font-bold bg-clip-text text-primary">
|
||||
{$t('dashboard.welcome_back')}, {user?.first_name
|
||||
? `${user.first_name}`
|
||||
: user?.username}!
|
||||
</h1>
|
||||
<p class="text-lg text-base-content/60 mt-2">
|
||||
{#if stats.adventure_count > 0}
|
||||
You've been on <span class="font-semibold text-primary"
|
||||
>{stats.adventure_count}</span
|
||||
> adventures so far
|
||||
{$t('dashboard.welcome_text_1')}
|
||||
<span class="font-semibold text-primary">{stats.adventure_count}</span>
|
||||
{$t('dashboard.welcome_text_2')}
|
||||
{:else}
|
||||
Ready to start your adventure journey?
|
||||
{$t('dashboard.welcome_text_3')}
|
||||
{/if}
|
||||
</p>
|
||||
</div>
|
||||
@@ -76,14 +74,16 @@
|
||||
</a>
|
||||
<a href="/worldtravel" class="btn btn-outline btn-lg gap-2">
|
||||
<FlagCheckeredVariantIcon class="w-5 h-5" />
|
||||
Explore World
|
||||
{$t('home.explore_world')}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Stats Grid -->
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6 mb-12">
|
||||
<div
|
||||
class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-3 gap-8 mb-12"
|
||||
>
|
||||
<!-- Countries Visited -->
|
||||
<div
|
||||
class="stat-card card bg-gradient-to-br from-primary/10 to-primary/5 shadow-xl border border-primary/20 hover:shadow-2xl transition-all duration-300"
|
||||
@@ -99,7 +99,7 @@
|
||||
</div>
|
||||
<div class="stat-desc text-primary/60 mt-2">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="font-medium">{completionPercentage}% of world</span>
|
||||
<span class="font-medium">{completionPercentage}% {$t('home.of_world')}</span>
|
||||
</div>
|
||||
<progress
|
||||
class="progress progress-primary w-full mt-1"
|
||||
@@ -128,12 +128,6 @@
|
||||
<div class="stat-value text-3xl font-bold text-success">
|
||||
{stats.visited_region_count}
|
||||
</div>
|
||||
<div class="stat-desc text-success/60 mt-2">
|
||||
<div class="flex items-center gap-1">
|
||||
<MapMarkerStarOutline class="w-4 h-4" />
|
||||
Unique regions
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="p-4 bg-success/20 rounded-2xl">
|
||||
<MapMarkerStarOutline class="w-8 h-8 text-success" />
|
||||
@@ -153,12 +147,6 @@
|
||||
{$t('dashboard.total_visited_cities')}
|
||||
</div>
|
||||
<div class="stat-value text-3xl font-bold text-info">{stats.visited_city_count}</div>
|
||||
<div class="stat-desc text-info/60 mt-2">
|
||||
<div class="flex items-center gap-1">
|
||||
<CityVariantOutline class="w-4 h-4" />
|
||||
Urban adventures
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="p-4 bg-info/20 rounded-2xl">
|
||||
<CityVariantOutline class="w-8 h-8 text-info" />
|
||||
@@ -178,11 +166,11 @@
|
||||
</div>
|
||||
<div>
|
||||
<h2 class="text-3xl font-bold">{$t('dashboard.recent_adventures')}</h2>
|
||||
<p class="text-base-content/60">Your latest travel experiences</p>
|
||||
<p class="text-base-content/60">{$t('home.latest_travel_experiences')}</p>
|
||||
</div>
|
||||
</div>
|
||||
<a href="/adventures" class="btn btn-ghost gap-2">
|
||||
View All
|
||||
{$t('dashboard.view_all')}
|
||||
<span class="badge badge-primary">{stats.adventure_count}</span>
|
||||
</a>
|
||||
</div>
|
||||
@@ -215,8 +203,7 @@
|
||||
{$t('dashboard.no_recent_adventures')}
|
||||
</h2>
|
||||
<p class="text-lg text-base-content/60 mb-8 max-w-md mx-auto leading-relaxed">
|
||||
{$t('dashboard.add_some')} Start documenting your travels and build your personal adventure
|
||||
map!
|
||||
{$t('dashboard.document_some_adventures')}
|
||||
</p>
|
||||
|
||||
<div class="flex flex-col sm:flex-row gap-4 justify-center">
|
||||
@@ -229,44 +216,9 @@
|
||||
</a>
|
||||
<a href="/worldtravel" class="btn btn-outline btn-lg gap-2">
|
||||
<FlagCheckeredVariantIcon class="w-5 h-5" />
|
||||
Explore World Map
|
||||
{$t('home.explore_world')}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Inspiration Cards -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 mt-12 max-w-4xl mx-auto">
|
||||
<div class="card bg-base-100/50 shadow-lg">
|
||||
<div class="card-body p-6 text-center">
|
||||
<div class="p-3 bg-primary/10 rounded-xl w-fit mx-auto mb-4">
|
||||
<Airplane class="w-6 h-6 text-primary" />
|
||||
</div>
|
||||
<h3 class="font-semibold text-primary">Plan Adventures</h3>
|
||||
<p class="text-sm text-base-content/60 mt-2">
|
||||
Create and organize your travel plans
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card bg-base-100/50 shadow-lg">
|
||||
<div class="card-body p-6 text-center">
|
||||
<div class="p-3 bg-secondary/10 rounded-xl w-fit mx-auto mb-4">
|
||||
<FlagCheckeredVariantIcon class="w-6 h-6 text-secondary" />
|
||||
</div>
|
||||
<h3 class="font-semibold text-secondary">Track Countries</h3>
|
||||
<p class="text-sm text-base-content/60 mt-2">Mark visited countries and regions</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card bg-base-100/50 shadow-lg">
|
||||
<div class="card-body p-6 text-center">
|
||||
<div class="p-3 bg-success/10 rounded-xl w-fit mx-auto mb-4">
|
||||
<MapMarkerStarOutline class="w-6 h-6 text-success" />
|
||||
</div>
|
||||
<h3 class="font-semibold text-success">Share Memories</h3>
|
||||
<p class="text-sm text-base-content/60 mt-2">Document and share your experiences</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -122,13 +122,14 @@
|
||||
<MapIcon 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"
|
||||
>
|
||||
<h1 class="text-3xl font-bold bg-clip-text text-primary">
|
||||
{$t('map.adventure_map')}
|
||||
</h1>
|
||||
<p class="text-sm text-base-content/60">
|
||||
{filteredAdventures.length} of {totalAdventures} adventures shown
|
||||
{filteredAdventures.length}
|
||||
{$t('worldtravel.of')}
|
||||
{totalAdventures}
|
||||
{$t('map.adventures_shown')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -138,11 +139,11 @@
|
||||
<div class="hidden md:flex items-center gap-2">
|
||||
<div class="stats stats-horizontal bg-base-100 shadow-lg">
|
||||
<div class="stat py-2 px-4">
|
||||
<div class="stat-title text-xs">Visited</div>
|
||||
<div class="stat-title text-xs">{$t('adventures.visited')}</div>
|
||||
<div class="stat-value text-lg text-success">{visitedAdventures}</div>
|
||||
</div>
|
||||
<div class="stat py-2 px-4">
|
||||
<div class="stat-title text-xs">Planned</div>
|
||||
<div class="stat-title text-xs">{$t('adventures.planned')}</div>
|
||||
<div class="stat-value text-lg text-info">{plannedAdventures}</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -190,7 +191,7 @@
|
||||
{#if adventure.latitude && adventure.longitude}
|
||||
<Marker
|
||||
lngLat={[adventure.longitude, adventure.latitude]}
|
||||
class="grid h-8 w-8 place-items-center rounded-full border border-gray-200 shadow-lg cursor-pointer transition-transform hover:scale-110 {adventure.is_visited
|
||||
class="grid h-8 w-8 place-items-center rounded-full border border-gray-200 shadow-lg cursor-pointer hover:scale-110 {adventure.is_visited
|
||||
? 'bg-red-300 hover:bg-red-400'
|
||||
: 'bg-blue-300 hover:bg-blue-400'} text-black focus:outline-6 focus:outline-black"
|
||||
on:click={togglePopup}
|
||||
@@ -318,43 +319,42 @@
|
||||
<div class="p-2 bg-primary/10 rounded-lg">
|
||||
<Filter class="w-6 h-6 text-primary" />
|
||||
</div>
|
||||
<h2 class="text-xl font-bold">Map Controls</h2>
|
||||
<h2 class="text-xl font-bold">{$t('map.map_controls')}</h2>
|
||||
</div>
|
||||
|
||||
<!-- Adventure Statistics -->
|
||||
<div class="card bg-base-200/50 p-4 mb-6">
|
||||
<h3 class="font-semibold text-lg mb-4 flex items-center gap-2">
|
||||
<MapIcon class="w-5 h-5" />
|
||||
Adventure Stats
|
||||
{$t('map.adventure_stats')}
|
||||
</h3>
|
||||
|
||||
<div class="space-y-4">
|
||||
<div class="stat p-0">
|
||||
<div class="stat-title text-sm">Total Adventures</div>
|
||||
<div class="stat-title text-sm">{$t('dashboard.total_adventures')}</div>
|
||||
<div class="stat-value text-2xl">{totalAdventures}</div>
|
||||
<div class="stat-desc">Across all locations</div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<div class="stat p-0">
|
||||
<div class="stat-title text-xs">Visited</div>
|
||||
<div class="stat-title text-xs">{$t('adventures.visited')}</div>
|
||||
<div class="stat-value text-lg text-success">{visitedAdventures}</div>
|
||||
</div>
|
||||
<div class="stat p-0">
|
||||
<div class="stat-title text-xs">Planned</div>
|
||||
<div class="stat-title text-xs">{$t('adventures.planned')}</div>
|
||||
<div class="stat-value text-lg text-info">{plannedAdventures}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="stat p-0">
|
||||
<div class="stat-title text-xs">Regions</div>
|
||||
<div class="stat-title text-xs">{$t('map.regions')}</div>
|
||||
<div class="stat-value text-lg text-accent">{totalRegions}</div>
|
||||
</div>
|
||||
|
||||
<!-- Progress Bar -->
|
||||
<div class="space-y-2">
|
||||
<div class="flex justify-between text-sm">
|
||||
<span>Completion</span>
|
||||
<span>{$t('map.completion')}</span>
|
||||
<span>{Math.round((visitedAdventures / totalAdventures) * 100)}%</span>
|
||||
</div>
|
||||
<progress
|
||||
@@ -370,7 +370,7 @@
|
||||
<div class="card bg-base-200/50 p-4 mb-6">
|
||||
<h3 class="font-semibold text-lg mb-4 flex items-center gap-2">
|
||||
<Eye class="w-5 h-5" />
|
||||
Display Options
|
||||
{$t('map.display_options')}
|
||||
</h3>
|
||||
|
||||
<div class="space-y-3">
|
||||
@@ -423,7 +423,7 @@
|
||||
<div class="space-y-3">
|
||||
<div class="alert alert-info">
|
||||
<Pin class="w-4 h-4" />
|
||||
<span class="text-sm">Marker placed on map</span>
|
||||
<span class="text-sm">{$t('map.marker_placed_on_map')}</span>
|
||||
</div>
|
||||
<button type="button" class="btn btn-primary w-full gap-2" on:click={newAdventure}>
|
||||
<Plus class="w-4 h-4" />
|
||||
@@ -437,7 +437,7 @@
|
||||
{:else}
|
||||
<div class="space-y-3">
|
||||
<p class="text-sm text-base-content/60">
|
||||
Click on the map to place a marker, or add an adventure without location.
|
||||
{$t('map.place_marker_desc')}
|
||||
</p>
|
||||
<button
|
||||
type="button"
|
||||
|
||||
@@ -175,8 +175,8 @@
|
||||
{#if stats}
|
||||
<div class="content-section mb-16">
|
||||
<div class="text-center mb-8">
|
||||
<h2 class="text-3xl font-bold mb-2">Travel Statistics</h2>
|
||||
<p class="text-base-content/60">Your adventure journey at a glance</p>
|
||||
<h2 class="text-3xl font-bold mb-2">{$t('profile.travel_statistics')}</h2>
|
||||
<p class="text-base-content/60">{$t('profile.your_journey_at_a_glance')}</p>
|
||||
</div>
|
||||
|
||||
<!-- Primary Stats Grid -->
|
||||
@@ -215,7 +215,7 @@
|
||||
{$t('navbar.collections')}
|
||||
</div>
|
||||
<div class="text-4xl font-bold text-secondary">{stats.trips_count}</div>
|
||||
<div class="text-secondary/60 mt-2">Curated trips</div>
|
||||
<div class="text-secondary/60 mt-2">{$t('profile.planned_trips')}</div>
|
||||
</div>
|
||||
<div class="p-4 bg-secondary/20 rounded-2xl">
|
||||
<CollectionIcon class="w-8 h-8 text-secondary" />
|
||||
@@ -237,7 +237,7 @@
|
||||
<div class="text-4xl font-bold text-success">{stats.visited_country_count}</div>
|
||||
<div class="text-success/60 mt-2">
|
||||
<div class="flex items-center justify-between mb-1">
|
||||
<span>{worldExplorationPercentage}% of world</span>
|
||||
<span>{worldExplorationPercentage}% {$t('home.of_world')}</span>
|
||||
<span class="text-xs"
|
||||
>{stats.visited_country_count}/{stats.total_countries}</span
|
||||
>
|
||||
@@ -272,7 +272,7 @@
|
||||
<div class="text-3xl font-bold text-info">{stats.visited_region_count}</div>
|
||||
<div class="text-info/60 mt-2">
|
||||
<div class="flex items-center justify-between mb-1">
|
||||
<span>{regionExplorationPercentage}% explored</span>
|
||||
<span>{regionExplorationPercentage}% {$t('profile.explored')}</span>
|
||||
<span class="text-xs">{stats.visited_region_count}/{stats.total_regions}</span
|
||||
>
|
||||
</div>
|
||||
@@ -303,7 +303,7 @@
|
||||
<div class="text-3xl font-bold text-warning">{stats.visited_city_count}</div>
|
||||
<div class="text-warning/60 mt-2">
|
||||
<div class="flex items-center justify-between mb-1">
|
||||
<span>{cityExplorationPercentage}% discovered</span>
|
||||
<span>{cityExplorationPercentage}% {$t('profile.discovered')}</span>
|
||||
<span class="text-xs">{stats.visited_city_count}/{stats.total_cities}</span>
|
||||
</div>
|
||||
<progress
|
||||
@@ -332,13 +332,13 @@
|
||||
</div>
|
||||
<div>
|
||||
<h2 class="text-3xl font-bold">{$t('auth.user_adventures')}</h2>
|
||||
<p class="text-base-content/60">Public adventure experiences</p>
|
||||
<p class="text-base-content/60">{$t('profile.public_adventure_experiences')}</p>
|
||||
</div>
|
||||
</div>
|
||||
{#if adventures && adventures.length > 0}
|
||||
<div class="badge badge-primary badge-lg">
|
||||
{adventures.length}
|
||||
{adventures.length === 1 ? 'Adventure' : 'Adventures'}
|
||||
{adventures.length === 1 ? $t('adventures.adventure') : $t('navbar.adventures')}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
@@ -352,7 +352,7 @@
|
||||
<h3 class="text-xl font-bold text-base-content/70 mb-2">
|
||||
{$t('auth.no_public_adventures')}
|
||||
</h3>
|
||||
<p class="text-base-content/50">This user hasn't shared any public adventures yet.</p>
|
||||
<p class="text-base-content/50">{$t('profile.no_shared_adventures')}</p>
|
||||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
@@ -375,13 +375,13 @@
|
||||
</div>
|
||||
<div>
|
||||
<h2 class="text-3xl font-bold">{$t('auth.user_collections')}</h2>
|
||||
<p class="text-base-content/60">Curated travel collections</p>
|
||||
<p class="text-base-content/60">{$t('profile.planned_trips')}</p>
|
||||
</div>
|
||||
</div>
|
||||
{#if collections && collections.length > 0}
|
||||
<div class="badge badge-secondary badge-lg">
|
||||
{collections.length}
|
||||
{collections.length === 1 ? 'Collection' : 'Collections'}
|
||||
{collections.length === 1 ? $t('adventures.collection') : $t('navbar.collections')}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
@@ -395,7 +395,7 @@
|
||||
<h3 class="text-xl font-bold text-base-content/70 mb-2">
|
||||
{$t('auth.no_public_collections')}
|
||||
</h3>
|
||||
<p class="text-base-content/50">This user hasn't shared any public collections yet.</p>
|
||||
<p class="text-base-content/50">{$t('profile.no_shared_collections')}</p>
|
||||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
|
||||
@@ -285,9 +285,7 @@
|
||||
<div class="container mx-auto px-6 py-8">
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<h1
|
||||
class="text-4xl font-bold bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent pb-1"
|
||||
>
|
||||
<h1 class="text-4xl font-bold bg-clip-text text-primary pb-1">
|
||||
{$t('settings.settings_page')}
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
@@ -108,13 +108,14 @@
|
||||
<Globe 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"
|
||||
>
|
||||
<h1 class="text-3xl font-bold text-primary bg-clip-text">
|
||||
{$t('worldtravel.country_list')}
|
||||
</h1>
|
||||
<p class="text-sm text-base-content/60">
|
||||
{filteredCountries.length} of {totalCountries} countries
|
||||
{filteredCountries.length}
|
||||
{$t('worldtravel.of')}
|
||||
{totalCountries}
|
||||
{$t('worldtravel.countries')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -124,11 +125,11 @@
|
||||
<div class="hidden md:flex items-center gap-2">
|
||||
<div class="stats stats-horizontal bg-base-100 shadow-lg">
|
||||
<div class="stat py-2 px-4">
|
||||
<div class="stat-title text-xs">Visited</div>
|
||||
<div class="stat-title text-xs">{$t('adventures.visited')}</div>
|
||||
<div class="stat-value text-lg text-success">{visitedCountries}</div>
|
||||
</div>
|
||||
<div class="stat py-2 px-4">
|
||||
<div class="stat-title text-xs">Remaining</div>
|
||||
<div class="stat-title text-xs">{$t('worldtravel.remaining')}</div>
|
||||
<div class="stat-value text-lg text-error">{notVisitedCountries}</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -164,45 +165,47 @@
|
||||
>
|
||||
{#if showMap}
|
||||
<Map class="w-4 h-4" />
|
||||
<span class="hidden sm:inline">Hide Map</span>
|
||||
<span class="hidden sm:inline">{$t('worldtravel.hide_map')}</span>
|
||||
{:else}
|
||||
<Map class="w-4 h-4" />
|
||||
<span class="hidden sm:inline">Show Map</span>
|
||||
<span class="hidden sm:inline">{$t('worldtravel.show_map')}</span>
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Filter Chips -->
|
||||
<div class="mt-4 flex flex-wrap items-center gap-2">
|
||||
<span class="text-sm font-medium text-base-content/60">Filter by:</span>
|
||||
<span class="text-sm font-medium text-base-content/60"
|
||||
>{$t('worldtravel.filter_by')}:</span
|
||||
>
|
||||
<div class="tabs tabs-boxed bg-base-200">
|
||||
<button
|
||||
class="tab tab-sm gap-2 {filterOption === 'all' ? 'tab-active' : ''}"
|
||||
on:click={() => (filterOption = 'all')}
|
||||
>
|
||||
<Globe class="w-3 h-3" />
|
||||
All
|
||||
{$t('adventures.all')}
|
||||
</button>
|
||||
<button
|
||||
class="tab tab-sm gap-2 {filterOption === 'complete' ? 'tab-active' : ''}"
|
||||
on:click={() => (filterOption = 'complete')}
|
||||
>
|
||||
<Check class="w-3 h-3" />
|
||||
Complete
|
||||
{$t('worldtravel.complete')}
|
||||
</button>
|
||||
<button
|
||||
class="tab tab-sm gap-2 {filterOption === 'partial' ? 'tab-active' : ''}"
|
||||
on:click={() => (filterOption = 'partial')}
|
||||
>
|
||||
<Progress class="w-3 h-3" />
|
||||
Partial
|
||||
{$t('worldtravel.partial')}
|
||||
</button>
|
||||
<button
|
||||
class="tab tab-sm gap-2 {filterOption === 'not' ? 'tab-active' : ''}"
|
||||
on:click={() => (filterOption = 'not')}
|
||||
>
|
||||
<Cancel class="w-3 h-3" />
|
||||
Not Visited
|
||||
{$t('adventures.not_visited')}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -218,7 +221,7 @@
|
||||
{#if searchQuery || filterOption !== 'all' || subRegionOption}
|
||||
<button class="btn btn-ghost btn-xs gap-1" on:click={clearFilters}>
|
||||
<Clear class="w-3 h-3" />
|
||||
Clear All
|
||||
{$t('worldtravel.clear_all')}
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
@@ -272,19 +275,19 @@
|
||||
{$t('worldtravel.no_countries_found')}
|
||||
</h3>
|
||||
<p class="text-base-content/50 text-center max-w-md mb-6">
|
||||
Try adjusting your search terms or filters to find the countries you're looking for.
|
||||
{$t('worldtravel.no_countries_found_desc')}
|
||||
</p>
|
||||
<button class="btn btn-primary gap-2" on:click={clearFilters}>
|
||||
<Clear class="w-4 h-4" />
|
||||
Clear Filters
|
||||
{$t('worldtravel.clear_filters')}
|
||||
</button>
|
||||
|
||||
{#if allCountries.length === 0}
|
||||
<div class="mt-8 text-center">
|
||||
<div class="alert alert-warning max-w-md">
|
||||
<div>
|
||||
<h4 class="font-bold">No country data available</h4>
|
||||
<p class="text-sm">Please check the documentation for updating region data.</p>
|
||||
<h4 class="font-bold">{$t('worldtravel.no_country_data_available')}</h4>
|
||||
<p class="text-sm">{$t('worldtravel.no_country_data_available_desc')}</p>
|
||||
</div>
|
||||
</div>
|
||||
<a
|
||||
@@ -300,7 +303,7 @@
|
||||
{:else}
|
||||
<!-- Countries Grid -->
|
||||
<div
|
||||
class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6"
|
||||
class="grid grid-cols-1 sm:grid-cols-1 md:grid-cols-2 lg:grid-cols-2 xl:grid-cols-3 gap-6"
|
||||
>
|
||||
{#each filteredCountries as country}
|
||||
<CountryCard {country} />
|
||||
@@ -320,41 +323,41 @@
|
||||
<div class="p-2 bg-primary/10 rounded-lg">
|
||||
<Filter class="w-6 h-6 text-primary" />
|
||||
</div>
|
||||
<h2 class="text-xl font-bold">Filters & Stats</h2>
|
||||
<h2 class="text-xl font-bold">{$t('adventures.filters_and_stats')}</h2>
|
||||
</div>
|
||||
|
||||
<!-- Travel Statistics -->
|
||||
<div class="card bg-base-200/50 p-4 mb-6">
|
||||
<h3 class="font-semibold text-lg mb-4 flex items-center gap-2">
|
||||
<Globe class="w-5 h-5" />
|
||||
Travel Progress
|
||||
{$t('adventures.travel_progress')}
|
||||
</h3>
|
||||
|
||||
<div class="space-y-4">
|
||||
<div class="stat p-0">
|
||||
<div class="stat-title text-sm">Total Countries</div>
|
||||
<div class="stat-title text-sm">{$t('worldtravel.total_countries')}</div>
|
||||
<div class="stat-value text-2xl">{totalCountries}</div>
|
||||
<div class="stat-desc">Available to explore</div>
|
||||
<div class="stat-desc">{$t('worldtravel.available_to_explore')}</div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<div class="stat p-0">
|
||||
<div class="stat-title text-xs">Visited</div>
|
||||
<div class="stat-title text-xs">{$t('adventures.visited')}</div>
|
||||
<div class="stat-value text-lg text-success">{visitedCountries}</div>
|
||||
</div>
|
||||
<div class="stat p-0">
|
||||
<div class="stat-title text-xs">Remaining</div>
|
||||
<div class="stat-title text-xs">{$t('worldtravel.remaining')}</div>
|
||||
<div class="stat-value text-lg text-error">{notVisitedCountries}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<div class="stat p-0">
|
||||
<div class="stat-title text-xs">Complete</div>
|
||||
<div class="stat-title text-xs">{$t('worldtravel.complete')}</div>
|
||||
<div class="stat-value text-sm text-success">{completeCountries}</div>
|
||||
</div>
|
||||
<div class="stat p-0">
|
||||
<div class="stat-title text-xs">Partial</div>
|
||||
<div class="stat-title text-xs">{$t('worldtravel.partial')}</div>
|
||||
<div class="stat-value text-sm text-warning">{partialCountries}</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -362,7 +365,7 @@
|
||||
<!-- Progress Bar -->
|
||||
<div class="space-y-2">
|
||||
<div class="flex justify-between text-sm">
|
||||
<span>Progress</span>
|
||||
<span>{$t('worldtravel.progress')}</span>
|
||||
<span>{Math.round((visitedCountries / totalCountries) * 100)}%</span>
|
||||
</div>
|
||||
<progress
|
||||
@@ -378,7 +381,7 @@
|
||||
<div class="card bg-base-200/50 p-4">
|
||||
<h3 class="font-semibold text-lg mb-4 flex items-center gap-2">
|
||||
<Pin class="w-5 h-5" />
|
||||
Filter by Region
|
||||
{$t('worldtravel.filter_by_region')}
|
||||
</h3>
|
||||
|
||||
<div class="space-y-2">
|
||||
@@ -390,7 +393,7 @@
|
||||
checked={subRegionOption === ''}
|
||||
on:change={() => (subRegionOption = '')}
|
||||
/>
|
||||
<span class="label-text">All Regions</span>
|
||||
<span class="label-text">{$t('worldtravel.all_regions')}</span>
|
||||
</label>
|
||||
|
||||
{#each worldSubregions as subregion}
|
||||
@@ -413,16 +416,16 @@
|
||||
<button class="btn btn-outline w-full gap-2" on:click={() => (showMap = !showMap)}>
|
||||
{#if showMap}
|
||||
<Map class="w-4 h-4" />
|
||||
Hide Map
|
||||
{$t('worldtravel.hide_map')}
|
||||
{:else}
|
||||
<Map class="w-4 h-4" />
|
||||
Show Map
|
||||
{$t('worldtravel.show_map')}
|
||||
{/if}
|
||||
</button>
|
||||
|
||||
<button class="btn btn-ghost w-full gap-2" on:click={clearFilters}>
|
||||
<Clear class="w-4 h-4" />
|
||||
Clear All Filters
|
||||
{$t('worldtravel.clear_all_filters')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -158,9 +158,7 @@
|
||||
<Flag 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"
|
||||
>
|
||||
<h1 class="text-3xl font-bold bg-clip-text text-primary">
|
||||
{$t('worldtravel.regions_in')}
|
||||
{country?.name}
|
||||
</h1>
|
||||
@@ -212,35 +210,37 @@
|
||||
|
||||
<!-- Filter Chips -->
|
||||
<div class="mt-4 flex flex-wrap items-center gap-2">
|
||||
<span class="text-sm font-medium text-base-content/60">Filter by:</span>
|
||||
<span class="text-sm font-medium text-base-content/60"
|
||||
>{$t('worldtravel.filter_by')}:</span
|
||||
>
|
||||
<div class="tabs tabs-boxed bg-base-200">
|
||||
<button
|
||||
class="tab tab-sm gap-2 {filterOption === 'all' ? 'tab-active' : ''}"
|
||||
on:click={() => (filterOption = 'all')}
|
||||
>
|
||||
<MapMarker class="w-3 h-3" />
|
||||
All
|
||||
{$t('adventures.all')}
|
||||
</button>
|
||||
<button
|
||||
class="tab tab-sm gap-2 {filterOption === 'visited' ? 'tab-active' : ''}"
|
||||
on:click={() => (filterOption = 'visited')}
|
||||
>
|
||||
<Check class="w-3 h-3" />
|
||||
Visited
|
||||
{$t('adventures.visited')}
|
||||
</button>
|
||||
<button
|
||||
class="tab tab-sm gap-2 {filterOption === 'not-visited' ? 'tab-active' : ''}"
|
||||
on:click={() => (filterOption = 'not-visited')}
|
||||
>
|
||||
<Cancel class="w-3 h-3" />
|
||||
Not Visited
|
||||
{$t('adventures.not_visited')}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{#if searchQuery || filterOption !== 'all'}
|
||||
<button class="btn btn-ghost btn-xs gap-1" on:click={clearFilters}>
|
||||
<Clear class="w-3 h-3" />
|
||||
Clear All
|
||||
{$t('worldtravel.clear_all')}
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
@@ -255,16 +255,16 @@
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<div class="flex items-center gap-2">
|
||||
<Map class="w-5 h-5 text-primary" />
|
||||
<h2 class="text-lg font-semibold">Interactive Map</h2>
|
||||
<h2 class="text-lg font-semibold">{$t('worldtravel.interactive_map')}</h2>
|
||||
</div>
|
||||
<div class="flex items-center gap-2 text-sm text-base-content/60">
|
||||
<div class="flex items-center gap-1">
|
||||
<div class="w-3 h-3 bg-green-200 rounded-full border"></div>
|
||||
<span>Visited</span>
|
||||
<span>{$t('adventures.visited')}</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-1">
|
||||
<div class="w-3 h-3 bg-red-200 rounded-full border"></div>
|
||||
<span>Not Visited</span>
|
||||
<span>{$t('adventures.not_visited')}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -305,19 +305,21 @@
|
||||
<div class="p-6 bg-base-200/50 rounded-2xl mb-6">
|
||||
<MapMarker class="w-16 h-16 text-base-content/30" />
|
||||
</div>
|
||||
<h3 class="text-xl font-semibold text-base-content/70 mb-2">No regions found</h3>
|
||||
<h3 class="text-xl font-semibold text-base-content/70 mb-2">
|
||||
{$t('worldtravel.no_regions_found')}
|
||||
</h3>
|
||||
<p class="text-base-content/50 text-center max-w-md mb-6">
|
||||
Try adjusting your search terms or filters to find the regions you're looking for.
|
||||
{$t('worldtravel.no_countries_found_desc')}
|
||||
</p>
|
||||
<button class="btn btn-primary gap-2" on:click={clearFilters}>
|
||||
<Clear class="w-4 h-4" />
|
||||
Clear Filters
|
||||
{$t('worldtravel.clear_filters')}
|
||||
</button>
|
||||
</div>
|
||||
{:else}
|
||||
<!-- Regions Grid -->
|
||||
<div
|
||||
class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6"
|
||||
class="grid grid-cols-1 sm:grid-cols-1 md:grid-cols-2 lg:grid-cols-2 xl:grid-cols-3 gap-6"
|
||||
>
|
||||
{#each filteredRegions as region}
|
||||
<RegionCard
|
||||
@@ -350,7 +352,7 @@
|
||||
<div class="p-2 bg-primary/10 rounded-lg">
|
||||
<Filter class="w-6 h-6 text-primary" />
|
||||
</div>
|
||||
<h2 class="text-xl font-bold">Progress & Stats</h2>
|
||||
<h2 class="text-xl font-bold">{$t('worldtravel.progress_and_stats')}</h2>
|
||||
</div>
|
||||
|
||||
<!-- Country Progress -->
|
||||
@@ -362,18 +364,18 @@
|
||||
|
||||
<div class="space-y-4">
|
||||
<div class="stat p-0">
|
||||
<div class="stat-title text-sm">Total Regions</div>
|
||||
<div class="stat-title text-sm">{$t('worldtravel.total_regions')}</div>
|
||||
<div class="stat-value text-2xl">{regions.length}</div>
|
||||
<div class="stat-desc">Available to explore</div>
|
||||
<div class="stat-desc">{$t('worldtravel.available_to_explore')}</div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<div class="stat p-0">
|
||||
<div class="stat-title text-xs">Visited</div>
|
||||
<div class="stat-title text-xs">{$t('adventures.visited')}</div>
|
||||
<div class="stat-value text-lg text-success">{visitedCount}</div>
|
||||
</div>
|
||||
<div class="stat p-0">
|
||||
<div class="stat-title text-xs">Remaining</div>
|
||||
<div class="stat-title text-xs">{$t('worldtravel.remaining')}</div>
|
||||
<div class="stat-value text-lg text-error">{notVisitedCount}</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -381,7 +383,7 @@
|
||||
<!-- Progress Bar -->
|
||||
<div class="space-y-2">
|
||||
<div class="flex justify-between text-sm">
|
||||
<span>Progress</span>
|
||||
<span>{$t('worldtravel.progress')}</span>
|
||||
<span>{completionPercentage}%</span>
|
||||
</div>
|
||||
<progress
|
||||
@@ -394,41 +396,21 @@
|
||||
{#if completionPercentage === 100}
|
||||
<div class="alert alert-success">
|
||||
<Trophy class="w-4 h-4" />
|
||||
<span class="text-sm">Country completed! 🎉</span>
|
||||
<span class="text-sm">{$t('worldtravel.country_completed')}! 🎉</span>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Map Controls
|
||||
<div class="card bg-base-200/50 p-4 mb-6">
|
||||
<h3 class="font-semibold text-lg mb-4 flex items-center gap-2">
|
||||
<Map class="w-5 h-5" />
|
||||
Map Settings
|
||||
</h3>
|
||||
|
||||
<div class="space-y-3">
|
||||
<label class="label cursor-pointer justify-start gap-3">
|
||||
<input type="checkbox" class="checkbox checkbox-primary" bind:checked={showGeo} />
|
||||
<span class="label-text">{$t('adventures.show_region_labels')}</span>
|
||||
</label>
|
||||
|
||||
<div class="text-xs text-base-content/60">
|
||||
Click markers on the map to toggle visited status
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<!-- Quick Actions -->
|
||||
{#if regions.some((region) => region.latitude && region.longitude)}
|
||||
<div class="space-y-3">
|
||||
<button class="btn btn-outline w-full gap-2" on:click={() => (showGeo = !showGeo)}>
|
||||
{#if showGeo}
|
||||
<Map class="w-4 h-4" />
|
||||
Hide Map Labels
|
||||
{$t('worldtravel.hide_map_labels')}
|
||||
{:else}
|
||||
<Map class="w-4 h-4" />
|
||||
Show Map Labels
|
||||
{$t('worldtravel.show_map_labels')}
|
||||
{/if}
|
||||
</button>
|
||||
|
||||
|
||||
@@ -150,14 +150,15 @@
|
||||
<CityIcon 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"
|
||||
>
|
||||
<h1 class="text-3xl font-bold bg-clip-text text-primary">
|
||||
{$t('worldtravel.cities_in')}
|
||||
{region?.name}
|
||||
</h1>
|
||||
<p class="text-sm text-base-content/60">
|
||||
{filteredCities.length} of {allCities.length} cities
|
||||
{filteredCities.length}
|
||||
{$t('worldtravel.of')}
|
||||
{allCities.length}
|
||||
{$t('worldtravel.cities')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -168,7 +169,7 @@
|
||||
{#if completionPercentage === 100}
|
||||
<div class="badge badge-success gap-2 p-3">
|
||||
<Trophy class="w-4 h-4" />
|
||||
Complete!
|
||||
{$t('worldtravel.complete')}
|
||||
</div>
|
||||
{:else}
|
||||
<div class="badge badge-primary gap-2 p-3">
|
||||
@@ -200,25 +201,13 @@
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<!-- Map Toggle -->
|
||||
<button
|
||||
class="btn btn-outline gap-2 {showGeo ? 'btn-active' : ''}"
|
||||
on:click={() => (showGeo = !showGeo)}
|
||||
>
|
||||
{#if showGeo}
|
||||
<Map class="w-4 h-4" />
|
||||
<span class="hidden sm:inline">Hide Labels</span>
|
||||
{:else}
|
||||
<Map class="w-4 h-4" />
|
||||
<span class="hidden sm:inline">Show Labels</span>
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Filter Chips -->
|
||||
<div class="mt-4 flex flex-wrap items-center gap-2">
|
||||
<span class="text-sm font-medium text-base-content/60">Filter by:</span>
|
||||
<span class="text-sm font-medium text-base-content/60"
|
||||
>{$t('worldtravel.filter_by')}:</span
|
||||
>
|
||||
<div class="tabs tabs-boxed bg-base-200">
|
||||
<button
|
||||
class="tab tab-sm gap-2 {filterOption === 'all' ? 'tab-active' : ''}"
|
||||
@@ -232,21 +221,21 @@
|
||||
on:click={() => (filterOption = 'visited')}
|
||||
>
|
||||
<Check class="w-3 h-3" />
|
||||
Visited
|
||||
{$t('adventures.visited')}
|
||||
</button>
|
||||
<button
|
||||
class="tab tab-sm gap-2 {filterOption === 'not-visited' ? 'tab-active' : ''}"
|
||||
on:click={() => (filterOption = 'not-visited')}
|
||||
>
|
||||
<Cancel class="w-3 h-3" />
|
||||
Not Visited
|
||||
{$t('adventures.not_visited')}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{#if searchQuery || filterOption !== 'all'}
|
||||
<button class="btn btn-ghost btn-xs gap-1" on:click={clearFilters}>
|
||||
<Clear class="w-3 h-3" />
|
||||
Clear All
|
||||
{$t('worldtravel.clear_all')}
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
@@ -261,16 +250,16 @@
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<div class="flex items-center gap-2">
|
||||
<Map class="w-5 h-5 text-primary" />
|
||||
<h2 class="text-lg font-semibold">Interactive Map</h2>
|
||||
<h2 class="text-lg font-semibold">{$t('worldtravel.interactive_map')}</h2>
|
||||
</div>
|
||||
<div class="flex items-center gap-2 text-sm text-base-content/60">
|
||||
<div class="flex items-center gap-1">
|
||||
<div class="w-3 h-3 bg-green-200 rounded-full border"></div>
|
||||
<span>Visited</span>
|
||||
<span>{$t('adventures.visited')}</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-1">
|
||||
<div class="w-3 h-3 bg-red-200 rounded-full border"></div>
|
||||
<span>Not Visited</span>
|
||||
<span>{$t('adventures.not_visited')}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -315,19 +304,21 @@
|
||||
<div class="p-6 bg-base-200/50 rounded-2xl mb-6">
|
||||
<CityIcon class="w-16 h-16 text-base-content/30" />
|
||||
</div>
|
||||
<h3 class="text-xl font-semibold text-base-content/70 mb-2">No cities found</h3>
|
||||
<h3 class="text-xl font-semibold text-base-content/70 mb-2">
|
||||
{$t('worldtravel.no_cities_found')}
|
||||
</h3>
|
||||
<p class="text-base-content/50 text-center max-w-md mb-6">
|
||||
Try adjusting your search terms or filters to find the cities you're looking for.
|
||||
{$t('worldtravel.no_countries_found_desc')}
|
||||
</p>
|
||||
<button class="btn btn-primary gap-2" on:click={clearFilters}>
|
||||
<Clear class="w-4 h-4" />
|
||||
Clear Filters
|
||||
{$t('worldtravel.clear_filters')}
|
||||
</button>
|
||||
</div>
|
||||
{:else}
|
||||
<!-- Cities Grid -->
|
||||
<div
|
||||
class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-6"
|
||||
class="grid grid-cols-1 sm:grid-cols-1 md:grid-cols-2 lg:grid-cols-2 xl:grid-cols-3 gap-6"
|
||||
>
|
||||
{#each filteredCities as city}
|
||||
<CityCard
|
||||
@@ -360,7 +351,7 @@
|
||||
<div class="p-2 bg-primary/10 rounded-lg">
|
||||
<Filter class="w-6 h-6 text-primary" />
|
||||
</div>
|
||||
<h2 class="text-xl font-bold">Progress & Stats</h2>
|
||||
<h2 class="text-xl font-bold">{$t('worldtravel.progress_and_stats')}</h2>
|
||||
</div>
|
||||
|
||||
<!-- Region Progress -->
|
||||
@@ -372,18 +363,18 @@
|
||||
|
||||
<div class="space-y-4">
|
||||
<div class="stat p-0">
|
||||
<div class="stat-title text-sm">Total Cities</div>
|
||||
<div class="stat-title text-sm">{$t('worldtravel.total_cities')}</div>
|
||||
<div class="stat-value text-2xl">{allCities.length}</div>
|
||||
<div class="stat-desc">Available to explore</div>
|
||||
<div class="stat-desc">{$t('worldtravel.available_to_explore')}</div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<div class="stat p-0">
|
||||
<div class="stat-title text-xs">Visited</div>
|
||||
<div class="stat-title text-xs">{$t('adventures.visited')}</div>
|
||||
<div class="stat-value text-lg text-success">{visitedCount}</div>
|
||||
</div>
|
||||
<div class="stat p-0">
|
||||
<div class="stat-title text-xs">Remaining</div>
|
||||
<div class="stat-title text-xs">{$t('worldtravel.remaining')}</div>
|
||||
<div class="stat-value text-lg text-error">{notVisitedCount}</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -391,7 +382,7 @@
|
||||
<!-- Progress Bar -->
|
||||
<div class="space-y-2">
|
||||
<div class="flex justify-between text-sm">
|
||||
<span>Progress</span>
|
||||
<span>{$t('worldtravel.progress')}</span>
|
||||
<span>{completionPercentage}%</span>
|
||||
</div>
|
||||
<progress
|
||||
@@ -404,7 +395,7 @@
|
||||
{#if completionPercentage === 100}
|
||||
<div class="alert alert-success">
|
||||
<Trophy class="w-4 h-4" />
|
||||
<span class="text-sm">Region completed! 🎉</span>
|
||||
<span class="text-sm">{$t('worldtravel.region_completed')}! 🎉</span>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
@@ -415,10 +406,10 @@
|
||||
<button class="btn btn-outline w-full gap-2" on:click={() => (showGeo = !showGeo)}>
|
||||
{#if showGeo}
|
||||
<Map class="w-4 h-4" />
|
||||
Hide Map Labels
|
||||
{$t('worldtravel.hide_map_labels')}
|
||||
{:else}
|
||||
<Map class="w-4 h-4" />
|
||||
Show Map Labels
|
||||
{$t('worldtravel.show_map_labels')}
|
||||
{/if}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user