mirror of
https://github.com/seanmorley15/AdventureLog.git
synced 2025-12-23 22:58:17 -05:00
UI and Translation Improvements (#889)
* Update translations from Weblate * Translated using Weblate (German) Currently translated at 100.0% (979 of 979 strings) Translation: AdventureLog/Web App Translate-URL: https://hosted.weblate.org/projects/adventurelog/web-app/de/ * Translated using Weblate (Slovak) Currently translated at 100.0% (979 of 979 strings) Translation: AdventureLog/Web App Translate-URL: https://hosted.weblate.org/projects/adventurelog/web-app/sk/ * Added translation using Weblate (Ukrainian) * Bump version to 0.11.0 and enhance hero section responsiveness in adventure details * Update Django version to 5.2.7 in requirements * feature added hu translation (#885) * feature added hu translation * Update dependencies and add Hungarian translation support --------- Co-authored-by: Petrekanics Máté <mate.petrekanics@webcapital.hu> Co-authored-by: Sean Morley <mail@seanmorley.com> * Fix "back" FR traduction (#858) Co-authored-by: Sean Morley <98704938+seanmorley15@users.noreply.github.com> --------- Co-authored-by: Alex <div@alexe.at> Co-authored-by: fantastron27 <fantastron27@gmail.com> Co-authored-by: Максим Горпиніч <gorpinicmaksim0@gmail.com> Co-authored-by: petrekanics <75931275+petrekanics@users.noreply.github.com> Co-authored-by: Petrekanics Máté <mate.petrekanics@webcapital.hu> Co-authored-by: Sebastien Laithier <kirby@hyrule.ovh>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
Django==5.2.6
|
||||
Django==5.2.7
|
||||
djangorestframework>=3.15.2
|
||||
django-allauth==0.63.3
|
||||
drf-yasg==1.21.4
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "adventurelog-frontend",
|
||||
"version": "0.10.0",
|
||||
"version": "0.11.0",
|
||||
"scripts": {
|
||||
"dev": "vite dev",
|
||||
"django": "cd .. && cd backend/server && python3 manage.py runserver",
|
||||
@@ -12,43 +12,43 @@
|
||||
"format": "prettier --write ."
|
||||
},
|
||||
"devDependencies": {
|
||||
"@event-calendar/core": "^3.7.1",
|
||||
"@event-calendar/day-grid": "^3.7.1",
|
||||
"@event-calendar/core": "^3.12.0",
|
||||
"@event-calendar/day-grid": "^3.12.0",
|
||||
"@event-calendar/interaction": "^3.12.0",
|
||||
"@event-calendar/time-grid": "^3.7.1",
|
||||
"@iconify-json/mdi": "^1.1.67",
|
||||
"@sveltejs/adapter-node": "^5.2.0",
|
||||
"@sveltejs/adapter-vercel": "^5.4.1",
|
||||
"@sveltejs/kit": "^2.8.3",
|
||||
"@sveltejs/vite-plugin-svelte": "^3.1.1",
|
||||
"@tailwindcss/typography": "^0.5.13",
|
||||
"@types/node": "^22.5.4",
|
||||
"@event-calendar/time-grid": "^3.12.0",
|
||||
"@iconify-json/mdi": "^1.2.3",
|
||||
"@sveltejs/adapter-node": "^5.2.12",
|
||||
"@sveltejs/adapter-vercel": "^5.7.0",
|
||||
"@sveltejs/kit": "^2.20.7",
|
||||
"@sveltejs/vite-plugin-svelte": "^3.1.2",
|
||||
"@tailwindcss/typography": "^0.5.16",
|
||||
"@types/node": "^22.15.2",
|
||||
"@types/qrcode": "^1.5.5",
|
||||
"autoprefixer": "^10.4.19",
|
||||
"daisyui": "^4.12.6",
|
||||
"postcss": "^8.4.38",
|
||||
"prettier": "^3.3.2",
|
||||
"prettier-plugin-svelte": "^3.2.5",
|
||||
"autoprefixer": "^10.4.21",
|
||||
"daisyui": "^4.12.24",
|
||||
"postcss": "^8.5.3",
|
||||
"prettier": "^3.5.3",
|
||||
"prettier-plugin-svelte": "^3.3.3",
|
||||
"svelte": "^4.2.19",
|
||||
"svelte-check": "^3.8.1",
|
||||
"tailwindcss": "^3.4.4",
|
||||
"tslib": "^2.6.3",
|
||||
"typescript": "^5.5.2",
|
||||
"unplugin-icons": "^0.19.0",
|
||||
"svelte-check": "^3.8.6",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.8.3",
|
||||
"unplugin-icons": "^0.19.3",
|
||||
"vite": "^5.4.19"
|
||||
},
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"@lukulent/svelte-umami": "^0.0.3",
|
||||
"dompurify": "^3.2.4",
|
||||
"emoji-picker-element": "^1.26.0",
|
||||
"dompurify": "^3.2.5",
|
||||
"emoji-picker-element": "^1.26.3",
|
||||
"gsap": "^3.12.7",
|
||||
"luxon": "^3.6.1",
|
||||
"marked": "^15.0.4",
|
||||
"marked": "^15.0.11",
|
||||
"psl": "^1.15.0",
|
||||
"qrcode": "^1.5.4",
|
||||
"svelte-i18n": "^4.0.1",
|
||||
"svelte-maplibre": "^0.9.8"
|
||||
"svelte-maplibre": "^0.9.14"
|
||||
},
|
||||
"overrides": {
|
||||
"esbuild": "^0.25.9"
|
||||
|
||||
58
frontend/pnpm-lock.yaml
generated
58
frontend/pnpm-lock.yaml
generated
@@ -15,10 +15,10 @@ importers:
|
||||
specifier: ^0.0.3
|
||||
version: 0.0.3(svelte@4.2.19)
|
||||
dompurify:
|
||||
specifier: ^3.2.4
|
||||
specifier: ^3.2.5
|
||||
version: 3.2.5
|
||||
emoji-picker-element:
|
||||
specifier: ^1.26.0
|
||||
specifier: ^1.26.3
|
||||
version: 1.26.3
|
||||
gsap:
|
||||
specifier: ^3.12.7
|
||||
@@ -27,7 +27,7 @@ importers:
|
||||
specifier: ^3.6.1
|
||||
version: 3.6.1
|
||||
marked:
|
||||
specifier: ^15.0.4
|
||||
specifier: ^15.0.11
|
||||
version: 15.0.11
|
||||
psl:
|
||||
specifier: ^1.15.0
|
||||
@@ -39,77 +39,77 @@ importers:
|
||||
specifier: ^4.0.1
|
||||
version: 4.0.1(svelte@4.2.19)
|
||||
svelte-maplibre:
|
||||
specifier: ^0.9.8
|
||||
specifier: ^0.9.14
|
||||
version: 0.9.14(svelte@4.2.19)
|
||||
devDependencies:
|
||||
'@event-calendar/core':
|
||||
specifier: ^3.7.1
|
||||
specifier: ^3.12.0
|
||||
version: 3.12.0
|
||||
'@event-calendar/day-grid':
|
||||
specifier: ^3.7.1
|
||||
specifier: ^3.12.0
|
||||
version: 3.12.0
|
||||
'@event-calendar/interaction':
|
||||
specifier: ^3.12.0
|
||||
version: 3.12.0
|
||||
'@event-calendar/time-grid':
|
||||
specifier: ^3.7.1
|
||||
specifier: ^3.12.0
|
||||
version: 3.12.0
|
||||
'@iconify-json/mdi':
|
||||
specifier: ^1.1.67
|
||||
specifier: ^1.2.3
|
||||
version: 1.2.3
|
||||
'@sveltejs/adapter-node':
|
||||
specifier: ^5.2.0
|
||||
specifier: ^5.2.12
|
||||
version: 5.2.12(@sveltejs/kit@2.20.7(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.19(@types/node@22.15.2)))(svelte@4.2.19)(vite@5.4.19(@types/node@22.15.2)))
|
||||
'@sveltejs/adapter-vercel':
|
||||
specifier: ^5.4.1
|
||||
specifier: ^5.7.0
|
||||
version: 5.7.0(@sveltejs/kit@2.20.7(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.19(@types/node@22.15.2)))(svelte@4.2.19)(vite@5.4.19(@types/node@22.15.2)))(rollup@4.40.2)
|
||||
'@sveltejs/kit':
|
||||
specifier: ^2.8.3
|
||||
specifier: ^2.20.7
|
||||
version: 2.20.7(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.19(@types/node@22.15.2)))(svelte@4.2.19)(vite@5.4.19(@types/node@22.15.2))
|
||||
'@sveltejs/vite-plugin-svelte':
|
||||
specifier: ^3.1.1
|
||||
specifier: ^3.1.2
|
||||
version: 3.1.2(svelte@4.2.19)(vite@5.4.19(@types/node@22.15.2))
|
||||
'@tailwindcss/typography':
|
||||
specifier: ^0.5.13
|
||||
specifier: ^0.5.16
|
||||
version: 0.5.16(tailwindcss@3.4.17)
|
||||
'@types/node':
|
||||
specifier: ^22.5.4
|
||||
specifier: ^22.15.2
|
||||
version: 22.15.2
|
||||
'@types/qrcode':
|
||||
specifier: ^1.5.5
|
||||
version: 1.5.5
|
||||
autoprefixer:
|
||||
specifier: ^10.4.19
|
||||
specifier: ^10.4.21
|
||||
version: 10.4.21(postcss@8.5.3)
|
||||
daisyui:
|
||||
specifier: ^4.12.6
|
||||
specifier: ^4.12.24
|
||||
version: 4.12.24(postcss@8.5.3)
|
||||
postcss:
|
||||
specifier: ^8.4.38
|
||||
specifier: ^8.5.3
|
||||
version: 8.5.3
|
||||
prettier:
|
||||
specifier: ^3.3.2
|
||||
specifier: ^3.5.3
|
||||
version: 3.5.3
|
||||
prettier-plugin-svelte:
|
||||
specifier: ^3.2.5
|
||||
specifier: ^3.3.3
|
||||
version: 3.3.3(prettier@3.5.3)(svelte@4.2.19)
|
||||
svelte:
|
||||
specifier: ^4.2.19
|
||||
version: 4.2.19
|
||||
svelte-check:
|
||||
specifier: ^3.8.1
|
||||
specifier: ^3.8.6
|
||||
version: 3.8.6(postcss-load-config@4.0.2(postcss@8.5.3))(postcss@8.5.3)(svelte@4.2.19)
|
||||
tailwindcss:
|
||||
specifier: ^3.4.4
|
||||
specifier: ^3.4.17
|
||||
version: 3.4.17
|
||||
tslib:
|
||||
specifier: ^2.6.3
|
||||
specifier: ^2.8.1
|
||||
version: 2.8.1
|
||||
typescript:
|
||||
specifier: ^5.5.2
|
||||
specifier: ^5.8.3
|
||||
version: 5.8.3
|
||||
unplugin-icons:
|
||||
specifier: ^0.19.0
|
||||
specifier: ^0.19.3
|
||||
version: 0.19.3
|
||||
vite:
|
||||
specifier: ^5.4.19
|
||||
@@ -733,8 +733,8 @@ packages:
|
||||
resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
caniuse-lite@1.0.30001715:
|
||||
resolution: {integrity: sha512-7ptkFGMm2OAOgvZpwgA4yjQ5SQbrNVGdRjzH0pBdy1Fasvcr+KAeECmbCAECzTuDuoX0FCY8KzUxjf9+9kfZEw==}
|
||||
caniuse-lite@1.0.30001750:
|
||||
resolution: {integrity: sha512-cuom0g5sdX6rw00qOoLNSFCJ9/mYIsuSOA+yzpDw8eopiFqcVwQvZHqov0vmEighRxX++cfC0Vg1G+1Iy/mSpQ==}
|
||||
|
||||
chokidar@3.6.0:
|
||||
resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
|
||||
@@ -2376,7 +2376,7 @@ snapshots:
|
||||
autoprefixer@10.4.21(postcss@8.5.3):
|
||||
dependencies:
|
||||
browserslist: 4.24.4
|
||||
caniuse-lite: 1.0.30001715
|
||||
caniuse-lite: 1.0.30001750
|
||||
fraction.js: 4.3.7
|
||||
normalize-range: 0.1.2
|
||||
picocolors: 1.1.1
|
||||
@@ -2408,7 +2408,7 @@ snapshots:
|
||||
|
||||
browserslist@4.24.4:
|
||||
dependencies:
|
||||
caniuse-lite: 1.0.30001715
|
||||
caniuse-lite: 1.0.30001750
|
||||
electron-to-chromium: 1.5.143
|
||||
node-releases: 2.0.19
|
||||
update-browserslist-db: 1.1.3(browserslist@4.24.4)
|
||||
@@ -2419,7 +2419,7 @@ snapshots:
|
||||
|
||||
camelcase@5.3.1: {}
|
||||
|
||||
caniuse-lite@1.0.30001715: {}
|
||||
caniuse-lite@1.0.30001750: {}
|
||||
|
||||
chokidar@3.6.0:
|
||||
dependencies:
|
||||
|
||||
@@ -65,7 +65,8 @@
|
||||
ar: 'العربية',
|
||||
'pt-br': 'Português (Brasil)',
|
||||
sk: 'Slovenský',
|
||||
tr: 'Türkçe'
|
||||
tr: 'Türkçe',
|
||||
hu: 'Magyar'
|
||||
};
|
||||
|
||||
const submitLocaleChange = (event: Event) => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export let appVersion = 'v0.11.0-main-09212025';
|
||||
export let appVersion = 'v0.11.0-main-10112025';
|
||||
export let versionChangelog = 'https://github.com/seanmorley15/AdventureLog/releases/tag/v0.11.0';
|
||||
export let appTitle = 'AdventureLog';
|
||||
export let copyrightYear = '2023-2025';
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -290,7 +290,7 @@
|
||||
"average_cadence": "Cadence moyenne",
|
||||
"average_speed": "Vitesse moyenne",
|
||||
"avg_speed": "Vitesse moyenne",
|
||||
"back": "Dos",
|
||||
"back": "Retour",
|
||||
"cadence": "Cadence",
|
||||
"calories": "Calories",
|
||||
"click_map": "Cliquez sur la carte pour sélectionner un emplacement",
|
||||
|
||||
1041
frontend/src/locales/hu.json
Normal file
1041
frontend/src/locales/hu.json
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
1
frontend/src/locales/uk.json
Normal file
1
frontend/src/locales/uk.json
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
@@ -22,6 +22,7 @@
|
||||
register('pt-br', () => import('../locales/pt-br.json'));
|
||||
register('sk', () => import('../locales/sk.json'));
|
||||
register('tr', () => import('../locales/tr.json'));
|
||||
register('hu', () => import('../locales/hu.json'));
|
||||
|
||||
let locales = [
|
||||
'en',
|
||||
@@ -40,7 +41,8 @@
|
||||
'ar',
|
||||
'pt-br',
|
||||
'sk',
|
||||
'tr'
|
||||
'tr',
|
||||
'hu'
|
||||
];
|
||||
|
||||
if (browser) {
|
||||
|
||||
@@ -173,8 +173,12 @@
|
||||
|
||||
<!-- Hero Section -->
|
||||
<div class="relative">
|
||||
{#if adventure.images && adventure.images.length > 0}
|
||||
<div class="hero min-h-[60vh] relative overflow-hidden">
|
||||
<div
|
||||
class="hero min-h-[60vh] relative overflow-hidden"
|
||||
class:min-h-[30vh]={!adventure.images || adventure.images.length === 0}
|
||||
>
|
||||
<!-- Background: Images or Gradient -->
|
||||
{#if adventure.images && adventure.images.length > 0}
|
||||
<div class="hero-overlay bg-gradient-to-t from-black/70 via-black/20 to-transparent"></div>
|
||||
{#each adventure.images as image, i}
|
||||
<div
|
||||
@@ -191,137 +195,129 @@
|
||||
</button>
|
||||
</div>
|
||||
{/each}
|
||||
{:else}
|
||||
<div class="absolute inset-0 bg-gradient-to-br from-primary/20 to-secondary/20"></div>
|
||||
{/if}
|
||||
|
||||
<div class="hero-content relative z-10 text-center text-white">
|
||||
<div class="max-w-4xl">
|
||||
<h1 class="text-6xl font-bold mb-4 drop-shadow-lg">{adventure.name}</h1>
|
||||
<!-- Content -->
|
||||
<div
|
||||
class="hero-content relative z-10 text-center"
|
||||
class:text-white={adventure.images?.length > 0}
|
||||
>
|
||||
<div class="max-w-4xl">
|
||||
<h1 class="text-6xl font-bold mb-4 drop-shadow-lg">{adventure.name}</h1>
|
||||
|
||||
<!-- Rating -->
|
||||
{#if adventure.rating !== undefined && adventure.rating !== null}
|
||||
<div class="flex justify-center mb-6">
|
||||
<div class="rating rating-lg">
|
||||
{#each Array.from({ length: 5 }, (_, i) => i + 1) as star}
|
||||
<input
|
||||
type="radio"
|
||||
name="rating-hero"
|
||||
class="mask mask-star-2 bg-warning"
|
||||
checked={star <= adventure.rating}
|
||||
disabled
|
||||
/>
|
||||
{/each}
|
||||
</div>
|
||||
<!-- Rating -->
|
||||
{#if adventure.rating !== undefined && adventure.rating !== null}
|
||||
<div class="flex justify-center mb-6">
|
||||
<div class="rating rating-lg">
|
||||
{#each Array.from({ length: 5 }, (_, i) => i + 1) as star}
|
||||
<input
|
||||
type="radio"
|
||||
name="rating-hero"
|
||||
class="mask mask-star-2 bg-warning"
|
||||
checked={star <= adventure.rating}
|
||||
disabled
|
||||
/>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- Quick Info Badges -->
|
||||
<div class="flex flex-wrap justify-center gap-4 mb-6">
|
||||
<a
|
||||
href="/locations?types={adventure.category?.name}"
|
||||
class="badge badge-lg badge-primary font-semibold px-4 py-3 cursor-pointer hover:brightness-110 transition-all"
|
||||
>
|
||||
{adventure.category?.display_name}
|
||||
{adventure.category?.icon}
|
||||
</a>
|
||||
{#if adventure.location}
|
||||
<div class="badge badge-lg badge-secondary font-semibold px-4 py-3">
|
||||
📍 {adventure.location}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- Quick Info Cards -->
|
||||
<div class="flex flex-wrap justify-center gap-4 mb-6">
|
||||
<div class="badge badge-lg badge-primary font-semibold px-4 py-3">
|
||||
{adventure.category?.display_name}
|
||||
{adventure.category?.icon}
|
||||
{#if adventure.visits.length > 0}
|
||||
<div class="badge badge-lg badge-accent font-semibold px-4 py-3">
|
||||
🎯 {adventure.visits.length}
|
||||
{adventure.visits.length === 1 ? $t('adventures.visit') : $t('adventures.visits')}
|
||||
</div>
|
||||
{#if adventure.location}
|
||||
<div class="badge badge-lg badge-secondary font-semibold px-4 py-3">
|
||||
📍 {adventure.location}
|
||||
{/if}
|
||||
{#if adventure.is_visited}
|
||||
<div class="badge badge-lg badge-success font-semibold px-4 py-3">
|
||||
✅ {$t('adventures.visited')}
|
||||
</div>
|
||||
{:else}
|
||||
<div class="badge badge-lg badge-warning font-semibold px-4 py-3">
|
||||
⏳ {$t('adventures.not_visited')}
|
||||
</div>
|
||||
{/if}
|
||||
{#if adventure.trails && adventure.trails.length > 0}
|
||||
<div class="badge badge-lg badge-info font-semibold px-4 py-3">
|
||||
🥾 {adventure.trails.length} Trail{adventure.trails.length === 1 ? '' : 's'}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<!-- Image Navigation (only shown when multiple images exist) -->
|
||||
{#if adventure.images && adventure.images.length > 1}
|
||||
<div class="w-full max-w-md mx-auto">
|
||||
<!-- Navigation arrows and current position -->
|
||||
<div class="flex items-center justify-center gap-4 mb-3">
|
||||
<button
|
||||
on:click={() =>
|
||||
goToSlide(currentSlide > 0 ? currentSlide - 1 : adventure.images.length - 1)}
|
||||
class="btn btn-circle btn-sm btn-primary"
|
||||
aria-label={$t('adventures.previous_image')}
|
||||
>
|
||||
❮
|
||||
</button>
|
||||
|
||||
<div class="text-sm font-medium bg-black/50 px-3 py-1 rounded-full">
|
||||
{currentSlide + 1} / {adventure.images.length}
|
||||
</div>
|
||||
{/if}
|
||||
{#if adventure.visits.length > 0}
|
||||
<div class="badge badge-lg badge-accent font-semibold px-4 py-3">
|
||||
🎯 {adventure.visits.length}
|
||||
{adventure.visits.length === 1 ? $t('adventures.visit') : $t('adventures.visits')}
|
||||
|
||||
<button
|
||||
on:click={() =>
|
||||
goToSlide(currentSlide < adventure.images.length - 1 ? currentSlide + 1 : 0)}
|
||||
class="btn btn-circle btn-sm btn-primary"
|
||||
aria-label={$t('adventures.next_image')}
|
||||
>
|
||||
❯
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Dot navigation -->
|
||||
{#if adventure.images.length <= 12}
|
||||
<div class="flex justify-center gap-2 flex-wrap">
|
||||
{#each adventure.images as _, i}
|
||||
<button
|
||||
on:click={() => goToSlide(i)}
|
||||
class="btn btn-circle btn-xs transition-all duration-200"
|
||||
class:btn-primary={i === currentSlide}
|
||||
class:btn-outline={i !== currentSlide}
|
||||
class:opacity-50={i !== currentSlide}
|
||||
>
|
||||
{i + 1}
|
||||
</button>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
{#if adventure.trails && adventure.trails.length > 0}
|
||||
<div class="badge badge-lg badge-info font-semibold px-4 py-3">
|
||||
🥾 {adventure.trails.length} Trail{adventure.trails.length === 1 ? '' : 's'}
|
||||
{:else}
|
||||
<div class="relative">
|
||||
<div
|
||||
class="absolute left-0 top-0 bottom-2 w-4 bg-gradient-to-r from-black/30 to-transparent pointer-events-none"
|
||||
></div>
|
||||
<div
|
||||
class="absolute right-0 top-0 bottom-2 w-4 bg-gradient-to-l from-black/30 to-transparent pointer-events-none"
|
||||
></div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<!-- Image Navigation -->
|
||||
{#if adventure.images.length > 1}
|
||||
<div class="w-full max-w-md mx-auto">
|
||||
<!-- Navigation arrows and current position indicator -->
|
||||
<div class="flex items-center justify-center gap-4 mb-3">
|
||||
<button
|
||||
on:click={() =>
|
||||
goToSlide(currentSlide > 0 ? currentSlide - 1 : adventure.images.length - 1)}
|
||||
class="btn btn-circle btn-sm btn-primary"
|
||||
aria-label={$t('adventures.previous_image')}
|
||||
>
|
||||
❮
|
||||
</button>
|
||||
|
||||
<div class="text-sm font-medium bg-black/50 px-3 py-1 rounded-full">
|
||||
{currentSlide + 1} / {adventure.images.length}
|
||||
</div>
|
||||
|
||||
<button
|
||||
on:click={() =>
|
||||
goToSlide(currentSlide < adventure.images.length - 1 ? currentSlide + 1 : 0)}
|
||||
class="btn btn-circle btn-sm btn-primary"
|
||||
aria-label={$t('adventures.next_image')}
|
||||
>
|
||||
❯
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Scrollable dot navigation for many images -->
|
||||
{#if adventure.images.length <= 12}
|
||||
<!-- Show all dots for 12 or fewer images -->
|
||||
<div class="flex justify-center gap-2 flex-wrap">
|
||||
{#each adventure.images as _, i}
|
||||
<button
|
||||
on:click={() => goToSlide(i)}
|
||||
class="btn btn-circle btn-xs transition-all duration-200"
|
||||
class:btn-primary={i === currentSlide}
|
||||
class:btn-outline={i !== currentSlide}
|
||||
class:opacity-50={i !== currentSlide}
|
||||
>
|
||||
{i + 1}
|
||||
</button>
|
||||
{/each}
|
||||
</div>
|
||||
{:else}
|
||||
<!-- Scrollable navigation for many images -->
|
||||
<div class="relative">
|
||||
<div
|
||||
class="absolute left-0 top-0 bottom-2 w-4 bg-gradient-to-r from-black/30 to-transparent pointer-events-none"
|
||||
></div>
|
||||
<div
|
||||
class="absolute right-0 top-0 bottom-2 w-4 bg-gradient-to-l from-black/30 to-transparent pointer-events-none"
|
||||
></div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
<!-- No image hero -->
|
||||
<div class="hero min-h-[40vh] bg-gradient-to-br from-primary/20 to-secondary/20">
|
||||
<div class="hero-content text-center">
|
||||
<div class="max-w-4xl">
|
||||
<h1 class="text-6xl font-bold mb-6">{adventure.name}</h1>
|
||||
{#if adventure.rating !== undefined && adventure.rating !== null}
|
||||
<div class="flex justify-center mb-6">
|
||||
<div class="rating rating-lg">
|
||||
{#each Array.from({ length: 5 }, (_, i) => i + 1) as star}
|
||||
<input
|
||||
type="radio"
|
||||
name="rating-hero-no-img"
|
||||
class="mask mask-star-2 bg-warning"
|
||||
checked={star <= adventure.rating}
|
||||
disabled
|
||||
/>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Main Content -->
|
||||
@@ -841,7 +837,7 @@
|
||||
{/if}
|
||||
|
||||
<!-- Additional Images -->
|
||||
{#if adventure.images && adventure.images.length > 1}
|
||||
{#if adventure.images}
|
||||
<div class="card bg-base-200 shadow-xl">
|
||||
<div class="card-body">
|
||||
<h3 class="card-title text-lg mb-4">🖼️ {$t('adventures.images')}</h3>
|
||||
|
||||
Reference in New Issue
Block a user