adds mobile drawer

This commit is contained in:
Christian Beutel
2024-02-24 16:01:09 +01:00
parent 90a683f268
commit 275874fba9
13 changed files with 215 additions and 67 deletions

View File

@@ -7,9 +7,11 @@
import "../css/app.css";
import "../css/components.css";
import "../css/theme.css";
</script>
<svelte:head>
<title> | wanderer</title>
</svelte:head>
<div class="theme {$theme}">
<NavBar></NavBar>
<Toast></Toast>

View File

@@ -64,7 +64,7 @@
style="height: calc(100vh - 112px)"
>
<div
class="flex flex-col justify-center gap-8 max-w-md mx-8 md:mx-auto -mt-24"
class="flex flex-col justify-center gap-8 max-w-md mx-8 md:mx-auto lg:-mt-24"
>
<h2 class="text-7xl font-bold">
Welcome to <span class="-tracking-[0.075em]">wanderer</span>
@@ -90,7 +90,10 @@
<section
class="max-w-7xl mx-auto mt-8 px-8 xl:px-0 grid grid-cols-1 md:grid-cols-2 items-center"
>
<div id="trails" class="flex flex-wrap justify-items-center gap-8 py-8 order-1 md:order-none">
<div
id="trails"
class="flex flex-wrap justify-items-center gap-8 py-8 order-1 md:order-none"
>
{#each $trails as trail}
<a href="/trail/view/{trail.id}">
<TrailCard {trail}></TrailCard></a
@@ -108,7 +111,7 @@
<a
class="inline-block btn-primary btn-large"
href="/trails"
role="button">All Trails</a
role="button">Explore</a
>
</div>
</section>
@@ -118,12 +121,18 @@
<div class="max-w-md md:mx-auto space-y-8">
<h2 class="text-4xl md:text-5xl font-bold">Categories</h2>
<h5>
Did you know? You cannot only save you hiking trails. There are many categories for all your adventures.
Did you know? You cannot only save you hiking trails. There are many
categories for all your adventures.
</h5>
</div>
<div id="categories" class="flex flex-wrap justify-items-center gap-8 py-8">
<div
id="categories"
class="grid grid-cols-1 lg:grid-cols-2 justify-items-center gap-8 py-8"
>
{#each $categories as category}
<CategoryCard {category}></CategoryCard>
<a href="/trails?category={category.id}">
<CategoryCard {category}></CategoryCard>
</a>
{/each}
</div>
</section>

View File

@@ -29,6 +29,7 @@
import TrailFilterPanel from "$lib/components/trail/trail_filter_panel.svelte";
import { categories } from "$lib/stores/category_store";
import { slide } from "svelte/transition";
import { browser } from "$app/environment";
let L: any;
let map: Map;
@@ -38,6 +39,7 @@
let searchDropdownItems: SearchItem[] = [];
let showFilter: boolean = false;
let showMap: boolean = true;
let filter: TrailFilter;
@@ -232,11 +234,11 @@
<main class="grid grid-cols-1 md:grid-cols-[400px_1fr]">
<div
class="overflow-y-auto overflow-x-hidden flex flex-col items-stretch gap-4 px-8"
style="height: calc(100vh - 124px)"
id="trail-list"
class="md:overflow-y-auto md:overflow-x-hidden flex flex-col items-stretch gap-4 px-8"
>
<div class="sticky top-0 z-10 bg-background pb-4 space-y-4">
<div class="flex items-center gap-4">
<div class="flex items-center gap-2 md:gap-4">
<Search
extraClasses="w-full"
on:update={(e) => search(e.detail)}
@@ -249,6 +251,11 @@
on:click={() => (showFilter = !showFilter)}
><i class="fa fa-sliders"></i></button
>
<button
class="btn-icon md:hidden"
on:click={() => (showMap = !showMap)}
><i class="fa-regular fa-{showMap ? 'rectangle-list' : 'map'}"></i></button
>
</div>
{#if showFilter}
<div in:slide out:slide>
@@ -263,27 +270,34 @@
{/if}
</div>
{#if $trails.length == 0}
<EmptyStateSearch></EmptyStateSearch>
{#if !showMap || (browser && window.innerWidth >= 768)}
{#if $trails.length == 0}
<EmptyStateSearch></EmptyStateSearch>
{/if}
{#each $trails as trail}
<a href="/trail/view/{trail.id}">
<TrailCard
{trail}
on:mouseenter={() => handleTrailCardMouseEnter(trail)}
on:mouseleave={() => handleTrailCardMouseLeave(trail)}
></TrailCard>
</a>
{/each}
{/if}
{#each $trails as trail}
<a href="/trail/view/{trail.id}">
<TrailCard
{trail}
on:mouseenter={() => handleTrailCardMouseEnter(trail)}
on:mouseleave={() => handleTrailCardMouseLeave(trail)}
></TrailCard>
</a>
{/each}
</div>
<div class="rounded-xl" id="map"></div>
<div id="map" class="rounded-xl z-0" class:hidden={!showMap && browser && window.innerWidth < 768}></div>
</main>
<style>
#map {
height: calc(100vh - 124px);
height: calc(100vh - 180px);
}
@media only screen and (min-width: 768px) {
#map,
#trail-list {
height: calc(100vh - 124px);
}
}
:global(.leaflet-popup-content) {
width: max-content !important;
max-width: 100%;

View File

@@ -81,7 +81,10 @@
) as HTMLFormElement;
const formData = new FormData(htmlForm);
if (!submittedTrail.id) {
const createdTrail = await trails_create(submittedTrail, formData);
const createdTrail = await trails_create(
submittedTrail,
formData,
);
$form.id = createdTrail.id;
} else {
await trails_update($trail, submittedTrail, formData);
@@ -194,11 +197,13 @@
reader.onload = async function (e) {
await addGPXLayer(e.target?.result as string);
const closestCity = (await ms.index("cities500").search("", {
filter: [`_geoRadius(${$form.lat}, ${$form.lon}, 10000)`],
sort: [`_geoPoint(${$form.lat}, ${$form.lon}):asc`],
limit: 1,
})).hits[0];
const closestCity = (
await ms.index("cities500").search("", {
filter: [`_geoRadius(${$form.lat}, ${$form.lon}, 10000)`],
sort: [`_geoPoint(${$form.lat}, ${$form.lon}):asc`],
limit: 1,
})
).hits[0];
$form.location = closestCity.name;
};
@@ -339,10 +344,10 @@
}
</script>
<main class="grid grid-cols-[400px_1fr]">
<main class="grid grid-cols-1 md:grid-cols-[400px_1fr]">
<form
id="trail-form"
class="overflow-y-auto overflow-x-hidden flex flex-col gap-4 px-8"
class="overflow-y-auto overflow-x-hidden flex flex-col gap-4 px-8 order-1 md:order-none mt-8 md:mt-0"
on:submit={handleSubmit}
>
<h3 class="text-xl font-semibold">Pick a trail</h3>
@@ -412,7 +417,7 @@
></Select>
{/if}
<Toggle name="public" label="Public" bind:value={$form.public}></Toggle>
<hr class="border-separator"/>
<hr class="border-separator" />
<h3 class="text-xl font-semibold">Waypoints</h3>
<ul>
{#each $form.expand.waypoints ?? [] as waypoint, i}
@@ -432,7 +437,7 @@
on:click={beforeWaypointModalOpen}
><i class="fa fa-plus mr-2"></i>Add Waypoint</button
>
<hr class="border-separator"/>
<hr class="border-separator" />
<h3 class="text-xl font-semibold">Photos</h3>
<div class="flex gap-4 max-w-full overflow-x-auto shrink-0">
<button
@@ -459,7 +464,7 @@
</div>
{/each}
</div>
<hr class="border-separator"/>
<hr class="border-separator" />
<h3 class="text-xl font-semibold">Summit Book</h3>
<ul>
{#each $form.expand.summit_logs ?? [] as log, i}
@@ -478,7 +483,7 @@
on:click={beforeSummitLogModalOpen}
><i class="fa fa-plus mr-2"></i>Add Entry</button
>
<hr class="border-separator"/>
<hr class="border-separator" />
<Button
primary={true}
large={true}
@@ -495,8 +500,13 @@
></SummitLogModal>
<style>
#map,
form {
height: calc(100vh - 124px);
#map {
height: calc(400px);
}
@media only screen and (min-width: 768px) {
#map,
form {
height: calc(100vh - 124px);
}
}
</style>

View File

@@ -1,4 +1,5 @@
<script lang="ts">
import { page } from "$app/stores";
import Select, {
type SelectItem,
} from "$lib/components/base/select.svelte";
@@ -26,19 +27,7 @@
let filterExpanded: boolean = true;
export const filter: TrailFilter = {
q: "",
category: [],
near: {
radius: 2000,
},
distanceMin: 0,
distanceMax: 20000,
elevationGainMin: 0,
elevationGainMax: 4000,
sort: "created",
sortOrder: "+",
};
const filter: TrailFilter = $page.data.filter;
onMount(() => {
const storedDisplayOption = localStorage.getItem("displayOption");

View File

@@ -1,8 +1,28 @@
import type { TrailFilter } from "$lib/models/trail";
import { categories_index } from "$lib/stores/category_store";
import { trails_index } from "$lib/stores/trail_store";
import { trails_search_filter } from "$lib/stores/trail_store";
import type { ServerLoad } from "@sveltejs/kit";
export const load: ServerLoad = async ({ params, locals }) => {
await trails_index()
export const load: ServerLoad = async ({ params, locals, url }) => {
const filter: TrailFilter = {
q: "",
category: [],
near: {
radius: 2000,
},
distanceMin: 0,
distanceMax: 20000,
elevationGainMin: 0,
elevationGainMax: 4000,
sort: "created",
sortOrder: "+",
};
const paramCategory = url.searchParams.get("category");
if (paramCategory) {
filter.category.push(paramCategory);
}
await trails_search_filter(filter);
await categories_index()
return {filter};
};