Updates and more

Dieser Commit ist enthalten in:
Chaoscaot 2023-11-03 20:31:27 +01:00
Ursprung b5a54d087b
Commit e97e86f9ac
22 geänderte Dateien mit 363 neuen und 80 gelöschten Zeilen

38
astro-i18n.adapter.ts Normale Datei
Datei anzeigen

@ -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
}

Datei anzeigen

@ -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", ... } }
}) })

Datei anzeigen

@ -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: {
} }

Datei anzeigen

@ -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",

Datei anzeigen

@ -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}

Datei anzeigen

@ -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}

Datei anzeigen

@ -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;

Datei anzeigen

@ -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()))

Datei anzeigen

@ -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
} }

Datei anzeigen

@ -0,0 +1,9 @@
---
title: How To
description: How to do anything on SteamWar
tags:
- how-to
slug: how-to
---
# How to

Datei anzeigen

@ -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"
} }
} }
} }

Datei anzeigen

@ -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",

Datei anzeigen

@ -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>

Datei anzeigen

@ -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;
} }

Datei anzeigen

@ -1,7 +0,0 @@
---
import NavBarLayout from '../layouts/NavbarLayout.astro'
---
<NavBarLayout title="Blog">
<h1>Blog!</h1>
</NavBarLayout>

Datei anzeigen

@ -0,0 +1,3 @@
---
---

Datei anzeigen

@ -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
Datei anzeigen

@ -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>

Datei anzeigen

@ -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
Datei anzeigen

@ -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>

Datei anzeigen

@ -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 {

Datei anzeigen

@ -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;
} }