Made the maps-page...
This commit is contained in:
parent
76d9ad836d
commit
7a9b2d5218
|
@ -1,12 +1,29 @@
|
||||||
import { Router } from 'express'
|
import { Router } from 'express'
|
||||||
import routex from '../libs/routex.js'
|
import wrapper from '../libs/database/wrapper.js'
|
||||||
|
import tx from '../libs/routex.js'
|
||||||
|
|
||||||
const routes = Router()
|
const routes = Router()
|
||||||
|
|
||||||
routes.get(
|
routes.get(
|
||||||
'/',
|
'/',
|
||||||
(req, res) => {
|
(req, res) => {
|
||||||
routex(req, res)('pages/landing.njk', null, { currentSection: null })
|
tx(req, res)('pages/landing.njk', null, { currentSection: null })
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
routes.get(
|
||||||
|
'/maps',
|
||||||
|
(req, res) => {
|
||||||
|
const maps = wrapper.allMaps()
|
||||||
|
tx(req, res)('pages/maps.njk', { maps }, { currentSection: "maps" })
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
routes.get(
|
||||||
|
'/maps/:map',
|
||||||
|
(req, res) => {
|
||||||
|
const map = wrapper.map(req.params.map)
|
||||||
|
tx(req, res)('pages/mapSingle.njk', { map }, { currentSection: "maps" })
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
67
src/sass/maps.scss
Normal file
67
src/sass/maps.scss
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
@use "partials/palette.scss";
|
||||||
|
@use "partials/settings.scss";
|
||||||
|
@use "partials/shadows.scss";
|
||||||
|
|
||||||
|
.maps-container {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-around;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map {
|
||||||
|
background-color: palette.$grey3;
|
||||||
|
border-radius: settings.$border_radius_m;
|
||||||
|
box-shadow: shadows.$small;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
margin: 2rem 1rem;
|
||||||
|
|
||||||
|
transition: transform .3s, box-shadow .3s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
transform: scale(1.05);
|
||||||
|
box-shadow: shadows.$large;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-image {
|
||||||
|
border-radius: settings.$border_radius_m settings.$border_radius_m 0 0;
|
||||||
|
width: 360px;
|
||||||
|
height: 225px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-name {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
font-weight: bold;
|
||||||
|
|
||||||
|
margin: .5rem 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-info {
|
||||||
|
margin: .25rem 2rem;
|
||||||
|
|
||||||
|
td:first-child {
|
||||||
|
width: 9ch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a.map-more-info {
|
||||||
|
margin: .75rem auto 1.25rem auto;
|
||||||
|
padding: .15rem .5rem;
|
||||||
|
|
||||||
|
border: .1rem solid palette.$accent;
|
||||||
|
border-radius: settings.$border_radius_s;
|
||||||
|
|
||||||
|
color: palette.$accent;
|
||||||
|
|
||||||
|
text-decoration: none transparent;
|
||||||
|
transition: color .3s, background-color .3s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: palette.$surface;
|
||||||
|
background-color: palette.$accent;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
@use "_palette.scss";
|
@use "_palette.scss";
|
||||||
|
|
||||||
$small: .25rem 0 2rem palette.$grey1;
|
$small: .25rem 0 2rem palette.$grey1;
|
||||||
|
$medium: .35rem 0 3rem palette.$grey1;
|
||||||
$large: .5rem 0 4rem palette.$grey1;
|
$large: .5rem 0 4rem palette.$grey1;
|
|
@ -92,6 +92,10 @@ header {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: palette.$blue5;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// FORMS, INPUT
|
// FORMS, INPUT
|
||||||
|
|
1
static/css/maps.css
Normal file
1
static/css/maps.css
Normal file
|
@ -0,0 +1 @@
|
||||||
|
.maps-container{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-around}.map{background-color:#20203f;border-radius:1rem;box-shadow:.25rem 0 2rem #00001f;display:flex;flex-direction:column;justify-content:center;margin:2rem 1rem;transition:transform .3s,box-shadow .3s}.map:hover{transform:scale(1.05);box-shadow:.5rem 0 4rem #00001f}.map-image{border-radius:1rem 1rem 0 0;width:360px;height:225px}.map-name{font-size:1.2rem;font-weight:bold;margin:.5rem 2rem}.map-info{margin:.25rem 2rem}.map-info td:first-child{width:9ch}a.map-more-info{margin:.75rem auto 1.25rem auto;padding:.15rem .5rem;border:.1rem solid #fba7c6;border-radius:.5rem;color:#fba7c6;text-decoration:none transparent;transition:color .3s,background-color .3s}a.map-more-info:hover{color:#10102f;background-color:#fba7c6}
|
|
@ -1 +1 @@
|
||||||
*{margin:0;padding:0;border:0 none transparent;box-sizing:border-box;scroll-behavior:smooth;font-family:"Manrope Regular",sans-serif;font-size:1rem;line-height:1.5}html,body{color:#e0e0ff;background-color:#10102f;height:100%}nav{display:flex;align-items:center;background-color:#20203f;border-radius:0 0 2rem 2rem;box-shadow:.5rem 0 4rem #00001f;margin:0 0 2rem 0;padding:1rem 2rem}nav .logo{width:3rem;height:3rem;margin-right:2rem;border-radius:100%;background-color:#ee588f}nav a{color:#fba7c6;border-bottom:.1rem solid transparent;margin:.25rem 1rem .5rem 1rem;padding:.15rem .5rem .25rem .5rem;font-size:1.25rem;text-decoration:none transparent;transition:border .3s}nav a:hover{border-bottom:.1rem solid #fba7c6}nav a.current{color:#ee588f}nav a.current:hover{border-bottom:.1rem solid #ee588f}header,h1,h2,h3,h4,h5,h6{color:#fba7c6}header{font-size:4rem}h1{font-size:1.5rem;font-weight:normal}h2{font-size:1.35rem;font-weight:normal}h3{font-size:1.2rem;font-weight:normal}h4{font-size:1.05rem;font-weight:normal}h5{font-size:.9rem;font-weight:normal}form{display:flex;flex-direction:column;justify-content:center;align-items:center}input{color:#e0e0ff;background-color:#20203f;margin:1em 0;padding:.75em 1.25em;width:min(80ch,80vw);outline:0 none transparent;border:.2rem solid transparent;border-radius:.5rem;box-shadow:.25rem 0 2rem #00001f;transition:border .3s,background-color .5s,border-radius .5s}input:hover{background-color:#30304f;border-radius:1rem}input:active,input:focus{border:.2rem solid #ee588f}footer{display:flex;flex-direction:column;align-items:center;margin:5vh 2rem}footer a{color:#74b6fb;font-size:.8rem}
|
*{margin:0;padding:0;border:0 none transparent;box-sizing:border-box;scroll-behavior:smooth;font-family:"Manrope Regular",sans-serif;font-size:1rem;line-height:1.5}html,body{color:#e0e0ff;background-color:#10102f;height:100%}nav{display:flex;align-items:center;background-color:#20203f;border-radius:0 0 2rem 2rem;box-shadow:.5rem 0 4rem #00001f;margin:0 0 2rem 0;padding:1rem 2rem}nav .logo{width:3rem;height:3rem;margin-right:2rem;border-radius:100%;background-color:#ee588f}nav a{color:#fba7c6;border-bottom:.1rem solid transparent;margin:.25rem 1rem .5rem 1rem;padding:.15rem .5rem .25rem .5rem;font-size:1.25rem;text-decoration:none transparent;transition:border .3s}nav a:hover{border-bottom:.1rem solid #fba7c6}nav a.current{color:#ee588f}nav a.current:hover{border-bottom:.1rem solid #ee588f}header,h1,h2,h3,h4,h5,h6{color:#fba7c6}header{font-size:4rem}h1{font-size:1.5rem;font-weight:normal}h2{font-size:1.35rem;font-weight:normal}h3{font-size:1.2rem;font-weight:normal}h4{font-size:1.05rem;font-weight:normal}h5{font-size:.9rem;font-weight:normal}a{color:#a3cefa}form{display:flex;flex-direction:column;justify-content:center;align-items:center}input{color:#e0e0ff;background-color:#20203f;margin:1em 0;padding:.75em 1.25em;width:min(80ch,80vw);outline:0 none transparent;border:.2rem solid transparent;border-radius:.5rem;box-shadow:.25rem 0 2rem #00001f;transition:border .3s,background-color .5s,border-radius .5s}input:hover{background-color:#30304f;border-radius:1rem}input:active,input:focus{border:.2rem solid #ee588f}footer{display:flex;flex-direction:column;align-items:center;margin:5vh 2rem}footer a{color:#74b6fb;font-size:.8rem}
|
||||||
|
|
24
static/scripts/lazyLoadImages.js
Normal file
24
static/scripts/lazyLoadImages.js
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
const observerConfig = {
|
||||||
|
rootMargin: '0px 0px 50px 0px',
|
||||||
|
threshold: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
const observer = new IntersectionObserver(
|
||||||
|
(entries, self) => {
|
||||||
|
for (const entry of entries) {
|
||||||
|
if (entry.isIntersecting) {
|
||||||
|
const element = entry.target
|
||||||
|
const src = entry.target.getAttribute("data-src")
|
||||||
|
|
||||||
|
element.setAttribute("src", src)
|
||||||
|
self.unobserve(element)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
observerConfig
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
const images = document.querySelectorAll('img[data-src]') ?? []
|
||||||
|
for (const image of images)
|
||||||
|
observer.observe(image)
|
38
views/components/_map.njk
Normal file
38
views/components/_map.njk
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
{% macro card(map) %}
|
||||||
|
<div class="map">
|
||||||
|
<img class="map-image" data-src="https://ddnet.tw/ranks/maps/{{ map.map | replace(r/[À-ž]/g, "__") | replace(r/[^a-zA-Z0-9]/g, "_") }}.png">
|
||||||
|
<h1 class="map-name">{{ map.map }}</h1>
|
||||||
|
<table class="map-info">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
{% if map.mappers[1] %}
|
||||||
|
Mappers:
|
||||||
|
{% else %}
|
||||||
|
Mapper:
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ map.mappers.join(", ") }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
Category:
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{ map.category }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
Rating:
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{% for i in range(0, map.stars) %}★{% endfor %}
|
||||||
|
{% for i in range(0, 5 - map.stars) %}☆{% endfor %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<a class="map-more-info" href="/maps/{{ map.map | urlencode }}">More Info</a>
|
||||||
|
</div>
|
||||||
|
{% endmacro %}
|
14
views/pages/mapSingle.njk
Normal file
14
views/pages/mapSingle.njk
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
{% extends "../templates/basic.njk" %}
|
||||||
|
{% import "../components/_map.njk" as mapComponent %}
|
||||||
|
|
||||||
|
{% block head %}
|
||||||
|
<title>DDStats - Maps!</title>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/assets/css/maps.css">
|
||||||
|
<script src="/assets/scripts/lazyLoadImages.js" defer></script>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
<main>
|
||||||
|
{{ mapComponent.card(data.map) }}
|
||||||
|
</main>
|
||||||
|
{% endblock %}
|
16
views/pages/maps.njk
Normal file
16
views/pages/maps.njk
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
{% extends "../templates/basic.njk" %}
|
||||||
|
{% import "../components/_map.njk" as mapComponent %}
|
||||||
|
|
||||||
|
{% block head %}
|
||||||
|
<title>DDStats - Maps!</title>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/assets/css/maps.css">
|
||||||
|
<script src="/assets/scripts/lazyLoadImages.js" defer></script>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
<main class="maps-container">
|
||||||
|
{% for map in data.maps %}
|
||||||
|
{{ mapComponent.card(map) }}
|
||||||
|
{% endfor %}
|
||||||
|
</main>
|
||||||
|
{% endblock %}
|
Loading…
Reference in New Issue
Block a user