Compare commits

...

2 Commits

18 changed files with 657 additions and 1258 deletions

View File

@ -1,61 +0,0 @@
---
interface Props {
title: string;
body: string;
href: string;
}
const { href, title, body } = Astro.props;
---
<li class="link-card">
<a href={href}>
<h2>
{title}
<span>&rarr;</span>
</h2>
<p>
{body}
</p>
</a>
</li>
<style>
.link-card {
list-style: none;
display: flex;
padding: 1px;
background-color: #23262d;
background-image: none;
background-size: 400%;
border-radius: 7px;
background-position: 100%;
transition: background-position 0.6s cubic-bezier(0.22, 1, 0.36, 1);
box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.1);
}
.link-card > a {
width: 100%;
text-decoration: none;
line-height: 1.4;
padding: calc(1.5rem - 1px);
border-radius: 8px;
color: white;
background-color: #23262d;
opacity: 0.8;
}
h2 {
margin: 0;
font-size: 1.25rem;
transition: color 0.6s cubic-bezier(0.22, 1, 0.36, 1);
}
p {
margin-top: 0.5rem;
margin-bottom: 0;
}
.link-card:is(:hover, :focus-within) {
background-position: 0;
background-image: var(--accent-gradient);
}
.link-card:is(:hover, :focus-within) h2 {
color: rgb(var(--accent-light));
}
</style>

View File

@ -1,5 +1,6 @@
--- ---
import { getHighestWeightedLanguage, getLocales, getName } from '../lib/utils/langDriver'; import { getHighestWeightedLanguage, getLocales, getName } from '../lib/utils/langDriver';
interface Props { interface Props {
loggedIn: string; loggedIn: string;
active: string; active: string;
@ -133,7 +134,6 @@ const bottomRow = filteredList.filter(element => element.position === "bottom");
const username = Astro.cookies.get('username')?.value ?? ""; const username = Astro.cookies.get('username')?.value ?? "";
--- ---
<nav> <nav>
<div class="row"> <div class="row">
<ul> <ul>
@ -166,7 +166,6 @@ const username = Astro.cookies.get('username')?.value ?? "";
</ul> </ul>
</div> </div>
</nav> </nav>
<style> <style>
nav { nav {
background-color: rgb(56, 59, 99); background-color: rgb(56, 59, 99);
@ -213,8 +212,6 @@ nav ul {
} }
.avatar-icon { .avatar-icon {
/* object-fit: contain; */
/* width: 100%; */
height: 50px; height: 50px;
border-radius: 50%; border-radius: 50%;
border: 1px solid white; border: 1px solid white;

View File

@ -4,6 +4,7 @@ import { getHighestWeightedLanguage, getLocales, getName } from '../lib/utils/la
import { getAllResources } from '../lib/db/resources'; import { getAllResources } from '../lib/db/resources';
import locationManager from '../lib/classes/managers/LocationManager'; import locationManager from '../lib/classes/managers/LocationManager';
import { Resource } from '../lib/classes/managers/abstract/ResourceManager'; import { Resource } from '../lib/classes/managers/abstract/ResourceManager';
import SystemManager from '../lib/classes/managers/SystemManager';
const resourceTypes = await getAllResources(); const resourceTypes = await getAllResources();
@ -11,7 +12,7 @@ const lang = await getLocales(Astro.cookies.get('language')?.value ?? await getH
const planetId = new ObjectId(Astro.cookies.get('currentPlanet')?.value ?? ''); const planetId = new ObjectId(Astro.cookies.get('currentPlanet')?.value ?? '');
const planet = locationManager.getPlanet(planetId); const planet = locationManager.findId(planetId);
if(!planet) return; if(!planet) return;
@ -27,7 +28,7 @@ for(const key of planet.resources.resources) {
<div class="resourcebar-circle-id" data-type="solid"></div> <div class="resourcebar-circle-id" data-type="solid"></div>
</div> </div>
<div class="resourcebar-planetname"> <div class="resourcebar-planetname">
{planet.name} {planet instanceof SystemManager ? <span style="color: red;">{planet.data.name}</span> : planet.name}
</div> </div>
<div id="resourcebar-elements" class="resourcebar-elements"> <div id="resourcebar-elements" class="resourcebar-elements">
{resourceArray.map(res => {resourceArray.map(res =>
@ -53,7 +54,6 @@ for(const key of planet.resources.resources) {
)} )}
</div> </div>
</div> </div>
<style> <style>
#resourcebar { #resourcebar {
color: white; color: white;
@ -143,13 +143,12 @@ for(const key of planet.resources.resources) {
opacity: 1; opacity: 1;
} }
</style> </style>
<script> <script>
function numWithPrefix(x: number) { function numWithPrefix(x: number) {
x = Math.floor(x); x = Math.floor(x);
if(x < 1_000) return x.toString(); if(x < 1_000) return x.toString();
if(x < 1_000_000) return (x / 1_000).toFixed(2) + "k"; if(x < 1_000_000) return (x / 1_000).toFixed(3) + "k";
if(x < 1_000_000_000) return (x / 1_000_000).toFixed(2) + "M"; if(x < 1_000_000_000) return (x / 1_000_000).toFixed(3) + "M";
return x.toString(); return x.toString();
} }

9
src/env.d.ts vendored
View File

@ -1,2 +1,11 @@
/// <reference path="../.astro/types.d.ts" /> /// <reference path="../.astro/types.d.ts" />
/// <reference types="astro/client" /> /// <reference types="astro/client" />
declare namespace App {
interface Locals {
token: string;
lang: { [key: string]: { id: string; name: string; description: string | null; }[]; };
user: User;
active: SystemManager | Planet;
}
}

View File

@ -19,7 +19,6 @@ if(!Astro.cookies.has('language')) {
}); });
} }
--- ---
<!doctype html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
@ -36,32 +35,3 @@ if(!Astro.cookies.has('language')) {
<!-- <PlanetView /> --> <!-- <PlanetView /> -->
</body> </body>
</html> </html>
<style is:global>
:root {
--accent: 136, 58, 234;
--accent-light: 224, 204, 250;
--accent-dark: 49, 10, 101;
--accent-gradient: linear-gradient(
45deg,
rgb(var(--accent)),
rgb(var(--accent-light)) 30%,
white 60%
);
}
html {
font-family: system-ui, sans-serif;
background: #13151a;
background-size: 224px;
}
code {
font-family:
Menlo,
Monaco,
Lucida Console,
Liberation Mono,
DejaVu Sans Mono,
Bitstream Vera Sans Mono,
Courier New,
monospace;
}
</style>

View File

@ -0,0 +1,34 @@
---
import NavBar from '../components/NavBar.astro';
import ResourceBar from '../components/ResourceBar.astro';
interface Props {
id: string;
title: string;
}
const { title } = Astro.props;
---
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="description" content="Astro description" />
<meta name="viewport" content="width=device-width" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<link rel="stylesheet" href="/css/markdown.css" />
<meta name="generator" content={Astro.generator} />
<title>{title}</title>
</head>
<body>
<NavBar loggedIn="true" active={Astro.props.id} />
<ResourceBar />
<slot />
</body>
</html>
<style>
html {
font-family: system-ui, sans-serif;
background: #13151a;
}
</style>

35
src/middleware.ts Normal file
View File

@ -0,0 +1,35 @@
import { getUserByAccessToken } from "./lib/db/users";
import { getHighestWeightedLanguage, getLocales } from "./lib/utils/langDriver";
import locationManager from "./lib/classes/managers/LocationManager";
import { defineMiddleware } from "astro/middleware";
import { APIContext, MiddlewareNext } from "astro";
import { ObjectId } from "mongodb";
const frontend = async (context: APIContext, next: MiddlewareNext) => {
const loggedToken = context.cookies.get('sessionToken')?.value ?? null;
const username = context.cookies.get('username')?.value ?? "";
if(loggedToken === null || username === "") return context.redirect('/logout');
const checkUser = await getUserByAccessToken(loggedToken);
if(checkUser === null || checkUser.username !== username) return context.redirect('/logout');
const user = locationManager.getUser(checkUser._id);
if(user === null) return context.redirect('/logout');
const lang = await getLocales(context.cookies.get('language')?.value ?? await getHighestWeightedLanguage(context.request.headers.get('accept-language')));
const activeId = context.cookies.get('currentPlanet')?.value ?? "0";
const active = locationManager.findId(new ObjectId(activeId));
if(active === null) return context.redirect('/logout');
context.locals.token = loggedToken;
context.locals.lang = lang;
context.locals.user = user;
context.locals.active = active;
return next();
}
export const onRequest = defineMiddleware(async (context, next) => {
return context.url.pathname.startsWith('/game') ? frontend(context, next) : next();
});

View File

@ -1,34 +1,21 @@
--- ---
import Layout from '../../layouts/Layout.astro';
import NavBar from '../../components/NavBar.astro';
import ItemCard from '../../components/ItemCard.astro'; import ItemCard from '../../components/ItemCard.astro';
import { getUserByAccessToken } from '../../lib/db/users'; import LoggedIn from '../../layouts/LoggedIn.astro';
import { getHighestWeightedLanguage, getLocales, getName, getObj } from '../../lib/utils/langDriver'; import { Planet } from '../../lib/classes/managers/PlanetManager';
import ResourceBar from '../../components/ResourceBar.astro'; import SystemManager from '../../lib/classes/managers/SystemManager';
import { getAllBuildings } from '../../lib/db/buildings'; import { getAllBuildings } from '../../lib/db/buildings';
import locationManager from '../../lib/classes/managers/LocationManager'; import { getName, getObj } from '../../lib/utils/langDriver';
import { ObjectId } from 'mongodb';
import DBBuilding from '../../types/db/DBBuilding'; import DBBuilding from '../../types/db/DBBuilding';
const { token, lang } = Astro.locals;
const active: SystemManager | Planet = Astro.locals.active;
if(active instanceof SystemManager) {
return Astro.redirect('/game');
}
const buildingsList = await getAllBuildings(); const buildingsList = await getAllBuildings();
const loggedToken = Astro.cookies.get('sessionToken')?.value ?? null;
const username = Astro.cookies.get('username')?.value ?? "";
if(loggedToken === null || username === "") return Astro.redirect('/logout');
const checkUser = await getUserByAccessToken(loggedToken);
if(checkUser === null || checkUser.username !== username) return Astro.redirect('/logout');
const locale = Astro.cookies.get('language')?.value ?? await getHighestWeightedLanguage(Astro.request.headers.get('accept-language'));
const lang = await getLocales(locale);
const planetId = Astro.cookies.get('currentPlanet')?.value ?? "";
if(planetId === "") return "No planet selected";
const planet = locationManager.getPlanet(new ObjectId(planetId));
if(!planet) return "Planet not found";
if(Astro.request.method === "POST") { if(Astro.request.method === "POST") {
const selectedBuildingId = (await Astro.request.formData()).get('id') as string | null; const selectedBuildingId = (await Astro.request.formData()).get('id') as string | null;
@ -36,10 +23,10 @@ if(Astro.request.method === "POST") {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'Authorization': 'Bearer ' + loggedToken 'Authorization': 'Bearer ' + token
}, },
body: JSON.stringify({ body: JSON.stringify({
planet: planetId, planet: active._id,
building: selectedBuildingId building: selectedBuildingId
}) })
})).json(); })).json();
@ -54,7 +41,7 @@ for(const building of buildingsList) {
resources: building.requirements.resources.map(resource => { resources: building.requirements.resources.map(resource => {
return { return {
id: resource.id, id: resource.id,
amount: Math.pow(building.multiplier, (planet.buildings.getBuildingById(building.id)?.level ?? 0) ) * resource.amount amount: Math.pow(building.multiplier, (active.buildings.getBuildingById(building.id)?.level ?? 0) ) * resource.amount
}; };
}), }),
research: building.requirements.research, research: building.requirements.research,
@ -65,15 +52,12 @@ for(const building of buildingsList) {
const buildingsByCategory = buildingsList.reduce((acc: { [key: string]: Array<DBBuilding & { level: number }> }, building) => { const buildingsByCategory = buildingsList.reduce((acc: { [key: string]: Array<DBBuilding & { level: number }> }, building) => {
if(!acc[building.category]) acc[building.category] = []; if(!acc[building.category]) acc[building.category] = [];
acc[building.category].push({ ...building, level: planet.buildings.getBuildingById(building.id)?.level ?? 0 }); acc[building.category].push({ ...building, level: active.buildings.getBuildingById(building.id)?.level ?? 0 });
return acc; return acc;
}, {}); }, {});
--- ---
<Layout title="Buildings"> <LoggedIn id="buildings" title="Buildings">
<NavBar loggedIn="true" active="buildings" />
<ResourceBar />
<div id="building-modal-background"> <div id="building-modal-background">
<div id="building-modal-details" data-building-id=""> <div id="building-modal-details" data-building-id="">
<h3>Required resources</h3> <h3>Required resources</h3>
@ -84,7 +68,6 @@ const buildingsByCategory = buildingsList.reduce((acc: { [key: string]: Array<DB
<div class="building-modal-text" id="building-modal-req-research">None</div> <div class="building-modal-text" id="building-modal-req-research">None</div>
</div> </div>
</div> </div>
{Object.entries(buildingsByCategory).map(([category, buildings]) => <> {Object.entries(buildingsByCategory).map(([category, buildings]) => <>
<h1>{getName(lang, 'buildings', `cat-${category}`)}</h1> <h1>{getName(lang, 'buildings', `cat-${category}`)}</h1>
<div class="building-cat"> <div class="building-cat">
@ -101,124 +84,55 @@ const buildingsByCategory = buildingsList.reduce((acc: { [key: string]: Array<DB
))} ))}
</div> </div>
</>)} </>)}
</Layout> </LoggedIn>
<style> <style>
* { .building-cat {
color: white; display: flex;
} flex-direction: row;
flex-wrap: wrap;
row-gap: 40px;
column-gap: 2%;
}
main { #building-modal-background {
margin: auto; display: none;
padding: 1rem; position: fixed;
width: 800px; top: 0;
max-width: calc(100% - 2rem); left: 0;
color: white; width: 100%;
font-size: 20px; height: 100%;
line-height: 1.6; background: rgba(0, 0, 0, 0.5);
} z-index: 100;
}
.building-cat { #building-modal-details {
display: flex; display: none;
flex-direction: row; position: fixed;
flex-wrap: wrap; top: 50%;
row-gap: 40px; left: 50%;
column-gap: 2%; transform: translate(-50%, -50%);
} width: 80%;
max-width: 800px;
background: rgba(0, 0, 0, 0.9);
border-radius: 8px;
padding: 1rem;
z-index: 101;
}
#building-modal-background { h1 {
display: none; font-size: 2rem;
position: fixed; font-weight: 700;
top: 0; line-height: 1;
left: 0; text-align: center;
width: 100%; margin-bottom: 1em;
height: 100%; color: white;
background: rgba(0, 0, 0, 0.5); }
z-index: 100;
}
#building-modal-details { .building-modal-text {
display: none; font-size: 1.5rem;
position: fixed; }
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 80%;
max-width: 800px;
background: rgba(0, 0, 0, 0.9);
border-radius: 8px;
padding: 1rem;
z-index: 101;
}
.astro-a {
position: absolute;
top: -32px;
left: 50%;
transform: translatex(-50%);
width: 220px;
height: auto;
z-index: -1;
}
h3 {
font-size: 2rem;
font-weight: 700;
line-height: 1;
text-align: center;
margin-bottom: 1em;
}
.building-modal-text {
font-size: 1.5rem;
}
.text-gradient {
background-image: var(--accent-gradient);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-size: 400%;
background-position: 0%;
}
.instructions {
margin-bottom: 2rem;
border: 1px solid rgba(var(--accent-light), 25%);
background: linear-gradient(rgba(var(--accent-dark), 66%), rgba(var(--accent-dark), 33%));
padding: 1.5rem;
border-radius: 8px;
}
.instructions code {
font-size: 0.8em;
font-weight: bold;
background: rgba(var(--accent-light), 12%);
color: rgb(var(--accent-light));
border-radius: 4px;
padding: 0.3em 0.4em;
}
.instructions strong {
color: rgb(var(--accent-light));
}
.link-card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(24ch, 1fr));
gap: 2rem;
padding: 0;
}
.a-button {
text-decoration: none;
color: green;
}
.a-button:hover {
color: lime;
}
</style> </style>
<script define:vars={{ modalSet, lang, planetId }}> <script define:vars={{ modalSet, lang }}>
const modalResources = document.getElementById("building-modal-req-resources"); const modalResources = document.getElementById("building-modal-req-resources");
const modalBuildings = document.getElementById("building-modal-req-buildings"); const modalBuildings = document.getElementById("building-modal-req-buildings");
const modalResearch = document.getElementById("building-modal-req-research"); const modalResearch = document.getElementById("building-modal-req-research");

View File

@ -1,30 +1,14 @@
--- ---
import Layout from '../../layouts/Layout.astro'; import LoggedIn from '../../layouts/LoggedIn.astro';
import NavBar from '../../components/NavBar.astro';
import { getUserByAccessToken } from '../../lib/db/users';
import { getHighestWeightedLanguage, getLocales, getName, getObj } from '../../lib/utils/langDriver';
import ResourceBar from '../../components/ResourceBar.astro';
import locationManager from '../../lib/classes/managers/LocationManager'; import locationManager from '../../lib/classes/managers/LocationManager';
import { Planet } from '../../lib/classes/managers/PlanetManager';
import SystemManager from '../../lib/classes/managers/SystemManager';
import { getAllFleetByUser } from '../../lib/db/fleet'; import { getAllFleetByUser } from '../../lib/db/fleet';
import { getAllShips } from '../../lib/db/ships'; import { getAllShips } from '../../lib/db/ships';
import { ObjectId } from 'mongodb'; import { getName } from '../../lib/utils/langDriver';
import SystemManager from '../../lib/classes/managers/SystemManager';
const loggedToken = Astro.cookies.get('sessionToken')?.value ?? null; const { token, user, lang } = Astro.locals;
const username = Astro.cookies.get('username')?.value ?? ""; const active: SystemManager | Planet = Astro.locals.active;
if(loggedToken === null || username === "") return Astro.redirect('/logout');
const checkUser = await getUserByAccessToken(loggedToken);
if(checkUser === null || checkUser.username !== username) return Astro.redirect('/logout');
const user = locationManager.getUser(checkUser._id);
if(!user) return Astro.redirect('/logout');
const planetId = Astro.cookies.get('currentPlanet')?.value ?? "";
if(planetId === "") return "No planet selected";
const planet = locationManager.getPlanet(new ObjectId(planetId));
if(!planet) return "Planet not found";
const ships = await getAllShips(); const ships = await getAllShips();
@ -47,7 +31,7 @@ if(Astro.request.method === "POST") {
}); });
const fleetData = { const fleetData = {
source: planet._id, source: active instanceof SystemManager ? active.data._id : active._id,
destination: form.get('toSystem') ? form.get('destination-system')?.toString() : form.get('destination-planet')?.toString(), destination: form.get('toSystem') ? form.get('destination-system')?.toString() : form.get('destination-planet')?.toString(),
mission: form.get('mission')?.toString() ?? "NULL", mission: form.get('mission')?.toString() ?? "NULL",
ships: ships.map(ship => { ships: ships.map(ship => {
@ -64,7 +48,7 @@ if(Astro.request.method === "POST") {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'Authorization': `Bearer ${loggedToken}` 'Authorization': `Bearer ${token}`
}, },
body: JSON.stringify(fleetData) body: JSON.stringify(fleetData)
}); });
@ -79,31 +63,21 @@ await locationManager.updateFleet();
const fleet = (await getAllFleetByUser(user.id)).filter(f => new Date().getTime() - f.arrivalTime.getTime() < 0); const fleet = (await getAllFleetByUser(user.id)).filter(f => new Date().getTime() - f.arrivalTime.getTime() < 0);
fleet.sort((a, b) => a.departureTime.getTime() - b.departureTime.getTime()); fleet.sort((a, b) => a.departureTime.getTime() - b.departureTime.getTime());
const userSystems = locationManager.getSystemsOwnedBy(user.id);
const galaxies = locationManager.galaxies; const galaxies = locationManager.galaxies;
let own = 0; let own = 0;
let friendly = 0; let friendly = 0;
let enemy = 0; let enemy = 0;
for(const system of userSystems) { for(const f of fleet) {
for(const planet of system.planets) { const source = locationManager.findId(f.source);
for(const f of fleet) { if(source !== null) {
if(f.source.equals(planet._id) || f.source.equals(system.data._id)) own++; if(source instanceof SystemManager) {
else if(f.destination.equals(planet._id) || f.destination.equals(system.data._id)) { if(source.data.ownedBy.id.equals(user.id)) own++;
if(f.mission === 'ATTACK') enemy++; else enemy++;
else { } else {
const sourceObj = locationManager.findId(f.source); if(source.system.data.ownedBy.id.equals(user.id)) own++;
const destinationObj = locationManager.findId(f.destination); else enemy++;
if(!sourceObj || !destinationObj) continue;
const source = sourceObj instanceof SystemManager ? sourceObj.data.ownedBy.id : sourceObj.system.data.ownedBy.id;
const destination = destinationObj instanceof SystemManager ? destinationObj.data.ownedBy.id : destinationObj.system.data.ownedBy.id;
if(!source?.equals(destination)) friendly++;
}
}
} }
} }
} }
@ -132,13 +106,8 @@ const sectorsList = galaxies.map(galaxy => {
}) })
} }
}); });
const lang = await getLocales(Astro.cookies.get('language')?.value ?? await getHighestWeightedLanguage(Astro.request.headers.get('accept-language')));
--- ---
<LoggedIn id="fleet" title="Fleet">
<Layout title="Fleet">
<NavBar loggedIn="true" active="fleet" />
<ResourceBar />
<label for="fleet-toggle"> <label for="fleet-toggle">
<input type="checkbox" id="fleet-toggle"> <input type="checkbox" id="fleet-toggle">
<div class="fleet-status"> <div class="fleet-status">
@ -166,11 +135,11 @@ const lang = await getLocales(Astro.cookies.get('language')?.value ?? await getH
</label> </label>
<div class="fleet-send-container"> <div class="fleet-send-container">
<form method="post"> <form method="post">
<h1>Sending fleet from {planet.name}</h1> <h1>Sending fleet from {active instanceof SystemManager ? active.data.name : active.name}</h1>
<hr /> <hr />
<h2>Ships</h2> <h2>Ships</h2>
<div class="fleet-send-ships"> <div class="fleet-send-ships">
{planet.ships.ships.map(ship => <div class="fleet-ship-card"> {active.ships.ships.map(ship => <div class="fleet-ship-card">
<h3>{getName(lang, 'ships', ship.data.id)} - {ship.amount}</h3> <h3>{getName(lang, 'ships', ship.data.id)} - {ship.amount}</h3>
<input type="number" value="0" min="0" max={ship.amount} id={ship.data.id} name={`ship-amount-${ship.data.id}`} /> <input type="number" value="0" min="0" max={ship.amount} id={ship.data.id} name={`ship-amount-${ship.data.id}`} />
</div>)} </div>)}
@ -220,207 +189,132 @@ const lang = await getLocales(Astro.cookies.get('language')?.value ?? await getH
<button type="submit">Send fleet</button> <button type="submit">Send fleet</button>
</form> </form>
</div> </div>
</Layout> </LoggedIn>
<style> <style>
* { * {
color: white; color: white;
} }
main { .ship-cards {
margin: auto; display: flex;
padding: 1rem; flex-direction: row;
width: 800px; flex-wrap: wrap;
max-width: calc(100% - 2rem); row-gap: 40px;
color: white; column-gap: 2%;
font-size: 20px; }
line-height: 1.6;
}
.astro-a { #ship-modal-background {
position: absolute; display: none;
top: -32px; position: fixed;
left: 50%; top: 0;
transform: translatex(-50%); left: 0;
width: 220px; width: 100%;
height: auto; height: 100%;
z-index: -1; background: rgba(0, 0, 0, 0.5);
} z-index: 100;
}
h3 { #ship-modal-details {
font-size: 2rem; display: none;
font-weight: 700; position: fixed;
line-height: 1; top: 50%;
text-align: center; left: 50%;
margin-bottom: 1em; transform: translate(-50%, -50%);
} width: 80%;
max-width: 800px;
background: rgba(0, 0, 0, 0.9);
border-radius: 8px;
padding: 1rem;
z-index: 101;
}
.text-gradient { .fleet-status {
background-image: var(--accent-gradient); margin-top: 40px;
-webkit-background-clip: text; background-color: gray;
-webkit-text-fill-color: transparent; border-radius: 10px;
background-size: 400%; padding: 2px;
background-position: 0%; }
}
.instructions { .fleet-status ul {
margin-bottom: 2rem; list-style-type: none;
border: 1px solid rgba(var(--accent-light), 25%); padding: 0;
background: linear-gradient(rgba(var(--accent-dark), 66%), rgba(var(--accent-dark), 33%)); opacity: 0;
padding: 1.5rem; max-height: 0;
border-radius: 8px; overflow: hidden;
} transition-property: max-height;
transition-duration: 0.5s;
transition-timing-function: ease;
}
.instructions code { #fleet-toggle {
font-size: 0.8em; position: absolute;
font-weight: bold; top: -9999px;
background: rgba(var(--accent-light), 12%); left: -9999px;
color: rgb(var(--accent-light)); }
border-radius: 4px;
padding: 0.3em 0.4em;
}
.instructions strong { label {
color: rgb(var(--accent-light)); -webkit-appearance: push-button;
} -moz-appearance: button;
margin: 60px 0 10px 0;
cursor: pointer;
}
.link-card-grid { #fleet-toggle:checked ~ .fleet-status ul {
display: grid; opacity: 1;
grid-template-columns: repeat(auto-fit, minmax(24ch, 1fr)); height: auto;
gap: 2rem; max-height: 1000px;
padding: 0; }
}
.a-button { .fleet-send-container {
text-decoration: none; margin-top: 40px;
color: green; background-color: gray;
height: fit-content; border-radius: 10px;
} padding: 2px;
}
.a-button:hover { .fleet-send-ships {
color: lime; display: flex;
} flex-direction: row;
flex-wrap: wrap;
row-gap: 40px;
column-gap: 2%;
margin-top: 40px;
}
.ship-cards { .fleet-ship-card {
display: flex; background-color: gray;
flex-direction: row; border-radius: 10px;
flex-wrap: wrap; padding: 2px;
row-gap: 40px; }
column-gap: 2%;
}
#ship-modal-background { .fleet-ship-card h3 {
display: none; margin: 0;
position: fixed; }
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
z-index: 100;
}
#ship-modal-details { .fleet-ship-card input {
display: none; width: 10rem;
position: fixed; color: black;
top: 50%; }
left: 50%;
transform: translate(-50%, -50%);
width: 80%;
max-width: 800px;
background: rgba(0, 0, 0, 0.9);
border-radius: 8px;
padding: 1rem;
z-index: 101;
}
.fleet-status { .fleet-destination select {
margin-top: 40px; width: 10rem;
background-color: gray; height: 3rem;
border-radius: 10px; color: black;
padding: 2px; background-color: darkgray;
} }
.fleet-status ul { .cargo-add-new {
list-style-type: none; background-color: #aaaaaa;
padding: 0; border-radius: 10px;
opacity: 0; padding: 2px;
max-height: 0; width: fit-content;
overflow: hidden; color: black;
}
transition-property: max-height; .select, .input {
transition-duration: 0.5s; color: black;
transition-timing-function: ease; }
}
#fleet-toggle {
position: absolute;
top: -9999px;
left: -9999px;
}
label {
-webkit-appearance: push-button;
-moz-appearance: button;
margin: 60px 0 10px 0;
cursor: pointer;
}
#fleet-toggle:checked ~ .fleet-status ul {
opacity: 1;
height: auto;
max-height: 1000px;
}
.fleet-send-container {
margin-top: 40px;
background-color: gray;
border-radius: 10px;
padding: 2px;
}
.fleet-send-ships {
display: flex;
flex-direction: row;
flex-wrap: wrap;
row-gap: 40px;
column-gap: 2%;
margin-top: 40px;
}
.fleet-ship-card {
background-color: gray;
border-radius: 10px;
padding: 2px;
}
.fleet-ship-card h3 {
margin: 0;
}
.fleet-ship-card input {
width: 10rem;
color: black;
}
.fleet-destination select {
width: 10rem;
height: 3rem;
color: black;
background-color: darkgray;
}
.cargo-add-new {
background-color: #aaaaaa;
border-radius: 10px;
padding: 2px;
width: fit-content;
color: black;
}
.select, .input {
color: black;
}
</style> </style>
<script define:vars={{ sectorsList }}> <script define:vars={{ sectorsList }}>
const destinationGalaxy = document.getElementById('destination-galaxy'); const destinationGalaxy = document.getElementById('destination-galaxy');
@ -552,5 +446,4 @@ const lang = await getLocales(Astro.cookies.get('language')?.value ?? await getH
cargoContainer.appendChild(cargoItem); cargoContainer.appendChild(cargoItem);
}); });
</script> </script>

View File

@ -1,16 +1,6 @@
--- ---
import Layout from '../../layouts/Layout.astro'; import LoggedIn from '../../layouts/LoggedIn.astro';
import NavBar from '../../components/NavBar.astro';
import { getUserByAccessToken } from '../../lib/db/users';
import locationManager from '../../lib/classes/managers/LocationManager'; import locationManager from '../../lib/classes/managers/LocationManager';
import ResourceBar from '../../components/ResourceBar.astro';
const loggedToken = Astro.cookies.get('sessionToken')?.value ?? null;
const username = Astro.cookies.get('username')?.value ?? "";
if(loggedToken === null || username === "") return Astro.redirect('/logout');
const checkUser = await getUserByAccessToken(loggedToken);
if(checkUser === null || checkUser.username !== username) return Astro.redirect('/logout');
const allGalaxies = locationManager.galaxies; const allGalaxies = locationManager.galaxies;
@ -33,10 +23,7 @@ const galaxies = allGalaxies.map(galaxy => {
}; };
}) })
--- ---
<LoggedIn id="galaxyView" title="Galaxy view">
<Layout title="Galaxy view">
<NavBar loggedIn="true" active="galaxyView" />
<ResourceBar />
<div class="container"> <div class="container">
<div class="galaxy-container"> <div class="galaxy-container">
{galaxies.map(galaxy => <> {galaxies.map(galaxy => <>
@ -49,73 +36,70 @@ const galaxies = allGalaxies.map(galaxy => {
</div> </div>
<div class="galaxy-details"> <div class="galaxy-details">
<h2></h2> <h2></h2>
<div class="galaxy-sector-list"> <div class="galaxy-sector-list"></div>
</div>
</div> </div>
</div> </div>
</Layout> </LoggedIn>
<style is:global> <style is:global>
.container { .container {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
color: white; color: white;
} }
.galaxy-container { .galaxy-container {
width: 70%; width: 70%;
height: 500px; height: 500px;
background-color: blue; background-color: blue;
margin-left: 50px; margin-left: 50px;
margin-right: auto; margin-right: auto;
margin-top: 50px; margin-top: 50px;
position: relative; position: relative;
} }
.galaxy-icon { .galaxy-icon {
position:absolute; position:absolute;
width: 40px; width: 40px;
height: 40px; height: 40px;
background-color: white; background-color: white;
border-radius: 20px; border-radius: 20px;
} }
.galaxy-icon:hover { .galaxy-icon:hover {
background-color: yellow !important; background-color: yellow !important;
} }
.galaxy-name { .galaxy-name {
position: absolute; position: absolute;
top: 40px; top: 40px;
left: -5px; left: -5px;
color: white; color: white;
} }
.galaxy-details { .galaxy-details {
width: 23%; width: 23%;
height: 500px; height: 500px;
margin-top: 50px; margin-top: 50px;
margin-right: 50px; margin-right: 50px;
} }
.galaxy-details h2 { .galaxy-details h2 {
text-align: center; text-align: center;
} }
.galaxy-sector-list { .galaxy-sector-list {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }
.galaxy-sector-list div { .galaxy-sector-list div {
text-align: center; text-align: center;
background-color: gray; background-color: gray;
margin-top: 10px; margin-top: 10px;
border-radius: 10px; border-radius: 10px;
padding-top: 10px; padding-top: 10px;
padding-bottom: 10px; padding-bottom: 10px;
} }
</style> </style>
<script> <script>
function gvinit() { function gvinit() {

View File

@ -1,100 +1,15 @@
--- ---
import Layout from '../../layouts/Layout.astro'; import LoggedIn from '../../layouts/LoggedIn.astro';
import NavBar from '../../components/NavBar.astro'; import { Planet } from '../../lib/classes/managers/PlanetManager';
import ResourceBar from '../../components/ResourceBar.astro'; import SystemManager from '../../lib/classes/managers/SystemManager';
import { getUserByAccessToken } from '../../lib/db/users';
import locationManager from '../../lib/classes/managers/LocationManager';
import { ObjectId } from 'mongodb';
const loggedToken = Astro.cookies.get('sessionToken')?.value ?? null; const active: SystemManager | Planet = Astro.locals.active;
const username = Astro.cookies.get('username')?.value ?? "";
if(loggedToken === null || username === "") return Astro.redirect('/logout');
const checkUser = await getUserByAccessToken(loggedToken);
if(checkUser === null || checkUser.username !== username) return Astro.redirect('/logout');
const currentPlanetId = Astro.cookies.get('currentPlanet')?.value ?? null;
if(currentPlanetId === null) return Astro.redirect('/logout');
const currentPlanet = locationManager.getPlanet(new ObjectId(currentPlanetId));
if(currentPlanet === undefined) {
Astro.cookies.delete('planetid');
return Astro.redirect('/logout');
}
--- ---
<LoggedIn id="overview" title="Overview">
<Layout title="Overview"> <h1>{active instanceof SystemManager ? `${active.data.name} system` : `${active.name} in ${active.system.data.name}`}</h1>
<NavBar loggedIn="true" active="overview" /> </LoggedIn>
<ResourceBar />
<h1>{currentPlanet.name} in {currentPlanet.system.data.name}</h1>
</Layout>
<style> <style>
* { h1 {
color: white; color: white;
} }
main {
margin: auto;
padding: 1rem;
width: 800px;
max-width: calc(100% - 2rem);
color: white;
font-size: 20px;
line-height: 1.6;
}
.astro-a {
position: absolute;
top: -32px;
left: 50%;
transform: translatex(-50%);
width: 220px;
height: auto;
z-index: -1;
}
h3 {
font-size: 2rem;
font-weight: 700;
line-height: 1;
text-align: center;
margin-bottom: 1em;
}
.text-gradient {
background-image: var(--accent-gradient);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-size: 400%;
background-position: 0%;
}
.instructions {
margin-bottom: 2rem;
border: 1px solid rgba(var(--accent-light), 25%);
background: linear-gradient(rgba(var(--accent-dark), 66%), rgba(var(--accent-dark), 33%));
padding: 1.5rem;
border-radius: 8px;
}
.instructions code {
font-size: 0.8em;
font-weight: bold;
background: rgba(var(--accent-light), 12%);
color: rgb(var(--accent-light));
border-radius: 4px;
padding: 0.3em 0.4em;
}
.instructions strong {
color: rgb(var(--accent-light));
}
.link-card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(24ch, 1fr));
gap: 2rem;
padding: 0;
}
</style> </style>

View File

@ -1,10 +1,11 @@
--- ---
import Layout from '../../layouts/Layout.astro'; import LoggedIn from '../../layouts/LoggedIn.astro';
import NavBar from '../../components/NavBar.astro'; import User from '../../lib/classes/User';
import { getUserByAccessToken, getUserByNickOrEmail } from '../../lib/db/users';
import { getHighestWeightedLanguage, getLocales, getName, getSupportedLanguages } from '../../lib/utils/langDriver';
import ResourceBar from '../../components/ResourceBar.astro';
import format from '../../lib/utils/format'; import format from '../../lib/utils/format';
import { getName, getSupportedLanguages } from '../../lib/utils/langDriver';
const { token, lang } = Astro.locals;
const user: User = Astro.locals.user;
const availableLanguages = await getSupportedLanguages(); const availableLanguages = await getSupportedLanguages();
@ -23,28 +24,10 @@ if(Astro.request.method === "POST") {
secure: true secure: true
}); });
} }
const loggedToken = Astro.cookies.get('sessionToken')?.value ?? null;
const username = Astro.cookies.get('username')?.value ?? "";
if(loggedToken === null || username === "") return Astro.redirect('/logout');
const checkUser = await getUserByAccessToken(loggedToken);
if(checkUser === null || checkUser.username !== username) return Astro.redirect('/logout');
const locale = Astro.cookies.get('language')?.value ?? await getHighestWeightedLanguage(Astro.request.headers.get('accept-language') ?? "en");
const user = await getUserByNickOrEmail(username);
const lang = await getLocales(locale);
const currentLanguage = Astro.cookies.get('language')?.value ?? "en"; const currentLanguage = Astro.cookies.get('language')?.value ?? "en";
--- ---
<LoggedIn id="profile" title="Profile">
<Layout title="Profile"> {token}
<NavBar loggedIn="true" active="profile" />
<ResourceBar loggedIn="true" />
{loggedToken}
<div class="wrapper"> <div class="wrapper">
<h3>{format(getName(lang, 'general', 'user-creation-date'), user?.createdAt.toISOString().slice(0, 19).replace(/-/g, "/").replace("T", " ").toString() ?? "")}</h3> <h3>{format(getName(lang, 'general', 'user-creation-date'), user?.createdAt.toISOString().slice(0, 19).replace(/-/g, "/").replace("T", " ").toString() ?? "")}</h3>
<a href="/logout" class="a-button">{getName(lang, 'general', 'nav-logout')}</a> <a href="/logout" class="a-button">{getName(lang, 'general', 'nav-logout')}</a>
@ -66,7 +49,7 @@ const currentLanguage = Astro.cookies.get('language')?.value ?? "en";
<input class="data-form-button" type="button" value={getName(lang, 'general', 'change-password')} /> <input class="data-form-button" type="button" value={getName(lang, 'general', 'change-password')} />
</form> </form>
<form id="changeLanguageForm" class="data-form" method="post"> <form id="changeLanguageForm" class="data-form" method="post">
<h4>{getName(lang, 'general', 'current-language')}: {availableLanguages.find(l => l.id === currentLanguage)?.name ?? "N/A"}</h4> <h3>{getName(lang, 'general', 'current-language')}: {availableLanguages.find(l => l.id === currentLanguage)?.name ?? "N/A"}</h3>
<select class="data-form-input" name="language"> <select class="data-form-input" name="language">
{availableLanguages.map((lang) => ( {availableLanguages.map((lang) => (
<option value={lang.id}>{lang.name}</option> <option value={lang.id}>{lang.name}</option>
@ -74,111 +57,46 @@ const currentLanguage = Astro.cookies.get('language')?.value ?? "en";
</select> </select>
<input type="submit" class="data-form-button" value={getName(lang, 'general', 'change-language')} /> <input type="submit" class="data-form-button" value={getName(lang, 'general', 'change-language')} />
</form> </form>
</Layout> </LoggedIn>
<style> <style>
* { h3 {
color: white; color: white;
} }
.data-form { .data-form {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
margin-top: 2rem; margin-top: 2rem;
} }
.data-form-input { .data-form-input {
color: black; color: black;
} }
.data-form-button { .data-form-button {
color: red; color: red;
font-weight: 700; font-weight: 700;
} }
.wrapper { .wrapper {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
margin-top: 2rem; margin-top: 2rem;
color: white; color: white;
} }
main { .a-button {
margin: auto; text-decoration: none;
padding: 1rem; color: green;
width: 800px; }
max-width: calc(100% - 2rem);
color: white;
font-size: 20px;
line-height: 1.6;
}
.astro-a { .a-button:hover {
position: absolute; color: lime;
top: -32px; }
left: 50%;
transform: translatex(-50%);
width: 220px;
height: auto;
z-index: -1;
}
h3 {
font-size: 2rem;
font-weight: 700;
line-height: 1;
text-align: center;
margin-bottom: 1em;
}
.text-gradient {
background-image: var(--accent-gradient);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-size: 400%;
background-position: 0%;
}
.instructions {
margin-bottom: 2rem;
border: 1px solid rgba(var(--accent-light), 25%);
background: linear-gradient(rgba(var(--accent-dark), 66%), rgba(var(--accent-dark), 33%));
padding: 1.5rem;
border-radius: 8px;
}
.instructions code {
font-size: 0.8em;
font-weight: bold;
background: rgba(var(--accent-light), 12%);
color: rgb(var(--accent-light));
border-radius: 4px;
padding: 0.3em 0.4em;
}
.instructions strong {
color: rgb(var(--accent-light));
}
.link-card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(24ch, 1fr));
gap: 2rem;
padding: 0;
}
.a-button {
text-decoration: none;
color: green;
}
.a-button:hover {
color: lime;
}
</style> </style>
<script> <script>
const changeUsernameForm = document.getElementById('changeUsernameForm'); const changeUsernameForm = document.getElementById('changeUsernameForm');

View File

@ -1,24 +1,18 @@
--- ---
import Layout from '../../layouts/Layout.astro';
import NavBar from '../../components/NavBar.astro';
import { getUserByAccessToken } from '../../lib/db/users';
import { getHighestWeightedLanguage, getLocales, getName, getObj } from '../../lib/utils/langDriver';
import ResourceBar from '../../components/ResourceBar.astro';
import ItemCard from '../../components/ItemCard.astro'; import ItemCard from '../../components/ItemCard.astro';
import LoggedIn from '../../layouts/LoggedIn.astro';
import User from '../../lib/classes/User';
import { Planet } from '../../lib/classes/managers/PlanetManager';
import SystemManager from '../../lib/classes/managers/SystemManager';
import { getAllResearch } from '../../lib/db/research'; import { getAllResearch } from '../../lib/db/research';
import { getObj } from '../../lib/utils/langDriver';
const { token, lang } = Astro.locals;
const active: SystemManager | Planet = Astro.locals.active;
const user: User = Astro.locals.user;
const researchList = await getAllResearch(); const researchList = await getAllResearch();
const loggedToken = Astro.cookies.get('sessionToken')?.value ?? null;
const username = Astro.cookies.get('username')?.value ?? "";
if(loggedToken === null || username === "") return Astro.redirect('/logout');
const checkUser = await getUserByAccessToken(loggedToken);
if(checkUser === null || checkUser.username !== username) return Astro.redirect('/logout');
const planetId = Astro.cookies.get('currentPlanet')?.value ?? "";
if(planetId === "") return Astro.redirect('/logout');
if(Astro.request.method === "POST") { if(Astro.request.method === "POST") {
const selectedResearchId = (await Astro.request.formData()).get('id') as string | null; const selectedResearchId = (await Astro.request.formData()).get('id') as string | null;
@ -26,21 +20,17 @@ if(Astro.request.method === "POST") {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'Authorization': 'Bearer ' + loggedToken 'Authorization': 'Bearer ' + token
}, },
body: JSON.stringify({ body: JSON.stringify({
research: selectedResearchId, research: selectedResearchId,
planetId planetId: active instanceof SystemManager ? active.data._id : active._id
}) })
})).json(); })).json();
console.log(request); console.log(request);
} }
const locale = Astro.cookies.get('language')?.value ?? await getHighestWeightedLanguage(Astro.request.headers.get('accept-language'));
const lang = await getLocales(locale);
const modalSet: { [key: string]: { resources: Array<any>, research: Array<any>, buildings: Array<any> } } = {}; const modalSet: { [key: string]: { resources: Array<any>, research: Array<any>, buildings: Array<any> } } = {};
for(const research of researchList) { for(const research of researchList) {
@ -52,11 +42,7 @@ for(const research of researchList) {
}; };
} }
--- ---
<LoggedIn id="research" title="Research">
<Layout title="Research">
<NavBar loggedIn="true" active="research" />
<ResourceBar />
<div id="research-modal-background"> <div id="research-modal-background">
<div id="research-modal-details" data-building-id=""> <div id="research-modal-details" data-building-id="">
<h3>Required resources</h3> <h3>Required resources</h3>
@ -67,136 +53,56 @@ for(const research of researchList) {
<div class="research-modal-text" id="research-modal-req-research">None</div> <div class="research-modal-text" id="research-modal-req-research">None</div>
</div> </div>
</div> </div>
<div class="research-cards"> <div class="research-cards">
{researchList.map(research => <> {researchList.map(research => <>
<ItemCard <ItemCard
category="research" category="research"
id={research.id} id={research.id}
name={getObj(lang, "research", research.id).name} name={getObj(lang, "research", research.id).name}
level={checkUser.research.find(x => x.id === research.id)?.level.toString() ?? "0"} level={user.research.getResearchById(research.id)?.level.toString() ?? "0"}
description={getObj(lang, "research", research.id).description ?? ""} description={getObj(lang, "research", research.id).description ?? ""}
image={`/images/research/${research.id}.jpeg`} image={`/images/research/${research.id}.jpeg`}
button_type="general" button_type="general"
button_name="nav-research" /> button_name="nav-research" />
</>)} </>)}
</div> </div>
</Layout> </LoggedIn>
<style> <style>
* { .research-cards {
color: white; display: flex;
} flex-direction: row;
flex-wrap: wrap;
row-gap: 40px;
column-gap: 2%;
margin-top: 40px;
}
main { #research-modal-background {
margin: auto; display: none;
padding: 1rem; position: fixed;
width: 800px; top: 0;
max-width: calc(100% - 2rem); left: 0;
color: white; width: 100%;
font-size: 20px; height: 100%;
line-height: 1.6; background: rgba(0, 0, 0, 0.5);
} z-index: 100;
}
.astro-a { #research-modal-details {
position: absolute; display: none;
top: -32px; position: fixed;
left: 50%; top: 50%;
transform: translatex(-50%); left: 50%;
width: 220px; transform: translate(-50%, -50%);
height: auto; width: 80%;
z-index: -1; max-width: 800px;
} background: rgba(0, 0, 0, 0.9);
border-radius: 8px;
h3 { padding: 1rem;
font-size: 2rem; z-index: 101;
font-weight: 700; }
line-height: 1;
text-align: center;
margin-bottom: 1em;
}
.text-gradient {
background-image: var(--accent-gradient);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-size: 400%;
background-position: 0%;
}
.instructions {
margin-bottom: 2rem;
border: 1px solid rgba(var(--accent-light), 25%);
background: linear-gradient(rgba(var(--accent-dark), 66%), rgba(var(--accent-dark), 33%));
padding: 1.5rem;
border-radius: 8px;
}
.instructions code {
font-size: 0.8em;
font-weight: bold;
background: rgba(var(--accent-light), 12%);
color: rgb(var(--accent-light));
border-radius: 4px;
padding: 0.3em 0.4em;
}
.instructions strong {
color: rgb(var(--accent-light));
}
.link-card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(24ch, 1fr));
gap: 2rem;
padding: 0;
}
.a-button {
text-decoration: none;
color: green;
height: fit-content;
}
.a-button:hover {
color: lime;
}
.research-cards {
display: flex;
flex-direction: row;
flex-wrap: wrap;
row-gap: 40px;
column-gap: 2%;
margin-top: 40px;
}
#research-modal-background {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
z-index: 100;
}
#research-modal-details {
display: none;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 80%;
max-width: 800px;
background: rgba(0, 0, 0, 0.9);
border-radius: 8px;
padding: 1rem;
z-index: 101;
}
</style> </style>
<script define:vars={{ modalSet, lang, planetId }}> <script define:vars={{ modalSet, lang }}>
const modalResources = document.getElementById("research-modal-req-resources"); const modalResources = document.getElementById("research-modal-req-resources");
const modalBuildings = document.getElementById("research-modal-req-buildings"); const modalBuildings = document.getElementById("research-modal-req-buildings");
const modalResearch = document.getElementById("research-modal-req-research"); const modalResearch = document.getElementById("research-modal-req-research");

