Updates and more
Dieser Commit ist enthalten in:
Ursprung
b5a54d087b
Commit
e97e86f9ac
38
astro-i18n.adapter.ts
Normale Datei
38
astro-i18n.adapter.ts
Normale Datei
@ -0,0 +1,38 @@
|
|||||||
|
import type { AstroIntegration } from "astro";
|
||||||
|
import { mkdir, rename, access, constants } from 'node:fs/promises'
|
||||||
|
import {rm} from "fs/promises";
|
||||||
|
|
||||||
|
const locales = ["de"];
|
||||||
|
|
||||||
|
export default function configureI18n(): AstroIntegration {
|
||||||
|
return {
|
||||||
|
name: "astro-i18n-renamer",
|
||||||
|
hooks: {
|
||||||
|
"astro:build:done": async ({pages, dir, logger, routes}) => {
|
||||||
|
for (let page of pages) {
|
||||||
|
let [locale, ...rest] = page.pathname.split("/");
|
||||||
|
if (locales.includes(locale)) {
|
||||||
|
let path = rest.join("/");
|
||||||
|
let oldPath = `${dir.pathname}${page.pathname}`
|
||||||
|
let newPath = `${dir.pathname}${path}`
|
||||||
|
try {
|
||||||
|
await access(cutPrefix(newPath), constants.R_OK | constants.W_OK)
|
||||||
|
} catch (e) {
|
||||||
|
await mkdir(cutPrefix(newPath), {recursive: true});
|
||||||
|
}
|
||||||
|
|
||||||
|
await rename(`${cutPrefix(oldPath)}index.html`, `${cutPrefix(newPath)}index.${locale}.html`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let locale of locales) {
|
||||||
|
await rm(`${cutPrefix(dir.pathname)}${locale}`, {recursive: true, force: true})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function cutPrefix(path: string): string {
|
||||||
|
return process.platform === "win32" ? path.substring(1) : path
|
||||||
|
}
|
@ -5,17 +5,17 @@ export default defineAstroI18nConfig({
|
|||||||
secondaryLocales: ["de"], // other supported locales
|
secondaryLocales: ["de"], // other supported locales
|
||||||
fallbackLocale: "en", // fallback locale (on missing translation)
|
fallbackLocale: "en", // fallback locale (on missing translation)
|
||||||
trailingSlash: "never", // "never" or "always"
|
trailingSlash: "never", // "never" or "always"
|
||||||
run: "server", //"client+server" or "server"
|
run: "client+server", //"client+server" or "server"
|
||||||
showPrimaryLocale: false, // "/en/about" vs "/about"
|
showPrimaryLocale: false, // "/en/about" vs "/about"
|
||||||
translationLoadingRules: [], // per page group loading
|
translationLoadingRules: [], // per page group loading
|
||||||
translationDirectory: {
|
translationDirectory: {}, // translation directory names
|
||||||
i18n: "i18n",
|
|
||||||
}, // translation directory names
|
|
||||||
translations: {}, // { [translation_group1]: { [locale1]: {}, ... } }
|
translations: {}, // { [translation_group1]: { [locale1]: {}, ... } }
|
||||||
routes: {
|
routes: {
|
||||||
de: {
|
de: {
|
||||||
about: "ueber-uns",
|
about: "ueber-uns",
|
||||||
join: "jetzt-spielen"
|
join: "jetzt-spielen",
|
||||||
|
imprint: "impressum",
|
||||||
|
"code-of-conduct": "verhaltensrichtlinien",
|
||||||
}
|
}
|
||||||
}, // { [secondary_locale1]: { about: "about-translated", ... } }
|
}, // { [secondary_locale1]: { about: "about-translated", ... } }
|
||||||
})
|
})
|
@ -1,6 +1,7 @@
|
|||||||
import { defineConfig, sharpImageService } from 'astro/config';
|
import { defineConfig, sharpImageService } from 'astro/config';
|
||||||
import svelte from "@astrojs/svelte";
|
import svelte from "@astrojs/svelte";
|
||||||
import tailwind from "@astrojs/tailwind";
|
import tailwind from "@astrojs/tailwind";
|
||||||
|
import configureI18n from "./astro-i18n.adapter";
|
||||||
|
|
||||||
// https://astro.build/config
|
// https://astro.build/config
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
@ -8,7 +9,8 @@ export default defineConfig({
|
|||||||
image: {
|
image: {
|
||||||
service: sharpImageService(),
|
service: sharpImageService(),
|
||||||
},
|
},
|
||||||
integrations: [svelte(), tailwind()],
|
compressHTML: true,
|
||||||
|
integrations: [svelte(), tailwind(), configureI18n()],
|
||||||
vite: {
|
vite: {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
20
package.json
20
package.json
@ -18,23 +18,25 @@
|
|||||||
"@astrojs/svelte": "^4.0.3",
|
"@astrojs/svelte": "^4.0.3",
|
||||||
"@astrojs/tailwind": "^5.0.2",
|
"@astrojs/tailwind": "^5.0.2",
|
||||||
"@astropub/icons": "^0.2.0",
|
"@astropub/icons": "^0.2.0",
|
||||||
|
"@types/color": "^3.0.5",
|
||||||
|
"@types/node": "^20.8.10",
|
||||||
"cssnano": "^6.0.1",
|
"cssnano": "^6.0.1",
|
||||||
"esbuild": "^0.19.4",
|
"esbuild": "^0.19.5",
|
||||||
"postcss-nesting": "^12.0.1",
|
"postcss-nesting": "^12.0.1",
|
||||||
"sass": "^1.69.3",
|
"sass": "^1.69.5",
|
||||||
"svelte": "^4.2.1",
|
"svelte": "^4.2.2",
|
||||||
"tailwind-merge": "^1.14.0",
|
"tailwind-merge": "^2.0.0",
|
||||||
"tailwindcss": "^3.3.3"
|
"tailwindcss": "^3.3.5"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@codemirror/lang-markdown": "^6.2.2",
|
"@codemirror/lang-markdown": "^6.2.2",
|
||||||
"@ddietr/codemirror-themes": "^1.4.2",
|
"@ddietr/codemirror-themes": "^1.4.2",
|
||||||
"astro": "^3.3.0",
|
"astro": "^3.4.3",
|
||||||
"astro-i18n": "^2.0.4",
|
"astro-i18n": "^2.1.18",
|
||||||
"color": "^4.2.3",
|
"color": "^4.2.3",
|
||||||
"flowbite": "^1.8.1",
|
"flowbite": "^1.8.1",
|
||||||
"flowbite-svelte": "^0.44.18",
|
"flowbite-svelte": "^0.44.19",
|
||||||
"flowbite-svelte-icons": "^0.4.4",
|
"flowbite-svelte-icons": "^0.4.5",
|
||||||
"moment": "^2.29.4",
|
"moment": "^2.29.4",
|
||||||
"sharp": "^0.32.6",
|
"sharp": "^0.32.6",
|
||||||
"svelte-awesome": "^3.2.1",
|
"svelte-awesome": "^3.2.1",
|
||||||
|
11
src/components/PlayerCount.svelte
Normale Datei
11
src/components/PlayerCount.svelte
Normale Datei
@ -0,0 +1,11 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
|
||||||
|
import {server} from "./stores/server.ts";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#await $server}
|
||||||
|
{:then data}
|
||||||
|
{data.players.online}
|
||||||
|
{:catch error}
|
||||||
|
Error
|
||||||
|
{/await}
|
19
src/components/ServerStatus.svelte
Normale Datei
19
src/components/ServerStatus.svelte
Normale Datei
@ -0,0 +1,19 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { t } from "astro-i18n"
|
||||||
|
import {server} from "./stores/server.ts";
|
||||||
|
|
||||||
|
function generateVersionString(version: string): string {
|
||||||
|
let versions = version.split(" ").slice(1)
|
||||||
|
return `${versions[0].replace(",", "")} - ${versions[versions.length - 1]}`
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#await $server}
|
||||||
|
<p>{t("status.loading")}</p>
|
||||||
|
{:then data}
|
||||||
|
<h2>{t("status.status")}: <span class="text-green-500">{t("status.online")}</span></h2>
|
||||||
|
<h2>{t("status.players", { count: `${data.players.online}/${data.players.max}`})}</h2>
|
||||||
|
<h2>{t("status.version", { version: generateVersionString(data.version.name)})}</h2>
|
||||||
|
{:catch error}
|
||||||
|
<h1>{t("status.status")}: <span class="text-red-500">{t("status.offline")}</span></h1>
|
||||||
|
{/await}
|
@ -33,7 +33,7 @@ export function cachedFamily<T, K>(normal: K, init: (arg0: T) => Promise<K>): (a
|
|||||||
const stores: Map<T, Cached<K>> = new Map();
|
const stores: Map<T, Cached<K>> = new Map();
|
||||||
return (arg: T) => {
|
return (arg: T) => {
|
||||||
if(stores.has(arg)) {
|
if(stores.has(arg)) {
|
||||||
return stores.get(arg);
|
return stores.get(arg)!!;
|
||||||
} else {
|
} else {
|
||||||
const store = writable<K>(normal);
|
const store = writable<K>(normal);
|
||||||
let first = true;
|
let first = true;
|
||||||
|
4
src/components/stores/server.ts
Normale Datei
4
src/components/stores/server.ts
Normale Datei
@ -0,0 +1,4 @@
|
|||||||
|
import {readable} from "svelte/store";
|
||||||
|
import type {Readable} from "svelte/store";
|
||||||
|
|
||||||
|
export const server = readable(fetch(import.meta.env.PUBLIC_API_SERVER + "/data/server").then(res => res.json()))
|
@ -1,5 +1,5 @@
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import { defineCollection, z } from 'astro:content';
|
import {defineCollection, reference, z} from 'astro:content';
|
||||||
|
|
||||||
export const pages = defineCollection({
|
export const pages = defineCollection({
|
||||||
type: "content",
|
type: "content",
|
||||||
@ -10,6 +10,30 @@ export const pages = defineCollection({
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export const help = defineCollection({
|
||||||
|
type: "content",
|
||||||
|
schema: z.object({
|
||||||
|
title: z.string().min(1).max(80),
|
||||||
|
description: z.string().min(1).max(120),
|
||||||
|
tags: z.array(z.string()),
|
||||||
|
related: z.array(reference('help')).optional()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
export const event = defineCollection({
|
||||||
|
type: "content",
|
||||||
|
schema: z.object({
|
||||||
|
name: z.string(),
|
||||||
|
start: z.date(),
|
||||||
|
end: z.date(),
|
||||||
|
mode: z.string().optional(),
|
||||||
|
leader: z.string().array().optional(),
|
||||||
|
eventId: z.number().gte(0)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
export const collections = {
|
export const collections = {
|
||||||
'pages': pages
|
'pages': pages,
|
||||||
|
'help': help,
|
||||||
|
'event': event
|
||||||
}
|
}
|
||||||
|
9
src/content/help/en/how-to.md
Normale Datei
9
src/content/help/en/how-to.md
Normale Datei
@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
title: How To
|
||||||
|
description: How to do anything on SteamWar
|
||||||
|
tags:
|
||||||
|
- how-to
|
||||||
|
slug: how-to
|
||||||
|
---
|
||||||
|
|
||||||
|
# How to
|
@ -2,8 +2,8 @@
|
|||||||
"home": {
|
"home": {
|
||||||
"page": "SteamWar - Startseite",
|
"page": "SteamWar - Startseite",
|
||||||
"subtitle": {
|
"subtitle": {
|
||||||
"1": "Spieler Online: ",
|
"1": "WarGears, AirShips, WarShips",
|
||||||
"2": "WarGears, AirShips, WarShips"
|
"2": "Spieler Online: "
|
||||||
},
|
},
|
||||||
"join": "Jetzt Spielen",
|
"join": "Jetzt Spielen",
|
||||||
"benefits": {
|
"benefits": {
|
||||||
@ -34,6 +34,10 @@
|
|||||||
"Arch": "Architekt"
|
"Arch": "Architekt"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"status": {
|
||||||
|
"loading": "Lade...",
|
||||||
|
"players": "Spieler: {# count #}"
|
||||||
|
},
|
||||||
"navbar": {
|
"navbar": {
|
||||||
"links": {
|
"links": {
|
||||||
"home": {
|
"home": {
|
||||||
@ -42,7 +46,7 @@
|
|||||||
"downloads": "Downloads",
|
"downloads": "Downloads",
|
||||||
"faq": "FAQ"
|
"faq": "FAQ"
|
||||||
},
|
},
|
||||||
"announcements": "Ankünigungen",
|
"announcements": "Ankündigungen",
|
||||||
"rules": {
|
"rules": {
|
||||||
"title": "Regeln",
|
"title": "Regeln",
|
||||||
"gamemode": "Spielmodi",
|
"gamemode": "Spielmodi",
|
||||||
@ -60,7 +64,8 @@
|
|||||||
"help": {
|
"help": {
|
||||||
"title": "Hilfe",
|
"title": "Hilfe",
|
||||||
"docs": "Dokumentation"
|
"docs": "Dokumentation"
|
||||||
}
|
},
|
||||||
|
"account": "Konto"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,8 +30,17 @@
|
|||||||
"title": "Help",
|
"title": "Help",
|
||||||
"center": "Helpcenter",
|
"center": "Helpcenter",
|
||||||
"docs": "Docs"
|
"docs": "Docs"
|
||||||
|
},
|
||||||
|
"account": "Account"
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"status": {
|
||||||
|
"loading": "Loading...",
|
||||||
|
"status": "Status",
|
||||||
|
"online": "Online",
|
||||||
|
"offline": "Offline",
|
||||||
|
"players": "Players: {# count #}",
|
||||||
|
"version": "Version: {# version #}"
|
||||||
},
|
},
|
||||||
"home": {
|
"home": {
|
||||||
"page": "SteamWar - Home",
|
"page": "SteamWar - Home",
|
||||||
@ -40,8 +49,8 @@
|
|||||||
"second": "War"
|
"second": "War"
|
||||||
},
|
},
|
||||||
"subtitle": {
|
"subtitle": {
|
||||||
"1": "Players Online: ",
|
"1": "WarGears, AirShips, WarShips",
|
||||||
"2": "WarGears, AirShips, WarShips",
|
"2": "Players Online: ",
|
||||||
"3": "Version: 1.12 - 1.20"
|
"3": "Version: 1.12 - 1.20"
|
||||||
},
|
},
|
||||||
"join": "Join Now",
|
"join": "Join Now",
|
||||||
|
@ -3,8 +3,11 @@ import { Image } from "astro:assets";
|
|||||||
import Basic from "./Basic.astro";
|
import Basic from "./Basic.astro";
|
||||||
import '../styles/button.css';
|
import '../styles/button.css';
|
||||||
import localLogo from "../images/logo.png"
|
import localLogo from "../images/logo.png"
|
||||||
import {YoutubeSolid, DiscordSolid} from "flowbite-svelte-icons"
|
import {YoutubeSolid, DiscordSolid, CaretDownOutline} from "flowbite-svelte-icons"
|
||||||
import {l, t} from "astro-i18n";
|
import {t} from "astro-i18n";
|
||||||
|
import {l} from "../util/util"
|
||||||
|
|
||||||
|
import ServerStatus from "../components/ServerStatus.svelte";
|
||||||
|
|
||||||
const { title } = Astro.props;
|
const { title } = Astro.props;
|
||||||
---
|
---
|
||||||
@ -22,11 +25,14 @@ const { title } = Astro.props;
|
|||||||
{t("navbar.title")}
|
{t("navbar.title")}
|
||||||
</h1>
|
</h1>
|
||||||
</a>
|
</a>
|
||||||
<div class="flex items-center flex-wrap">
|
<div class="flex justify-center flex-wrap">
|
||||||
<div class="btn-dropdown my-1">
|
<div class="btn-dropdown my-1">
|
||||||
<a class="btn btn-gray" href={l("/")}>
|
<div class="btn btn-gray" tabindex="1">
|
||||||
|
<a href={l("/")}>
|
||||||
<span class="btn__text">{t("navbar.links.home.title")}</span>
|
<span class="btn__text">{t("navbar.links.home.title")}</span>
|
||||||
</a>
|
</a>
|
||||||
|
<CaretDownOutline class="ml-2 mt-auto" />
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<a class="btn btn-gray" href={l("/about")}>{t("navbar.links.home.about")}</a>
|
<a class="btn btn-gray" href={l("/about")}>{t("navbar.links.home.about")}</a>
|
||||||
<a class="btn btn-gray">{t("navbar.links.home.downloads")}</a>
|
<a class="btn btn-gray">{t("navbar.links.home.downloads")}</a>
|
||||||
@ -37,9 +43,12 @@ const { title } = Astro.props;
|
|||||||
<span class="btn__text">{t("navbar.links.announcements")}</span>
|
<span class="btn__text">{t("navbar.links.announcements")}</span>
|
||||||
</a>
|
</a>
|
||||||
<div class="btn-dropdown my-1">
|
<div class="btn-dropdown my-1">
|
||||||
<a class="btn btn-gray" rel="prefetch" href={l("/blog")}>
|
<div class="btn btn-gray" tabindex="1">
|
||||||
|
<a rel="prefetch" href={l("/blog")}>
|
||||||
<span class="btn__text">{t("navbar.links.rules.title")}</span>
|
<span class="btn__text">{t("navbar.links.rules.title")}</span>
|
||||||
</a>
|
</a>
|
||||||
|
<CaretDownOutline class="ml-2 mt-auto" />
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<h2 class="px-2 text-gray-300">{t("navbar.links.rules.gamemode")}</h2>
|
<h2 class="px-2 text-gray-300">{t("navbar.links.rules.gamemode")}</h2>
|
||||||
<a class="btn btn-gray">{t("navbar.links.rules.wg")}</a>
|
<a class="btn btn-gray">{t("navbar.links.rules.wg")}</a>
|
||||||
@ -55,14 +64,20 @@ const { title } = Astro.props;
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="btn-dropdown my-1">
|
<div class="btn-dropdown my-1">
|
||||||
<a class="btn btn-gray" rel="prefetch">
|
<div class="btn btn-gray" tabindex="1">
|
||||||
|
<a rel="prefetch">
|
||||||
<span class="btn__text">{t("navbar.links.help.title")}</span>
|
<span class="btn__text">{t("navbar.links.help.title")}</span>
|
||||||
</a>
|
</a>
|
||||||
|
<CaretDownOutline class="ml-2 mt-auto" />
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<a class="btn btn-gray">{t("navbar.links.help.center")}</a>
|
<a class="btn btn-gray" href={l("/help")}>{t("navbar.links.help.center")}</a>
|
||||||
<a class="btn btn-gray">{t("navbar.links.help.docs")}</a>
|
<a class="btn btn-gray">{t("navbar.links.help.docs")}</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<a class="btn my-1" href={l("/login")}>
|
||||||
|
<span class="btn__text">{t("navbar.links.account")}</span>
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</nav-bar>
|
</nav-bar>
|
||||||
@ -91,10 +106,11 @@ const { title } = Astro.props;
|
|||||||
<main class="flex-1">
|
<main class="flex-1">
|
||||||
<slot />
|
<slot />
|
||||||
</main>
|
</main>
|
||||||
<footer class="bg-gray-900 w-screen h-80 mt-4 rounded-t-2xl flex flex-col dark:bg-neutral-900">
|
<footer class="bg-gray-900 w-screen min-h-80 mt-4 rounded-t-2xl flex flex-col dark:bg-neutral-900">
|
||||||
<div class="flex-1 flex justify-evenly mt-4 ">
|
<div class="flex-1 flex justify-evenly items-center md:items-start mt-4 md:flex-row flex-col">
|
||||||
<div class="footer-card">
|
<div class="footer-card">
|
||||||
<h1>Serverstatus</h1>
|
<h1>Serverstatus</h1>
|
||||||
|
<ServerStatus client:only="svelte" />
|
||||||
</div>
|
</div>
|
||||||
<div class="footer-card">
|
<div class="footer-card">
|
||||||
<h1>Links</h1>
|
<h1>Links</h1>
|
||||||
@ -121,7 +137,7 @@ const { title } = Astro.props;
|
|||||||
|
|
||||||
<style>
|
<style>
|
||||||
.footer-card {
|
.footer-card {
|
||||||
@apply w-36 text-gray-400 flex flex-col;
|
@apply w-40 text-gray-400 flex flex-col;
|
||||||
>h1 {
|
>h1 {
|
||||||
@apply text-xl font-bold text-gray-100;
|
@apply text-xl font-bold text-gray-100;
|
||||||
}
|
}
|
||||||
@ -139,6 +155,6 @@ const { title } = Astro.props;
|
|||||||
}
|
}
|
||||||
|
|
||||||
.match {
|
.match {
|
||||||
width: clamp(75%, 25rem, 100vw);
|
width: min(100vw, 70em);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -2,14 +2,16 @@
|
|||||||
import { getCollection } from 'astro:content'
|
import { getCollection } from 'astro:content'
|
||||||
import NavbarLayout from "../layouts/NavbarLayout.astro";
|
import NavbarLayout from "../layouts/NavbarLayout.astro";
|
||||||
import {astroI18n, createGetStaticPaths} from "astro-i18n";
|
import {astroI18n, createGetStaticPaths} from "astro-i18n";
|
||||||
|
import localBau from "../images/2023-10-08_20.43.43.png";
|
||||||
|
import {Image} from "astro:assets";
|
||||||
|
|
||||||
export const getStaticPaths = async () => {
|
export const getStaticPaths = createGetStaticPaths(async () => {
|
||||||
let posts = await getCollection("pages");
|
let posts = await getCollection("pages");
|
||||||
|
|
||||||
return posts.filter(value => value.id.split("/")[0] === astroI18n.locale).map((page) => ({
|
return posts.filter(value => value.id.split("/")[0] === astroI18n.locale).map((page) => ({
|
||||||
props: { page }, params: { slug: page.slug }
|
props: { page }, params: { slug: page.slug }
|
||||||
}) )
|
}) )
|
||||||
}
|
})
|
||||||
|
|
||||||
const { page } = Astro.props;
|
const { page } = Astro.props;
|
||||||
const { Content } = await page.render();
|
const { Content } = await page.render();
|
||||||
@ -17,16 +19,19 @@ const { Content } = await page.render();
|
|||||||
|
|
||||||
|
|
||||||
<NavbarLayout title={page.data.title}>
|
<NavbarLayout title={page.data.title}>
|
||||||
|
<div>
|
||||||
|
<Image src={localBau} alt="Bau" width="1920" height="1080" class="w-screen h-screen dark:brightness-75 fixed -z-10 object-cover" draggable="false" />
|
||||||
<article>
|
<article>
|
||||||
<h1 class="text-left">{page.data.title}</h1>
|
<h1 class="text-left">{page.data.title}</h1>
|
||||||
<Content />
|
<Content />
|
||||||
</article>
|
</article>
|
||||||
|
</div>
|
||||||
</NavbarLayout>
|
</NavbarLayout>
|
||||||
|
|
||||||
<style is:global>
|
<style is:global>
|
||||||
article {
|
article {
|
||||||
width: clamp(75%, 25rem, 100vw);
|
width: min(100vw, 75em);
|
||||||
@apply mx-auto bg-gray-100 px-4 py-8 rounded-b-md shadow-md pt-40 sm:pt-28 md:pt-14
|
@apply mx-auto bg-gray-100 p-8 rounded-b-md shadow-md pt-40 sm:pt-28 md:pt-14
|
||||||
dark:text-white dark:bg-neutral-900;
|
dark:text-white dark:bg-neutral-900;
|
||||||
|
|
||||||
p {
|
p {
|
||||||
@ -65,6 +70,10 @@ const { Content } = await page.render();
|
|||||||
@apply list-disc;
|
@apply list-disc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
@apply dark:text-neutral-400 text-neutral-800;
|
||||||
|
}
|
||||||
|
|
||||||
pre.astro-code {
|
pre.astro-code {
|
||||||
@apply w-fit p-4 rounded-md border-2 border-gray-600 my-4;
|
@apply w-fit p-4 rounded-md border-2 border-gray-600 my-4;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
---
|
|
||||||
import NavBarLayout from '../layouts/NavbarLayout.astro'
|
|
||||||
---
|
|
||||||
|
|
||||||
<NavBarLayout title="Blog">
|
|
||||||
<h1>Blog!</h1>
|
|
||||||
</NavBarLayout>
|
|
3
src/pages/event/[...slug].astro
Normale Datei
3
src/pages/event/[...slug].astro
Normale Datei
@ -0,0 +1,3 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
---
|
72
src/pages/help/[...slug].astro
Normale Datei
72
src/pages/help/[...slug].astro
Normale Datei
@ -0,0 +1,72 @@
|
|||||||
|
---
|
||||||
|
import { getCollection } from 'astro:content'
|
||||||
|
import NavbarLayout from "../../layouts/NavbarLayout.astro";
|
||||||
|
import {astroI18n, createGetStaticPaths} from "astro-i18n";
|
||||||
|
|
||||||
|
export const getStaticPaths = createGetStaticPaths(async () => {
|
||||||
|
let posts = await getCollection("help");
|
||||||
|
|
||||||
|
return posts.filter(value => value.id.split("/")[0] === astroI18n.locale).map((page) => ({
|
||||||
|
props: { page }, params: { slug: page.slug }
|
||||||
|
}) )
|
||||||
|
})
|
||||||
|
|
||||||
|
const { page } = Astro.props;
|
||||||
|
const { Content } = await page.render();
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
<NavbarLayout title={page.data.title}>
|
||||||
|
<article>
|
||||||
|
<h1 class="text-left">{page.data.title}</h1>
|
||||||
|
<Content />
|
||||||
|
</article>
|
||||||
|
</NavbarLayout>
|
||||||
|
|
||||||
|
<style is:global>
|
||||||
|
article {
|
||||||
|
width: clamp(75%, 25rem, 100vw);
|
||||||
|
@apply mx-auto bg-gray-100 px-4 py-8 rounded-b-md shadow-md pt-40 sm:pt-28 md:pt-14
|
||||||
|
dark:text-white dark:bg-neutral-900;
|
||||||
|
|
||||||
|
p {
|
||||||
|
@apply my-4 leading-7;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
@apply text-4xl font-bold mt-4 text-center;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
@apply text-3xl font-bold mt-4;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
@apply text-2xl font-bold mt-4;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
@apply text-xl font-bold mt-4;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
@apply text-blue-500 hover:text-blue-700;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol>li, ul>li {
|
||||||
|
@apply ml-4;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol {
|
||||||
|
@apply list-decimal;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
@apply list-disc;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre.astro-code {
|
||||||
|
@apply w-fit p-4 rounded-md border-2 border-gray-600 my-4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
26
src/pages/help/index.astro
Normale Datei
26
src/pages/help/index.astro
Normale Datei
@ -0,0 +1,26 @@
|
|||||||
|
---
|
||||||
|
import {getCollection} from "astro:content";
|
||||||
|
import {astroI18n} from "astro-i18n";
|
||||||
|
|
||||||
|
import NavbarLayout from "../../layouts/NavbarLayout.astro";
|
||||||
|
import {l} from "../../util/util";
|
||||||
|
let posts = await getCollection("help", entry => entry.id.split("/")[0] === astroI18n.locale);
|
||||||
|
---
|
||||||
|
|
||||||
|
<NavbarLayout title="Helpcenter">
|
||||||
|
<div>
|
||||||
|
<h1>Helpcenter</h1>
|
||||||
|
{posts.map(value => (
|
||||||
|
<a href={l("/help/" + value.slug)}>
|
||||||
|
<h2>{value.data.title}</h2>
|
||||||
|
</a>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</NavbarLayout>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
div {
|
||||||
|
@apply mx-auto bg-gray-100 px-4 py-8 rounded-b-md shadow-md pt-40 sm:pt-28 md:pt-14
|
||||||
|
dark:text-white dark:bg-neutral-900;
|
||||||
|
}
|
||||||
|
</style>
|
@ -4,7 +4,9 @@ import NavbarLayout from "../layouts/NavbarLayout.astro";
|
|||||||
import { Image } from "astro:assets";
|
import { Image } from "astro:assets";
|
||||||
import localBau from "../images/2023-10-08_20.43.43.png";
|
import localBau from "../images/2023-10-08_20.43.43.png";
|
||||||
import {CaretRight, Archive, Rocket, Bell} from "@astropub/icons"
|
import {CaretRight, Archive, Rocket, Bell} from "@astropub/icons"
|
||||||
import {astroI18n, l, t} from "astro-i18n";
|
import {astroI18n, t} from "astro-i18n";
|
||||||
|
import {l} from "../util/util"
|
||||||
|
import PlayerCount from "../components/PlayerCount.svelte";
|
||||||
|
|
||||||
const teamMember = await fetch("http://localhost:1337/data/team").then(value => value.json())
|
const teamMember = await fetch("http://localhost:1337/data/team").then(value => value.json())
|
||||||
|
|
||||||
@ -38,13 +40,13 @@ function mapMap<T, K, J>(i: Map<T, K>, fn: (key: T, value: K) => J): J[] {
|
|||||||
<div class="w-screen h-screen relative mb-4">
|
<div class="w-screen h-screen relative mb-4">
|
||||||
<Image src={localBau} alt="Bau" width="1920" height="1080" class="w-screen object-cover rounded-b-2xl shadow-2xl dark:brightness-75" style="height: calc(100vh + 1rem)" draggable="false" />
|
<Image src={localBau} alt="Bau" width="1920" height="1080" class="w-screen object-cover rounded-b-2xl shadow-2xl dark:brightness-75" style="height: calc(100vh + 1rem)" draggable="false" />
|
||||||
<drop-in class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 flex flex-col items-center">
|
<drop-in class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 flex flex-col items-center">
|
||||||
<h1 class="text-2xl sm:text-8xl font-extrabold text-white -translate-y-16 opacity-0 barlow" style="transition: transform .7s ease-out, opacity .7s linear; text-shadow: 2px 2px 5px black;">
|
<h1 class="text-4xl sm:text-6xl md:text-8xl font-extrabold text-white -translate-y-16 opacity-0 barlow" style="transition: transform .7s ease-out, opacity .7s linear; text-shadow: 2px 2px 5px black;">
|
||||||
<span class="text-yellow-400">{t("home.title.first")}</span>
|
<span class="text-yellow-400">{t("home.title.first")}</span>
|
||||||
<span class="text-neutral-600">{t("home.title.second")}</span>
|
<span class="text-neutral-600">{t("home.title.second")}</span>
|
||||||
</h1>
|
</h1>
|
||||||
<text-carousel class="h-20 w-full relative select-none">
|
<text-carousel class="h-20 w-full relative select-none">
|
||||||
<h2 class="-translate-y-16">{t("home.subtitle.1")}<player-count /></h2>
|
<h2 class="-translate-y-16">{t("home.subtitle.1")}</h2>
|
||||||
<h2>{t("home.subtitle.2")}</h2>
|
<h2>{t("home.subtitle.2")}<PlayerCount client:only="svelte" /></h2>
|
||||||
<h2>{t("home.subtitle.3")}</h2>
|
<h2>{t("home.subtitle.3")}</h2>
|
||||||
</text-carousel>
|
</text-carousel>
|
||||||
<a href={l("join")} class="btn mt-32 px-8 flex opacity-0 -translate-y-16" style="transition: transform .3s ease-out, opacity .3s linear">{t("home.join")} <CaretRight width="24" heigth="24" /></a>
|
<a href={l("join")} class="btn mt-32 px-8 flex opacity-0 -translate-y-16" style="transition: transform .3s ease-out, opacity .3s linear">{t("home.join")} <CaretRight width="24" heigth="24" /></a>
|
||||||
@ -81,12 +83,6 @@ function mapMap<T, K, J>(i: Map<T, K>, fn: (key: T, value: K) => J): J[] {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class PlayerCount extends HTMLElement {
|
|
||||||
connectedCallback() {
|
|
||||||
this.innerText = String(Math.floor(Math.random() * 100))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class DropIn extends HTMLElement {
|
class DropIn extends HTMLElement {
|
||||||
connectedCallback() {
|
connectedCallback() {
|
||||||
for (let child of this.children) {
|
for (let child of this.children) {
|
||||||
@ -101,7 +97,6 @@ function mapMap<T, K, J>(i: Map<T, K>, fn: (key: T, value: K) => J): J[] {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define("player-count", PlayerCount);
|
|
||||||
customElements.define("text-carousel", TextCarousel);
|
customElements.define("text-carousel", TextCarousel);
|
||||||
customElements.define("drop-in", DropIn);
|
customElements.define("drop-in", DropIn);
|
||||||
</script>
|
</script>
|
||||||
|
42
src/pages/login.astro
Normale Datei
42
src/pages/login.astro
Normale Datei
@ -0,0 +1,42 @@
|
|||||||
|
---
|
||||||
|
import NavbarLayout from "../layouts/NavbarLayout.astro";
|
||||||
|
import localBau from "../images/2023-10-08_20.43.43.png";
|
||||||
|
import {Image} from "astro:assets";
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<NavbarLayout title="Login">
|
||||||
|
<Image src={localBau} alt="Bau" width="1920" height="1080" class="w-screen h-screen dark:brightness-75 fixed -z-10 object-cover" draggable="false" />
|
||||||
|
<div class="h-screen mx-auto p-8 rounded-b-md shadow-md pt-40 sm:pt-28 md:pt-14 flex flex-col justify-center items-center
|
||||||
|
dark:text-white " style="width: min(100vw, 75em);">
|
||||||
|
<div class="bg-gray-100 dark:bg-neutral-900 p-12 rounded-2xl shadow-2xl border-2 border-gray-600 flex flex-col">
|
||||||
|
<h1 class="text-4xl text-white text-center">Login</h1>
|
||||||
|
<div class="ml-2 flex flex-col">
|
||||||
|
<label for="username">Username</label>
|
||||||
|
<input type="text" id="username" name="username" placeholder="Username..." />
|
||||||
|
<label for="password">Password</label>
|
||||||
|
<input type="password" id="password" name="password" placeholder="****************" />
|
||||||
|
</div>
|
||||||
|
<button class="btn mt-4 !mx-0 justify-center">Login</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
import {l} from "../util/util";
|
||||||
|
|
||||||
|
if (localStorage.getItem("sw-api-token") !== null) {
|
||||||
|
window.location.href = l("/account")
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</NavbarLayout>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
input {
|
||||||
|
@apply border-2 rounded-md p-2 shadow-2xl w-80
|
||||||
|
dark:bg-neutral-800
|
||||||
|
focus:outline-none focus:ring-2 focus:ring-neutral-500 focus:border-transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
@apply text-neutral-300;
|
||||||
|
}
|
||||||
|
</style>
|
@ -1,5 +1,5 @@
|
|||||||
.btn {
|
.btn {
|
||||||
@apply bg-yellow-400 font-bold py-2 px-4 rounded cursor-pointer select-none mx-2 text-black;
|
@apply bg-yellow-400 font-bold py-2 px-4 rounded cursor-pointer select-none mx-2 text-black flex flex-row;
|
||||||
@apply hover:bg-yellow-300 hover:text-black hover:shadow-2xl hover:scale-105;
|
@apply hover:bg-yellow-300 hover:text-black hover:shadow-2xl hover:scale-105;
|
||||||
transition: all 0.5s cubic-bezier(.2,3,.67,.6),
|
transition: all 0.5s cubic-bezier(.2,3,.67,.6),
|
||||||
background-color .1s ease-in-out,
|
background-color .1s ease-in-out,
|
||||||
@ -16,11 +16,11 @@
|
|||||||
@apply relative mx-2;
|
@apply relative mx-2;
|
||||||
|
|
||||||
>:nth-child(1) {
|
>:nth-child(1) {
|
||||||
@apply block !mx-0;
|
@apply !mx-0;
|
||||||
}
|
}
|
||||||
|
|
||||||
>:nth-child(2) {
|
>:nth-child(2) {
|
||||||
@apply hidden absolute top-full left-1/2 -translate-x-1/2 bg-gray-800 list-none text-white rounded py-2 flex-col text-sm;
|
@apply hidden absolute top-full left-1/2 -translate-x-1/2 bg-gray-800 list-none text-white rounded py-2 flex-col text-sm z-20;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover,&:focus-within {
|
&:hover,&:focus-within {
|
||||||
|
@ -1,14 +1,18 @@
|
|||||||
|
import { l as proxyL } from 'astro-i18n'
|
||||||
|
|
||||||
import { randomBytes } from 'crypto'
|
const locales = ["de"];
|
||||||
|
|
||||||
const usedIds = new Set<string>()
|
export const l = (route: string) => {
|
||||||
|
const transPath = proxyL(route)
|
||||||
|
|
||||||
export const getRandomId = () => {
|
if(import.meta.env.DEV) {
|
||||||
while (true) {
|
return transPath;
|
||||||
const id = randomBytes(4).toString('hex')
|
|
||||||
if (!usedIds.has(id)) {
|
|
||||||
usedIds.add(id)
|
|
||||||
return id
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let [empty, locale, ...rest] = transPath.split("/");
|
||||||
|
if (locales.includes(locale)) {
|
||||||
|
return "/" + rest.join("/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return transPath;
|
||||||
}
|
}
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren