mirror of
https://github.com/gpxstudio/gpx.studio.git
synced 2025-08-31 23:53:25 +00:00
add faq section
This commit is contained in:
@@ -1,112 +1,112 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { browser } from '$app/environment';
|
import { browser } from '$app/environment';
|
||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
import { base } from '$app/paths';
|
import { base } from '$app/paths';
|
||||||
import { _, locale } from 'svelte-i18n';
|
import { _, locale } from 'svelte-i18n';
|
||||||
|
|
||||||
export let path: string;
|
export let path: string;
|
||||||
export let titleOnly: boolean = false;
|
export let titleOnly: boolean = false;
|
||||||
|
|
||||||
let module = undefined;
|
let module = undefined;
|
||||||
let metadata: Record<string, any> = {};
|
let metadata: Record<string, any> = {};
|
||||||
|
|
||||||
const modules = import.meta.glob('/src/lib/docs/**/*.mdx');
|
const modules = import.meta.glob('/src/lib/docs/**/*.mdx');
|
||||||
|
|
||||||
function loadModule(path: string) {
|
function loadModule(path: string) {
|
||||||
modules[path]?.().then((mod) => {
|
modules[path]?.().then((mod) => {
|
||||||
module = mod.default;
|
module = mod.default;
|
||||||
metadata = mod.metadata;
|
metadata = mod.metadata;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
$: if ($locale) {
|
$: if ($locale) {
|
||||||
if (modules.hasOwnProperty(`/src/lib/docs/${$locale}/${path}`)) {
|
if (modules.hasOwnProperty(`/src/lib/docs/${$locale}/${path}`)) {
|
||||||
loadModule(`/src/lib/docs/${$locale}/${path}`);
|
loadModule(`/src/lib/docs/${$locale}/${path}`);
|
||||||
} else if (browser) {
|
} else if (browser) {
|
||||||
goto(`${base}/404`);
|
goto(`${base}/404`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if module !== undefined}
|
{#if module !== undefined}
|
||||||
{#if titleOnly}
|
{#if titleOnly}
|
||||||
{metadata.title}
|
{metadata.title}
|
||||||
{:else}
|
{:else}
|
||||||
<div class="markdown flex flex-col gap-3">
|
<div class="markdown flex flex-col gap-3">
|
||||||
<svelte:component this={module} />
|
<svelte:component this={module} />
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<style lang="postcss">
|
<style lang="postcss">
|
||||||
:global(.markdown) {
|
:global(.markdown) {
|
||||||
@apply text-muted-foreground;
|
@apply text-muted-foreground;
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.markdown h1) {
|
:global(.markdown h1) {
|
||||||
@apply text-foreground;
|
@apply text-foreground;
|
||||||
@apply text-3xl;
|
@apply text-3xl;
|
||||||
@apply font-semibold;
|
@apply font-semibold;
|
||||||
@apply mb-3 pt-6;
|
@apply mb-3 pt-6;
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.markdown h2) {
|
:global(.markdown h2) {
|
||||||
@apply text-foreground;
|
@apply text-foreground;
|
||||||
@apply text-2xl;
|
@apply text-2xl;
|
||||||
@apply font-semibold;
|
@apply font-semibold;
|
||||||
@apply pt-3;
|
@apply pt-3;
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.markdown h3) {
|
:global(.markdown h3) {
|
||||||
@apply text-foreground;
|
@apply text-foreground;
|
||||||
@apply text-lg;
|
@apply text-lg;
|
||||||
@apply font-semibold;
|
@apply font-semibold;
|
||||||
@apply pt-1.5;
|
@apply pt-1.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.markdown p > button) {
|
:global(.markdown p > button, .markdown li > button) {
|
||||||
@apply border;
|
@apply border;
|
||||||
@apply rounded-md;
|
@apply rounded-md;
|
||||||
@apply px-1;
|
@apply px-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.markdown > a) {
|
:global(.markdown > a) {
|
||||||
@apply text-blue-500;
|
@apply text-blue-500;
|
||||||
@apply hover:underline;
|
@apply hover:underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.markdown p > a) {
|
:global(.markdown p > a) {
|
||||||
@apply text-blue-500;
|
@apply text-blue-500;
|
||||||
@apply hover:underline;
|
@apply hover:underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.markdown li > a) {
|
:global(.markdown li > a) {
|
||||||
@apply text-blue-500;
|
@apply text-blue-500;
|
||||||
@apply hover:underline;
|
@apply hover:underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.markdown kbd) {
|
:global(.markdown kbd) {
|
||||||
@apply p-1;
|
@apply p-1;
|
||||||
@apply rounded-md;
|
@apply rounded-md;
|
||||||
@apply border;
|
@apply border;
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.markdown ul) {
|
:global(.markdown ul) {
|
||||||
@apply list-disc;
|
@apply list-disc;
|
||||||
@apply pl-4;
|
@apply pl-4;
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.markdown ol) {
|
:global(.markdown ol) {
|
||||||
@apply list-decimal;
|
@apply list-decimal;
|
||||||
@apply pl-4;
|
@apply pl-4;
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.markdown li) {
|
:global(.markdown li) {
|
||||||
@apply mt-1;
|
@apply mt-1;
|
||||||
@apply first:mt-0;
|
@apply first:mt-0;
|
||||||
}
|
}
|
||||||
|
|
||||||
:global(.markdown hr) {
|
:global(.markdown hr) {
|
||||||
@apply my-5;
|
@apply my-5;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@@ -9,6 +9,7 @@ export const guides: Record<string, string[]> = {
|
|||||||
'map-controls': [],
|
'map-controls': [],
|
||||||
'gpx': [],
|
'gpx': [],
|
||||||
'integration': [],
|
'integration': [],
|
||||||
|
'faq': [],
|
||||||
};
|
};
|
||||||
|
|
||||||
export const guideIcons: Record<string, string | ComponentType<Icon>> = {
|
export const guideIcons: Record<string, string | ComponentType<Icon>> = {
|
||||||
@@ -31,6 +32,7 @@ export const guideIcons: Record<string, string | ComponentType<Icon>> = {
|
|||||||
"map-controls": "🗺",
|
"map-controls": "🗺",
|
||||||
"gpx": "💾",
|
"gpx": "💾",
|
||||||
"integration": "{ 👩💻 }",
|
"integration": "{ 👩💻 }",
|
||||||
|
"faq": "🔮",
|
||||||
};
|
};
|
||||||
|
|
||||||
export function getPreviousGuide(currentGuide: string): string | undefined {
|
export function getPreviousGuide(currentGuide: string): string | undefined {
|
||||||
|
39
website/src/lib/docs/en/faq.mdx
Normal file
39
website/src/lib/docs/en/faq.mdx
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
---
|
||||||
|
title: FAQ
|
||||||
|
---
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
# { title }
|
||||||
|
|
||||||
|
### Do I need to donate to use the website?
|
||||||
|
|
||||||
|
No, you don't need to donate to use the website or unlock any features.
|
||||||
|
The website is free to use and always will be (as long as it is financially sustainable).
|
||||||
|
However, donations are appreciated and help keep the website running.
|
||||||
|
|
||||||
|
### Why is this route chosen over that one? *Or* how can I add something to the map?
|
||||||
|
|
||||||
|
**gpx.studio** uses data from <a href="https://www.openstreetmap.org/" target="_blank">OpenStreetMap</a>, which is a crowd-sourced map of the world.
|
||||||
|
This means you can contribute to the map by adding or editing data on OpenStreetMap.
|
||||||
|
|
||||||
|
If you have never used OpenStreetMap before, you can:
|
||||||
|
1. Go to the location where you want to add or edit data on the <a href="https://www.openstreetmap.org/" target="_blank">map</a>.
|
||||||
|
2. Use the <button>Query features</button> tool on the right to inspect the existing data.
|
||||||
|
3. Right-click on the location and select <button>Add a note here</button>.
|
||||||
|
4. Explain what is incorrect or missing in the note and click <button>Add note</button> to submit it.
|
||||||
|
|
||||||
|
Someone more experienced with OpenStreetMap will then review your note and take the necessary action.
|
||||||
|
|
||||||
|
<DocsNote>
|
||||||
|
|
||||||
|
More information on how to contribute to OpenStreetMap can be found <a href="https://wiki.openstreetmap.org/wiki/How_to_contribute" target="_blank">here</a>.
|
||||||
|
|
||||||
|
</DocsNote>
|
||||||
|
|
||||||
|
### Why is the elevation profile for my GPX file empty?
|
||||||
|
|
||||||
|
If the elevation profile for your GPX file is empty, it means that the GPX file does not contain elevation data.
|
||||||
|
You can add elevation data to your GPX file by using <a href="https://www.gpsvisualizer.com/elevation" target="_blank">GPS Visualizer</a>.
|
@@ -1,62 +1,63 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import '../app.pcss';
|
import '../app.pcss';
|
||||||
import { ModeWatcher } from 'mode-watcher';
|
import { ModeWatcher } from 'mode-watcher';
|
||||||
import { isLoading, _, locale } from 'svelte-i18n';
|
import { isLoading, _, locale } from 'svelte-i18n';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/stores';
|
||||||
import Nav from '$lib/components/Nav.svelte';
|
import Nav from '$lib/components/Nav.svelte';
|
||||||
import Footer from '$lib/components/Footer.svelte';
|
import Footer from '$lib/components/Footer.svelte';
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import { convertOldEmbeddingOptions } from '$lib/components/embedding/Embedding';
|
import { convertOldEmbeddingOptions } from '$lib/components/embedding/Embedding';
|
||||||
import { base } from '$app/paths';
|
import { base } from '$app/paths';
|
||||||
import { languages } from '$lib/languages';
|
import { languages } from '$lib/languages';
|
||||||
import { browser } from '$app/environment';
|
import { browser } from '$app/environment';
|
||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
import { getURLForLanguage } from '$lib/utils';
|
import { getURLForLanguage } from '$lib/utils';
|
||||||
|
|
||||||
const appRoutes = ['/[[language]]/app', '/[[language]]/embed'];
|
const appRoutes = ['/[[language]]/app', '/[[language]]/embed'];
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
if ($page.url.searchParams.has('embed')) {
|
if ($page.url.searchParams.has('embed')) {
|
||||||
// convert old embedding options to new format and redirect to new embed page
|
// convert old embedding options to new format and redirect to new embed page
|
||||||
let folders = $page.url.pathname.split('/');
|
let folders = $page.url.pathname.split('/');
|
||||||
let locale = folders.indexOf('l') >= 0 ? folders[folders.indexOf('l') + 1] ?? 'en' : 'en';
|
let locale =
|
||||||
window.location.href = `${getURLForLanguage(locale, '/embed')}?options=${encodeURIComponent(JSON.stringify(convertOldEmbeddingOptions($page.url.searchParams)))}`;
|
folders.indexOf('l') >= 0 ? folders[folders.indexOf('l') + 1] ?? 'en' : 'en';
|
||||||
}
|
window.location.href = `${getURLForLanguage(locale, '/embed')}?options=${encodeURIComponent(JSON.stringify(convertOldEmbeddingOptions($page.url.searchParams)))}`;
|
||||||
});
|
}
|
||||||
|
});
|
||||||
|
|
||||||
$: if ($page.params.language) {
|
$: if ($page.route.id.includes('[[language]]')) {
|
||||||
if ($page.params.language === '' && $locale !== 'en') {
|
if ($page.params.language) {
|
||||||
locale.set('en');
|
let lang = $page.params.language.replace('/', '');
|
||||||
} else if ($page.params.language) {
|
if ($locale !== lang) {
|
||||||
let lang = $page.params.language.replace('/', '');
|
if (languages.hasOwnProperty(lang)) {
|
||||||
if ($locale !== lang) {
|
locale.set(lang);
|
||||||
if (languages.hasOwnProperty(lang)) {
|
} else if (browser) {
|
||||||
locale.set(lang);
|
goto(`${base}/404`);
|
||||||
} else if (browser) {
|
}
|
||||||
goto(`${base}/404`);
|
}
|
||||||
}
|
} else if ($locale !== 'en') {
|
||||||
}
|
locale.set('en');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$: if (browser && !$isLoading && $_) {
|
$: if (browser && !$isLoading && $_) {
|
||||||
document.title = `gpx.studio — ${$_(`metadata.${$page.route.id?.replace('/[[language]]', '').split('/')[1] ?? 'home'}_title`)}`;
|
document.title = `gpx.studio — ${$_(`metadata.${$page.route.id?.replace('/[[language]]', '').split('/')[1] ?? 'home'}_title`)}`;
|
||||||
}
|
}
|
||||||
$: showNavAndFooter = $page.route.id === null || !appRoutes.includes($page.route.id);
|
$: showNavAndFooter = $page.route.id === null || !appRoutes.includes($page.route.id);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<ModeWatcher />
|
<ModeWatcher />
|
||||||
|
|
||||||
<div class="flex flex-col min-h-screen">
|
<div class="flex flex-col min-h-screen">
|
||||||
{#if !$isLoading}
|
{#if !$isLoading}
|
||||||
{#if showNavAndFooter}
|
{#if showNavAndFooter}
|
||||||
<Nav />
|
<Nav />
|
||||||
{/if}
|
{/if}
|
||||||
<main class="grow flex flex-col">
|
<main class="grow flex flex-col">
|
||||||
<slot />
|
<slot />
|
||||||
</main>
|
</main>
|
||||||
{#if showNavAndFooter}
|
{#if showNavAndFooter}
|
||||||
<Footer />
|
<Footer />
|
||||||
{/if}
|
{/if}
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
@@ -1,41 +1,43 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Button } from '$lib/components/ui/button';
|
import { Button } from '$lib/components/ui/button';
|
||||||
import { getURLForLanguage } from '$lib/utils';
|
import { getURLForLanguage } from '$lib/utils';
|
||||||
import { locale } from 'svelte-i18n';
|
import { locale } from 'svelte-i18n';
|
||||||
import DocsLoader from '$lib/components/docs/DocsLoader.svelte';
|
import DocsLoader from '$lib/components/docs/DocsLoader.svelte';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/stores';
|
||||||
import { guides } from '$lib/components/docs/docs';
|
import { guides } from '$lib/components/docs/docs';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="px-12 pt-6 pb-12 flex flex-row gap-24">
|
<div class="grow px-12 pt-6 pb-12 flex flex-row gap-24">
|
||||||
<div class="hidden md:flex flex-col gap-2 w-40 sticky top-[108px] self-start shrink-0">
|
<div
|
||||||
{#each Object.keys(guides) as guide}
|
class="hidden md:flex flex-col gap-2 w-40 sticky mt-[27px] top-[108px] self-start shrink-0"
|
||||||
<Button
|
>
|
||||||
variant="link"
|
{#each Object.keys(guides) as guide}
|
||||||
href={getURLForLanguage($locale, `/help/${guide}`)}
|
<Button
|
||||||
class="h-fit p-0 w-fit text-muted-foreground hover:text-foreground hover:no-underline font-normal hover:font-semibold items-start whitespace-normal {$page
|
variant="link"
|
||||||
.params.guide === guide
|
href={getURLForLanguage($locale, `/help/${guide}`)}
|
||||||
? 'font-semibold text-foreground'
|
class="h-fit p-0 w-fit text-muted-foreground hover:text-foreground hover:no-underline font-normal hover:font-semibold items-start whitespace-normal {$page
|
||||||
: ''}"
|
.params.guide === guide
|
||||||
>
|
? 'font-semibold text-foreground'
|
||||||
<DocsLoader path={`${guide}.mdx`} titleOnly={true} />
|
: ''}"
|
||||||
</Button>
|
>
|
||||||
{#each guides[guide] as subGuide}
|
<DocsLoader path={`${guide}.mdx`} titleOnly={true} />
|
||||||
<Button
|
</Button>
|
||||||
variant="link"
|
{#each guides[guide] as subGuide}
|
||||||
href={getURLForLanguage($locale, `/help/${guide}/${subGuide}`)}
|
<Button
|
||||||
class="h-fit p-0 w-fit text-muted-foreground hover:text-foreground hover:no-underline font-normal hover:font-semibold items-start whitespace-normal ml-3 {$page
|
variant="link"
|
||||||
.params.guide ===
|
href={getURLForLanguage($locale, `/help/${guide}/${subGuide}`)}
|
||||||
guide + '/' + subGuide
|
class="h-fit p-0 w-fit text-muted-foreground hover:text-foreground hover:no-underline font-normal hover:font-semibold items-start whitespace-normal ml-3 {$page
|
||||||
? 'font-semibold text-foreground'
|
.params.guide ===
|
||||||
: ''}"
|
guide + '/' + subGuide
|
||||||
>
|
? 'font-semibold text-foreground'
|
||||||
<DocsLoader path={`${guide}/${subGuide}.mdx`} titleOnly={true} />
|
: ''}"
|
||||||
</Button>
|
>
|
||||||
{/each}
|
<DocsLoader path={`${guide}/${subGuide}.mdx`} titleOnly={true} />
|
||||||
{/each}
|
</Button>
|
||||||
</div>
|
{/each}
|
||||||
<div class="grow">
|
{/each}
|
||||||
<slot />
|
</div>
|
||||||
</div>
|
<div class="grow">
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Reference in New Issue
Block a user