3rd ed.
This commit is contained in:
parent
dfaf542c4b
commit
045977f9fb
7 changed files with 933 additions and 762 deletions
6
.gitignore
vendored
6
.gitignore
vendored
|
|
@ -18,9 +18,9 @@ ios/
|
|||
www/
|
||||
|
||||
# Environment files
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
#.env
|
||||
#.env.*
|
||||
#!.env.example
|
||||
|
||||
# System files
|
||||
.DS_Store
|
||||
|
|
|
|||
791
app/app.js
791
app/app.js
File diff suppressed because it is too large
Load diff
|
|
@ -14,6 +14,8 @@
|
|||
<div id="setup-page" class="hidden">
|
||||
<h2>Configurazione</h2>
|
||||
|
||||
<button id="cfg-refresh">Aggiorna ora</button>
|
||||
|
||||
<label>URL</label>
|
||||
<input id="cfg-url" type="text">
|
||||
|
||||
|
|
@ -37,5 +39,10 @@
|
|||
</div>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
|
||||
<script src="app.js"></script>
|
||||
|
||||
<!-- --> <script src="https://cdn.jsdelivr.net/npm/eruda"></script>
|
||||
<script>
|
||||
eruda.init();
|
||||
</script> <!-- -->
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
4
app/start.sh
Executable file
4
app/start.sh
Executable file
|
|
@ -0,0 +1,4 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Avvia un server HTTP sulla porta 11002 senza cache
|
||||
npx http-server . -c-1 -p 11002
|
||||
|
|
@ -254,3 +254,6 @@ html, body {
|
|||
border: none;
|
||||
}
|
||||
|
||||
#cfg-refresh {
|
||||
display: none;
|
||||
}
|
||||
|
|
|
|||
16
server/backend/.env
Normal file
16
server/backend/.env
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
# === SERVER CONFIG ===
|
||||
PORT=11001
|
||||
|
||||
# === JWT CONFIG ===
|
||||
# Cambialo SEMPRE in produzione
|
||||
JWT_SECRET=master66
|
||||
|
||||
# === MONGO CONFIG ===
|
||||
# In locale:
|
||||
# MONGO_URI=mongodb://localhost:27017/mydb
|
||||
#
|
||||
# In Docker (usato dal docker-compose):
|
||||
MONGO_URI=mongodb://root:example@192.168.1.3:27017/myapphttps?authSource=admin
|
||||
# === UPLOADS ===
|
||||
# Cartella dove Express serve le icone
|
||||
UPLOAD_DIR=uploads
|
||||
|
|
@ -1,98 +0,0 @@
|
|||
import {
|
||||
login,
|
||||
register,
|
||||
getLinks,
|
||||
createLink,
|
||||
deleteLink,
|
||||
updateLink
|
||||
} from "./api.js";
|
||||
|
||||
const authSection = document.getElementById("authSection");
|
||||
const linkSection = document.getElementById("linkSection");
|
||||
const authStatus = document.getElementById("authStatus");
|
||||
const list = document.getElementById("list");
|
||||
|
||||
let token = null;
|
||||
|
||||
// ------------------------------
|
||||
// AUTH
|
||||
// ------------------------------
|
||||
|
||||
function setToken(t) {
|
||||
token = t;
|
||||
if (token) {
|
||||
authSection.style.display = "none";
|
||||
linkSection.style.display = "block";
|
||||
loadLinks();
|
||||
} else {
|
||||
authSection.style.display = "block";
|
||||
linkSection.style.display = "none";
|
||||
}
|
||||
}
|
||||
|
||||
document.getElementById("loginForm").addEventListener("submit", async e => {
|
||||
e.preventDefault();
|
||||
const email = e.target.email.value;
|
||||
const password = e.target.password.value;
|
||||
|
||||
try {
|
||||
const t = await login(email, password);
|
||||
setToken(t);
|
||||
} catch (err) {
|
||||
authStatus.textContent = err.message;
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById("registerForm").addEventListener("submit", async e => {
|
||||
e.preventDefault();
|
||||
const email = e.target.email.value;
|
||||
const password = e.target.password.value;
|
||||
|
||||
try {
|
||||
await register(email, password);
|
||||
authStatus.textContent = "Registrato! Ora effettua il login.";
|
||||
} catch (err) {
|
||||
authStatus.textContent = err.message;
|
||||
}
|
||||
});
|
||||
|
||||
// ------------------------------
|
||||
// LINKS
|
||||
// ------------------------------
|
||||
|
||||
async function loadLinks() {
|
||||
const links = await getLinks(token);
|
||||
|
||||
list.innerHTML = links
|
||||
.map(
|
||||
link => `
|
||||
<div class="item">
|
||||
${link.icon ? `<img src="http://192.168.1.3:3000${link.icon}">` : ""}
|
||||
<div>
|
||||
<strong>${link.name}</strong><br>
|
||||
<a href="${link.url}" target="_blank">${link.url}</a>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
)
|
||||
.join("");
|
||||
}
|
||||
|
||||
document.getElementById("linkForm").addEventListener("submit", async e => {
|
||||
e.preventDefault();
|
||||
|
||||
const formData = new FormData(e.target);
|
||||
const iconFile = formData.get("icon");
|
||||
|
||||
await createLink(token, {
|
||||
name: formData.get("name"),
|
||||
url: formData.get("url"),
|
||||
iconFile: iconFile.size > 0 ? iconFile : null
|
||||
});
|
||||
|
||||
e.target.reset();
|
||||
loadLinks();
|
||||
});
|
||||
|
||||
// Init
|
||||
setToken(null);
|
||||
Loading…
Reference in a new issue