Add building modal with details

This commit is contained in:
Aelita4 2024-07-31 17:57:36 +02:00
parent 5f305c8983
commit 4db4cc97ad
Signed by: Aelita4
GPG Key ID: E44490C2025906C1
6 changed files with 324 additions and 18 deletions

View File

@ -1,11 +1,37 @@
{ {
"Label": { "Label": {
"mines": "Mines", "mines": "Mines",
"iron-mine": "Iron mine", "iron-mine": {
"gold-mine": "Gold mine", "name": "Iron mine",
"description": "Iron mines produce iron ore, which is used to build and upgrade buildings."
},
"gold-mine": {
"name": "Gold mine",
"description": "Gold mines produce gold ore, useful for trading and building."
},
"coal-mine": {
"name": "Coal mine",
"description": "Coal mines produce coal, which is used to power buildings."
},
"utilities": "Utilities", "utilities": "Utilities",
"research-lab": "Research lab", "research-lab": {
"research-facility": "Research facility" "name": "Research lab",
"description": "Research labs are used to research new technologies and improve existing ones."
},
"research-facility": {
"name": "Research facility",
"description": "Research facilities are used to research advanced technologies."
},
"power-plants": "Power plants",
"coal-power-plant": {
"name": "Coal power plant",
"description": "Coal power plants produce electricity using coal."
},
"nuclear-power-plant": {
"name": "Nuclear power plant",
"description": "Nuclear power plants produce electricity using uranium."
}
} }
} }

View File

@ -30,6 +30,10 @@
"advanced-technologies": { "advanced-technologies": {
"name": "Advanced Technologies", "name": "Advanced Technologies",
"description": "Various advanced technologies" "description": "Various advanced technologies"
},
"nuclear-power": {
"name": "Nuclear Power",
"description": "Advanced power generation using nuclear energy"
} }
} }
} }

View File

@ -0,0 +1,78 @@
---
import { getHighestWeightedLanguage, getLocales } from '../lib/utils/langDriver';
interface Props {
id: string;
name: string;
description: string;
image: string;
}
const lang = await getLocales(await getHighestWeightedLanguage(Astro.request.headers.get('accept-language')), ['resources', 'game', 'buildings', 'research']);
---
<div class="building-card" data-id={Astro.props.id}>
<div><img src={Astro.props.image} /></div>
<div>
<div class="building-card-name">{Astro.props.name}</div>
<div class="building-card-description">{Astro.props.description}</div>
<a id={`build_${Astro.props.id}`} href="#" class="building-card-build">{lang["game"]['Link_build']}</a>
<div class="building-card-info-button">i</div>
</div>
</div>
<style>
.building-card {
background-color: #fff;
color: #333;
border-radius: 8px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
overflow: hidden;
position: relative;
width: 100%;
display: flex;
flex-direction: row;
width: 49%;
}
.building-card-expanded {
height: auto;
}
.building-card-name {
font-size: 48px;
}
.building-card-description {
font-size: 24px;
margin-top: 16px;
margin-bottom: 16px;
}
.building-card-build {
background-color: #333;
color: #fff;
border-radius: 8px;
padding: 8px 16px;
display: inline-block;
margin-top: 16px;
position: absolute;
bottom: 16px;
right: 16px;
}
.building-card-info-button {
background-color: #333;
color: #fff;
border-radius: 50%;
width: 32px;
height: 32px;
display: flex;
justify-content: center;
align-items: center;
position: absolute;
top: 16px;
right: 16px;
cursor: pointer;
}
</style>

View File

