adds server list to docs

This commit is contained in:
Christian Beutel
2025-06-27 17:33:45 +02:00
parent d9c3cbe605
commit 67aa566888
14 changed files with 656 additions and 124 deletions

View File

@@ -6,125 +6,126 @@ import node from "@astrojs/node";
import starlightOpenAPI, { openAPISidebarGroups } from 'starlight-openapi' import starlightOpenAPI, { openAPISidebarGroups } from 'starlight-openapi'
import tailwindcss from "@tailwindcss/vite"; import tailwindcss from "@tailwindcss/vite";
import svelte from '@astrojs/svelte';
// https://astro.build/config // https://astro.build/config
export default defineConfig({ export default defineConfig({
integrations: [ integrations: [starlight({
starlight({ title: 'wanderer Documentation',
title: 'wanderer Documentation', logo: {
logo: { light: '/src/assets/logo_text_dark.svg',
light: '/src/assets/logo_text_dark.svg', dark: '/src/assets/logo_text_light.svg',
dark: '/src/assets/logo_text_light.svg', replacesTitle: true
replacesTitle: true },
}, social: [
social: [ { icon: 'github', label: 'GitHub', href: 'https://github.com/flomp/wanderer' },
{ icon: 'github', label: 'GitHub', href: 'https://github.com/flomp/wanderer' }, ],
], components: {
components: { Footer: './src/components/footer.astro'
Footer: './src/components/footer.astro' },
}, plugins: [
plugins: [ starlightOpenAPI([
starlightOpenAPI([
{
base: 'api-reference',
label: 'API Reference',
schema: 'wanderer.openapi.yaml',
},
]),
],
sidebar: [
{ {
label: 'Welcome to wanderer', base: 'api-reference',
link: '/welcome' label: 'API Reference',
schema: 'wanderer.openapi.yaml',
}, },
{ ]),
label: 'Using wanderer', ],
items: [{ sidebar: [
label: 'Authentication', {
link: '/use/authentication/' label: 'Welcome to wanderer',
}, { link: '/welcome'
label: 'Create a trail', },
link: '/use/create-a-trail/' {
}, label: 'Using wanderer',
{ items: [{
label: 'Summit logs', label: 'Authentication',
link: '/use/summit-logs/' link: '/use/authentication/'
},
{
label: 'Interact with the community',
link: '/use/community-interaction/'
},
{
label: 'Share trails',
link: '/use/share-trails/'
}, {
label: 'Lists',
link: '/use/lists/'
},
{
label: 'Statistics',
link: '/use/statistics/'
},
{
label: 'Customize the map',
link: '/use/customize-map/'
},
{
label: 'Import/Export',
link: '/use/import-export/'
},
{
label: 'Integrations',
link: '/use/integrations/'
},
]
},
{
label: 'Running wanderer',
items: [
{
label: 'Installation',
link: '/run/installation/'
},
{
label: 'Environment configuration',
link: '/run/environment-configuration/'
},
{
label: 'Backend configuration',
link: '/run/backend-configuration/'
},
{
label: 'Custom categories',
link: '/run/custom-categories/'
},
{
label: 'Backing up your server',
link: '/run/backup-server/'
},
{
label: 'Changelog',
link: '/run/changelog/'
}]
}, { }, {
label: 'Develop wanderer', label: 'Create a trail',
items: [ link: '/use/create-a-trail/'
{
label: 'Local development',
link: '/develop/local-development/'
},
{
label: 'API',
link: '/develop/api/'
},
{
label: 'Federation',
link: '/develop/federation/'
},
]
}, },
...openAPISidebarGroups,], {
customCss: ['./src/custom.css', './src/tailwind.css', '@fontsource/ibm-plex-sans/400.css', '@fontsource/ibm-plex-sans/600.css', '@fontsource/ibm-plex-mono/400.css', '@fontsource/ibm-plex-mono/600.css'] label: 'Summit logs',
})], link: '/use/summit-logs/'
},
{
label: 'Interact with the community',
link: '/use/community-interaction/'
},
{
label: 'Share trails',
link: '/use/share-trails/'
}, {
label: 'Lists',
link: '/use/lists/'
},
{
label: 'Statistics',
link: '/use/statistics/'
},
{
label: 'Customize the map',
link: '/use/customize-map/'
},
{
label: 'Import/Export',
link: '/use/import-export/'
},
{
label: 'Integrations',
link: '/use/integrations/'
},
]
},
{
label: 'Running wanderer',
items: [
{
label: 'Installation',
link: '/run/installation/'
},
{
label: 'Environment configuration',
link: '/run/environment-configuration/'
},
{
label: 'Backend configuration',
link: '/run/backend-configuration/'
},
{
label: 'Custom categories',
link: '/run/custom-categories/'
},
{
label: 'Backing up your server',
link: '/run/backup-server/'
},
{
label: 'Changelog',
link: '/run/changelog/'
}]
}, {
label: 'Develop wanderer',
items: [
{
label: 'Local development',
link: '/develop/local-development/'
},
{
label: 'API',
link: '/develop/api/'
},
{
label: 'Federation',
link: '/develop/federation/'
},
]
},
...openAPISidebarGroups,],
customCss: ['./src/custom.css', './src/tailwind.css', '@fontsource/ibm-plex-sans/400.css', '@fontsource/ibm-plex-sans/600.css', '@fontsource/ibm-plex-mono/400.css', '@fontsource/ibm-plex-mono/600.css']
}), svelte()],
output: "server", output: "server",
vite: { plugins: [tailwindcss()] }, vite: { plugins: [tailwindcss()] },
adapter: node({ adapter: node({

191
docs/package-lock.json generated
View File

@@ -6,20 +6,22 @@
"packages": { "packages": {
"": { "": {
"name": "docs", "name": "docs",
"version": "0.16.4", "version": "0.17.0",
"dependencies": { "dependencies": {
"@astrojs/check": "^0.9.4", "@astrojs/check": "^0.9.4",
"@astrojs/node": "^9.2.2", "@astrojs/node": "^9.2.2",
"@astrojs/starlight": "^0.34.4", "@astrojs/starlight": "^0.34.4",
"@astrojs/starlight-tailwind": "^4.0.1", "@astrojs/starlight-tailwind": "^4.0.1",
"@astrojs/svelte": "^7.1.0",
"@fontsource/ibm-plex-mono": "^5.0.13", "@fontsource/ibm-plex-mono": "^5.0.13",
"@fontsource/ibm-plex-sans": "^5.0.20", "@fontsource/ibm-plex-sans": "^5.0.20",
"@tailwindcss/vite": "^4.1.10", "@tailwindcss/vite": "^4.1.10",
"astro": "^5.9.3", "astro": "^5.9.3",
"sharp": "^0.32.5", "sharp": "^0.32.5",
"starlight-openapi": "^0.9.0", "starlight-openapi": "^0.9.0",
"svelte": "^5.34.8",
"tailwindcss": "^4.1.10", "tailwindcss": "^4.1.10",
"typescript": "^5.4.5" "typescript": "^5.8.3"
} }
}, },
"node_modules/@ampproject/remapping": { "node_modules/@ampproject/remapping": {
@@ -253,6 +255,25 @@
"tailwindcss": "^4.0.0" "tailwindcss": "^4.0.0"
} }
}, },
"node_modules/@astrojs/svelte": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/@astrojs/svelte/-/svelte-7.1.0.tgz",
"integrity": "sha512-nNAO7iFgCZXCN31N4xBSS/k7vZAZxeZ/v8V6VWZOKG47gVlxeAJBHzn2GlXMMVkxIamr6dhrkDrhYFKIPzoGpw==",
"license": "MIT",
"dependencies": {
"@sveltejs/vite-plugin-svelte": "^5.0.3",
"svelte2tsx": "^0.7.39",
"vite": "^6.3.5"
},
"engines": {
"node": "18.20.8 || ^20.3.0 || >=22.0.0"
},
"peerDependencies": {
"astro": "^5.0.0",
"svelte": "^5.1.16",
"typescript": "^5.3.3"
}
},
"node_modules/@astrojs/telemetry": { "node_modules/@astrojs/telemetry": {
"version": "3.3.0", "version": "3.3.0",
"resolved": "https://registry.npmjs.org/@astrojs/telemetry/-/telemetry-3.3.0.tgz", "resolved": "https://registry.npmjs.org/@astrojs/telemetry/-/telemetry-3.3.0.tgz",
@@ -1903,6 +1924,53 @@
"integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==", "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/@sveltejs/acorn-typescript": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/@sveltejs/acorn-typescript/-/acorn-typescript-1.0.5.tgz",
"integrity": "sha512-IwQk4yfwLdibDlrXVE04jTZYlLnwsTT2PIOQQGNLWfjavGifnk1JD1LcZjZaBTRcxZu2FfPfNLOE04DSu9lqtQ==",
"license": "MIT",
"peerDependencies": {
"acorn": "^8.9.0"
}
},
"node_modules/@sveltejs/vite-plugin-svelte": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-5.1.0.tgz",
"integrity": "sha512-wojIS/7GYnJDYIg1higWj2ROA6sSRWvcR1PO/bqEyFr/5UZah26c8Cz4u0NaqjPeVltzsVpt2Tm8d2io0V+4Tw==",
"license": "MIT",
"dependencies": {
"@sveltejs/vite-plugin-svelte-inspector": "^4.0.1",
"debug": "^4.4.1",
"deepmerge": "^4.3.1",
"kleur": "^4.1.5",
"magic-string": "^0.30.17",
"vitefu": "^1.0.6"
},
"engines": {
"node": "^18.0.0 || ^20.0.0 || >=22"
},
"peerDependencies": {
"svelte": "^5.0.0",
"vite": "^6.0.0"
}
},
"node_modules/@sveltejs/vite-plugin-svelte-inspector": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-4.0.1.tgz",
"integrity": "sha512-J/Nmb2Q2y7mck2hyCX4ckVHcR5tu2J+MtBEQqpDrrgELZ2uvraQcK/ioCV61AqkdXFgriksOKIceDcQmqnGhVw==",
"license": "MIT",
"dependencies": {
"debug": "^4.3.7"
},
"engines": {
"node": "^18.0.0 || ^20.0.0 || >=22"
},
"peerDependencies": {
"@sveltejs/vite-plugin-svelte": "^5.0.0",
"svelte": "^5.0.0",
"vite": "^6.0.0"
}
},
"node_modules/@swc/helpers": { "node_modules/@swc/helpers": {
"version": "0.5.17", "version": "0.5.17",
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.17.tgz", "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.17.tgz",
@@ -3375,6 +3443,12 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/dedent-js": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dedent-js/-/dedent-js-1.0.1.tgz",
"integrity": "sha512-OUepMozQULMLUmhxS95Vudo0jb0UchLimi3+pQ2plj61Fcy8axbP9hbiD4Sz6DPqn6XG3kfmziVfQ1rSys5AJQ==",
"license": "MIT"
},
"node_modules/deep-extend": { "node_modules/deep-extend": {
"version": "0.6.0", "version": "0.6.0",
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
@@ -3384,6 +3458,15 @@
"node": ">=4.0.0" "node": ">=4.0.0"
} }
}, },
"node_modules/deepmerge": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
"integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/defu": { "node_modules/defu": {
"version": "6.1.4", "version": "6.1.4",
"resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz", "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz",
@@ -3673,6 +3756,21 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/esm-env": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.2.2.tgz",
"integrity": "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==",
"license": "MIT"
},
"node_modules/esrap": {
"version": "1.4.9",
"resolved": "https://registry.npmjs.org/esrap/-/esrap-1.4.9.tgz",
"integrity": "sha512-3OMlcd0a03UGuZpPeUC1HxR3nA23l+HEyCiZw3b3FumJIN9KphoGzDJKMXI1S72jVS1dsenDyQC0kJlO1U9E1g==",
"license": "MIT",
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.4.15"
}
},
"node_modules/estree-util-attach-comments": { "node_modules/estree-util-attach-comments": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/estree-util-attach-comments/-/estree-util-attach-comments-3.0.0.tgz", "resolved": "https://registry.npmjs.org/estree-util-attach-comments/-/estree-util-attach-comments-3.0.0.tgz",
@@ -4664,6 +4762,15 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/is-reference": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.3.tgz",
"integrity": "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==",
"license": "MIT",
"dependencies": {
"@types/estree": "^1.0.6"
}
},
"node_modules/is-wsl": { "node_modules/is-wsl": {
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz",
@@ -4982,6 +5089,12 @@
"url": "https://opencollective.com/parcel" "url": "https://opencollective.com/parcel"
} }
}, },
"node_modules/locate-character": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz",
"integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==",
"license": "MIT"
},
"node_modules/lodash": { "node_modules/lodash": {
"version": "4.17.21", "version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
@@ -4998,6 +5111,15 @@
"url": "https://github.com/sponsors/wooorm" "url": "https://github.com/sponsors/wooorm"
} }
}, },
"node_modules/lower-case": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz",
"integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==",
"license": "MIT",
"dependencies": {
"tslib": "^2.0.3"
}
},
"node_modules/lru-cache": { "node_modules/lru-cache": {
"version": "10.4.3", "version": "10.4.3",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
@@ -6296,6 +6418,16 @@
"url": "https://opencollective.com/unified" "url": "https://opencollective.com/unified"
} }
}, },
"node_modules/no-case": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz",
"integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==",
"license": "MIT",
"dependencies": {
"lower-case": "^2.0.2",
"tslib": "^2.0.3"
}
},
"node_modules/node-abi": { "node_modules/node-abi": {
"version": "3.75.0", "version": "3.75.0",
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.75.0.tgz", "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.75.0.tgz",
@@ -6555,6 +6687,16 @@
"url": "https://github.com/inikulin/parse5?sponsor=1" "url": "https://github.com/inikulin/parse5?sponsor=1"
} }
}, },
"node_modules/pascal-case": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz",
"integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==",
"license": "MIT",
"dependencies": {
"no-case": "^3.0.4",
"tslib": "^2.0.3"
}
},
"node_modules/path-browserify": { "node_modules/path-browserify": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz",
@@ -7674,6 +7816,45 @@
"inline-style-parser": "0.2.4" "inline-style-parser": "0.2.4"
} }
}, },
"node_modules/svelte": {
"version": "5.34.8",
"resolved": "https://registry.npmjs.org/svelte/-/svelte-5.34.8.tgz",
"integrity": "sha512-TF+8irl7rpj3+fpaLuPRX5BqReTAqckp0Fumxa/mCeK3fo0/MnBb9W/Z2bLwtqj3C3r5Lm6NKIAw7YrgIv1Fwg==",
"license": "MIT",
"dependencies": {
"@ampproject/remapping": "^2.3.0",
"@jridgewell/sourcemap-codec": "^1.5.0",
"@sveltejs/acorn-typescript": "^1.0.5",
"@types/estree": "^1.0.5",
"acorn": "^8.12.1",
"aria-query": "^5.3.1",
"axobject-query": "^4.1.0",
"clsx": "^2.1.1",
"esm-env": "^1.2.1",
"esrap": "^1.4.8",
"is-reference": "^3.0.3",
"locate-character": "^3.0.0",
"magic-string": "^0.30.11",
"zimmerframe": "^1.1.2"
},
"engines": {
"node": ">=18"
}
},
"node_modules/svelte2tsx": {
"version": "0.7.40",
"resolved": "https://registry.npmjs.org/svelte2tsx/-/svelte2tsx-0.7.40.tgz",
"integrity": "sha512-Fgqe2lzC9DWT/kQTIXqN39O2ot9rUqzUu9dqpbuI6EsaEJ6+RSXVmXnxcNYMlKb2LRPDoIg9TVzXYWwi0zhCmQ==",
"license": "MIT",
"dependencies": {
"dedent-js": "^1.0.1",
"pascal-case": "^3.1.1"
},
"peerDependencies": {
"svelte": "^3.55 || ^4.0.0-next.0 || ^4.0 || ^5.0.0-next.0",
"typescript": "^4.9.4 || ^5.0.0"
}
},
"node_modules/tailwindcss": { "node_modules/tailwindcss": {
"version": "4.1.10", "version": "4.1.10",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.10.tgz", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.10.tgz",
@@ -8888,6 +9069,12 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/zimmerframe": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/zimmerframe/-/zimmerframe-1.1.2.tgz",
"integrity": "sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w==",
"license": "MIT"
},
"node_modules/zod": { "node_modules/zod": {
"version": "3.25.64", "version": "3.25.64",
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.64.tgz", "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.64.tgz",

View File

@@ -14,13 +14,15 @@
"@astrojs/node": "^9.2.2", "@astrojs/node": "^9.2.2",
"@astrojs/starlight": "^0.34.4", "@astrojs/starlight": "^0.34.4",
"@astrojs/starlight-tailwind": "^4.0.1", "@astrojs/starlight-tailwind": "^4.0.1",
"@astrojs/svelte": "^7.1.0",
"@fontsource/ibm-plex-mono": "^5.0.13", "@fontsource/ibm-plex-mono": "^5.0.13",
"@fontsource/ibm-plex-sans": "^5.0.20", "@fontsource/ibm-plex-sans": "^5.0.20",
"@tailwindcss/vite": "^4.1.10", "@tailwindcss/vite": "^4.1.10",
"astro": "^5.9.3", "astro": "^5.9.3",
"sharp": "^0.32.5", "sharp": "^0.32.5",
"starlight-openapi": "^0.9.0", "starlight-openapi": "^0.9.0",
"svelte": "^5.34.8",
"tailwindcss": "^4.1.10", "tailwindcss": "^4.1.10",
"typescript": "^5.4.5" "typescript": "^5.8.3"
} }
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@@ -0,0 +1,11 @@
[
{
"name": "Demo Server",
"url": "https://demo.wanderer.to",
"description": "A public demo instance of wanderer. Everyone can log in and try out all features—upload trails, create lists, explore the interface, and test federation. Data is reset periodically, so feel free to experiment.",
"image": "/server/imgs/demo-logo.png",
"region": "World",
"language": "English",
"category": "General"
}
]

View File

@@ -0,0 +1,38 @@
<script lang="ts">
import { type SelectItem } from "../models/select_item";
interface Props {
name?: string;
items?: SelectItem[];
value?: any;
label?: string;
disabled?: boolean;
}
let {
name = "",
items = [],
value = $bindable(items.at(0)?.value ?? ""),
label = "",
disabled = false,
}: Props = $props();
</script>
<div>
{#if label.length}
<label for={name} class="text-sm font-medium pb-1">
{label}
</label>
{/if}
<select
{name}
class="block bg-input-background p-4 border-r-8 border-transparent outline-1 outline-input-border rounded-md focus:outline-input-border-focus transition-colors"
class:text-gray-500={disabled}
{disabled}
bind:value
>
{#each items as item}
<option value={item.value}>{item.text}</option>
{/each}
</select>
</div>

View File

@@ -0,0 +1,120 @@
<script lang="ts">
import TextField from "./text_field.svelte";
import Select from "./select.svelte";
interface Props {
servers: Server[];
}
let { servers }: Props = $props();
import type { Server } from "../models/server";
import type { SelectItem } from "../models/select_item";
let search = $state("");
let region = $state("");
let language = $state("");
let category = $state("");
const uniqueValues = (key: keyof Server) => [
...new Set(servers.map((s) => s[key])),
];
const regionItems: SelectItem[] = [
{ text: "All regions", value: "" },
...uniqueValues("region").map((v) => ({ text: v, value: v })),
];
const languageItems: SelectItem[] = [
{ text: "All languages", value: "" },
...uniqueValues("language").map((v) => ({ text: v, value: v })),
];
const categoryItems: SelectItem[] = [
{ text: "All categories", value: "" },
...uniqueValues("category").map((v) => ({ text: v, value: v })),
];
const filteredServers = $derived(
servers.filter(
(server) =>
(server.name.toLowerCase().includes(search.toLowerCase()) ||
server.description.toLowerCase().includes(search.toLowerCase())) &&
(!region || server.region === region) &&
(!language || server.language === language) &&
(!category || server.category === category),
),
);
</script>
<p class="max-w-3xl">
In wanderer, a <strong>server</strong> (also called an <em>instance</em>) is
a self-hosted installation of the platform. Each server runs independently
and hosts its own users, trails, and content. Thanks to federation via
ActivityPub, servers can interact—so you can follow users, view trails, and
share content across instances.
</p>
<p class="max-w-3xl mb-12">
You can join an existing server or host your own. This page helps you
discover publicly listed wanderer servers you might want to explore or
become part of.
</p>
<div
class="grid grid-cols-1 md:grid-cols-[1fr_auto_auto_auto] justify-end gap-4 mb-8"
>
<div class="sm:max-w-sm">
<TextField
type="text"
placeholder="Search servers..."
bind:value={search}
></TextField>
</div>
<div class="mt-0">
<Select items={regionItems} bind:value={region}></Select>
</div>
<div class="mt-0">
<Select items={languageItems} bind:value={language}></Select>
</div>
<div class="mt-0">
<Select items={categoryItems} bind:value={category}></Select>
</div>
</div>
{#if filteredServers.length == 0}
<p class="text-center text-gray-500 text-xl w-full mt-16">
There are no servers that match your query
</p>
{/if}
<div class="grid sm:grid-cols-2 lg:grid-cols-3 gap-6">
{#each filteredServers as server}
<div
class="mt-0 rounded-lg border border-input-border transition overflow-hidden"
>
<img
src={server.image}
alt={server.name}
class="w-full h-40 object-cover"
/>
<div class="flex items-center gap-x-1 px-4">
{#each ["category", "region", "language"] as key}
<div
class="mt-0 text-xs border border-input-border bg-menu-item-background-hover' px-2 py-1 rounded-full flex items-center gap-1"
>
{(server as any)[key]}
</div>
{/each}
</div>
<div class="p-4 -mt-2">
<h4 class="mb-1">{server.name}</h4>
<p class="text-sm">{server.description}</p>
</div>
<div class="mt-0 px-4 pb-4 pt-2">
<a
class="block text-center min-h-10 text-white rounded-lg p-4 py-2 bg-primary font-semibold transition-all hover:bg-primary-hover focus:ring-4 ring-input-ring"
href={server.url}
target="_blank">Create account</a
>
</div>
</div>
{/each}
</div>

View File

@@ -0,0 +1,64 @@
<script lang="ts">
interface Props {
name?: string;
value?: string | number;
placeholder?: string;
disabled?: boolean;
label?: string;
error?: string | string[] | null;
icon?: string;
extraClasses?: string;
type?: "text" | "password" | "search";
autocomplete?: "on" | "off";
}
let {
name = "",
value = $bindable(""),
placeholder = "",
disabled = false,
label = "",
error = "",
icon = "",
extraClasses = "",
type = "text",
autocomplete = "on",
}: Props = $props();
function typeAction(node: HTMLInputElement) {
node.type = type;
}
</script>
<div>
{#if label.length}
<label for={name} class="text-sm font-medium pb-1">
{label}
</label>
{/if}
<div class="flex items-center gap-2">
{#if icon.length > 0}
<div class="w-6">
<i class="fa fa-{icon}"></i>
</div>
{/if}
<input
{name}
class="bg-input-background border border-input-border rounded-md p-3 transition-colors focus:border-input-border-focus focus:outline-none focus:ring-0 w-full {extraClasses}"
class:border-red-400={(error?.length ?? 0) > 0}
class:bg-input-background-error={(error?.length ?? 0) > 0}
class:text-gray-500={disabled}
{disabled}
{autocomplete}
use:typeAction
bind:value
{placeholder}
/>
</div>
{#if error}
<span class="textfield-error text-xs text-red-400">
{error}
</span>
{/if}
</div>

View File

@@ -10,12 +10,12 @@ hero:
html: | html: |
<video class="rounded-xl hidden md:block" poster="/favicon.svg" width="100%" src="/trailer.mp4" controls autoplay /> <video class="rounded-xl hidden md:block" poster="/favicon.svg" width="100%" src="/trailer.mp4" controls autoplay />
actions: actions:
- text: Try the demo - text: Join a server
link: https://demo.wanderer.to link: /servers
icon: rocket icon: right-arrow
- text: Read the docs - text: Read the docs
link: /welcome link: /welcome
icon: right-arrow icon: open-book
variant: secondary variant: secondary
--- ---
@@ -23,7 +23,7 @@ hero:
import { Card, CardGrid } from '@astrojs/starlight/components'; import { Card, CardGrid } from '@astrojs/starlight/components';
<div class="grid grid-cols-1 md:grid-cols-2 gap-16"> <div class="grid grid-cols-1 md:grid-cols-2 gap-16">
<div> <div class="order-">
![Mockups of wanderer on laptop, tablet and phone](../../assets/hero.png) ![Mockups of wanderer on laptop, tablet and phone](../../assets/hero.png)
</div> </div>
<div> <div>
@@ -39,10 +39,10 @@ import { Card, CardGrid } from '@astrojs/starlight/components';
</p> </p>
</div> </div>
<div> <div>
![Shocase of wanderer integrations](../../assets/integrations.png) ![Showcase of wanderer integrations](../../assets/integrations.png)
</div> </div>
<div> <div>
![Shocase of wanderer's social features](../../assets/social.png) ![Showcase of wanderer's social features](../../assets/social.png)
</div> </div>
<div> <div>
<h1>Explore together, even apart</h1> <h1>Explore together, even apart</h1>

View File

@@ -0,0 +1,4 @@
export type SelectItem = {
text: string;
value: any;
};

View File

@@ -0,0 +1,9 @@
export interface Server {
name: string;
url: string;
description: string;
image: string;
region: string;
language: string;
category: string;
}

View File

@@ -0,0 +1,16 @@
---
import StarlightPage from "@astrojs/starlight/components/StarlightPage.astro";
import ServerList from "../components/server_list.svelte";
import servers from "../../public/server/servers.json";
---
<StarlightPage
frontmatter={{
title: "Discover wanderer Servers",
description: "A list of wanderer servers",
template: "splash",
}}
>
<ServerList {servers} client:load />
</StarlightPage>

View File

@@ -5,8 +5,83 @@
@import "tailwindcss/preflight.css" layer(base); @import "tailwindcss/preflight.css" layer(base);
@import "tailwindcss/utilities.css"; @import "tailwindcss/utilities.css";
/* Dark mode colors. */
:root {
--primary: 36, 39, 52;
--primary-hover: 55, 60, 80;
--secondary-hover: 55, 65, 81;
--secondary-hover-inverse: 243, 244, 246;
--background: 18, 20, 28;
--background-inverse: 255, 255, 255;
--content: 255, 255, 255;
--content-inverse: 0, 0, 0;
--input-background: 38, 40, 49;
--input-background-error: 76, 17, 17;
--input-border: 50, 54, 64;
--input-border-focus: 148, 163, 184;
--input-ring: 148, 163, 184;
--menu-background: 30, 32, 40;
--menu-item-background-hover: 55, 65, 81;
--menu-item-background-focus: 75, 85, 99;
--footer-background: 24, 26, 36;
--separator: 55, 65, 81;
}
/* Light mode colors. */
:root[data-theme='light'] {
--primary: 36, 39, 52;
--primary-hover: 17, 24, 39;
--secondary-hover: 243, 244, 246;
--secondary-hover-inverse: 36, 39, 52;
--background: 255, 255, 255;
--background-inverse: 7, 10, 36;
--content: 0, 0, 0;
--content-inverse: 255, 255, 255;
--input-background: 249, 250, 251;
--input-background-error: 254, 242, 242;
--input-border: 209, 213, 219;
--input-border-focus: 36, 39, 52;
--input-ring: 148, 163, 184;
--menu-background: 255, 255, 255;
--menu-item-background-hover: 243, 244, 246;
--menu-item-background-focus: 229, 231, 235;
--footer-background: 36, 39, 52;
--separator: 209, 213, 219;
}
@theme { @theme {
--color-primary: #242734; /* wanderer theme */
--color-primary: rgba(var(--primary));
--color-background: rgba(var(--background));
--color-background-inverse: rgba(var(--background-inverse));
--color-content: rgba(var(--content));
--color-content-inverse: rgba(var(--content-inverse));
--color-primary: rgba(var(--primary));
--color-primary-hover: rgba(var(--primary-hover));
--color-secondary-hover: rgba(var(--secondary-hover));
--color-input-background: rgba(var(--input-background));
--color-input-background-error: rgba(var(--input-background-error));
--color-input-border: rgba(var(--input-border));
--color-input-border-focus: rgba(var(--input-border-focus));
--color-input-ring: rgba(var(--input-ring));
--color-menu-background: rgba(var(--menu-background));
--color-menu-item-background-hover: rgba(var(--menu-item-background-hover));
--color-menu-item-background-focus: rgba(var(--menu-item-background-focus));
--color-footer-background: rgba(var(--footer-background));
--color-separator: rgba(var(--separator));
/* Generated accent color palettes. */ /* Generated accent color palettes. */
--color-accent-200: #b3c7ff; --color-accent-200: #b3c7ff;

5
docs/svelte.config.js Normal file
View File

@@ -0,0 +1,5 @@
import { vitePreprocess } from '@astrojs/svelte';
export default {
preprocess: vitePreprocess(),
}