now multi lingual

This commit is contained in:
Ricardo Band 2025-08-17 15:11:40 +02:00
commit 83cef1824b
No known key found for this signature in database
2 changed files with 147 additions and 14 deletions

View file

@ -60,11 +60,33 @@
<script src="js/qr-creator.min.js"></script> <script src="js/qr-creator.min.js"></script>
</head> </head>
<body> <body>
<nav class="navbar" role="navigation" aria-label="main navigation">
<div class="navbar-brand">
<a role="button" class="navbar-burger" data-target="navMenu" aria-label="menu" aria-expanded="false">
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
<span aria-hidden="true"></span>
</a><!--/.navbar-burger-->
</div><!--/.navbar-brand-->
<div class="navbar-menu" id="navMenu">
<div class="navbar-end">
<div class="navbar-item has-dropdown" id="language-dropdown">
<a class="navbar-link" id="current-language">&#x1F1EC;&#x1F1E7; EN</a>
<div class="navbar-dropdown" id="language-selector">
<!-- language items filled from js -->
</div><!--/.navbar-dropdown-->
</div><!--/.navbar-item .has-dropdown .is-hoverable-->
</div><!--/.navbar-end-->
</div><!--/.navbar-menu-->
</nav><!--/.navbar-->
<section class="section"> <section class="section">
<div class="container"> <div class="container">
<h1 class="title">BezahlBrudi</h1> <h1 class="title">BezahlBrudi</h1>
<p class="subtitle">Transfer money without any 3rd parties</p> <p class="subtitle" data-i18n="subtitle"></p>
<p>The QR code can be scanned by most banking apps. Give it a try!</p> <p data-i18n="explain"></p>
</div> </div>
</section> </section>
@ -73,7 +95,7 @@
<div class="columns"> <div class="columns">
<div class="column"> <div class="column">
<div id="name" class="field"> <div id="name" class="field">
<label for="input-name" class="label">Receiver Name</label> <label for="input-name" class="label" data-i18n="name"></label>
<div class="control has-icons-right"> <div class="control has-icons-right">
<input id="input-name" class="input" type="text" placeholder="Receiver Name" value="" maxlength="70" required> <input id="input-name" class="input" type="text" placeholder="Receiver Name" value="" maxlength="70" required>
<span class="icon is-small is-right"></span> <span class="icon is-small is-right"></span>
@ -81,7 +103,7 @@
</div> </div>
<div id="iban" class="field"> <div id="iban" class="field">
<label for="input-iban" class="label">Receiver IBAN</label> <label for="input-iban" class="label" data-i18n="iban"></label>
<div class="control has-icons-right"> <div class="control has-icons-right">
<input id="input-iban" class="input" type="text" value="" required> <input id="input-iban" class="input" type="text" value="" required>
<span class="icon is-small is-right"></span> <span class="icon is-small is-right"></span>
@ -89,16 +111,16 @@
</div> </div>
<div id="bic" class="field"> <div id="bic" class="field">
<label for="input-bic" class="label">Receiver BIC</label> <label for="input-bic" class="label" data-i18n="bic"></label>
<div class="control has-icons-right"> <div class="control has-icons-right">
<input id="input-bic" class="input" type="text" value=""> <input id="input-bic" class="input" type="text" value="">
<span class="icon is-small is-right"></span> <span class="icon is-small is-right"></span>
</div> </div>
<p class="help">Only needed if the Sender and/or Receiver IBAN is outside the EU</p> <p class="help" data-i18n="bic-help"></p>
</div> </div>
<div id="amount" class="field"> <div id="amount" class="field">
<label for="input-amount" class="label">Amount</label> <label for="input-amount" class="label" data-i18n="amount"></label>
<div class="control has-icons-left has-icons-right"> <div class="control has-icons-left has-icons-right">
<input id="input-amount" class="input" type="number" min="0.00" step="0.01" value="0.00" pattern="[0-9]+.[0-9]{2}" placeholder="0.00" required> <input id="input-amount" class="input" type="number" min="0.00" step="0.01" value="0.00" pattern="[0-9]+.[0-9]{2}" placeholder="0.00" required>
<span class="icon is-small is-left"><b>&euro;</b></span> <span class="icon is-small is-left"><b>&euro;</b></span>
@ -107,7 +129,7 @@
</div> </div>
<div id="purpose" class="field"> <div id="purpose" class="field">
<label for="input-purpose" class="label">Purpose</label> <label for="input-purpose" class="label" data-i18n="purpose"></label>
<div class="control has-icons-right"> <div class="control has-icons-right">
<input id="input-purpose" class="input" type="text" placeholder="Pizza night!" value="" maxlength="140" required> <input id="input-purpose" class="input" type="text" placeholder="Pizza night!" value="" maxlength="140" required>
<span class="icon is-small is-right"></span> <span class="icon is-small is-right"></span>
@ -117,7 +139,7 @@
<div class="field"> <div class="field">
<label class="checkbox"> <label class="checkbox">
<input id="rememberme" type="checkbox" /> <input id="rememberme" type="checkbox" />
Remember me <span data-i18n="remember"></span>
</label> </label>
</div> </div>
</div> </div>
@ -134,14 +156,63 @@
<footer class="footer"> <footer class="footer">
<div class="content has-text-centered"> <div class="content has-text-centered">
<p> <p>
<strong>BezahlBrudi v1.1.0</strong> by <a href="https://xengi.de">XenGi</a>. <strong>BezahlBrudi v1.2.0</strong> by <a href="https://xengi.de">XenGi</a>.
The source code is licensed <a href="https://opensource.org/license/mit">MIT</a>. Find the source code on <a href="https://gitlab.com/xengi/bezahlbrudi/">GitLab</a>. <span data-i18n="disclaimer">
The source code is licensed under <a href="https://opensource.org/license/mit">MIT</a>, you can find it <a href="https://gitlab.com/xengi/bezahlbrudi/">here</a>.
<br/> <br/>
This site doesn't store any data outside your browser, not even cookies. The "Remember me" function stores your data in your browsers local storage. This site doesn't provide any financial services. It is a simple QR code generator. This site doesn't store any data outside your browser, not even cookies. The "Remember data" function stores your data in your browsers local storage. This site doesn't provide any financial services. It is a simple QR code generator.</span>
</p> </p>
</div> </div>
</footer> </footer>
<script type="application/json" id="i18n-data">
{
"_flags": {
"en": "&#x1F1EC;&#x1F1E7;",
"de": "&#x1F1E9;&#x1F1EA;"
},
"subtitle": {
"en": "Transfer money without any 3rd parties",
"de": "Geld überweisen ohne Drittanbieter"
},
"explain": {
"en": "Simply fill in your details and scan the QR code with your banking app. Give it a try!",
"de": "Einfach deine Daten eintragen und den QR Code mit deiner Banking-App scannen. Probier es aus!"
},
"name": {
"en": "Receiver Name",
"de": "Empfänger Name"
},
"iban": {
"en": "Receiver IBAN",
"de": "Empfänger IBAN"
},
"bic": {
"en": "Receiver BIC",
"de": "Empfänger BIC"
},
"bic-help": {
"en": "Only needed if the Sender or Receiver IBAN is outside the EU",
"de": "Nur nötig wenn Sender oder Empfänger IBAN außerhalb der EU sind"
},
"amount": {
"en": "Amount",
"de": "Betrag"
},
"purpose": {
"en": "Purpose",
"de": "Verwendungszweck"
},
"remember": {
"en": "Remember data",
"de": "Daten merken"
},
"disclaimer": {
"en": "The source code is licensed under <a href=\"https://opensource.org/license/mit\">MIT</a>, you can find it <a href=\"https://gitlab.com/xengi/bezahlbrudi/\">here</a>.<br/>This site doesn't store any data outside your browser, not even cookies. The \"Remember data\" function stores your data in your browsers local storage. This site doesn't provide any financial services. It is a simple QR code generator.",
"de": "Der Quellcode ist lizensiert unter <a href=\"https://opensource.org/license/mit\">MIT</a>, du kannst ihn <a href=\"https://gitlab.com/xengi/bezahlbrudi/\">hier</a> finden.<br/>Diese Seite speichert keine Daten außerhalb deines Browsers, noch nicht einmal Cookies. Die \"Daten merken\" Funktion speichert Daten im Local Storage des Browsers. Diese Seite bietet keine Finanzdienstleistungen an. Sie ist lediglich ein simpler QR Code Generator."
}
}
</script>
<script src="js/index.js"></script> <script src="js/index.js"></script>
</body> </body>
</html> </html>

View file

@ -1,10 +1,60 @@
// bulma hamburger menu
document.addEventListener('DOMContentLoaded', () => {
// Get all "navbar-burger" elements
const $navbarBurgers = Array.prototype.slice.call(document.querySelectorAll('.navbar-burger'), 0);
// Add a click event on each of them
$navbarBurgers.forEach(el => {
el.addEventListener('click', () => {
// Get the target from the "data-target" attribute
const target = el.dataset.target;
const $target = document.getElementById(target);
// Toggle the "is-active" class on both the "navbar-burger" and the "navbar-menu"
el.classList.toggle('is-active');
$target.classList.toggle('is-active');
});
});
});
// language selector
document.getElementById("current-language").addEventListener("click", (e) => {
e.preventDefault();
document.getElementById("language-dropdown").classList.toggle("is-active");
});
const i18n = JSON.parse(document.getElementById("i18n-data").textContent);
const i18nSupported = Object.keys(i18n._flags)
// build language selector
const langSelector = document.getElementById("language-selector")
for (const l of i18nSupported) {
const a = document.createElement("a");
a.classList.add("navbar-item");
a.innerHTML = `${i18n._flags[l]} ${l.toUpperCase()}`;
a.href = "#";
a.addEventListener("click", (e) => {
changeLanguage(e.target.textContent.slice(-2).toLowerCase());
document.getElementById("language-dropdown").classList.remove("is-active");
});
langSelector.appendChild(a);
}
changeLanguage = (l) => {
const lang = i18nSupported.includes(l) ? l : "en";
document.querySelectorAll("[data-i18n]").forEach(el => {
el.innerHTML = i18n[el.dataset.i18n][lang];
});
document.getElementById("current-language").innerHTML = `${i18n._flags[lang]} ${lang.toUpperCase()}`;
console.log(`Switching language to ${lang}`);
};
saveFormData = () => { saveFormData = () => {
localStorage.setItem("bezahlbrudiFormData", JSON.stringify({ localStorage.setItem("bezahlbrudiFormData", JSON.stringify({
name: document.querySelector("#name input").value, name: document.querySelector("#name input").value,
iban: document.querySelector("#iban input").value.toUpperCase(), iban: document.querySelector("#iban input").value.toUpperCase(),
bic: document.querySelector("#bic input").value.toUpperCase(), bic: document.querySelector("#bic input").value.toUpperCase(),
amount: parseFloat(document.querySelector("#amount input").value).toFixed(2), amount: parseFloat(document.querySelector("#amount input").value).toFixed(2),
purpose: document.querySelector("#purpose input").value purpose: document.querySelector("#purpose input").value,
lang: document.getElementById("current-language").textContent.slice(-2).toLowerCase()
})); }));
} }
@ -224,6 +274,18 @@ if (savedData) {
document.querySelector("#amount input").value = formData["amount"]; document.querySelector("#amount input").value = formData["amount"];
document.querySelector("#purpose input").value = formData["purpose"]; document.querySelector("#purpose input").value = formData["purpose"];
document.querySelector("#rememberme").checked = true; document.querySelector("#rememberme").checked = true;
changeLanguage(formData["lang"]);
} else {
// get browser language
let lang = "en"; // default fallback
for (const l of navigator.languages) {
const base = l.split("-")[0];
if (i18nSupported.includes(base)) {
lang = base;
break;
}
}
changeLanguage(lang);
} }
// Validate all fields to set css properties // Validate all fields to set css properties