@ -47,6 +47,29 @@
}, },
"energy": 11, "energy": 11,
"multiplier": 2.5 "multiplier": 2.5
},
{
"id": "coal-mine",
"requirements": {
"buildings": [],
"research": [],
"resources": [
{
"name": "iron",
"amount": 1
},
{
"name": "gold",
"amount": 1
},
{
"name": "coal",
"amount": 1
}
]
},
"energy": 11,
"multiplier": 3
} }
] ]
}, { }, {
@ -109,5 +132,65 @@
"multiplier": 2 "multiplier": 2
} }
] ]
}, {
"category": "power-plants",
"buildings": [
{
"id": "coal-power-plant",
"requirements": {
"buildings": [],
"research": [],
"resources": [
{
"name": "iron",
"amount": 1
},
{
"name": "gold",
"amount": 1
},
{
"name": "coal",
"amount": 1
}
]
},
"energy": 100,
"multiplier": 3
},
{
"id": "nuclear-power-plant",
"requirements": {
"buildings": [
{
"id": "coal-power-plant",
"level": 3
}
],
"research": [
{
"id": "nuclear-power",
"level": 2
}
],
"resources": [
{
"name": "iron",
"amount": 1
},
{
"name": "gold",
"amount": 1
},
{
"name": "coal",
"amount": 1
}
]
},
"energy": 100,
"multiplier": 2
}
]
} }
] ]

View File

@ -123,5 +123,20 @@
}, },
"time": 1500, "time": 1500,
"multiplier": 4 "multiplier": 4
}, {
"id": "nuclear-power",
"requirements": {
"buildings": [
{
"id": "research-lab",
"level": 10
}
],
"research": [],
"resources": {
"iron": 1000,
"gold": 500
}
}
} }
] ]

View File

@ -1,6 +1,7 @@
--- ---
import Layout from '../../layouts/Layout.astro'; import Layout from '../../layouts/Layout.astro';
import NavBar from '../../components/NavBar.astro'; import NavBar from '../../components/NavBar.astro';
import BuildingCard from '../../components/BuildingCard.astro';
import { getUserByAccessToken } from '../../lib/db/users'; import { getUserByAccessToken } from '../../lib/db/users';
import { getHighestWeightedLanguage, getLocales } from '../../lib/utils/langDriver'; import { getHighestWeightedLanguage, getLocales } from '../../lib/utils/langDriver';
import ResourceBar from '../../components/ResourceBar.astro'; import ResourceBar from '../../components/ResourceBar.astro';
@ -17,28 +18,47 @@ if(checkUser === null || checkUser.username !== username) return Astro.redirect(
const locale = await getHighestWeightedLanguage(Astro.request.headers.get('accept-language')); const locale = await getHighestWeightedLanguage(Astro.request.headers.get('accept-language'));
const lang = await getLocales(locale, ['resources', 'game', 'buildings', 'research']); const lang = await getLocales(locale, ['resources', 'game', 'buildings', 'research']);
const modalSet: { [key: string]: { resources: Array<any>, research: Array<any>, buildings: Array<any>, energy: number } } = {};
buildingsList.forEach(cat => {
cat.buildings.forEach(building => {
modalSet[building.id] = {
"resources": building.requirements.resources,
"research": building.requirements.research,
"buildings": building.requirements.buildings,
"energy": building.energy
};
});
});
--- ---
<Layout title="Buildings"> <Layout title="Buildings">
<NavBar loggedIn="true" active="buildings" /> <NavBar loggedIn="true" active="buildings" />
<ResourceBar /> <ResourceBar />
<div id="building-modal-background">
<div id="building-modal-details" data-building-id="">
<h3>Required resources</h3>
<div class="building-modal-text" id="building-modal-req-resources">None</div>
<h3>Required buildings</h3>
<div class="building-modal-text" id="building-modal-req-buildings">None</div>
<h3>Required research</h3>
<div class="building-modal-text" id="building-modal-req-research">None</div>
</div>
</div>
{buildingsList.map(cat => ( {buildingsList.map(cat => (
<div class="building-card"> <div class="building-card">
{console.log(cat.category)}
<h3>{lang["buildings"][`Label_${cat.category}`]}</h3> <h3>{lang["buildings"][`Label_${cat.category}`]}</h3>
{cat.buildings.map(building => ( <> <div class="building-cat">
<h4>{lang["buildings"][`Label_${building.id}`]}</h4> {cat.buildings.map(building => <BuildingCard
{building.requirements.resources.map(res => ( id={building.id}
<div>{lang["resources"][`Label_${res.name}`]}: {res.amount}</div> name={lang["buildings"][`Label_${building.id}`].name}
))} description={lang["buildings"][`Label_${building.id}`].description}
{building.requirements.buildings.map(b => ( image="/favicon.svg" />)}
<div>{lang["buildings"][`Label_${b.id}`]}: {b.level}</div> </div>
))}
{building.requirements.research.map(t => (
<div>{lang["research"][`Label_${t.id}`].name}: {t.level}</div>
))}
<a id={`build_${building.id}`} href="#" class="a-button">{lang["game"]['Link_build']}</a>
</>))}
</div> </div>
))} ))}
</Layout> </Layout>
@ -58,6 +78,39 @@ const lang = await getLocales(locale, ['resources', 'game', 'buildings', 'resear
line-height: 1.6; line-height: 1.6;
} }
.building-cat {
display: flex;
flex-direction: row;
flex-wrap: wrap;
row-gap: 40px;
column-gap: 2%;
}
#building-modal-background {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
z-index: 100;
}
#building-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;
}
.astro-a { .astro-a {
position: absolute; position: absolute;
top: -32px; top: -32px;
@ -76,6 +129,10 @@ const lang = await getLocales(locale, ['resources', 'game', 'buildings', 'resear
margin-bottom: 1em; margin-bottom: 1em;
} }
.building-modal-text {
font-size: 1.5rem;
}
.text-gradient { .text-gradient {
background-image: var(--accent-gradient); background-image: var(--accent-gradient);
-webkit-background-clip: text; -webkit-background-clip: text;
@ -121,7 +178,50 @@ const lang = await getLocales(locale, ['resources', 'game', 'buildings', 'resear
color: lime; color: lime;
} }
</style> </style>
<script> <script define:vars={{ modalSet, lang }}>
const modalResources = document.getElementById("building-modal-req-resources");
const modalBuildings = document.getElementById("building-modal-req-buildings");
const modalResearch = document.getElementById("building-modal-req-research");
document.querySelectorAll('.building-card-info-button').forEach((el) => {
el.addEventListener('click', () => {
// modal
const modalDiv = document.getElementById('building-modal-details');
if(!modalDiv) return;
modalDiv.style.display = 'block';
modalResources.innerHTML = modalSet[el.parentElement.parentElement.dataset.id].resources.map(resource => {
return `${lang['resources'][`Label_${resource.name}`]}: ${resource.amount}`;
}).join("<br />");
modalBuildings.innerHTML = modalSet[el.parentElement.parentElement.dataset.id].buildings.map(building => {
return `${lang['buildings'][`Label_${building.id}`].name}: ${building.level}`;
}).join("<br />");
modalResearch.innerHTML = modalSet[el.parentElement.parentElement.dataset.id].research.map(research => {
return `${lang['research'][`Label_${research.id}`].name}: ${research.level}`;
}).join("<br />");
// background
const backgroundDiv = document.getElementById('building-modal-background');
if(!backgroundDiv) return;
backgroundDiv.style.display = 'block';
});
});
// close modal on background click
const bg = document.getElementById('building-modal-background');
bg?.addEventListener('click', () => {
const modalDiv = document.getElementById('building-modal-details');
if(!modalDiv) return;
modalDiv.style.display = 'none';
const backgroundDiv = document.getElementById('building-modal-background');
if(!backgroundDiv) return;
backgroundDiv.style.display = 'none';
});
const allButtons = document.getElementsByClassName("a-button"); const allButtons = document.getElementsByClassName("a-button");
for(const buildingButton of allButtons) { for(const buildingButton of allButtons) {