Dieser Commit ist enthalten in:
Ursprung
4afd833276
Commit
22f24e92c3
@ -23,6 +23,8 @@
|
|||||||
|
|
||||||
export let gamemode: string;
|
export let gamemode: string;
|
||||||
|
|
||||||
|
export let topFive: boolean = false;
|
||||||
|
|
||||||
let request = getRequest();
|
let request = getRequest();
|
||||||
|
|
||||||
function getRequest() {
|
function getRequest() {
|
||||||
@ -33,6 +35,7 @@
|
|||||||
{#await request}
|
{#await request}
|
||||||
<p>Loading...</p>
|
<p>Loading...</p>
|
||||||
{:then data}
|
{:then data}
|
||||||
|
{@const topFiveData = data.slice(0, 5)}
|
||||||
<div>
|
<div>
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
@ -43,7 +46,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{#each data as player, i (player.name)}
|
{#each (topFive ? topFiveData : data) as player, i (player.name)}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{`${i + 1}.`}</td>
|
<td>{`${i + 1}.`}</td>
|
||||||
<td>{player.name}</td>
|
<td>{player.name}</td>
|
||||||
|
@ -42,20 +42,31 @@
|
|||||||
value: branch
|
value: branch
|
||||||
}));
|
}));
|
||||||
|
|
||||||
async function createBranch() {
|
async function createBranch(name: string | null = null): Promise<string> {
|
||||||
const name = prompt("Branch name:");
|
return new Promise(async (resolve) => {
|
||||||
if (name) {
|
if (!name) {
|
||||||
selected = null;
|
name = prompt("Branch name:");
|
||||||
await $pageRepo.createBranch(name);
|
|
||||||
let inter = setInterval(() => {
|
if (!name) {
|
||||||
branches.reload();
|
resolve("");
|
||||||
if ($branches.includes(name)) {
|
return;
|
||||||
selectedBranch = name;
|
|
||||||
searchValue = "";
|
|
||||||
clearInterval(inter);
|
|
||||||
}
|
}
|
||||||
}, 1000);
|
}
|
||||||
}
|
if (name) {
|
||||||
|
selected = null;
|
||||||
|
await $pageRepo.createBranch(name);
|
||||||
|
let inter = setInterval(() => {
|
||||||
|
branches.reload();
|
||||||
|
if ($branches.includes(name!)) {
|
||||||
|
selectedBranch = name!;
|
||||||
|
searchValue = "";
|
||||||
|
clearInterval(inter);
|
||||||
|
|
||||||
|
resolve(name!);
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function changePage(id: number) {
|
function changePage(id: number) {
|
||||||
@ -101,6 +112,33 @@
|
|||||||
selectedBranch = "###!";
|
selectedBranch = "###!";
|
||||||
selectedBranch = w;
|
selectedBranch = w;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function newAnnouncement() {
|
||||||
|
const title = prompt("Title: ");
|
||||||
|
|
||||||
|
if (!title) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const slug = title.toLowerCase().replace(/ /g, "-");
|
||||||
|
|
||||||
|
const branch = await createBranch(slug)
|
||||||
|
|
||||||
|
selectedPath = "announcements/de/"
|
||||||
|
|
||||||
|
await $pageRepo.createFile(`${selectedPath}${slug}.md`, branch, slug, title);
|
||||||
|
reload();
|
||||||
|
|
||||||
|
const pages = await $pageRepo.listPages(branch);
|
||||||
|
|
||||||
|
const page = pages.find(page => page.path === `${selectedPath}${slug}.md`);
|
||||||
|
|
||||||
|
if (page) {
|
||||||
|
changePage(page.id);
|
||||||
|
} else {
|
||||||
|
alert("Error creating page");
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="flex flex-col h-screen overflow-scroll">
|
<div class="flex flex-col h-screen overflow-scroll">
|
||||||
@ -139,10 +177,6 @@
|
|||||||
<ul>
|
<ul>
|
||||||
{#if (selectedPath)}
|
{#if (selectedPath)}
|
||||||
{@const value = pagesMap.get(selectedPath) || []}
|
{@const value = pagesMap.get(selectedPath) || []}
|
||||||
{#if value.length === 0}
|
|
||||||
<li class="p-4">No pages found</li>
|
|
||||||
<li class="p-4">Select a path on the top</li>
|
|
||||||
{/if}
|
|
||||||
{#each value as page}
|
{#each value as page}
|
||||||
{@const nameRegexExec = nameRegex.exec(page.path)}
|
{@const nameRegexExec = nameRegex.exec(page.path)}
|
||||||
{@const match = nameRegexExec ? nameRegexExec[0] : ""}
|
{@const match = nameRegexExec ? nameRegexExec[0] : ""}
|
||||||
@ -156,6 +190,8 @@
|
|||||||
class:text-orange-600={selected === page.id}>{page.path.substring(endIndex, page.path.length)}</span>
|
class:text-orange-600={selected === page.id}>{page.path.substring(endIndex, page.path.length)}</span>
|
||||||
</li>
|
</li>
|
||||||
{/each}
|
{/each}
|
||||||
|
{:else}
|
||||||
|
<Button on:click={newAnnouncement}>Neue Ankündigung</Button>
|
||||||
{/if}
|
{/if}
|
||||||
</ul>
|
</ul>
|
||||||
{:catch error}
|
{:catch error}
|
||||||
|
@ -88,7 +88,7 @@
|
|||||||
</ToolbarGroup>
|
</ToolbarGroup>
|
||||||
</Toolbar>
|
</Toolbar>
|
||||||
</div>
|
</div>
|
||||||
{#if page?.name.endsWith("md")}
|
{#if page?.name.endsWith("md") || page?.name.endsWith("mdx")}
|
||||||
<MDEMarkdownEditor bind:value={pageContent} bind:dirty/>
|
<MDEMarkdownEditor bind:value={pageContent} bind:dirty/>
|
||||||
{:else}
|
{:else}
|
||||||
<CodeMirror bind:value={pageContent} lang={json()} theme={materialDark} on:change={() => dirty = true}/>
|
<CodeMirror bind:value={pageContent} lang={json()} theme={materialDark} on:change={() => dirty = true}/>
|
||||||
|
@ -57,4 +57,8 @@
|
|||||||
color: black;
|
color: black;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
:global(.CodeMirror) {
|
||||||
|
font-family: monospace !important;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
@ -65,8 +65,8 @@ export class PageRepo {
|
|||||||
await fetchWithToken(this.token, "/page/branch", {method: "DELETE", body: JSON.stringify({branch})});
|
await fetchWithToken(this.token, "/page/branch", {method: "DELETE", body: JSON.stringify({branch})});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async createFile(path: string, branch: string = "master"): Promise<void> {
|
public async createFile(path: string, branch: string = "master", slug: string | null = null, title: string | null = null): Promise<void> {
|
||||||
await fetchWithToken(this.token, `/page?branch=${branch}`, {method: "POST", body: JSON.stringify({path})});
|
await fetchWithToken(this.token, `/page?branch=${branch}`, {method: "POST", body: JSON.stringify({path, slug, title})});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async merge(branch: string, message: string): Promise<void> {
|
public async merge(branch: string, message: string): Promise<void> {
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {fetchWithToken, tokenStore} from "./repo.ts";
|
import {fetchWithToken, tokenStore} from "./repo.ts";
|
||||||
import type {SchematicInfo, SchematicList} from "@type/schem.ts";
|
import {type Schematic, type SchematicInfo, type SchematicList, SchematicSchema} from "@type/schem.ts";
|
||||||
import {SchematicInfoSchema, SchematicListSchema} from "@type/schem.ts";
|
import {SchematicInfoSchema, SchematicListSchema} from "@type/schem.ts";
|
||||||
import {derived} from "svelte/store";
|
import {derived} from "svelte/store";
|
||||||
|
|
||||||
@ -38,6 +38,14 @@ export class SchematicRepo {
|
|||||||
return await fetchWithToken(this.token, `/schem/${id}`).then(value => value.json()).then(SchematicInfoSchema.parse);
|
return await fetchWithToken(this.token, `/schem/${id}`).then(value => value.json()).then(SchematicInfoSchema.parse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async getSchematicCodeInfo(code: string): Promise<Schematic> {
|
||||||
|
return await fetchWithToken(this.token, `/schem/download/${code}/info`).then(value => value.json()).then(SchematicSchema.parse);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getSchematicDownloadUrl(code: string): string {
|
||||||
|
return `/schem/download/${code}`;
|
||||||
|
}
|
||||||
|
|
||||||
public async uploadSchematic(name: string, content: string) {
|
public async uploadSchematic(name: string, content: string) {
|
||||||
return await fetchWithToken(this.token, "/schem", {
|
return await fetchWithToken(this.token, "/schem", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
---
|
|
||||||
title: [Enter Title]
|
|
||||||
description: [Enter Description]
|
|
||||||
slug: [Enter Slug]
|
|
||||||
---
|
|
||||||
|
|
||||||
# announcements/de/ein-test.md
|
|
@ -65,6 +65,7 @@ export const rules = defineCollection({
|
|||||||
type: "content",
|
type: "content",
|
||||||
schema: z.object({
|
schema: z.object({
|
||||||
translationKey: z.string(),
|
translationKey: z.string(),
|
||||||
|
mode: reference("modes").optional(),
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
---
|
---
|
||||||
translationKey: as
|
translationKey: as
|
||||||
|
mode: airship
|
||||||
---
|
---
|
||||||
|
|
||||||
# AirShip-Regelwerk
|
# AirShip-Regelwerk
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
---
|
---
|
||||||
translationKey: mwg
|
translationKey: mwg
|
||||||
|
mode: miniwargear
|
||||||
---
|
---
|
||||||
|
|
||||||
# MiniWarGear-Regelwerk
|
# MiniWarGear-Regelwerk
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
---
|
---
|
||||||
translationKey: wg
|
translationKey: wg
|
||||||
|
mode: wargear
|
||||||
---
|
---
|
||||||
import Link from "../../../components/Link.svelte";
|
import Link from "../../../components/Link.svelte";
|
||||||
|
|
||||||
# WarGear
|
|
||||||
|
|
||||||
Ein WarGear ist eine Redstone-Kampfmaschine in Minecraft. Diese werden mit einer Vielzahl von Redstonetechniken und TNT-Kanonen ausgestattet und werden gebaut, um anderen WarGears Schaden zuzufügen.
|
Ein WarGear ist eine Redstone-Kampfmaschine in Minecraft. Diese werden mit einer Vielzahl von Redstonetechniken und TNT-Kanonen ausgestattet und werden gebaut, um anderen WarGears Schaden zuzufügen.
|
||||||
|
|
||||||
## Basic Wargear
|
## Basic Wargear
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
---
|
---
|
||||||
translationKey: ws
|
translationKey: ws
|
||||||
|
mode: warship
|
||||||
---
|
---
|
||||||
|
|
||||||
# WarShip-Regelwerk
|
# WarShip-Regelwerk
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
"description": "Jeder Spieler bekommt einen eigenen Bauserver, auf dem ohne Einschränkungen und Lags mit FaWe und Axiom gebaut werden kann."
|
"description": "Jeder Spieler bekommt einen eigenen Bauserver, auf dem ohne Einschränkungen und Lags mit FaWe und Axiom gebaut werden kann."
|
||||||
},
|
},
|
||||||
"minigames": {
|
"minigames": {
|
||||||
"title": "Kleine Pause gefällig?",
|
"title": "Minigames",
|
||||||
"description": {
|
"description": {
|
||||||
"1": "Neben der Arena gibt es auch noch Minigames, die du mit anderen Spielern spielen kannst.",
|
"1": "Neben der Arena gibt es auch noch Minigames, die du mit anderen Spielern spielen kannst.",
|
||||||
"2": "Klassiker wie MissleWars, TowerRun oder TNTLeague warten auf dich."
|
"2": "Klassiker wie MissleWars, TowerRun oder TNTLeague warten auf dich."
|
||||||
@ -37,11 +37,11 @@
|
|||||||
"read": "Mehr Lesen"
|
"read": "Mehr Lesen"
|
||||||
},
|
},
|
||||||
"prefix": {
|
"prefix": {
|
||||||
"admin": "Administrator",
|
"Admin": "Administrator",
|
||||||
"developer": "Developer",
|
"Dev": "Developer",
|
||||||
"moderator": "Moderator",
|
"Mod": "Moderator",
|
||||||
"supporter": "Supporter",
|
"Sup": "Supporter",
|
||||||
"builder": "Architekt"
|
"Arch": "Architekt"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"status": {
|
"status": {
|
||||||
|
@ -46,7 +46,7 @@
|
|||||||
"description": "Every player gets their own build server to ensure maximum performance and minimal limitations with leading tools like FaWe or Axiom"
|
"description": "Every player gets their own build server to ensure maximum performance and minimal limitations with leading tools like FaWe or Axiom"
|
||||||
},
|
},
|
||||||
"minigames": {
|
"minigames": {
|
||||||
"title": "Need a Break?",
|
"title": "Minigames",
|
||||||
"description": {
|
"description": {
|
||||||
"1": "Besides the Arena, you can also play minigames with other players.",
|
"1": "Besides the Arena, you can also play minigames with other players.",
|
||||||
"2": "like MissleWars, Towerrun or TNTLeague"
|
"2": "like MissleWars, Towerrun or TNTLeague"
|
||||||
@ -58,11 +58,11 @@
|
|||||||
"read": "Read More"
|
"read": "Read More"
|
||||||
},
|
},
|
||||||
"prefix": {
|
"prefix": {
|
||||||
"admin": "Admin",
|
"Admin": "Admin",
|
||||||
"developer": "Developer",
|
"Dev": "Developer",
|
||||||
"moderator": "Moderator",
|
"Mod": "Moderator",
|
||||||
"supporter": "Supporter",
|
"Sup": "Supporter",
|
||||||
"builder": "Builder"
|
"Arch": "Builder"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"footer": {
|
"footer": {
|
||||||
|
@ -35,11 +35,11 @@ const latestPost = posts.sort((a, b) => dayjs(b.data.created).unix() - dayjs(a.d
|
|||||||
const prefixColorMap: {
|
const prefixColorMap: {
|
||||||
[key: string]: string;
|
[key: string]: string;
|
||||||
} = {
|
} = {
|
||||||
PREFIX_ADMIN: "border-red-600 dark:border-red-800 shadow-red-600 dark:shadow-red-800",
|
Admin: "border-red-600 dark:border-red-800 shadow-red-600 dark:shadow-red-800",
|
||||||
PREFIX_DEVELOPER: "border-sky-600 dark:border-sky-800 shadow-sky-600 dark:shadow-sky-800",
|
Dev: "border-sky-600 dark:border-sky-800 shadow-sky-600 dark:shadow-sky-800",
|
||||||
PREFIX_MODERATOR: "border-amber-600 dark:border-amber-800 shadow-amber-600 dark:shadow-amber-800",
|
Mod: "border-amber-600 dark:border-amber-800 shadow-amber-600 dark:shadow-amber-800",
|
||||||
PREFIX_SUPPORTER: "border-blue-700 dark:border-blue-900 shadow-blue-700 dark:shadow-blue-900",
|
Sup: "border-blue-700 dark:border-blue-900 shadow-blue-700 dark:shadow-blue-900",
|
||||||
PREFIX_BUILDER: "border-green-500 dark:border-green-700 shadow-green-500 dark:shadow-green-700",
|
Arch: "border-green-500 dark:border-green-700 shadow-green-500 dark:shadow-green-700",
|
||||||
};
|
};
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -164,7 +164,7 @@ const prefixColorMap: {
|
|||||||
<Fragment>
|
<Fragment>
|
||||||
{players.map((v, index) => (
|
{players.map((v, index) => (
|
||||||
<div class="inline-flex flex-col justify-end">
|
<div class="inline-flex flex-col justify-end">
|
||||||
{index == 0 ? <h2 class="dark:text-white text-4xl font-bold text-center md:text-left md:pl-4">{t("home.prefix." + prefix.replace("PREFIX_", "").toLowerCase())}</h2> : null}
|
{index == 0 ? <h2 class="dark:text-white text-4xl font-bold text-center md:text-left md:pl-4">{t("home.prefix." + prefix)}</h2> : null}
|
||||||
<Card extraClasses={`pt-8 pb-10 px-8 w-fit shadow-md ${prefixColorMap[prefix]}`} client:idle>
|
<Card extraClasses={`pt-8 pb-10 px-8 w-fit shadow-md ${prefixColorMap[prefix]}`} client:idle>
|
||||||
<figure class="flex flex-col items-center" style="width: 150px">
|
<figure class="flex flex-col items-center" style="width: 150px">
|
||||||
<figcaption class="text-center mb-4 text-2xl">{v.name}</figcaption>
|
<figcaption class="text-center mb-4 text-2xl">{v.name}</figcaption>
|
||||||
|
@ -26,8 +26,9 @@ const { schem }: { schem: CollectionEntry<"publics">} = Astro.props;
|
|||||||
<PublicPreview client:idle pub={schem} imageHeight={schem.data.image.height}>
|
<PublicPreview client:idle pub={schem} imageHeight={schem.data.image.height}>
|
||||||
<Image class="object-contain" transition:name={schem.data.id + "-img"} src={schem.data.alt || schem.data.image} alt={schem.data.name}></Image>
|
<Image class="object-contain" transition:name={schem.data.id + "-img"} src={schem.data.alt || schem.data.image} alt={schem.data.name}></Image>
|
||||||
</PublicPreview>
|
</PublicPreview>
|
||||||
|
<!--
|
||||||
<p transition:name={schem.data.id + "-desc"}>{schem.data.description}</p>
|
<p transition:name={schem.data.id + "-desc"}>{schem.data.description}</p>
|
||||||
<p>
|
<p>
|
||||||
Erbauer: {schem.data.creator.join(", ")}
|
Erbauer: {schem.data.creator.join(", ")}
|
||||||
</p>
|
</p>-->
|
||||||
</PageLayout>
|
</PageLayout>
|
@ -39,7 +39,6 @@ const publics = await getCollection("publics", entry => entry.data.gamemode.id =
|
|||||||
</XRayPreview>
|
</XRayPreview>
|
||||||
</div>
|
</div>
|
||||||
<h2 class="font-bold text-3xl" transition:name={pub.data.id + "-title"}>{pub.data.name}</h2>
|
<h2 class="font-bold text-3xl" transition:name={pub.data.id + "-title"}>{pub.data.name}</h2>
|
||||||
<h3 transition:name={pub.data.id + "-desc"}>{pub.data.description}</h3>
|
|
||||||
</Card>
|
</Card>
|
||||||
</a>
|
</a>
|
||||||
))}
|
))}
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
---
|
---
|
||||||
import {getCollection, CollectionEntry} from "astro:content";
|
import {getCollection, type CollectionEntry} from "astro:content";
|
||||||
import {astroI18n, createGetStaticPaths, t} from "astro-i18n";
|
import {astroI18n, createGetStaticPaths, t} from "astro-i18n";
|
||||||
import PageLayout from "@layouts/PageLayout.astro";
|
import PageLayout from "@layouts/PageLayout.astro";
|
||||||
import LanguageWarning from "@components/LanguageWarning.astro";
|
import LanguageWarning from "@components/LanguageWarning.astro";
|
||||||
|
import EloTable from "@components/EloTable.svelte";
|
||||||
|
import {l} from "../../util/util";
|
||||||
|
import { Image } from "astro:assets";
|
||||||
|
|
||||||
export const getStaticPaths = createGetStaticPaths(async () => {
|
export const getStaticPaths = createGetStaticPaths(async () => {
|
||||||
let posts = await getCollection("rules", value => value.id.split("/")[0] === astroI18n.locale);
|
let posts = await getCollection("rules", value => value.id.split("/")[0] === astroI18n.locale);
|
||||||
@ -17,21 +20,55 @@ export const getStaticPaths = createGetStaticPaths(async () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const modes = await getCollection("modes");
|
||||||
|
const publics = await getCollection("publics");
|
||||||
|
|
||||||
return posts.map((page) => ({
|
return posts.map((page) => ({
|
||||||
props: {page, german: page.id.split("/")[0] != astroI18n.locale}, params: {mode: page.slug.split("/")[1]},
|
props: {
|
||||||
}));
|
page,
|
||||||
|
german: page.id.split("/")[0] != astroI18n.locale,
|
||||||
|
mode: modes.find(value => value.id === page.id.split("/")[1].split(".")[0]),
|
||||||
|
publics: publics.filter(value => value.data.gamemode.id === page.id.split("/")[1].split(".")[0]),
|
||||||
|
},
|
||||||
|
params: {
|
||||||
|
mode: page.slug.split("/")[1],
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
page: CollectionEntry<"rules">,
|
page: CollectionEntry<"rules">,
|
||||||
|
mode: CollectionEntry<"modes">,
|
||||||
|
publics: CollectionEntry<"publics">[],
|
||||||
german: boolean
|
german: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const {page, german} = Astro.props;
|
const {page, german, mode, publics} = Astro.props;
|
||||||
|
|
||||||
const {Content} = await page.render();
|
const {Content} = await page.render();
|
||||||
---
|
---
|
||||||
|
|
||||||
<PageLayout title={t("rules.title", {mode: t(`${page.data.translationKey}.title`)})}>
|
<PageLayout title={t("rules.title", {mode: t(`${page.data.translationKey}.title`)})}>
|
||||||
|
<h1 class="text-3xl font-bold">{t(`${page.data.translationKey}.title`)}</h1>
|
||||||
|
{mode && mode.data.ranked && (
|
||||||
|
<Fragment>
|
||||||
|
<EloTable gamemode={page.id.split("/")[1].split(".")[0]} client:load/>
|
||||||
|
<a class="text-neutral-800 dark:text-neutral-400 hover:underline" href={l(`/rangliste/${page.id.split("/")[1].split(".")[0]}`)}>{t("rules.ranking")}</a>
|
||||||
|
</Fragment>
|
||||||
|
)}
|
||||||
|
{publics && (
|
||||||
|
<Fragment>
|
||||||
|
<div class="flex overflow-x-scroll">
|
||||||
|
{publics.map(value => (
|
||||||
|
<a href={l(`/publics/${value.id}`)} style="display: contents">
|
||||||
|
<Image src={value.data.image} alt={value.data.name} height={300} width={300} class="drop-shadow"></Image>
|
||||||
|
</a>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
<a class="text-neutral-800 dark:text-neutral-400 hover:underline" href={l(`/publics/${page.id.split("/")[1].split(".")[0]}`)}>{t("rules.publics")}</a>
|
||||||
|
</Fragment>
|
||||||
|
)}
|
||||||
<article>
|
<article>
|
||||||
{german && (
|
{german && (
|
||||||
<LanguageWarning/>
|
<LanguageWarning/>
|
||||||
|
@ -1,14 +1,9 @@
|
|||||||
---
|
---
|
||||||
import wg from "../../images/WarGears.png";
|
|
||||||
import mwg from "../../images/MiniWarGears.png";
|
|
||||||
import as from "../../images/AirShips.png";
|
|
||||||
import ws from "../../images/WarShips.png";
|
|
||||||
import {t} from "astro-i18n";
|
import {t} from "astro-i18n";
|
||||||
import {getCollection} from "astro:content";
|
import {getCollection, type CollectionEntry} from "astro:content";
|
||||||
import PageLayout from "../../layouts/PageLayout.astro";
|
import PageLayout from "@layouts/PageLayout.astro";
|
||||||
import {Image} from "astro:assets";
|
import {Image} from "astro:assets";
|
||||||
import {l} from "../../util/util";
|
import {l} from "@utils/util";
|
||||||
import {ImageMetadata} from "astro";
|
|
||||||
|
|
||||||
const imageMap = {
|
const imageMap = {
|
||||||
"wg": await getRandomFromMode("wargear"),
|
"wg": await getRandomFromMode("wargear"),
|
||||||
@ -18,10 +13,10 @@ const imageMap = {
|
|||||||
"qg": await getRandomFromMode("quickgear"),
|
"qg": await getRandomFromMode("quickgear"),
|
||||||
};
|
};
|
||||||
|
|
||||||
async function getRandomFromMode(mode: "wargear" | "airship" | "megawargear" | "microwargear" | "miniwargear" | "quickgear" | "streetfight" | "warship"): Promise<ImageMetadata> {
|
async function getRandomFromMode(mode: "wargear" | "airship" | "megawargear" | "microwargear" | "miniwargear" | "quickgear" | "streetfight" | "warship"): Promise<CollectionEntry<"publics">> {
|
||||||
const publics = await getCollection("publics", entry => entry.data.gamemode.id === mode);
|
const publics = await getCollection("publics", entry => entry.data.gamemode.id === mode);
|
||||||
|
|
||||||
return publics[Math.floor(Math.random() * publics.length)].data.image;
|
return publics[Math.floor(Math.random() * publics.length)];
|
||||||
}
|
}
|
||||||
|
|
||||||
const modes = await getCollection("modes", entry => entry.data.main);
|
const modes = await getCollection("modes", entry => entry.data.main);
|
||||||
@ -31,16 +26,16 @@ const modes = await getCollection("modes", entry => entry.data.main);
|
|||||||
{modes.map(value => (
|
{modes.map(value => (
|
||||||
<div class="dark:bg-neutral-800 rounded-md p-4 border border-neutral-400 shadow-md my-4 flex flex-col
|
<div class="dark:bg-neutral-800 rounded-md p-4 border border-neutral-400 shadow-md my-4 flex flex-col
|
||||||
md:flex-row">
|
md:flex-row">
|
||||||
<Image height="300" width="300" src={imageMap[value.data.translationKey]}
|
<a href={l(`/publics/${imageMap[value.data.translationKey].id}`)}>
|
||||||
alt={t("rules." + value.data.translationKey + ".title")}></Image>
|
<Image height="200" width="200" src={imageMap[value.data.translationKey].data.image}
|
||||||
|
alt={t("rules." + value.data.translationKey + ".title")} class="h-full aspect-square max-w-fit"></Image>
|
||||||
|
</a>
|
||||||
<div class="ml-4">
|
<div class="ml-4">
|
||||||
<h1 class="text-2xl font-bold">{t(value.data.translationKey + ".title")}</h1>
|
<h1 class="text-2xl font-bold">{t(value.data.translationKey + ".title")}</h1>
|
||||||
<div>{t("rules." + value.data.translationKey + ".description")}</div>
|
<div>{t("rules." + value.data.translationKey + ".description")}</div>
|
||||||
<div class="mt-2 flex flex-col">
|
<div class="mt-2 flex flex-col">
|
||||||
<a href={l(`/rules/${value.id}`)} class="text-yellow-300 hover:underline w-fit">{t("rules.rules")}</a>
|
<a href={l(`/rules/${value.id}`)} class="text-yellow-300 hover:underline w-fit">{t("rules.rules")}</a>
|
||||||
<a href={l(`/publics/${value.id}`)} class="text-yellow-300 hover:underline w-fit">{t("rules.publics")}</a>
|
<a href={l(`/publics/${value.id}`)} class="text-yellow-300 hover:underline w-fit">{t("rules.publics")}</a>
|
||||||
<a href={l(`/announcements/tags/${value.id}`)}
|
|
||||||
class="text-yellow-300 hover:underline w-fit">{t("rules.announcements")}</a>
|
|
||||||
{value.data.ranked
|
{value.data.ranked
|
||||||
? <a href={l(`/ranked/${value.id}`)}
|
? <a href={l(`/ranked/${value.id}`)}
|
||||||
class="text-yellow-300 hover:underline w-fit">{t("rules.ranking")}</a>
|
class="text-yellow-300 hover:underline w-fit">{t("rules.ranking")}</a>
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren