adds trail date filter
This commit is contained in:
@@ -22,7 +22,8 @@ func indexRecord(r *models.Record, client *meilisearch.Client) error {
|
|||||||
"difficulty": r.Get("difficulty"),
|
"difficulty": r.Get("difficulty"),
|
||||||
"category": r.Get("category"),
|
"category": r.Get("category"),
|
||||||
"completed": len(r.GetStringSlice("summit_logs")) > 0,
|
"completed": len(r.GetStringSlice("summit_logs")) > 0,
|
||||||
"created": r.GetDateTime("created"),
|
"date": r.GetDateTime("date").Time().Unix(),
|
||||||
|
"created": r.GetDateTime("created").Time().Unix(),
|
||||||
"public": r.GetBool("public"),
|
"public": r.GetBool("public"),
|
||||||
"_geo": map[string]float64{
|
"_geo": map[string]float64{
|
||||||
"lat": r.GetFloat("lat"),
|
"lat": r.GetFloat("lat"),
|
||||||
|
|||||||
Binary file not shown.
@@ -10,9 +10,9 @@
|
|||||||
import type { RadioItem } from "../base/radio_group.svelte";
|
import type { RadioItem } from "../base/radio_group.svelte";
|
||||||
import RadioGroup from "../base/radio_group.svelte";
|
import RadioGroup from "../base/radio_group.svelte";
|
||||||
import Search, { type SearchItem } from "../base/search.svelte";
|
import Search, { type SearchItem } from "../base/search.svelte";
|
||||||
import Slider from "../base/slider.svelte";
|
|
||||||
import type { SelectItem } from "../base/select.svelte";
|
import type { SelectItem } from "../base/select.svelte";
|
||||||
import { page } from "$app/stores";
|
import Slider from "../base/slider.svelte";
|
||||||
|
import Datepicker from "../base/datepicker.svelte";
|
||||||
|
|
||||||
export let categories: Category[];
|
export let categories: Category[];
|
||||||
export let filterExpanded: boolean = true;
|
export let filterExpanded: boolean = true;
|
||||||
@@ -238,6 +238,23 @@
|
|||||||
: ""}</span
|
: ""}</span
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
<hr class="my-4 border-separator" />
|
||||||
|
|
||||||
|
<div class="space-y-2">
|
||||||
|
<Datepicker
|
||||||
|
name="startDate"
|
||||||
|
label="After"
|
||||||
|
bind:value={filter.startDate}
|
||||||
|
on:change={update}
|
||||||
|
></Datepicker>
|
||||||
|
<Datepicker
|
||||||
|
name="endDate"
|
||||||
|
label="Before"
|
||||||
|
bind:value={filter.endDate}
|
||||||
|
on:change={update}
|
||||||
|
></Datepicker>
|
||||||
|
</div>
|
||||||
|
|
||||||
<hr class="my-4 border-separator" />
|
<hr class="my-4 border-separator" />
|
||||||
<p class="text-sm font-medium pb-4">{$_("completion-status")}</p>
|
<p class="text-sm font-medium pb-4">{$_("completion-status")}</p>
|
||||||
<RadioGroup
|
<RadioGroup
|
||||||
|
|||||||
@@ -101,6 +101,8 @@ interface TrailFilter {
|
|||||||
elevationGainMin: number;
|
elevationGainMin: number;
|
||||||
elevationGainMax: number;
|
elevationGainMax: number;
|
||||||
elevationGainLimit: number;
|
elevationGainLimit: number;
|
||||||
|
startDate?: string;
|
||||||
|
endDate?: string;
|
||||||
completed?: boolean;
|
completed?: boolean;
|
||||||
sort: "name" | "distance" | "elevation_gain" | "created";
|
sort: "name" | "distance" | "elevation_gain" | "created";
|
||||||
sortOrder: "+" | "-"
|
sortOrder: "+" | "-"
|
||||||
|
|||||||
@@ -34,30 +34,8 @@ export async function trails_index(data: { perPage: number, random?: boolean, f:
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function trails_search_filter(filter: TrailFilter, page: number = 1, f: (url: RequestInfo | URL, config?: RequestInit) => Promise<Response> = fetch) {
|
export async function trails_search_filter(filter: TrailFilter, page: number = 1, f: (url: RequestInfo | URL, config?: RequestInit) => Promise<Response> = fetch) {
|
||||||
let filterText: string = `distance >= ${filter.distanceMin} AND elevation_gain >= ${filter.elevationGainMin}`
|
let filterText: string = buildFilterText(filter, true);
|
||||||
|
|
||||||
if (filter.distanceMax < filter.distanceLimit) {
|
|
||||||
filterText += ` AND distance <= ${filter.distanceMax}`
|
|
||||||
}
|
|
||||||
|
|
||||||
if (filter.elevationGainMax < filter.elevationGainLimit) {
|
|
||||||
filterText += ` AND elevation_gain <= ${filter.elevationGainMax}`
|
|
||||||
}
|
|
||||||
|
|
||||||
filterText += ` AND difficulty IN [${filter.difficulty.join(",")}]`
|
|
||||||
|
|
||||||
if (filter.category.length > 0) {
|
|
||||||
filterText += ` AND category IN [${filter.category.join(",")}]`;
|
|
||||||
}
|
|
||||||
if (filter.completed !== undefined) {
|
|
||||||
filterText += ` AND completed = ${filter.completed}`;
|
|
||||||
}
|
|
||||||
if (filter.near.lat && filter.near.lon) {
|
|
||||||
filterText += ` AND _geoRadius(${filter.near.lat}, ${filter.near.lon}, ${filter.near.radius})`
|
|
||||||
}
|
|
||||||
if (filter.near.lat && filter.near.lon) {
|
|
||||||
filterText += ` AND _geoRadius(${filter.near.lat}, ${filter.near.lon}, ${filter.near.radius})`
|
|
||||||
}
|
|
||||||
let r = await f("/api/v1/search/trails", {
|
let r = await f("/api/v1/search/trails", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: JSON.stringify({ q: filter.q, options: { filter: filterText, hitsPerPage: 21, page: page } }),
|
body: JSON.stringify({ q: filter.q, options: { filter: filterText, hitsPerPage: 21, page: page } }),
|
||||||
@@ -98,24 +76,7 @@ export async function trails_search_bounding_box(northEast: LatLng, southWest: L
|
|||||||
let filterText: string = "";
|
let filterText: string = "";
|
||||||
|
|
||||||
if (filter) {
|
if (filter) {
|
||||||
filterText += `distance >= ${filter.distanceMin} AND elevation_gain >= ${filter.elevationGainMin}`;
|
filterText = buildFilterText(filter, false);
|
||||||
|
|
||||||
if (filter.distanceMax < filter.distanceLimit) {
|
|
||||||
filterText += ` AND distance <= ${filter.distanceMax}`
|
|
||||||
}
|
|
||||||
|
|
||||||
if (filter.elevationGainMax < filter.elevationGainLimit) {
|
|
||||||
filterText += ` AND elevation_gain <= ${filter.elevationGainMax}`
|
|
||||||
}
|
|
||||||
|
|
||||||
filterText += ` AND difficulty IN [${filter.difficulty.join(",")}]`
|
|
||||||
|
|
||||||
if (filter.category.length > 0) {
|
|
||||||
filterText += ` AND category IN [${filter.category.join(",")}]`;
|
|
||||||
}
|
|
||||||
if (filter.completed !== undefined) {
|
|
||||||
filterText += ` AND completed = ${filter.completed}`;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let r = await fetch("/api/v1/search/trails", {
|
let r = await fetch("/api/v1/search/trails", {
|
||||||
@@ -375,7 +336,7 @@ export async function trails_get_bounding_box(f: (url: RequestInfo | URL, config
|
|||||||
method: 'GET',
|
method: 'GET',
|
||||||
})
|
})
|
||||||
|
|
||||||
if (r.ok) {
|
if (r.ok) {
|
||||||
return await r.json();
|
return await r.json();
|
||||||
} else {
|
} else {
|
||||||
throw new ClientResponseError(await r.json())
|
throw new ClientResponseError(await r.json())
|
||||||
@@ -393,6 +354,46 @@ export async function fetchGPX(trail: Trail, f: (url: RequestInfo | URL, config?
|
|||||||
return gpxData
|
return gpxData
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function buildFilterText(filter: TrailFilter, includeGeo: boolean): string {
|
||||||
|
let filterText: string = "";
|
||||||
|
|
||||||
|
filterText += `distance >= ${filter.distanceMin} AND elevation_gain >= ${filter.elevationGainMin}`
|
||||||
|
|
||||||
|
if (filter.distanceMax < filter.distanceLimit) {
|
||||||
|
filterText += ` AND distance <= ${filter.distanceMax}`
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter.elevationGainMax < filter.elevationGainLimit) {
|
||||||
|
filterText += ` AND elevation_gain <= ${filter.elevationGainMax}`
|
||||||
|
}
|
||||||
|
|
||||||
|
filterText += ` AND difficulty IN [${filter.difficulty.join(",")}]`
|
||||||
|
|
||||||
|
if(filter.startDate) {
|
||||||
|
filterText += ` AND date >= ${new Date(filter.startDate).getTime() / 1000}`
|
||||||
|
}
|
||||||
|
|
||||||
|
if(filter.endDate) {
|
||||||
|
filterText += ` AND date <= ${new Date(filter.endDate).getTime() / 1000}`
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter.category.length > 0) {
|
||||||
|
filterText += ` AND category IN [${filter.category.join(",")}]`;
|
||||||
|
}
|
||||||
|
if (filter.completed !== undefined) {
|
||||||
|
filterText += ` AND completed = ${filter.completed}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter.near.lat && filter.near.lon && includeGeo) {
|
||||||
|
filterText += ` AND _geoRadius(${filter.near.lat}, ${filter.near.lon}, ${filter.near.radius})`
|
||||||
|
}
|
||||||
|
if (filter.near.lat && filter.near.lon && includeGeo) {
|
||||||
|
filterText += ` AND _geoRadius(${filter.near.lat}, ${filter.near.lon}, ${filter.near.radius})`
|
||||||
|
}
|
||||||
|
|
||||||
|
return filterText
|
||||||
|
}
|
||||||
|
|
||||||
function compareObjectArrays<T extends { id?: string }>(oldArray: T[], newArray: T[]) {
|
function compareObjectArrays<T extends { id?: string }>(oldArray: T[], newArray: T[]) {
|
||||||
const newObjects = [];
|
const newObjects = [];
|
||||||
const updatedObjects = [];
|
const updatedObjects = [];
|
||||||
|
|||||||
@@ -471,7 +471,7 @@
|
|||||||
type="file"
|
type="file"
|
||||||
name="gpx"
|
name="gpx"
|
||||||
id="fileInput"
|
id="fileInput"
|
||||||
accept=".gpx,.kml,.tcx"
|
accept=".gpx,.GPX,.tcx,.TCX,.kml,.KML"
|
||||||
style="display: none;"
|
style="display: none;"
|
||||||
on:change={handleFileSelection}
|
on:change={handleFileSelection}
|
||||||
/>
|
/>
|
||||||
|
|||||||
Reference in New Issue
Block a user