adds trail sort on map
This commit is contained in:
@@ -92,7 +92,7 @@ export async function trails_search_filter(filter: TrailFilter, page: number = 1
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function trails_search_bounding_box(northEast: M.LngLat, southWest: M.LngLat, filter?: TrailFilter, page: number = 1, includePolyline: boolean = true) {
|
export async function trails_search_bounding_box(northEast: M.LngLat, southWest: M.LngLat, filter: TrailFilter, page: number = 1, includePolyline: boolean = true) {
|
||||||
const user = get(currentUser)
|
const user = get(currentUser)
|
||||||
|
|
||||||
let filterText: string = "";
|
let filterText: string = "";
|
||||||
@@ -110,6 +110,7 @@ export async function trails_search_bounding_box(northEast: M.LngLat, southWest:
|
|||||||
`_geoBoundingBox([${northEast.lat}, ${northEast.lng}], [${southWest.lat}, ${southWest.lng}])`,
|
`_geoBoundingBox([${northEast.lat}, ${northEast.lng}], [${southWest.lat}, ${southWest.lng}])`,
|
||||||
filterText
|
filterText
|
||||||
],
|
],
|
||||||
|
sort: [`${filter.sort}:${filter.sortOrder == "+" ? "asc" : "desc"}`,],
|
||||||
attributesToRetrieve: [...defaultTrailSearchAttributes, ...(includePolyline ? ["polyline"] : [])],
|
attributesToRetrieve: [...defaultTrailSearchAttributes, ...(includePolyline ? ["polyline"] : [])],
|
||||||
hitsPerPage: 500,
|
hitsPerPage: 500,
|
||||||
page: page
|
page: page
|
||||||
@@ -527,9 +528,9 @@ function buildFilterText(user: AuthRecord, filter: TrailFilter, includeGeo: bool
|
|||||||
if (filter.public !== undefined || filter.private !== undefined || filter.shared !== undefined) {
|
if (filter.public !== undefined || filter.private !== undefined || filter.shared !== undefined) {
|
||||||
filterText += " AND ("
|
filterText += " AND ("
|
||||||
|
|
||||||
const showPublic = filter.public === undefined || filter.public === true;
|
const showPublic = filter.public === undefined || filter.public === true;
|
||||||
const showPrivate = filter.private === undefined || filter.private === true;
|
const showPrivate = filter.private === undefined || filter.private === true;
|
||||||
const showShared = filter.shared !== undefined && filter.shared === true;
|
const showShared = filter.shared !== undefined && filter.shared === true;
|
||||||
|
|
||||||
if (showPublic === true) {
|
if (showPublic === true) {
|
||||||
filterText += "(public = TRUE";
|
filterText += "(public = TRUE";
|
||||||
@@ -551,7 +552,7 @@ function buildFilterText(user: AuthRecord, filter: TrailFilter, includeGeo: bool
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
filterText += ")";
|
filterText += ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
import Search, {
|
import Search, {
|
||||||
type SearchItem,
|
type SearchItem,
|
||||||
} from "$lib/components/base/search.svelte";
|
} from "$lib/components/base/search.svelte";
|
||||||
|
import type { SelectItem } from "$lib/components/base/select.svelte";
|
||||||
|
import Select from "$lib/components/base/select.svelte";
|
||||||
import SkeletonCard from "$lib/components/base/skeleton_card.svelte";
|
import SkeletonCard from "$lib/components/base/skeleton_card.svelte";
|
||||||
import EmptyStateSearch from "$lib/components/empty_states/empty_state_search.svelte";
|
import EmptyStateSearch from "$lib/components/empty_states/empty_state_search.svelte";
|
||||||
import MapWithElevationMaplibre from "$lib/components/trail/map_with_elevation_maplibre.svelte";
|
import MapWithElevationMaplibre from "$lib/components/trail/map_with_elevation_maplibre.svelte";
|
||||||
@@ -54,6 +56,18 @@
|
|||||||
totalPages: 1,
|
totalPages: 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const sortOptions: SelectItem[] = [
|
||||||
|
{ text: $_("name"), value: "name" },
|
||||||
|
{ text: $_("distance"), value: "distance" },
|
||||||
|
{ text: $_("duration"), value: "duration" },
|
||||||
|
{ text: $_("difficulty"), value: "difficulty" },
|
||||||
|
{ text: $_("elevation-gain"), value: "elevation_gain" },
|
||||||
|
{ text: $_("elevation-loss"), value: "elevation_loss" },
|
||||||
|
{ text: $_("likes"), value: "like_count" },
|
||||||
|
{ text: $_("creation-date"), value: "created" },
|
||||||
|
{ text: $_("date"), value: "date" },
|
||||||
|
];
|
||||||
|
|
||||||
export const snapshot: Snapshot<TrailFilter> = {
|
export const snapshot: Snapshot<TrailFilter> = {
|
||||||
capture: () => filter,
|
capture: () => filter,
|
||||||
restore: (value) => {
|
restore: (value) => {
|
||||||
@@ -126,6 +140,8 @@
|
|||||||
pagination.page = 1;
|
pagination.page = 1;
|
||||||
loading = true;
|
loading = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log(filter);
|
||||||
const trailsInBox = await trails_search_bounding_box(
|
const trailsInBox = await trails_search_bounding_box(
|
||||||
northEast,
|
northEast,
|
||||||
southWest,
|
southWest,
|
||||||
@@ -146,6 +162,27 @@
|
|||||||
mapWithElevation?.unHighlightCluster();
|
mapWithElevation?.unHighlightCluster();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setSort() {
|
||||||
|
if (!filter) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
localStorage.setItem("sort", filter.sort);
|
||||||
|
handleFilterUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
function setSortOrder() {
|
||||||
|
if (!filter) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (filter.sortOrder === "+") {
|
||||||
|
filter.sortOrder = "-";
|
||||||
|
} else {
|
||||||
|
filter.sortOrder = "+";
|
||||||
|
}
|
||||||
|
localStorage.setItem("sort_order", filter.sortOrder);
|
||||||
|
handleFilterUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
async function handleFilterUpdate() {
|
async function handleFilterUpdate() {
|
||||||
if (!map) {
|
if (!map) {
|
||||||
return;
|
return;
|
||||||
@@ -222,7 +259,10 @@
|
|||||||
maxBoundingBox.min_lat == maxBoundingBox.max_lat
|
maxBoundingBox.min_lat == maxBoundingBox.max_lat
|
||||||
) {
|
) {
|
||||||
map?.setZoom(12);
|
map?.setZoom(12);
|
||||||
map?.setCenter([maxBoundingBox.min_lon, maxBoundingBox.min_lat]);
|
map?.setCenter([
|
||||||
|
maxBoundingBox.min_lon,
|
||||||
|
maxBoundingBox.min_lat,
|
||||||
|
]);
|
||||||
} else {
|
} else {
|
||||||
const boundingBox: M.LngLatBoundsLike = [
|
const boundingBox: M.LngLatBoundsLike = [
|
||||||
[maxBoundingBox.min_lon, maxBoundingBox.max_lat],
|
[maxBoundingBox.min_lon, maxBoundingBox.max_lat],
|
||||||
@@ -288,7 +328,7 @@
|
|||||||
class="flex flex-col items-stretch gap-4 px-3 md:px-8 overflow-y-scroll"
|
class="flex flex-col items-stretch gap-4 px-3 md:px-8 overflow-y-scroll"
|
||||||
onscroll={onListScroll}
|
onscroll={onListScroll}
|
||||||
>
|
>
|
||||||
<div class="sticky top-0 z-10 bg-background pb-4 space-y-4">
|
<div class="sticky top-0 z-10 bg-background pb-4">
|
||||||
<div class="flex items-center gap-2 md:gap-4">
|
<div class="flex items-center gap-2 md:gap-4">
|
||||||
<Search
|
<Search
|
||||||
extraClasses="w-full"
|
extraClasses="w-full"
|
||||||
@@ -297,12 +337,6 @@
|
|||||||
placeholder="{$_('search-for-trails-places')}..."
|
placeholder="{$_('search-for-trails-places')}..."
|
||||||
items={searchDropdownItems}
|
items={searchDropdownItems}
|
||||||
></Search>
|
></Search>
|
||||||
<button
|
|
||||||
aria-label="Open filter"
|
|
||||||
class="btn-icon"
|
|
||||||
onclick={() => (showFilter = !showFilter)}
|
|
||||||
><i class="fa fa-sliders"></i></button
|
|
||||||
>
|
|
||||||
<button
|
<button
|
||||||
aria-label="Toggle map"
|
aria-label="Toggle map"
|
||||||
class="btn-icon md:hidden"
|
class="btn-icon md:hidden"
|
||||||
@@ -314,6 +348,28 @@
|
|||||||
></i></button
|
></i></button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="flex items-center gap-2 mt-2 mb-4">
|
||||||
|
<Select
|
||||||
|
bind:value={filter.sort}
|
||||||
|
items={sortOptions}
|
||||||
|
onchange={setSort}
|
||||||
|
></Select>
|
||||||
|
<button
|
||||||
|
aria-label="Change sort order"
|
||||||
|
id="sort-order-btn"
|
||||||
|
class="btn-icon"
|
||||||
|
class:rotated={filter.sortOrder == "-"}
|
||||||
|
onclick={() => setSortOrder()}
|
||||||
|
><i class="fa fa-arrow-up"></i></button
|
||||||
|
>
|
||||||
|
<div class="basis-full"></div>
|
||||||
|
<button
|
||||||
|
aria-label="Open filter"
|
||||||
|
class="btn-icon"
|
||||||
|
onclick={() => (showFilter = !showFilter)}
|
||||||
|
><i class="fa fa-sliders"></i></button
|
||||||
|
>
|
||||||
|
</div>
|
||||||
{#if showFilter}
|
{#if showFilter}
|
||||||
<div in:slide out:slide>
|
<div in:slide out:slide>
|
||||||
<TrailFilterPanel
|
<TrailFilterPanel
|
||||||
@@ -345,6 +401,8 @@
|
|||||||
<TrailCard
|
<TrailCard
|
||||||
{trail}
|
{trail}
|
||||||
fullWidth={true}
|
fullWidth={true}
|
||||||
|
hovered={false}
|
||||||
|
selected={false}
|
||||||
onmouseenter={() =>
|
onmouseenter={() =>
|
||||||
handleTrailCardMouseEnter(trail)}
|
handleTrailCardMouseEnter(trail)}
|
||||||
onmouseleave={() =>
|
onmouseleave={() =>
|
||||||
@@ -384,4 +442,11 @@
|
|||||||
height: calc(100vh - 124px);
|
height: calc(100vh - 124px);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#sort-order-btn {
|
||||||
|
transition: transform 0.5s ease;
|
||||||
|
}
|
||||||
|
:global(.rotated) {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ export const load: ServerLoad = async ({ params, locals, fetch }) => {
|
|||||||
elevationLossMax: filterValues.max_elevation_loss,
|
elevationLossMax: filterValues.max_elevation_loss,
|
||||||
elevationLossLimit: filterValues.max_elevation_gain,
|
elevationLossLimit: filterValues.max_elevation_gain,
|
||||||
sort: "created",
|
sort: "created",
|
||||||
sortOrder: "+",
|
sortOrder: "-",
|
||||||
};
|
};
|
||||||
|
|
||||||
await categories_index(fetch)
|
await categories_index(fetch)
|
||||||
|
|||||||
Reference in New Issue
Block a user