View File

@ -1,37 +1,16 @@
--- ---
import Layout from '../../layouts/Layout.astro';
import NavBar from '../../components/NavBar.astro';
import { getUserByAccessToken } from '../../lib/db/users';
import { getHighestWeightedLanguage, getLocales, getObj } from '../../lib/utils/langDriver';
import ResourceBar from '../../components/ResourceBar.astro';
import { getAllShips } from '../../lib/db/ships';
import ItemCard from '../../components/ItemCard.astro'; import ItemCard from '../../components/ItemCard.astro';
import locationManager from '../../lib/classes/managers/LocationManager'; import LoggedIn from '../../layouts/LoggedIn.astro';
import { ObjectId } from 'mongodb'; import { Planet } from '../../lib/classes/managers/PlanetManager';
import SystemManager from '../../lib/classes/managers/SystemManager';
import { getAllShips } from '../../lib/db/ships';
import { getObj } from '../../lib/utils/langDriver';
const loggedToken = Astro.cookies.get('sessionToken')?.value ?? null; const { lang } = Astro.locals;
const username = Astro.cookies.get('username')?.value ?? ""; const active: SystemManager | Planet = Astro.locals.active;
if(loggedToken === null || username === "") return Astro.redirect('/logout');
const checkUser = await getUserByAccessToken(loggedToken);
if(checkUser === null || checkUser.username !== username) return Astro.redirect('/logout');
const ships = await getAllShips(); const ships = await getAllShips();
const planetId = Astro.cookies.get('currentPlanet')?.value ?? "";
if(planetId === "") {
console.error("No planet selected");
return Astro.redirect('/logout');
}
const planet = locationManager.getPlanet(new ObjectId(planetId));
if(!planet) {
console.error("Planet not found");
return Astro.redirect('/logout');
}
const lang = await getLocales(Astro.cookies.get('language')?.value ?? await getHighestWeightedLanguage(Astro.request.headers.get('accept-language')));
const modalSet: { [key: string]: { resources: Array<any>, research: Array<any>, buildings: Array<any> } } = {}; const modalSet: { [key: string]: { resources: Array<any>, research: Array<any>, buildings: Array<any> } } = {};
for(const ship of ships) { for(const ship of ships) {
@ -42,12 +21,10 @@ for(const ship of ships) {
// energy: building.energy // energy: building.energy
}; };
} }
const planetId = active instanceof SystemManager ? active.data._id : active._id;
--- ---
<LoggedIn id="ships" title="Ships">
<Layout title="Ships">
<NavBar loggedIn="true" active="ships" />
<ResourceBar />
<div id="ship-modal-background"> <div id="ship-modal-background">
<div id="ship-modal-details" data-building-id=""> <div id="ship-modal-details" data-building-id="">
<h3>Required resources</h3> <h3>Required resources</h3>
@ -65,127 +42,49 @@ for(const ship of ships) {
category="ships" category="ships"
id={ship.id} id={ship.id}
name={getObj(lang, "ships", ship.id).name} name={getObj(lang, "ships", ship.id).name}
level={planet.ships.getShipById(ship.id)?.amount.toString() ?? "0"} level={active.ships.getShipById(ship.id)?.amount.toString() ?? "0"}
description={getObj(lang, "ships", ship.id).description ?? ""} description={getObj(lang, "ships", ship.id).description ?? ""}
image={`/images/ships/${ship.id}.jpeg`} image={`/images/ships/${ship.id}.jpeg`}
button_type="general" button_type="general"
button_name="nav-build" /> button_name="nav-build" />
</>)} </>)}
</div> </div>
</Layout> </LoggedIn>
<style> <style>
* { .ship-cards {
color: white; display: flex;
} flex-direction: row;
flex-wrap: wrap;
row-gap: 40px;
column-gap: 2%;
margin-top: 40px;
}
main { #ship-modal-background {
margin: auto; display: none;
padding: 1rem; position: fixed;
width: 800px; top: 0;
max-width: calc(100% - 2rem); left: 0;
color: white; width: 100%;
font-size: 20px; height: 100%;
line-height: 1.6; background: rgba(0, 0, 0, 0.5);
} z-index: 100;
}
.astro-a { #ship-modal-details {
position: absolute; display: none;
top: -32px; position: fixed;
left: 50%; top: 50%;
transform: translatex(-50%); left: 50%;
width: 220px; transform: translate(-50%, -50%);
height: auto; width: 80%;
z-index: -1; max-width: 800px;
} background: rgba(0, 0, 0, 0.9);
border-radius: 8px;
h3 { padding: 1rem;
font-size: 2rem; z-index: 101;
font-weight: 700; }
line-height: 1;
text-align: center;
margin-bottom: 1em;
}
.text-gradient {
background-image: var(--accent-gradient);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-size: 400%;
background-position: 0%;
}
.instructions {
margin-bottom: 2rem;
border: 1px solid rgba(var(--accent-light), 25%);
background: linear-gradient(rgba(var(--accent-dark), 66%), rgba(var(--accent-dark), 33%));
padding: 1.5rem;
border-radius: 8px;
}
.instructions code {
font-size: 0.8em;
font-weight: bold;
background: rgba(var(--accent-light), 12%);
color: rgb(var(--accent-light));
border-radius: 4px;
padding: 0.3em 0.4em;
}
.instructions strong {
color: rgb(var(--accent-light));
}
.link-card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(24ch, 1fr));
gap: 2rem;
padding: 0;
}
.a-button {
text-decoration: none;
color: green;
height: fit-content;
}
.a-button:hover {
color: lime;
}
.ship-cards {
display: flex;
flex-direction: row;
flex-wrap: wrap;
row-gap: 40px;
column-gap: 2%;
margin-top: 40px;
}
#ship-modal-background {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
z-index: 100;
}
#ship-modal-details {
display: none;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 80%;
max-width: 800px;
background: rgba(0, 0, 0, 0.9);
border-radius: 8px;
padding: 1rem;
z-index: 101;
}
</style> </style>
<script define:vars={{ modalSet, lang, planetId }}> <script define:vars={{ modalSet, lang, planetId }}>
const modalResources = document.getElementById("ship-modal-req-resources"); const modalResources = document.getElementById("ship-modal-req-resources");

