Compare commits
10 Commits
67b4beadd9
...
bd4e1322be
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bd4e1322be | ||
|
|
4af3812983 | ||
|
|
617ff597dd | ||
| ae59d9654c | |||
| 98ad3ec030 | |||
| 6ad6158e3b | |||
| ba79998d66 | |||
| 26413854c0 | |||
| 718bb33a6e | |||
| ad8d872a4c |
68
.gitlab-ci.yml
Normal file
@@ -0,0 +1,68 @@
|
||||
# .gitlab-ci.yaml
|
||||
|
||||
# Define the default image to be used for all jobs.
|
||||
# This image should have bash and rsync/ssh client available.
|
||||
image: alpine/git:latest
|
||||
|
||||
# Define stages for the pipeline.
|
||||
# 'deploy' is the main stage responsible for deployment.
|
||||
stages:
|
||||
- deploy
|
||||
|
||||
# Define the 'deploy_website' job.
|
||||
deploy_website:
|
||||
stage: deploy
|
||||
tags:
|
||||
- jmp-site
|
||||
# Only run this job when changes are pushed to the 'main' branch.
|
||||
only:
|
||||
- main
|
||||
|
||||
# Define variables required for SSH connection and deployment path.
|
||||
variables:
|
||||
# Replace with your actual SSH user for the target server.
|
||||
SSH_USER: "root"
|
||||
# Replace with the IP address or hostname of your target server.
|
||||
# If the GitLab Runner is on the same machine as /var/www/jmpgames.it,
|
||||
# you can use 'localhost' or '127.0.0.1'.
|
||||
SSH_HOST: "localhost"
|
||||
# The absolute path on the target server where the website files will be deployed.
|
||||
DEPLOY_PATH: "/var/www/jmpgames.it"
|
||||
# The local path within the GitLab Runner's working directory where your website files are located.
|
||||
# Assuming your website files are in the root of your repository.
|
||||
WEBSITE_SOURCE_PATH: "./"
|
||||
|
||||
# Before the script runs, ensure SSH key is added and permissions are set.
|
||||
before_script:
|
||||
# Ensure the .ssh directory exists with correct permissions.
|
||||
- mkdir -p ~/.ssh
|
||||
- chmod 700 ~/.ssh
|
||||
|
||||
# Add the private SSH key. SSH_PRIVATE_KEY should be a CI/CD variable
|
||||
# configured in GitLab with your deployment key.
|
||||
# Make sure this variable is "masked" and "protected".
|
||||
- echo "$SSH_PRIVATE_KEY" | tr -d '\r' > ~/.ssh/id_rsa
|
||||
- chmod 600 ~/.ssh/id_rsa
|
||||
|
||||
# Add your server's host key to known_hosts to avoid host key checking prompts.
|
||||
# This is crucial for non-interactive scripts.
|
||||
# Replace with your server's actual public host key.
|
||||
# You can get it by running `ssh-keyscan your_server_ip_or_hostname` on your local machine.
|
||||
- ssh-keyscan "$SSH_HOST" >> ~/.ssh/known_hosts
|
||||
- chmod 644 ~/.ssh/known_hosts
|
||||
|
||||
# The main script to execute for deployment.
|
||||
script:
|
||||
# Use rsync to synchronize files from the GitLab Runner to the target server.
|
||||
# -a: archive mode (preserves permissions, ownership, timestamps, recursive)
|
||||
# -v: verbose output
|
||||
# -z: compress file data during the transfer
|
||||
# --delete: delete extraneous files from dest dirs (DANGER: USE WITH CAUTION!)
|
||||
# Only use if you want to ensure the target directory exactly mirrors the source.
|
||||
# Otherwise, remove this flag.
|
||||
- rsync -avz --delete $WEBSITE_SOURCE_PATH $SSH_USER@$SSH_HOST:$DEPLOY_PATH
|
||||
|
||||
# Define what happens if the job succeeds or fails.
|
||||
after_script:
|
||||
# Optional: Clean up the SSH key from the runner's environment for security.
|
||||
- rm -f ~/.ssh/id_rsa
|
||||
18
Dockerfile
Normal file
@@ -0,0 +1,18 @@
|
||||
FROM nginx:latest
|
||||
|
||||
# Remove the default Nginx configuration file
|
||||
RUN rm /etc/nginx/conf.d/default.conf
|
||||
# Copy our custom configuration
|
||||
COPY nginx.conf /etc/nginx/conf.d/jmpgames.conf
|
||||
|
||||
# Create the directory and copy website files
|
||||
# Ensure the folder structure matches your 'root' directive in nginx.conf
|
||||
WORKDIR /var/www/jmpgames.it
|
||||
COPY..
|
||||
|
||||
# Fix permissions so Nginx can read the files
|
||||
RUN chown -R nginx:nginx /var/www/jmpgames.it && \
|
||||
chmod -R 755 /var/www/jmpgames.it
|
||||
|
||||
# Expose port 80 (internal container port)
|
||||
EXPOSE 80
|
||||
BIN
assets/android-chrome-192x192.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
assets/android-chrome-512x512.png
Normal file
|
After Width: | Height: | Size: 32 KiB |
BIN
assets/apple-touch-icon.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
BIN
assets/favicon-16x16.png
Normal file
|
After Width: | Height: | Size: 462 B |
BIN
assets/favicon-32x32.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
assets/favicon.ico
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
assets/instagram.jpeg
Normal file
|
After Width: | Height: | Size: 8.1 KiB |
BIN
assets/instagram.png
Normal file
|
After Width: | Height: | Size: 53 KiB |
BIN
assets/linkedin.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
1
assets/site.webmanifest
Normal file
@@ -0,0 +1 @@
|
||||
{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}
|
||||
BIN
assets/steam.png
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
BIN
assets/tiktok.png
Normal file
|
After Width: | Height: | Size: 5.3 KiB |
BIN
assets/youtube.png
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
BIN
favicon.ico
Normal file
|
After Width: | Height: | Size: 15 KiB |
16
index.html
@@ -14,19 +14,25 @@
|
||||
<main class="container">
|
||||
<div class="card logo-card">
|
||||
<img src="assets/jmpbianco.png" alt="JMP Games" class="logo">
|
||||
<h1>Enter the next Level</h1>
|
||||
</div>
|
||||
|
||||
<div class="card game-card">
|
||||
<h2>GAMES</h2>
|
||||
<div class="game-preview">
|
||||
<h3>The Drunken Beard</h3>
|
||||
<iframe style="width:100%" height="315" src="https://youtu.be/IGv_IGnXH6s" title="The Drunken Beard" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
|
||||
<iframe style="width:100%" height="315" src="https://www.youtube.com/embed/IGv_IGnXH6s?si=nnKGEUqYjIs4Nw90" title="The Drunken Beard" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
|
||||
<br/>
|
||||
<br/>
|
||||
<p>In The Drunken Beard, you take the reins of a lively tavern where every pint tells a story. Brew craft beers, manage orders between thirsty dwarves and impatient adventurers, expand the inn and turn it into a legendary haven. Between secret recipes, rustic furnishings, and demanding customers, only the finest innkeeper will win over hearts and livers. Glory awaits.. one beer at a time!
|
||||
</p>
|
||||
<div class="release-date">Demo available May 9th 2025</div>
|
||||
<div class="release-date">Demo available May 2025</div>
|
||||
<div class="release-date">Coming December 2025</div>
|
||||
<a href="https://store.steampowered.com/app/3622810/THE_DRUNKEN_BEARD/" target="_blank"><img src="assets/steam.png" width="50px" alt="Steam"></a>
|
||||
<div id="steam-events">
|
||||
<p>
|
||||
Searching Steam events...
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -80,7 +86,11 @@
|
||||
</div>
|
||||
<div class="contact-links">
|
||||
<a href="https://steamcommunity.com/id/jmpgames/" target="_blank"><img src="assets/steam.png" height="50px" alt="Steam JMP Games"></a>
|
||||
<a href="https://www.instagram.com/jmpgamesstudio/" target="_blank"><img src="assets/instagram.png" height="50px" alt="Instagram JMP Games"></a>
|
||||
<a href="https://discord.gg/QudFnQkEcQ" target="_blank"><img src="assets/discord.png" height="50px" alt="Discord JMP Games"></a>
|
||||
<a href="https://www.youtube.com/@JMPGames-x7b" target="_blank"><img src="assets/youtube.png" height="50px" alt="YouTube JMP Games"></a>
|
||||
<a href="https://www.tiktok.com/@jmpgamesstudio" target="_blank"><img src="assets/tiktok.png" height="50px" alt="TikTok JMP Games"></a>
|
||||
<a href="https://www.linkedin.com/company/108363891/" target="_blank"><img src="assets/linkedin.png" height="50px" alt="Linkedin JMP Games"></a>
|
||||
</div>
|
||||
<div class="copyright">
|
||||
<p>© 2025 JMP Games srls. All rights reserved.</p>
|
||||
|
||||
31
nginx.conf
Normal file
@@ -0,0 +1,31 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name jmpgames.it www.jmpgames.it;
|
||||
|
||||
# Serve static files
|
||||
root /var/www/jmpgames.it;
|
||||
index index.html;
|
||||
|
||||
# Logging: We use the default paths so they output to Docker logs (stdout/stderr)
|
||||
# This allows 'homepage' and 'fail2ban' to monitor them easily.
|
||||
access_log /var/log/nginx/access.log;
|
||||
error_log /var/log/nginx/error.log;
|
||||
|
||||
# Performance: Enable Gzip
|
||||
gzip on;
|
||||
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
|
||||
|
||||
# Security: Hide Nginx version number
|
||||
server_tokens off;
|
||||
|
||||
location / {
|
||||
# First attempt to serve request as file, then as directory, then 404
|
||||
try_files $uri $uri/ =404;
|
||||
}
|
||||
|
||||
# Cache settings for static assets (images, css, js)
|
||||
location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
||||
expires 30d;
|
||||
add_header Cache-Control "public, no-transform";
|
||||
}
|
||||
}
|
||||
84
script.js
@@ -1,4 +1,5 @@
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
|
||||
// Newsletter form submission
|
||||
const form = document.getElementById('newsletter-form');
|
||||
form.addEventListener('submit', async (e) => {
|
||||
@@ -8,7 +9,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
const message = e.target.querySelector('input[id="sub_message"]');
|
||||
message.setAttribute('type','text');
|
||||
message.type = 'text';
|
||||
const response = await fetch('http://localhost:3001/newsletter', {
|
||||
const response = await fetch('/api/newsletter', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
"email": email,
|
||||
@@ -28,4 +29,83 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
const video = document.getElementById('background-video');
|
||||
video.style.transform = `scale(1.1) translate(${mouseX * -20}px, ${mouseY * -20}px)`;
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
//retrieve steam events
|
||||
(async () => {
|
||||
const container = document.querySelector("#steam-events");
|
||||
console.log(container);
|
||||
if (!container) return;
|
||||
|
||||
const appId = container.dataset.appid || "3622810";
|
||||
const count = 5;
|
||||
|
||||
async function loadSteamEvents({ appId, count }) {
|
||||
const url = `/api/steamevents?appId=${appId}&count=${count}`;
|
||||
const res = await fetch(url);
|
||||
if (!res.ok) throw new Error("Unable to retrieve events");
|
||||
return res.json();
|
||||
}
|
||||
|
||||
function escapeHTML(str) {
|
||||
const p = document.createElement("p");
|
||||
p.textContent = str || "";
|
||||
return p.innerHTML;
|
||||
}
|
||||
|
||||
function renderSteamEvents(container, data) {
|
||||
if (!data.items?.length) {
|
||||
container.innerHTML = "<p>No event available.</p>";
|
||||
return;
|
||||
}
|
||||
|
||||
const list = document.createElement("ul");
|
||||
list.style.listStyle = "none";
|
||||
list.style.padding = "0";
|
||||
list.style.margin = "0";
|
||||
|
||||
data.items.forEach(item => {
|
||||
const li = document.createElement("li");
|
||||
li.style.border = "1px solid #ddd";
|
||||
li.style.borderRadius = "12px";
|
||||
li.style.padding = "12px 16px";
|
||||
li.style.margin = "8px 0";
|
||||
li.style.background = "#fff";
|
||||
li.style.boxShadow = "0 1px 2px rgba(0,0,0,0.05)";
|
||||
|
||||
const title = document.createElement("a");
|
||||
title.href = item.url;
|
||||
title.target = "_blank";
|
||||
title.rel = "noopener";
|
||||
title.textContent = item.title || "Update";
|
||||
|
||||
const meta = document.createElement("div");
|
||||
meta.style.fontSize = "12px";
|
||||
meta.style.opacity = "0.7";
|
||||
const d = item.date ? new Date(item.date).toLocaleString() : "";
|
||||
meta.textContent = [d, item.feedlabel].filter(Boolean).join(" • ");
|
||||
|
||||
const excerpt = document.createElement("p");
|
||||
const short = (item.contents || "").replace(/\s+/g, " ").trim().slice(0, 240);
|
||||
excerpt.innerHTML = escapeHTML(short) + (short.length >= 240 ? "…" : "");
|
||||
|
||||
li.appendChild(title);
|
||||
li.appendChild(meta);
|
||||
li.appendChild(excerpt);
|
||||
list.appendChild(li);
|
||||
});
|
||||
|
||||
container.innerHTML = "";
|
||||
container.appendChild(list);
|
||||
}
|
||||
|
||||
try {
|
||||
const data = await loadSteamEvents({ appId, count });
|
||||
renderSteamEvents(container, data);
|
||||
} catch (e) {
|
||||
container.innerHTML = "<p>Error loading Steam events.</p>";
|
||||
console.error(e);
|
||||
}
|
||||
})();
|
||||
|
||||
});
|
||||
1
site-server
Submodule
10
styles.css
@@ -18,7 +18,6 @@
|
||||
body {
|
||||
font-family: 'Rajdhani', sans-serif;
|
||||
background-color: var(--bg-dark);
|
||||
background-image: url('norse-pattern.png');
|
||||
background-blend-mode: overlay;
|
||||
color: var(--text-light);
|
||||
min-height: 100vh;
|
||||
@@ -41,6 +40,7 @@ body {
|
||||
}
|
||||
|
||||
.container {
|
||||
height: 100%;
|
||||
max-width: 1200px;
|
||||
width: 90%;
|
||||
margin: 2rem auto;
|
||||
@@ -74,7 +74,7 @@ body {
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 150px;
|
||||
width: 250px;
|
||||
height: auto;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
@@ -94,6 +94,12 @@ h2 {
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: clamp(1.4rem, 4vw, 1.8rem);
|
||||
margin-top: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.tagline {
|
||||
font-size: 1.2rem;
|
||||
opacity: 0.8;
|
||||
|
||||