Adds option to mark trail as completed (#920)

* initial commit

* add completed for komoot tours

* mark hammerhead activities as completed

* fix review suggestions

* adds completed modal to trail edit page

---------

Co-authored-by: Christian Beutel <>
Co-authored-by: slothful-vassal <89943360+slothful-vassal@users.noreply.github.com>
This commit is contained in:
Flomp
2026-04-27 20:37:11 +02:00
committed by GitHub
parent 7e84e39cda
commit 7bdf0d3151
25 changed files with 244 additions and 18 deletions

View File

@@ -150,7 +150,9 @@
{/if}
<div class="p-4">
<div>
<h4 class="font-semibold text-lg line-clamp-2 wrap-anywhere">{trail.name}</h4>
<h4 class="font-semibold text-lg line-clamp-2 wrap-anywhere">
{trail.name}
</h4>
{#if trail.date}
<p class="text-xs text-gray-500 mb-3">
{new Date(trail.date).toLocaleDateString(undefined, {
@@ -200,7 +202,11 @@
<div class="flex gap-x-4 gap-y-1 text-base flex-wrap">
{#if trail.expand?.category?.name || trail.category}
<p>
<i class="fa fa-shapes mr-3"> </i>{$_(trail.expand?.category?.name ?? trail.category ?? "-")}
<i class="fa fa-shapes mr-3"> </i>{$_(
trail.expand?.category?.name ??
trail.category ??
"-",
)}
</p>
{/if}
{#if trail.location}

View File

@@ -56,6 +56,7 @@
import { handleFromRecordWithIRI } from "$lib/util/activitypub_util";
import LikeButton from "./like_button.svelte";
import Editor from "../base/editor.svelte";
import { trails_update } from "$lib/stores/trail_store";
interface Props {
initTrail: Trail;
@@ -75,6 +76,7 @@
let summitLogModal: SummitLogModal;
let confirmModal: ConfirmModal;
let markTrailAsCompletedModal: ConfirmModal;
let trail = $state(untrack(() => initTrail));
@@ -243,6 +245,13 @@
log.trail = trail.id;
const newLog = await summit_logs_create(log);
summitLogs.set([...$summitLogs, newLog]);
if (
$summitLogs.length == 1 &&
trail.author == $currentUser?.actor &&
!trail.completed
) {
markTrailAsCompletedModal.openModal();
}
}
summitLogCreateLoading = false;
}
@@ -259,6 +268,12 @@
);
summitLogs.set(newSummitLogList);
}
async function markTrailAsCompleted() {
trail.completed = true;
const updatedTrail: Trail = { ...trail };
await trails_update(trail, updatedTrail);
}
</script>
<div
@@ -280,7 +295,7 @@
</button>
{/if}
<div
class="grid gap-[1px] {headerPhotos.length > 1
class="grid gap-px {headerPhotos.length > 1
? 'grid-cols-[8fr_5fr]'
: 'grid-cols-1'} h-80 rounded-t-3xl overflow-hidden cursor-pointer"
>
@@ -391,10 +406,20 @@
{trail.location}
</h3>
{/if}
<h3 class="text-lg">
<h3>
<i class="fa fa-gauge mr-2"></i>
{$_(trail.difficulty ?? "?")}
</h3>
<h3>
<i
class="fa {trail.completed
? 'fa-flag-checkered'
: 'fa-compass-drafting'} mr-2"
></i>
{$_(
trail.completed ? "completed" : "not-completed",
)}
</h3>
</div>
</div>
<div class="flex flex-col items-center gap-y-2">
@@ -675,6 +700,16 @@
<SummitLogModal bind:this={summitLogModal} onsave={(log) => saveSummitLog(log)}
></SummitLogModal>
<ConfirmModal
id="mark-trail-as-completed-modal"
title={$_("mark-trail-as-completed")}
text={$_("mark-trail-as-completed-modal-text")}
action={$_("yes")}
deny={$_("no")}
bind:this={markTrailAsCompletedModal}
onconfirm={markTrailAsCompleted}
></ConfirmModal>
<ConfirmModal
id="confirm-summit-log-delete-modal"
text={$_("delete-summit-log-confirm")}

View File

@@ -133,7 +133,8 @@
{#if trail.tags.length && trail.expand?.tags}
<div class="flex flex-wrap gap-1 mb-3 items-center">
{#each expandedTags ? trail.expand.tags : trail.expand.tags.slice(0, 2) as tag}
<Chip text={tag.name} closable={false} primary={false}></Chip>
<Chip text={tag.name} closable={false} primary={false}
></Chip>
{/each}
{#if trail.expand.tags.length > 2}
@@ -154,7 +155,9 @@
<div class="flex flex-wrap gap-x-8 gap-y-1">
{#if trail.expand?.category?.name || trail.category}
<p>
<i class="fa fa-shapes mr-3"> </i>{$_(trail.expand?.category?.name ?? trail.category ?? "-")}
<i class="fa fa-shapes mr-3"> </i>{$_(
trail.expand?.category?.name ?? trail.category ?? "-",
)}
</p>
{/if}
{#if trail.location}
@@ -165,6 +168,14 @@
<p class="whitespace-nowrap">
<i class="fa fa-gauge mr-3"></i>{$_(trail.difficulty ?? "?")}
</p>
<p class="whitespace-nowrap">
<i
class="fa {trail.completed
? 'fa-flag-checkered'
: 'fa-compass-drafting'} mr-2"
></i>
{$_(trail.completed ? "completed" : "not-completed")}
</p>
</div>
<div class="flex flex-wrap mt-1 gap-x-4 gap-y-2 text-sm text-gray-500">