View File

@ -1,24 +1,12 @@
--- ---
import { ObjectId } from "mongodb"; import { ObjectId } from "mongodb";
import NavBar from "../../../components/NavBar.astro"; import LoggedIn from "../../../layouts/LoggedIn.astro";
import ResourceBar from "../../../components/ResourceBar.astro";
import Layout from "../../../layouts/Layout.astro";
import locationManager from "../../../lib/classes/managers/LocationManager"; import locationManager from "../../../lib/classes/managers/LocationManager";
import { getUserByAccessToken } from "../../../lib/db/users";
const loggedToken = Astro.cookies.get('sessionToken')?.value ?? null;
const username = Astro.cookies.get('username')?.value ?? "";
if(loggedToken === null || username === "") return Astro.redirect('/logout');
const checkUser = await getUserByAccessToken(loggedToken);
if(checkUser === null || checkUser.username !== username) return Astro.redirect('/logout');
const currentSystemId = Astro.cookies.get('currentSystem')?.value ?? null; const currentSystemId = Astro.cookies.get('currentSystem')?.value ?? null;
if(currentSystemId === null) return Astro.redirect('/game/systemManager/select'); if(currentSystemId === null) return Astro.redirect('/game/systemManager/select');
const currentSystem = locationManager.getSystem(new ObjectId(currentSystemId)); const currentSystem = locationManager.getSystem(new ObjectId(currentSystemId));
if(currentSystem === undefined) { if(currentSystem === undefined) {
Astro.cookies.delete('currentSystem'); Astro.cookies.delete('currentSystem');
return Astro.redirect('/game/systemManager/select'); return Astro.redirect('/game/systemManager/select');
@ -35,12 +23,11 @@ if(Astro.request.method === "POST") {
secure: true secure: true
}); });
} }
return Astro.redirect('/game/systemManager');
} }
--- ---
<Layout title="System Manager"> <LoggedIn id="systemManager" title="System Manager">
<NavBar loggedIn="true" active="systemManager" />
<ResourceBar />
<h1>Selected system: {currentSystem.data.name} in {currentSystem.data.sector.name} in {currentSystem.data.sector.galaxy.name} <a href="/game/systemManager/select">(change)</a></h1> <h1>Selected system: {currentSystem.data.name} in {currentSystem.data.sector.name} in {currentSystem.data.sector.galaxy.name} <a href="/game/systemManager/select">(change)</a></h1>
<div class="system-links"> <div class="system-links">
<a href="/game/systemManager">Overview</a> <a href="/game/systemManager">Overview</a>
@ -48,10 +35,22 @@ if(Astro.request.method === "POST") {
<a href="/game/systemManager/spaceStations">Space stations</a> <a href="/game/systemManager/spaceStations">Space stations</a>
<a href="/game/systemManager/asteroids">Asteroids</a> <a href="/game/systemManager/asteroids">Asteroids</a>
</div> </div>
<div class="resources">
<p>Resources: {currentSystem.resources.resources.map(r => `${r.id}: ${r.amount}`).join(", ")}</p>
</div>
<div class="planet-list"> <div class="planet-list">
<div class="system-card">
<h2 style="color: red;">{currentSystem.data.name}<div><form method="post"><input type="hidden" name="planetId" value={currentSystem.data._id.toString()} /><input type="submit" value="Select" /></form></div></h2>
<h3>Resources:</h3>
<div>
{currentSystem.resources.resources.length === 0 ? <span>None</span> : currentSystem.resources.resources.map(res => (
<p>{res.data.id} - {res.amount}</p>
))}
</div>
<h3>Ships: </h3>
<div>
{currentSystem.ships.ships.length === 0 ? <span>None</span> : currentSystem.ships.ships.map(ship => (
<p>{ship.data.id} - {ship.amount}</p>
))}
</div>
</div>
{currentSystem.planets.length === 0 ? <span>No planets in this sector</span> : currentSystem.planets.map(planet => ( {currentSystem.planets.length === 0 ? <span>No planets in this sector</span> : currentSystem.planets.map(planet => (
<div class="planet-card"> <div class="planet-card">
<h2>{planet.name}<div><form method="post"><input type="hidden" name="planetId" value={planet._id.toString()} /><input type="submit" value="Select" /></form></div></h2> <h2>{planet.name}<div><form method="post"><input type="hidden" name="planetId" value={planet._id.toString()} /><input type="submit" value="Select" /></form></div></h2>
@ -71,64 +70,71 @@ if(Astro.request.method === "POST") {
</div> </div>
))} ))}
</div> </div>
</Layout> </LoggedIn>
<style> <style>
* { * {
color: white; color: white;
} }
h1 { h1 {
text-align: center; text-align: center;
color: white; color: white;
} }
h1 a { h1 a {
color: lime; color: lime;
} }
.system-links { .system-links {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: center; justify-content: center;
margin-bottom: 1rem; margin-bottom: 1rem;
} }
.system-links a { .system-links a {
color: white; color: white;
background-color: #555; background-color: #555;
padding: 0.5rem; padding: 0.5rem;
margin: 0 1rem; margin: 0 1rem;
border-radius: 5px; border-radius: 5px;
text-decoration: none; text-decoration: none;
} }
.resources { .resources {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: center; justify-content: center;
margin-bottom: 1rem; margin-bottom: 1rem;
} }
.planet-list { .ships {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
flex-wrap: wrap; justify-content: center;
justify-content: space-evenly; margin-bottom: 1rem;
color: white; }
}
.system-card input { .planet-list {
background-color: #555; display: flex;
color: white; flex-direction: row;
border: none; flex-wrap: wrap;
padding: 0.5rem; justify-content: space-evenly;
border-radius: 5px; color: white;
cursor: pointer; }
}
.system-card div { .system-card input {
margin-top: auto; background-color: #555;
margin-bottom: auto; color: white;
margin-left: 2rem; border: none;
} padding: 0.5rem;
border-radius: 5px;
cursor: pointer;
}
.system-card div {
margin-top: auto;
margin-bottom: auto;
margin-left: 2rem;
}
</style> </style>

View File

@ -1,16 +1,9 @@
--- ---
import NavBar from "../../../components/NavBar.astro"; import LoggedIn from "../../../layouts/LoggedIn.astro";
import ResourceBar from "../../../components/ResourceBar.astro"; import User from "../../../lib/classes/User";
import Layout from "../../../layouts/Layout.astro";
import locationManager from "../../../lib/classes/managers/LocationManager"; import locationManager from "../../../lib/classes/managers/LocationManager";
import { getUserByAccessToken } from "../../../lib/db/users";
const loggedToken = Astro.cookies.get('sessionToken')?.value ?? null; const user: User = Astro.locals.user;
const username = Astro.cookies.get('username')?.value ?? "";
if(loggedToken === null || username === "") return Astro.redirect('/logout');
const checkUser = await getUserByAccessToken(loggedToken);
if(checkUser === null || checkUser.username !== username) return Astro.redirect('/logout');
if(Astro.request.method === "POST") { if(Astro.request.method === "POST") {
const selectedSystemId = (await Astro.request.formData()).get('systemId') as string | null; const selectedSystemId = (await Astro.request.formData()).get('systemId') as string | null;
@ -27,12 +20,9 @@ if(Astro.request.method === "POST") {
} }
} }
const systems = locationManager.getSystemsOwnedBy(checkUser._id); const systems = locationManager.getSystemsOwnedBy(user.id);
--- ---
<Layout title="System Manager"> <LoggedIn id="systemManager" title="System Manager">
<NavBar loggedIn="true" active="systemManager" />
<ResourceBar />
<div class="systems-list"> <div class="systems-list">
{systems.map(system => ( {systems.map(system => (
<div class="system-card"> <div class="system-card">
@ -41,37 +31,37 @@ const systems = locationManager.getSystemsOwnedBy(checkUser._id);
</div> </div>
))} ))}
</div> </div>
</Layout> </LoggedIn>
<style> <style>
.systems-list { .systems-list {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
flex-wrap: wrap; flex-wrap: wrap;
justify-content: center; justify-content: center;
} }
.system-card { .system-card {
background-color: #333; background-color: #333;
color: white; color: white;
padding: 1rem; padding: 1rem;
margin: 1rem; margin: 1rem;
border-radius: 5px; border-radius: 5px;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
} }
.system-card input { .system-card input {
background-color: #555; background-color: #555;
color: white; color: white;
border: none; border: none;
padding: 0.5rem; padding: 0.5rem;
border-radius: 5px; border-radius: 5px;
cursor: pointer; cursor: pointer;
} }
.system-card div { .system-card div {
margin-top: auto; margin-top: auto;
margin-bottom: auto; margin-bottom: auto;
margin-left: 2rem; margin-left: 2rem;
} }
</style> </style>

View File

@ -1,26 +1,16 @@
--- ---
import { ObjectId } from "mongodb"; import { ObjectId } from "mongodb";
import NavBar from "../../../components/NavBar.astro";
import ResourceBar from "../../../components/ResourceBar.astro";
import Layout from "../../../layouts/Layout.astro";
import locationManager from "../../../lib/classes/managers/LocationManager";
import { getUserByAccessToken } from "../../../lib/db/users";
import { getHighestWeightedLanguage, getLocales, getName, getObj } from "../../../lib/utils/langDriver";
import ItemCard from "../../../components/ItemCard.astro"; import ItemCard from "../../../components/ItemCard.astro";
import LoggedIn from "../../../layouts/LoggedIn.astro";
import locationManager from "../../../lib/classes/managers/LocationManager";
import { getName, getObj } from "../../../lib/utils/langDriver";
const loggedToken = Astro.cookies.get('sessionToken')?.value ?? null; const { token, lang } = Astro.locals;
const username = Astro.cookies.get('username')?.value ?? "";
if(loggedToken === null || username === "") return Astro.redirect('/logout');
const checkUser = await getUserByAccessToken(loggedToken);
if(checkUser === null || checkUser.username !== username) return Astro.redirect('/logout');
const currentSystemId = Astro.cookies.get('currentSystem')?.value ?? null; const currentSystemId = Astro.cookies.get('currentSystem')?.value ?? null;
if(currentSystemId === null) return Astro.redirect('/game/systemManager/select'); if(currentSystemId === null) return Astro.redirect('/game/systemManager/select');
const currentSystem = locationManager.getSystem(new ObjectId(currentSystemId)); const currentSystem = locationManager.getSystem(new ObjectId(currentSystemId));
if(currentSystem === undefined) { if(currentSystem === undefined) {
Astro.cookies.delete('currentSystem'); Astro.cookies.delete('currentSystem');
return Astro.redirect('/game/systemManager/select'); return Astro.redirect('/game/systemManager/select');
@ -33,7 +23,7 @@ if(Astro.request.method === "POST") {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'Authorization': 'Bearer ' + loggedToken 'Authorization': 'Bearer ' + token
}, },
body: JSON.stringify({ body: JSON.stringify({
system: currentSystemId, system: currentSystemId,
@ -44,8 +34,6 @@ if(Astro.request.method === "POST") {
console.log(request); console.log(request);
} }
const lang = await getLocales(Astro.cookies.get('language')?.value ?? await getHighestWeightedLanguage(Astro.request.headers.get('accept-language')));
const modalSet: { [key: string]: { resources: Array<any>, research: Array<any>, structures: Array<any>, energy: number } } = {}; const modalSet: { [key: string]: { resources: Array<any>, research: Array<any>, structures: Array<any>, energy: number } } = {};
const structureList = currentSystem.structures.structuresDB; const structureList = currentSystem.structures.structuresDB;
@ -63,10 +51,7 @@ for(const structure of structureList) {
}; };
} }
--- ---
<Layout title="System Manager"> <LoggedIn id="systemManager" title="System Manager">
<NavBar loggedIn="true" active="systemManager" />
<ResourceBar />
<h1>Selected system: {currentSystem.data.name} <a href="/game/systemManager/select">(change)</a></h1> <h1>Selected system: {currentSystem.data.name} <a href="/game/systemManager/select">(change)</a></h1>
<div class="system-links"> <div class="system-links">
<a href="/game/systemManager">Overview</a> <a href="/game/systemManager">Overview</a>
@ -98,81 +83,81 @@ for(const structure of structureList) {
/> />
))} ))}
</div> </div>
</Layout> </LoggedIn>
<style> <style>
* { * {
color: white; color: white;
} }
h1 { h1 {
text-align: center; text-align: center;
color: white; color: white;
} }
h1 a { h1 a {
color: lime; color: lime;
} }
#structure-modal-background { #structure-modal-background {
display: none; display: none;
position: fixed; position: fixed;
top: 0; top: 0;
left: 0; left: 0;
width: 100%; width: 100%;
height: 100%; height: 100%;
background: rgba(0, 0, 0, 0.5); background: rgba(0, 0, 0, 0.5);
z-index: 100; z-index: 100;
} }
#structure-modal-details { #structure-modal-details {
display: none; display: none;
position: fixed; position: fixed;
top: 50%; top: 50%;
left: 50%; left: 50%;
transform: translate(-50%, -50%); transform: translate(-50%, -50%);
width: 80%; width: 80%;
max-width: 800px; max-width: 800px;
background: rgba(0, 0, 0, 0.9); background: rgba(0, 0, 0, 0.9);
border-radius: 8px; border-radius: 8px;
padding: 1rem; padding: 1rem;
z-index: 101; z-index: 101;
} }
.structure-modal-text { .structure-modal-text {
font-size: 1.5rem; font-size: 1.5rem;
} }
.system-links { .system-links {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: center; justify-content: center;
margin-bottom: 1rem; margin-bottom: 1rem;
} }
.system-links a { .system-links a {
color: white; color: white;
background-color: #555; background-color: #555;
padding: 0.5rem; padding: 0.5rem;
margin: 0 1rem; margin: 0 1rem;
border-radius: 5px; border-radius: 5px;
text-decoration: none; text-decoration: none;
} }
.structure-list { .structure-list {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
flex-wrap: wrap; flex-wrap: wrap;
justify-content: space-evenly; justify-content: space-evenly;
color: white; color: white;
row-gap: 40px; row-gap: 40px;
column-gap: 2%; column-gap: 2%;
} }
.structure-card div { .structure-card div {
margin-top: auto; margin-top: auto;
margin-bottom: auto; margin-bottom: auto;
margin-left: 2rem; margin-left: 2rem;
} }
</style> </style>
<script define:vars={{ modalSet, lang }}> <script define:vars={{ modalSet, lang }}>
const modalResources = document.getElementById("structure-modal-req-resources"); const modalResources = document.getElementById("structure-modal-req-resources");

View File

@ -4,5 +4,11 @@
"verbatimModuleSyntax": false, "verbatimModuleSyntax": false,
"module": "ES2022", "module": "ES2022",
"moduleResolution": "node" "moduleResolution": "node"
} },
"include": [
"src/env.d.ts",
"src/**/*.ts",
"src/**/*.tsx",
"src/**/*.astro"
]
} }