Added countdown and error-pages
This commit is contained in:
parent
d566a95288
commit
20e62ea01b
3 changed files with 417 additions and 0 deletions
90
static/internal/countdown/index.html
Normal file
90
static/internal/countdown/index.html
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<!--
|
||||||
|
(c) Sangelo
|
||||||
|
Simple countdown webpage that can be used as a startpage
|
||||||
|
You can feed the date the counter should be counting down to in the URL like this:
|
||||||
|
http://<countdown>/?date=YYYY-MM-DDTHH:MM:SS
|
||||||
|
-->
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Countdown Timer</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background: radial-gradient(circle, #414144, #202123);
|
||||||
|
background-size: 100% 500%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 100vh;
|
||||||
|
margin: 0;
|
||||||
|
font-family: monospace, monospace;
|
||||||
|
color: #ffffff75;
|
||||||
|
}
|
||||||
|
|
||||||
|
#countdown {
|
||||||
|
font-size: 200px;
|
||||||
|
margin: 0 20px;
|
||||||
|
opacity: 1;
|
||||||
|
transition: opacity 0.5s;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.completed {
|
||||||
|
color: #fff; /* Full opacity when countdown is completed */
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="countdown">000:00:00:00</div>
|
||||||
|
|
||||||
|
<script async>
|
||||||
|
function formatWithLeadingZeros(number, length) {
|
||||||
|
return number.toLocaleString('en-US', {minimumIntegerDigits: length, useGrouping: false});
|
||||||
|
}
|
||||||
|
|
||||||
|
const countdownElement = document.getElementById("countdown");
|
||||||
|
const countdownDate = getDateFromUrl();
|
||||||
|
|
||||||
|
function updateCountdown() {
|
||||||
|
const now = new Date().getTime();
|
||||||
|
const distance = countdownDate - now;
|
||||||
|
|
||||||
|
if (distance <= 0) {
|
||||||
|
countdownElement.innerHTML = "🥳";
|
||||||
|
countdownElement.classList.add("completed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const days = Math.floor(distance / (1000 * 60 * 60 * 24));
|
||||||
|
const hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
|
||||||
|
const minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
|
||||||
|
const seconds = Math.floor((distance % (1000 * 60)) / 1000);
|
||||||
|
|
||||||
|
const formattedDays = formatWithLeadingZeros(days, 3);
|
||||||
|
const formattedHours = formatWithLeadingZeros(hours, 2);
|
||||||
|
const formattedMinutes = formatWithLeadingZeros(minutes, 2);
|
||||||
|
const formattedSeconds = formatWithLeadingZeros(seconds, 2);
|
||||||
|
|
||||||
|
countdownElement.innerHTML = `${formattedDays}:${formattedHours}:${formattedMinutes}:${formattedSeconds}`;
|
||||||
|
requestAnimationFrame(updateCountdown);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDateFromUrl() {
|
||||||
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
|
const dateParam = urlParams.get('date');
|
||||||
|
if (dateParam) {
|
||||||
|
const timestamp = Date.parse(dateParam);
|
||||||
|
if (!isNaN(timestamp)) {
|
||||||
|
return timestamp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new Date("1970-01-01T00:00:00").getTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
requestAnimationFrame(updateCountdown);
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
166
static/internal/error/400.html
Normal file
166
static/internal/error/400.html
Normal file
|
@ -0,0 +1,166 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<title>Error {{placeholder "http.error.status_code"}}</title>
|
||||||
|
<style>
|
||||||
|
@import url("https://fonts.cdnfonts.com/css/manrope");
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: stretch;
|
||||||
|
height: 100vh;
|
||||||
|
background-color: #121316;
|
||||||
|
color: #fff;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text {
|
||||||
|
flex: 1 1 50%;
|
||||||
|
padding: 2em;
|
||||||
|
overflow: auto;
|
||||||
|
font-family: "Manrope", sans-serif;
|
||||||
|
z-index: 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text h1 {
|
||||||
|
font-size: 80px;
|
||||||
|
margin-bottom: 0;
|
||||||
|
margin-top: 0.2em;
|
||||||
|
font-weight: 800;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text h2 {
|
||||||
|
font-size: 40px;
|
||||||
|
font-weight: 500;
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text p {
|
||||||
|
font-weight: 300;
|
||||||
|
font-size: 22px;
|
||||||
|
margin-bottom: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text a.button {
|
||||||
|
text-decoration: none;
|
||||||
|
background-color: #ffffff;
|
||||||
|
padding: 0.6em;
|
||||||
|
padding-left: 1.5em;
|
||||||
|
padding-right: 1.5em;
|
||||||
|
border-radius: 8px;
|
||||||
|
color: #121316;
|
||||||
|
font-weight: 700;
|
||||||
|
transition: opacity ease-in-out 0.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text a.button:hover {
|
||||||
|
opacity: 0.9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text a.button:active {
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blob {
|
||||||
|
position: relative;
|
||||||
|
flex: 1 1 50%;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blob svg {
|
||||||
|
height: 100vh;
|
||||||
|
width: auto;
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 850px) {
|
||||||
|
.blob {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="text">
|
||||||
|
<h1>{{placeholder "http.error.status_code"}}</h1>
|
||||||
|
<h2>{{placeholder "http.error.status_text"}}</h2>
|
||||||
|
<p>
|
||||||
|
Looks like you got lost in space. Try searching again at planet earth.
|
||||||
|
</p>
|
||||||
|
<a class="button" href="/">Fly back home</a>
|
||||||
|
</div>
|
||||||
|
<div class="blob">
|
||||||
|
<svg
|
||||||
|
width="686"
|
||||||
|
height="1080"
|
||||||
|
viewBox="0 0 686 1080"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<g filter="url(#filter0_i_1002_1047)">
|
||||||
|
<path
|
||||||
|
d="M88.6758 136C88.6758 34.6337 0 -8.02344 0 -66H686V1146H0C0 1146 88.6758 1044.94 88.6758 944C88.6758 843.064 0 843.419 0 742.582C0 641.745 88.6758 641.124 88.6758 540C88.6758 438.876 0 439.674 0 338.938C0 238.201 88.6758 237.366 88.6758 136Z"
|
||||||
|
fill="url(#paint0_radial_1002_1047)"
|
||||||
|
/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<filter
|
||||||
|
id="filter0_i_1002_1047"
|
||||||
|
x="0"
|
||||||
|
y="-66"
|
||||||
|
width="689"
|
||||||
|
height="1214"
|
||||||
|
filterUnits="userSpaceOnUse"
|
||||||
|
color-interpolation-filters="sRGB"
|
||||||
|
>
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix" />
|
||||||
|
<feBlend
|
||||||
|
mode="normal"
|
||||||
|
in="SourceGraphic"
|
||||||
|
in2="BackgroundImageFix"
|
||||||
|
result="shape"
|
||||||
|
/>
|
||||||
|
<feColorMatrix
|
||||||
|
in="SourceAlpha"
|
||||||
|
type="matrix"
|
||||||
|
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
||||||
|
result="hardAlpha"
|
||||||
|
/>
|
||||||
|
<feOffset dx="3" dy="2" />
|
||||||
|
<feGaussianBlur stdDeviation="4" />
|
||||||
|
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1" />
|
||||||
|
<feColorMatrix
|
||||||
|
type="matrix"
|
||||||
|
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.35 0"
|
||||||
|
/>
|
||||||
|
<feBlend
|
||||||
|
mode="normal"
|
||||||
|
in2="shape"
|
||||||
|
result="effect1_innerShadow_1002_1047"
|
||||||
|
/>
|
||||||
|
</filter>
|
||||||
|
<radialGradient
|
||||||
|
id="paint0_radial_1002_1047"
|
||||||
|
cx="0"
|
||||||
|
cy="0"
|
||||||
|
r="1"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="translate(32 540) scale(654 3651.84)"
|
||||||
|
>
|
||||||
|
<stop offset="0.34828" stop-color="#00B2FA" />
|
||||||
|
<stop offset="1" stop-color="#007DFF" />
|
||||||
|
</radialGradient>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
161
static/internal/error/500.html
Normal file
161
static/internal/error/500.html
Normal file
|
@ -0,0 +1,161 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<title>Error {{placeholder "http.err.status_code"}}</title>
|
||||||
|
<style>
|
||||||
|
@import url("https://fonts.cdnfonts.com/css/manrope");
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: stretch;
|
||||||
|
height: 100vh;
|
||||||
|
background-color: #121316;
|
||||||
|
color: #fff;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text {
|
||||||
|
flex: 1 1 50%;
|
||||||
|
padding: 2em;
|
||||||
|
overflow: auto;
|
||||||
|
font-family: "Manrope", sans-serif;
|
||||||
|
z-index: 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text h1 {
|
||||||
|
font-size: 80px;
|
||||||
|
margin-bottom: 0;
|
||||||
|
margin-top: 0.2em;
|
||||||
|
font-weight: 800;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text h2 {
|
||||||
|
font-size: 40px;
|
||||||
|
font-weight: 500;
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text p {
|
||||||
|
font-weight: 300;
|
||||||
|
font-size: 22px;
|
||||||
|
margin-bottom: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text a {
|
||||||
|
color: #00c4fb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text a:hover {
|
||||||
|
opacity: 0.9;
|
||||||
|
color: #00b2fa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text a:active {
|
||||||
|
opacity: 0.9;
|
||||||
|
color: #0091fb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blob {
|
||||||
|
position: relative;
|
||||||
|
flex: 1 1 50%;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blob svg {
|
||||||
|
height: 100vh;
|
||||||
|
width: auto;
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 850px) {
|
||||||
|
.blob {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="text">
|
||||||
|
<h1>{{placeholder "http.err.status_code"}}</h1>
|
||||||
|
<h2>{{placeholder "http.err.status_text"}}</h2>
|
||||||
|
<p>
|
||||||
|
Looks like the website is down at the moment. Please try again later.<br />If
|
||||||
|
the error persists, contact me at
|
||||||
|
<a href="mailto:me@stelian.net">me@stelian.net</a>.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="blob">
|
||||||
|
<svg
|
||||||
|
width="686"
|
||||||
|
height="1080"
|
||||||
|
viewBox="0 0 686 1080"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<g filter="url(#filter0_i_1002_1047)">
|
||||||
|
<path
|
||||||
|
d="M88.6758 136C88.6758 34.6337 0 -8.02344 0 -66H686V1146H0C0 1146 88.6758 1044.94 88.6758 944C88.6758 843.064 0 843.419 0 742.582C0 641.745 88.6758 641.124 88.6758 540C88.6758 438.876 0 439.674 0 338.938C0 238.201 88.6758 237.366 88.6758 136Z"
|
||||||
|
fill="url(#paint0_radial_1002_1047)"
|
||||||
|
/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<filter
|
||||||
|
id="filter0_i_1002_1047"
|
||||||
|
x="0"
|
||||||
|
y="-66"
|
||||||
|
width="689"
|
||||||
|
height="1214"
|
||||||
|
filterUnits="userSpaceOnUse"
|
||||||
|
color-interpolation-filters="sRGB"
|
||||||
|
>
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix" />
|
||||||
|
<feBlend
|
||||||
|
mode="normal"
|
||||||
|
in="SourceGraphic"
|
||||||
|
in2="BackgroundImageFix"
|
||||||
|
result="shape"
|
||||||
|
/>
|
||||||
|
<feColorMatrix
|
||||||
|
in="SourceAlpha"
|
||||||
|
type="matrix"
|
||||||
|
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
||||||
|
result="hardAlpha"
|
||||||
|
/>
|
||||||
|
<feOffset dx="3" dy="2" />
|
||||||
|
<feGaussianBlur stdDeviation="4" />
|
||||||
|
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1" />
|
||||||
|
<feColorMatrix
|
||||||
|
type="matrix"
|
||||||
|
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.35 0"
|
||||||
|
/>
|
||||||
|
<feBlend
|
||||||
|
mode="normal"
|
||||||
|
in2="shape"
|
||||||
|
result="effect1_innerShadow_1002_1047"
|
||||||
|
/>
|
||||||
|
</filter>
|
||||||
|
<radialGradient
|
||||||
|
id="paint0_radial_1002_1047"
|
||||||
|
cx="0"
|
||||||
|
cy="0"
|
||||||
|
r="1"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="translate(32 540) scale(654 3651.84)"
|
||||||
|
>
|
||||||
|
<stop offset="0.34828" stop-color="#00B2FA" />
|
||||||
|
<stop offset="1" stop-color="#007DFF" />
|
||||||
|
</radialGradient>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
Loading…
Reference in a new issue