mirror of
https://github.com/gpxstudio/gpx.studio.git
synced 2025-08-31 23:53:25 +00:00
use homepage as default page
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
import { Button } from '$lib/components/ui/button';
|
import { Button } from '$lib/components/ui/button';
|
||||||
import LanguageSelect from '$lib/components/LanguageSelect.svelte';
|
import LanguageSelect from '$lib/components/LanguageSelect.svelte';
|
||||||
import Logo from '$lib/components/Logo.svelte';
|
import Logo from '$lib/components/Logo.svelte';
|
||||||
import { AtSign, BookOpenText, Heart, Info, Map } from 'lucide-svelte';
|
import { AtSign, BookOpenText, Heart, Home, Map } from 'lucide-svelte';
|
||||||
import { _ } from 'svelte-i18n';
|
import { _ } from 'svelte-i18n';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -24,14 +24,14 @@
|
|||||||
<div class="grow max-w-2xl flex flex-row flex-wrap justify-between gap-x-10 gap-y-6">
|
<div class="grow max-w-2xl flex flex-row flex-wrap justify-between gap-x-10 gap-y-6">
|
||||||
<div class="flex flex-col items-start gap-1">
|
<div class="flex flex-col items-start gap-1">
|
||||||
<span class="font-semibold">{$_('homepage.website')}</span>
|
<span class="font-semibold">{$_('homepage.website')}</span>
|
||||||
|
<Button variant="link" class="h-6 px-0 text-muted-foreground" href="./about">
|
||||||
|
<Home size="16" class="mr-1" />
|
||||||
|
{$_('homepage.home')}
|
||||||
|
</Button>
|
||||||
<Button variant="link" class="h-6 px-0 text-muted-foreground" href="./">
|
<Button variant="link" class="h-6 px-0 text-muted-foreground" href="./">
|
||||||
<Map size="16" class="mr-1" />
|
<Map size="16" class="mr-1" />
|
||||||
{$_('homepage.app')}
|
{$_('homepage.app')}
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="link" class="h-6 px-0 text-muted-foreground" href="./about">
|
|
||||||
<Info size="16" class="mr-1" />
|
|
||||||
{$_('menu.about')}
|
|
||||||
</Button>
|
|
||||||
<Button variant="link" class="h-6 px-0 text-muted-foreground" href="./documentation">
|
<Button variant="link" class="h-6 px-0 text-muted-foreground" href="./documentation">
|
||||||
<BookOpenText size="16" class="mr-1" />
|
<BookOpenText size="16" class="mr-1" />
|
||||||
{$_('homepage.documentation')}
|
{$_('homepage.documentation')}
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
import * as Select from '$lib/components/ui/select';
|
import * as Select from '$lib/components/ui/select';
|
||||||
import { languages } from '$lib/languages';
|
import { getURLForLanguage, languages } from '$lib/languages';
|
||||||
import { Languages } from 'lucide-svelte';
|
import { Languages } from 'lucide-svelte';
|
||||||
import { _, locale } from 'svelte-i18n';
|
import { _, locale } from 'svelte-i18n';
|
||||||
|
|
||||||
@@ -16,21 +16,6 @@
|
|||||||
label: languages[$locale]
|
label: languages[$locale]
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function getURLForLanguage(lang?: string): string {
|
|
||||||
let currentPath = window.location.pathname;
|
|
||||||
let currentPathArray = currentPath.split('/');
|
|
||||||
|
|
||||||
if (currentPathArray.length > 1 && languages.hasOwnProperty(currentPathArray[1])) {
|
|
||||||
currentPathArray.splice(1, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lang !== undefined && lang !== 'en') {
|
|
||||||
currentPathArray.splice(1, 0, lang);
|
|
||||||
}
|
|
||||||
|
|
||||||
return currentPathArray.join('/');
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Select.Root bind:selected onSelectedChange={(s) => goto(getURLForLanguage(s?.value))}>
|
<Select.Root bind:selected onSelectedChange={(s) => goto(getURLForLanguage(s?.value))}>
|
||||||
|
@@ -72,9 +72,7 @@
|
|||||||
import Export from '$lib/components/Export.svelte';
|
import Export from '$lib/components/Export.svelte';
|
||||||
import { mode, setMode, systemPrefersMode } from 'mode-watcher';
|
import { mode, setMode, systemPrefersMode } from 'mode-watcher';
|
||||||
import { _, locale } from 'svelte-i18n';
|
import { _, locale } from 'svelte-i18n';
|
||||||
import { languages } from '$lib/languages';
|
import { getURLForLanguage, languages } from '$lib/languages';
|
||||||
import { goto } from '$app/navigation';
|
|
||||||
import { base } from '$app/paths';
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
distanceUnits,
|
distanceUnits,
|
||||||
@@ -125,8 +123,10 @@
|
|||||||
<div
|
<div
|
||||||
class="w-fit flex flex-row items-center justify-center p-1 bg-background rounded-b-md md:rounded-md pointer-events-auto shadow-md"
|
class="w-fit flex flex-row items-center justify-center p-1 bg-background rounded-b-md md:rounded-md pointer-events-auto shadow-md"
|
||||||
>
|
>
|
||||||
<Logo class="h-5 mt-0.5 mx-2 md:hidden" iconOnly={true} />
|
<a href="./" target="_blank">
|
||||||
<Logo class="h-5 mt-0.5 mx-2 hidden md:block" />
|
<Logo class="h-5 mt-0.5 mx-2 md:hidden" iconOnly={true} />
|
||||||
|
<Logo class="h-5 mt-0.5 mx-2 hidden md:block" />
|
||||||
|
</a>
|
||||||
<Menubar.Root class="border-none h-fit p-0">
|
<Menubar.Root class="border-none h-fit p-0">
|
||||||
<Menubar.Menu>
|
<Menubar.Menu>
|
||||||
<Menubar.Trigger>
|
<Menubar.Trigger>
|
||||||
@@ -362,16 +362,11 @@
|
|||||||
{$_('menu.language')}
|
{$_('menu.language')}
|
||||||
</Menubar.SubTrigger>
|
</Menubar.SubTrigger>
|
||||||
<Menubar.SubContent>
|
<Menubar.SubContent>
|
||||||
<Menubar.RadioGroup
|
<Menubar.RadioGroup bind:value={$locale}>
|
||||||
bind:value={$locale}
|
|
||||||
onValueChange={(value) => {
|
|
||||||
if (value) {
|
|
||||||
goto(base + '/' + (value === 'en' ? '' : value));
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{#each Object.entries(languages) as [code, name]}
|
{#each Object.entries(languages) as [code, name]}
|
||||||
<Menubar.RadioItem value={code}>{name}</Menubar.RadioItem>
|
<a href={getURLForLanguage(code)}>
|
||||||
|
<Menubar.RadioItem value={code}>{name}</Menubar.RadioItem>
|
||||||
|
</a>
|
||||||
{/each}
|
{/each}
|
||||||
</Menubar.RadioGroup>
|
</Menubar.RadioGroup>
|
||||||
</Menubar.SubContent>
|
</Menubar.SubContent>
|
||||||
@@ -420,20 +415,20 @@
|
|||||||
<div class="h-fit flex flex-row items-center ml-1 gap-1">
|
<div class="h-fit flex flex-row items-center ml-1 gap-1">
|
||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
href="./about"
|
href="./documentation"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
class="cursor-default h-fit rounded-sm"
|
class="cursor-default h-fit rounded-sm px-3 py-0.5"
|
||||||
>
|
>
|
||||||
<Info size="18" class="md:hidden" />
|
<Info size="18" class="md:hidden" />
|
||||||
<span class="hidden md:block">
|
<span class="hidden md:block">
|
||||||
{$_('menu.about')}
|
{$_('menu.help')}
|
||||||
</span>
|
</span>
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
href="https://ko-fi.com/gpxstudio"
|
href="https://ko-fi.com/gpxstudio"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
class="cursor-default h-fit rounded-sm font-bold text-support hover:text-support"
|
class="cursor-default h-fit rounded-sm font-bold text-support hover:text-support px-3 py-0.5"
|
||||||
>
|
>
|
||||||
<HeartHandshake size="18" class="md:hidden" />
|
<HeartHandshake size="18" class="md:hidden" />
|
||||||
<span class="hidden md:flex flex-row items-center">
|
<span class="hidden md:flex flex-row items-center">
|
||||||
@@ -574,10 +569,4 @@
|
|||||||
@apply px-3;
|
@apply px-3;
|
||||||
@apply py-0.5;
|
@apply py-0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
div :global(a) {
|
|
||||||
@apply hover:bg-accent;
|
|
||||||
@apply px-3;
|
|
||||||
@apply py-0.5;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
import Logo from '$lib/components/Logo.svelte';
|
import Logo from '$lib/components/Logo.svelte';
|
||||||
import { Button } from '$lib/components/ui/button';
|
import { Button } from '$lib/components/ui/button';
|
||||||
import ModeSwitch from '$lib/components/ModeSwitch.svelte';
|
import ModeSwitch from '$lib/components/ModeSwitch.svelte';
|
||||||
import { BookOpenText, Info, Map } from 'lucide-svelte';
|
import { BookOpenText, Home, Map } from 'lucide-svelte';
|
||||||
import { _ } from 'svelte-i18n';
|
import { _ } from 'svelte-i18n';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -13,13 +13,13 @@
|
|||||||
<Logo class="h-7 hidden sm:block" />
|
<Logo class="h-7 hidden sm:block" />
|
||||||
</a>
|
</a>
|
||||||
<Button variant="link" class="text-base px-0" href="./">
|
<Button variant="link" class="text-base px-0" href="./">
|
||||||
|
<Home size="18" class="mr-1.5" />
|
||||||
|
{$_('homepage.home')}
|
||||||
|
</Button>
|
||||||
|
<Button variant="link" class="text-base px-0" href="./app">
|
||||||
<Map size="18" class="mr-1.5" />
|
<Map size="18" class="mr-1.5" />
|
||||||
{$_('homepage.app')}
|
{$_('homepage.app')}
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="link" class="text-base px-0" href="./about">
|
|
||||||
<Info size="18" class="mr-1.5" />
|
|
||||||
{$_('menu.about')}
|
|
||||||
</Button>
|
|
||||||
<Button variant="link" class="text-base px-0" href="./documentation">
|
<Button variant="link" class="text-base px-0" href="./documentation">
|
||||||
<BookOpenText size="18" class="mr-1.5" />
|
<BookOpenText size="18" class="mr-1.5" />
|
||||||
{$_('homepage.documentation')}
|
{$_('homepage.documentation')}
|
||||||
|
@@ -1,3 +1,18 @@
|
|||||||
export const languages: Record<string, string> = {
|
export const languages: Record<string, string> = {
|
||||||
'en': 'English',
|
'en': 'English',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export function getURLForLanguage(lang?: string): string {
|
||||||
|
let currentPath = window.location.pathname;
|
||||||
|
let currentPathArray = currentPath.split('/');
|
||||||
|
|
||||||
|
if (currentPathArray.length > 1 && languages.hasOwnProperty(currentPathArray[1])) {
|
||||||
|
currentPathArray.splice(1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lang !== undefined && lang !== 'en') {
|
||||||
|
currentPathArray.splice(1, 0, lang);
|
||||||
|
}
|
||||||
|
|
||||||
|
return currentPathArray.join('/');
|
||||||
|
}
|
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"app_title": "the online GPX file editor",
|
"app_title": "the online GPX file editor",
|
||||||
"about_title": "about",
|
"home_title": "home",
|
||||||
"description": "View, edit and create GPX files online with advanced route planning capabilities and file processing tools, beautiful maps and detailed data visualizations."
|
"description": "View, edit and create GPX files online with advanced route planning capabilities and file processing tools, beautiful maps and detailed data visualizations."
|
||||||
},
|
},
|
||||||
"menu": {
|
"menu": {
|
||||||
@@ -51,7 +51,7 @@
|
|||||||
"layers": "Map layers...",
|
"layers": "Map layers...",
|
||||||
"distance_markers": "Distance markers",
|
"distance_markers": "Distance markers",
|
||||||
"direction_markers": "Direction markers",
|
"direction_markers": "Direction markers",
|
||||||
"about": "About",
|
"help": "Help",
|
||||||
"donate": "Donate",
|
"donate": "Donate",
|
||||||
"ctrl": "Ctrl",
|
"ctrl": "Ctrl",
|
||||||
"click": "Click",
|
"click": "Click",
|
||||||
@@ -346,6 +346,7 @@
|
|||||||
},
|
},
|
||||||
"homepage": {
|
"homepage": {
|
||||||
"website": "Website",
|
"website": "Website",
|
||||||
|
"home": "Home",
|
||||||
"app": "App",
|
"app": "App",
|
||||||
"documentation": "Documentation",
|
"documentation": "Documentation",
|
||||||
"contact": "Contact",
|
"contact": "Contact",
|
||||||
|
@@ -11,7 +11,7 @@
|
|||||||
locale.set($page.params.language);
|
locale.set($page.params.language);
|
||||||
}
|
}
|
||||||
|
|
||||||
const appRoute = '/[...language]';
|
const appRoute = '/[...language]/app';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<ModeWatcher />
|
<ModeWatcher />
|
||||||
|
@@ -1,16 +1,50 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import App from '$lib/components/App.svelte';
|
|
||||||
import { base } from '$app/paths';
|
import { base } from '$app/paths';
|
||||||
|
import { Button } from '$lib/components/ui/button';
|
||||||
|
import DocsLoader from '$lib/components/docs/DocsLoader.svelte';
|
||||||
|
import Logo from '$lib/components/Logo.svelte';
|
||||||
|
import ElevationProfile from '$lib/components/ElevationProfile.svelte';
|
||||||
|
import GPXStatistics from '$lib/components/GPXStatistics.svelte';
|
||||||
|
import Routing from '$lib/components/toolbar/tools/routing/Routing.svelte';
|
||||||
import { languages } from '$lib/languages';
|
import { languages } from '$lib/languages';
|
||||||
|
import { settings } from '$lib/db';
|
||||||
|
import { BookOpenText, Heart, Map } from 'lucide-svelte';
|
||||||
import { _ } from 'svelte-i18n';
|
import { _ } from 'svelte-i18n';
|
||||||
|
import { exampleGPXFile } from '$lib/assets/example';
|
||||||
|
import { writable } from 'svelte/store';
|
||||||
|
import Toolbar from '$lib/components/toolbar/Toolbar.svelte';
|
||||||
|
import { currentTool, Tool } from '$lib/stores';
|
||||||
|
import { onDestroy, onMount } from 'svelte';
|
||||||
|
import routingScreenshot from '$lib/assets/img/routing.png?enhanced';
|
||||||
|
import mapboxOutdoorsMap from '$lib/assets/img/mapbox-outdoors.png?enhanced';
|
||||||
|
import mapboxSatelliteMap from '$lib/assets/img/mapbox-satellite.png?enhanced';
|
||||||
|
import ignMap from '$lib/assets/img/ign.png?enhanced';
|
||||||
|
import cyclosmMap from '$lib/assets/img/cyclosm.png?enhanced';
|
||||||
|
import waymarkedMap from '$lib/assets/img/waymarked.png?enhanced';
|
||||||
|
import mapScreenshot from '$lib/assets/img/map.png?enhanced';
|
||||||
|
|
||||||
|
let gpxStatistics = writable(exampleGPXFile.getStatistics());
|
||||||
|
let slicedGPXStatistics = writable(undefined);
|
||||||
|
let additionalDatasets = writable(['speed', 'atemp']);
|
||||||
|
let elevationFill = writable<'slope' | 'surface' | undefined>(undefined);
|
||||||
|
|
||||||
|
const { distanceUnits, velocityUnits, temperatureUnits } = settings;
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
currentTool.set(Tool.SCISSORS);
|
||||||
|
});
|
||||||
|
|
||||||
|
onDestroy(() => {
|
||||||
|
currentTool.set(null);
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
<title>gpx.studio — {$_('metadata.app_title')}</title>
|
<title>gpx.studio — {$_('metadata.home_title')}</title>
|
||||||
<meta name="description" content={$_('metadata.description')} />
|
<meta name="description" content={$_('metadata.description')} />
|
||||||
<meta property="og:title" content="gpx.studio — {$_('metadata.app_title')}" />
|
<meta property="og:title" content="gpx.studio — {$_('metadata.home_title')}" />
|
||||||
<meta property="og:description" content={$_('metadata.description')} />
|
<meta property="og:description" content={$_('metadata.description')} />
|
||||||
<meta name="twitter:title" content="gpx.studio — {$_('metadata.app_title')}" />
|
<meta name="twitter:title" content="gpx.studio — {$_('metadata.home_title')}" />
|
||||||
<meta name="twitter:description" content={$_('metadata.description')} />
|
<meta name="twitter:description" content={$_('metadata.description')} />
|
||||||
|
|
||||||
<link rel="alternate" hreflang="x-default" href="{base}/" />
|
<link rel="alternate" hreflang="x-default" href="{base}/" />
|
||||||
@@ -23,4 +57,168 @@
|
|||||||
{/each}
|
{/each}
|
||||||
</svelte:head>
|
</svelte:head>
|
||||||
|
|
||||||
<App />
|
<div class="space-y-24 my-24">
|
||||||
|
<div class="px-12 w-full flex flex-col items-center">
|
||||||
|
<div class="flex flex-col gap-6 items-center max-w-3xl">
|
||||||
|
<div class="text-6xl font-black text-center">{$_('metadata.app_title')}</div>
|
||||||
|
<div class="text-xl text-muted-foreground text-center">
|
||||||
|
{$_('metadata.description')}
|
||||||
|
</div>
|
||||||
|
<div class="w-full flex flex-row justify-center gap-3">
|
||||||
|
<Button href="./app" class="w-1/3 min-w-fit">
|
||||||
|
<Map size="18" class="mr-1.5" />
|
||||||
|
{$_('homepage.app')}
|
||||||
|
</Button>
|
||||||
|
<Button variant="secondary" href="./documentation" class="w-1/3 min-w-fit">
|
||||||
|
<BookOpenText size="18" class="mr-1.5" />
|
||||||
|
<span>{$_('homepage.documentation')}</span>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="relative">
|
||||||
|
<enhanced:img
|
||||||
|
src={routingScreenshot}
|
||||||
|
alt="Screenshot of the gpx.studio map in 3D."
|
||||||
|
class="w-full"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
class="absolute top-0 left-0 w-full h-full bg-gradient-to-b from-background via-transparent to-background"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="px-24 w-full flex flex-col items-center">
|
||||||
|
<div class="flex flex-col md:flex-row gap-x-12 gap-y-6 items-center justify-between max-w-5xl">
|
||||||
|
<div class="markdown text-center">
|
||||||
|
<h1>{$_('homepage.route_planning')}</h1>
|
||||||
|
<p class="text-muted-foreground">{$_('homepage.route_planning_description')}</p>
|
||||||
|
</div>
|
||||||
|
<div class="p-3 w-fit rounded-md border shadow-xl">
|
||||||
|
<Routing minimizable={false} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="px-24 w-full flex flex-col items-center">
|
||||||
|
<div class="flex flex-col md:flex-row gap-x-12 gap-y-6 items-center justify-between max-w-5xl">
|
||||||
|
<div class="markdown text-center md:hidden">
|
||||||
|
<h1>{$_('homepage.file_processing')}</h1>
|
||||||
|
<p class="text-muted-foreground">{$_('homepage.file_processing_description')}</p>
|
||||||
|
</div>
|
||||||
|
<div class="relative">
|
||||||
|
<Toolbar />
|
||||||
|
</div>
|
||||||
|
<div class="markdown text-center hidden md:block">
|
||||||
|
<h1>{$_('homepage.file_processing')}</h1>
|
||||||
|
<p class="text-muted-foreground">{$_('homepage.file_processing_description')}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="px-24 w-full flex flex-col items-center">
|
||||||
|
<div
|
||||||
|
class="markdown flex flex-col md:flex-row gap-x-12 gap-y-6 items-center justify-between max-w-5xl"
|
||||||
|
>
|
||||||
|
<div class="markdown text-center">
|
||||||
|
<h1>{$_('homepage.maps')}</h1>
|
||||||
|
<p class="text-muted-foreground">{$_('homepage.maps_description')}</p>
|
||||||
|
</div>
|
||||||
|
<div class="relative h-80 aspect-square rounded-2xl shadow-xl overflow-clip">
|
||||||
|
<enhanced:img
|
||||||
|
src={mapboxOutdoorsMap}
|
||||||
|
alt="Mapbox Outdoors map screenshot."
|
||||||
|
class="absolute"
|
||||||
|
style="clip-path: inset(0 50% 50% 0);"
|
||||||
|
/>
|
||||||
|
<enhanced:img
|
||||||
|
src={mapboxSatelliteMap}
|
||||||
|
alt="Mapbox Satellite map screenshot."
|
||||||
|
class="absolute"
|
||||||
|
style="clip-path: inset(0 0 50% 50%);"
|
||||||
|
/>
|
||||||
|
<enhanced:img
|
||||||
|
src={ignMap}
|
||||||
|
alt="IGN map screenshot."
|
||||||
|
class="absolute"
|
||||||
|
style="clip-path: inset(50% 50% 0 0);"
|
||||||
|
/>
|
||||||
|
<enhanced:img
|
||||||
|
src={cyclosmMap}
|
||||||
|
alt="CyclOSM map screenshot."
|
||||||
|
class="absolute"
|
||||||
|
style="clip-path: inset(50% 0 0 50%);"
|
||||||
|
/>
|
||||||
|
<enhanced:img src={waymarkedMap} alt="Waymarked Trails map screenshot." class="absolute" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="px-6 md:px-12">
|
||||||
|
<div class="markdown text-center">
|
||||||
|
<h1>{$_('homepage.data_visualization')}</h1>
|
||||||
|
<p class="text-muted-foreground">{$_('homepage.data_visualization_description')}</p>
|
||||||
|
</div>
|
||||||
|
<div class="h-48 w-full">
|
||||||
|
<ElevationProfile
|
||||||
|
{gpxStatistics}
|
||||||
|
{slicedGPXStatistics}
|
||||||
|
additionalDatasets={$additionalDatasets}
|
||||||
|
elevationFill={$elevationFill}
|
||||||
|
panelSize={200}
|
||||||
|
distanceUnits={$distanceUnits}
|
||||||
|
velocityUnits={$velocityUnits}
|
||||||
|
temperatureUnits={$temperatureUnits}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-col items-center">
|
||||||
|
<div class="h-10 w-fit">
|
||||||
|
<GPXStatistics
|
||||||
|
{gpxStatistics}
|
||||||
|
{slicedGPXStatistics}
|
||||||
|
panelSize={192}
|
||||||
|
orientation={'horizontal'}
|
||||||
|
velocityUnits={$velocityUnits}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="relative">
|
||||||
|
<enhanced:img
|
||||||
|
src={mapScreenshot}
|
||||||
|
alt="Screenshot of the gpx.studio map in 3D."
|
||||||
|
class="w-full"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
class="absolute top-0 left-0 w-full h-full bg-gradient-to-b from-background via-transparent to-background"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="px-12 flex flex-col items-center">
|
||||||
|
<div class="max-w-5xl flex flex-col items-center gap-6">
|
||||||
|
<DocsLoader path="about/funding.md" />
|
||||||
|
<Button
|
||||||
|
href="https://ko-fi.com/gpxstudio"
|
||||||
|
target="_blank"
|
||||||
|
class="w-1/3 min-w-fit bg-support text-base"
|
||||||
|
>
|
||||||
|
<Heart size="16" class="mr-1" fill="rgb(var(--support))" />
|
||||||
|
<span>{$_('homepage.support_button')}</span>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="px-12 flex flex-col items-center">
|
||||||
|
<div class="max-w-5xl">
|
||||||
|
<DocsLoader path="about/translation.md" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="px-12 md:px-24 flex flex-col items-center">
|
||||||
|
<div
|
||||||
|
class="max-w-4xl flex flex-col md:flex-row items-center justify-center gap-x-12 gap-y-6 p-6 border rounded-2xl shadow-xl"
|
||||||
|
>
|
||||||
|
<div class="shrink-0 flex flex-col sm:flex-row md:flex-col items-center gap-x-4 gap-y-2">
|
||||||
|
<div class="text-lg font-semibold text-muted-foreground">
|
||||||
|
❤️ {$_('homepage.supported_by')}
|
||||||
|
</div>
|
||||||
|
<a href="https://www.mapbox.com/" target="_blank">
|
||||||
|
<Logo company="mapbox" class="w-60" />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<DocsLoader path="about/mapbox.md" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@@ -1,224 +0,0 @@
|
|||||||
<script lang="ts">
|
|
||||||
import { base } from '$app/paths';
|
|
||||||
import { Button } from '$lib/components/ui/button';
|
|
||||||
import DocsLoader from '$lib/components/docs/DocsLoader.svelte';
|
|
||||||
import Logo from '$lib/components/Logo.svelte';
|
|
||||||
import ElevationProfile from '$lib/components/ElevationProfile.svelte';
|
|
||||||
import GPXStatistics from '$lib/components/GPXStatistics.svelte';
|
|
||||||
import Routing from '$lib/components/toolbar/tools/routing/Routing.svelte';
|
|
||||||
import { languages } from '$lib/languages';
|
|
||||||
import { settings } from '$lib/db';
|
|
||||||
import { BookOpenText, Heart, Map } from 'lucide-svelte';
|
|
||||||
import { _ } from 'svelte-i18n';
|
|
||||||
import { exampleGPXFile } from '$lib/assets/example';
|
|
||||||
import { writable } from 'svelte/store';
|
|
||||||
import Toolbar from '$lib/components/toolbar/Toolbar.svelte';
|
|
||||||
import { currentTool, Tool } from '$lib/stores';
|
|
||||||
import { onDestroy, onMount } from 'svelte';
|
|
||||||
import routingScreenshot from '$lib/assets/img/routing.png?enhanced';
|
|
||||||
import mapboxOutdoorsMap from '$lib/assets/img/mapbox-outdoors.png?enhanced';
|
|
||||||
import mapboxSatelliteMap from '$lib/assets/img/mapbox-satellite.png?enhanced';
|
|
||||||
import ignMap from '$lib/assets/img/ign.png?enhanced';
|
|
||||||
import cyclosmMap from '$lib/assets/img/cyclosm.png?enhanced';
|
|
||||||
import waymarkedMap from '$lib/assets/img/waymarked.png?enhanced';
|
|
||||||
import mapScreenshot from '$lib/assets/img/map.png?enhanced';
|
|
||||||
|
|
||||||
let gpxStatistics = writable(exampleGPXFile.getStatistics());
|
|
||||||
let slicedGPXStatistics = writable(undefined);
|
|
||||||
let additionalDatasets = writable(['speed', 'atemp']);
|
|
||||||
let elevationFill = writable<'slope' | 'surface' | undefined>(undefined);
|
|
||||||
|
|
||||||
const { distanceUnits, velocityUnits, temperatureUnits } = settings;
|
|
||||||
|
|
||||||
onMount(() => {
|
|
||||||
currentTool.set(Tool.SCISSORS);
|
|
||||||
});
|
|
||||||
|
|
||||||
onDestroy(() => {
|
|
||||||
currentTool.set(null);
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<svelte:head>
|
|
||||||
<title>gpx.studio — {$_('metadata.about_title')}</title>
|
|
||||||
<meta name="description" content={$_('metadata.description')} />
|
|
||||||
<meta property="og:title" content="gpx.studio — {$_('metadata.about_title')}" />
|
|
||||||
<meta property="og:description" content={$_('metadata.description')} />
|
|
||||||
<meta name="twitter:title" content="gpx.studio — {$_('metadata.about_title')}" />
|
|
||||||
<meta name="twitter:description" content={$_('metadata.description')} />
|
|
||||||
|
|
||||||
<link rel="alternate" hreflang="x-default" href="{base}/" />
|
|
||||||
{#each Object.keys(languages) as lang}
|
|
||||||
{#if lang === 'en'}
|
|
||||||
<link rel="alternate" hreflang="en" href="{base}/" />
|
|
||||||
{:else}
|
|
||||||
<link rel="alternate" hreflang={lang} href="{base}/{lang}/" />
|
|
||||||
{/if}
|
|
||||||
{/each}
|
|
||||||
</svelte:head>
|
|
||||||
|
|
||||||
<div class="space-y-24 my-24">
|
|
||||||
<div class="px-12 w-full flex flex-col items-center">
|
|
||||||
<div class="flex flex-col gap-6 items-center max-w-3xl">
|
|
||||||
<div class="text-6xl font-black text-center">{$_('metadata.app_title')}</div>
|
|
||||||
<div class="text-xl text-muted-foreground text-center">
|
|
||||||
{$_('metadata.description')}
|
|
||||||
</div>
|
|
||||||
<div class="w-full flex flex-row justify-center gap-3">
|
|
||||||
<Button href="./" class="w-1/3 min-w-fit">
|
|
||||||
<Map size="18" class="mr-1.5" />
|
|
||||||
{$_('homepage.app')}
|
|
||||||
</Button>
|
|
||||||
<Button variant="secondary" href="./documentation" class="w-1/3 min-w-fit">
|
|
||||||
<BookOpenText size="18" class="mr-1.5" />
|
|
||||||
<span>{$_('homepage.documentation')}</span>
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="relative">
|
|
||||||
<enhanced:img
|
|
||||||
src={routingScreenshot}
|
|
||||||
alt="Screenshot of the gpx.studio map in 3D."
|
|
||||||
class="w-full"
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
class="absolute top-0 left-0 w-full h-full bg-gradient-to-b from-background via-transparent to-background"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="px-24 w-full flex flex-col items-center">
|
|
||||||
<div class="flex flex-col md:flex-row gap-x-12 gap-y-6 items-center justify-between max-w-5xl">
|
|
||||||
<div class="markdown text-center">
|
|
||||||
<h1>{$_('homepage.route_planning')}</h1>
|
|
||||||
<p class="text-muted-foreground">{$_('homepage.route_planning_description')}</p>
|
|
||||||
</div>
|
|
||||||
<div class="p-3 w-fit rounded-md border shadow-xl">
|
|
||||||
<Routing minimizable={false} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="px-24 w-full flex flex-col items-center">
|
|
||||||
<div class="flex flex-col md:flex-row gap-x-12 gap-y-6 items-center justify-between max-w-5xl">
|
|
||||||
<div class="markdown text-center md:hidden">
|
|
||||||
<h1>{$_('homepage.file_processing')}</h1>
|
|
||||||
<p class="text-muted-foreground">{$_('homepage.file_processing_description')}</p>
|
|
||||||
</div>
|
|
||||||
<div class="relative">
|
|
||||||
<Toolbar />
|
|
||||||
</div>
|
|
||||||
<div class="markdown text-center hidden md:block">
|
|
||||||
<h1>{$_('homepage.file_processing')}</h1>
|
|
||||||
<p class="text-muted-foreground">{$_('homepage.file_processing_description')}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="px-24 w-full flex flex-col items-center">
|
|
||||||
<div
|
|
||||||
class="markdown flex flex-col md:flex-row gap-x-12 gap-y-6 items-center justify-between max-w-5xl"
|
|
||||||
>
|
|
||||||
<div class="markdown text-center">
|
|
||||||
<h1>{$_('homepage.maps')}</h1>
|
|
||||||
<p class="text-muted-foreground">{$_('homepage.maps_description')}</p>
|
|
||||||
</div>
|
|
||||||
<div class="relative h-80 aspect-square rounded-2xl shadow-xl overflow-clip">
|
|
||||||
<enhanced:img
|
|
||||||
src={mapboxOutdoorsMap}
|
|
||||||
alt="Mapbox Outdoors map screenshot."
|
|
||||||
class="absolute"
|
|
||||||
style="clip-path: inset(0 50% 50% 0);"
|
|
||||||
/>
|
|
||||||
<enhanced:img
|
|
||||||
src={mapboxSatelliteMap}
|
|
||||||
alt="Mapbox Satellite map screenshot."
|
|
||||||
class="absolute"
|
|
||||||
style="clip-path: inset(0 0 50% 50%);"
|
|
||||||
/>
|
|
||||||
<enhanced:img
|
|
||||||
src={ignMap}
|
|
||||||
alt="IGN map screenshot."
|
|
||||||
class="absolute"
|
|
||||||
style="clip-path: inset(50% 50% 0 0);"
|
|
||||||
/>
|
|
||||||
<enhanced:img
|
|
||||||
src={cyclosmMap}
|
|
||||||
alt="CyclOSM map screenshot."
|
|
||||||
class="absolute"
|
|
||||||
style="clip-path: inset(50% 0 0 50%);"
|
|
||||||
/>
|
|
||||||
<enhanced:img src={waymarkedMap} alt="Waymarked Trails map screenshot." class="absolute" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="px-6 md:px-12">
|
|
||||||
<div class="markdown text-center">
|
|
||||||
<h1>{$_('homepage.data_visualization')}</h1>
|
|
||||||
<p class="text-muted-foreground">{$_('homepage.data_visualization_description')}</p>
|
|
||||||
</div>
|
|
||||||
<div class="h-48 w-full">
|
|
||||||
<ElevationProfile
|
|
||||||
{gpxStatistics}
|
|
||||||
{slicedGPXStatistics}
|
|
||||||
additionalDatasets={$additionalDatasets}
|
|
||||||
elevationFill={$elevationFill}
|
|
||||||
panelSize={200}
|
|
||||||
distanceUnits={$distanceUnits}
|
|
||||||
velocityUnits={$velocityUnits}
|
|
||||||
temperatureUnits={$temperatureUnits}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="flex flex-col items-center">
|
|
||||||
<div class="h-10 w-fit">
|
|
||||||
<GPXStatistics
|
|
||||||
{gpxStatistics}
|
|
||||||
{slicedGPXStatistics}
|
|
||||||
panelSize={192}
|
|
||||||
orientation={'horizontal'}
|
|
||||||
velocityUnits={$velocityUnits}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="relative">
|
|
||||||
<enhanced:img
|
|
||||||
src={mapScreenshot}
|
|
||||||
alt="Screenshot of the gpx.studio map in 3D."
|
|
||||||
class="w-full"
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
class="absolute top-0 left-0 w-full h-full bg-gradient-to-b from-background via-transparent to-background"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div class="px-12 flex flex-col items-center">
|
|
||||||
<div class="max-w-5xl flex flex-col items-center gap-6">
|
|
||||||
<DocsLoader path="about/funding.md" />
|
|
||||||
<Button
|
|
||||||
href="https://ko-fi.com/gpxstudio"
|
|
||||||
target="_blank"
|
|
||||||
class="w-1/3 min-w-fit bg-support text-base"
|
|
||||||
>
|
|
||||||
<Heart size="16" class="mr-1" fill="rgb(var(--support))" />
|
|
||||||
<span>{$_('homepage.support_button')}</span>
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="px-12 flex flex-col items-center">
|
|
||||||
<div class="max-w-5xl">
|
|
||||||
<DocsLoader path="about/translation.md" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="px-12 md:px-24 flex flex-col items-center">
|
|
||||||
<div
|
|
||||||
class="max-w-4xl flex flex-col md:flex-row items-center justify-center gap-x-12 gap-y-6 p-6 border rounded-2xl shadow-xl"
|
|
||||||
>
|
|
||||||
<div class="shrink-0 flex flex-col sm:flex-row md:flex-col items-center gap-x-4 gap-y-2">
|
|
||||||
<div class="text-lg font-semibold text-muted-foreground">
|
|
||||||
❤️ {$_('homepage.supported_by')}
|
|
||||||
</div>
|
|
||||||
<a href="https://www.mapbox.com/" target="_blank">
|
|
||||||
<Logo company="mapbox" class="w-60" />
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<DocsLoader path="about/mapbox.md" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
26
website/src/routes/[...language]/app/+page.svelte
Normal file
26
website/src/routes/[...language]/app/+page.svelte
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import App from '$lib/components/App.svelte';
|
||||||
|
import { base } from '$app/paths';
|
||||||
|
import { languages } from '$lib/languages';
|
||||||
|
import { _ } from 'svelte-i18n';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svelte:head>
|
||||||
|
<title>gpx.studio — {$_('metadata.app_title')}</title>
|
||||||
|
<meta name="description" content={$_('metadata.description')} />
|
||||||
|
<meta property="og:title" content="gpx.studio — {$_('metadata.app_title')}" />
|
||||||
|
<meta property="og:description" content={$_('metadata.description')} />
|
||||||
|
<meta name="twitter:title" content="gpx.studio — {$_('metadata.app_title')}" />
|
||||||
|
<meta name="twitter:description" content={$_('metadata.description')} />
|
||||||
|
|
||||||
|
<link rel="alternate" hreflang="x-default" href="{base}/" />
|
||||||
|
{#each Object.keys(languages) as lang}
|
||||||
|
{#if lang === 'en'}
|
||||||
|
<link rel="alternate" hreflang="en" href="{base}/" />
|
||||||
|
{:else}
|
||||||
|
<link rel="alternate" hreflang={lang} href="{base}/{lang}/" />
|
||||||
|
{/if}
|
||||||
|
{/each}
|
||||||
|
</svelte:head>
|
||||||
|
|
||||||
|
<App />
|
Reference in New Issue
Block a user