feat: update site

This commit is contained in:
Strix 2025-03-25 22:46:00 +01:00
parent 71b2aaae4f
commit a6ff285b2e
6 changed files with 321 additions and 37 deletions

103
public/res/locale.js Normal file
View file

@ -0,0 +1,103 @@
(() => {
const getLocale = () => {
const cacheLocale = localStorage.getItem('preferredLocale')
if (cacheLocale) return cacheLocale
localStorage.setItem('preferredLocale', navigator.language);
return locale
}
const setPreferredLocale = (locale) => {
localStorage.setItem('preferredLocale', locale);
setLocale()
}
const getLocaleURL = (locale = getLocale()) => {
const lang = locale.split('-')[0];
return `/res/locale/${lang}.json`
}
const loadLocale = async (locale = getLocale()) => {
// check localStorage
const cacheDate = localStorage.getItem(`locale-${locale}`)
if (cacheDate) {
if (Date.now() - cacheDate < 1000 * 60 * 60 * 24) { // 1 day
return JSON.parse(localStorage.getItem(`locale-${locale}-data`))
}
}
try {
const response = await fetch(getLocaleURL(locale), { cache: 'no-store' })
if (response.ok) {
const data = await response.json()
localStorage.setItem(`locale-${locale}`, Date.now())
localStorage.setItem(`locale-${locale}-data`, JSON.stringify(data))
return data
}
} catch (error) {
console.error(error)
if (cacheDate) { // if error then return cache even if expired
return JSON.parse(localStorage.getItem(`locale-${locale}-data`))
} else {
if (locale !== 'en') return await loadLocale('en');
}
}
return {}
}
const setLocale = async (locale = getLocale()) => {
const data = await loadLocale(locale)
document.querySelectorAll('[data-i18n]').forEach(async (element) => {
try {
// main.intro.title => {main: {intro: {title: 'value'}}}
const keys = element.getAttribute('data-i18n').split('.');
console.log(keys)
let value = data;
keys.forEach((key) => value = value[key]);
console.log(value)
// if array then into ul list
if (Array.isArray(value)) {
element.innerHTML = ''
const ul = document.createElement('ul')
value.forEach((item) => {
const li = document.createElement('li')
li.innerHTML = item
ul.appendChild(li)
})
element.appendChild(ul)
} else {
element.innerHTML = value ?? '###';
}
} catch (error) {
console.error(error)
element.innerHTML = '###';
}
});
document.querySelectorAll('[data-i18n-show').forEach(el => el.removeAttribute('data-i18n-show'))
}
window.locale = {
setPreferredLocale,
getLocale,
getLocaleURL,
loadLocale,
setLocale,
expireLocale: () => {
localStorage.removeItem(`locale-${getLocale()}`)
localStorage.removeItem(`locale-${getLocale()}-data`)
setLocale()
}
}
window.locale.setLocale();
// expiry management
// check if locale is older than EXPIRY_TIME then fetch again
function checkExpiry() {
const cacheDate = localStorage.getItem(`locale-${getLocale()}`)
if (cacheDate) {
if (Date.now() - cacheDate > 1000 * 60 * 60 * 24) { // 1 day
window.locale.expireLocale()
}
}
}
setInterval(checkExpiry, 1000 * 60 * 60); // 1 hour
checkExpiry()
})()

66
public/res/locale/en.json Normal file
View file

@ -0,0 +1,66 @@
{
"$": {
"name": "Nebulosus",
"kvk": 93409583,
"mail": "info@nebulosus.nl",
"motto": "Focused on innovation."
},
"about": {
"title": "About",
"text": "Nebulosus is a Dutch company focused on intuition, <span style='letter-spacing: 1px;'>simplicity</span>, <b style='color: darkgoldenrod;'>redundancy</b>, <span style='color: darkcyan; text-decoration: underline;'>reliability</span>, and <i style='color: green'>friendliness</i>. <br /> We believe software should be intuitive and aware of its environment. This is the standard we aim for at Nebulosus.<br />Looking to develop an app with intuitive design and robust infrastructure? Get in touch!<br />Need a company website? Lets discuss how we can help."
},
"offer": {
"title": "Offer",
"it-consultancy": {
"title": "IT Consultancy",
"tagline": "IT consultancy services for your business.",
"description": "Nebulosus offers IT consultancy services for your business. Giving you a clear understanding of the technology you need to move forward.",
"solutions": [
"IT Strategy",
"Infrastructure",
"Security",
"Compliance",
"Training"
]
},
"managed-hosting": {
"title": "Managed Hosting",
"tagline": "Managed hosting services for your website.",
"description": "Nebulosus offers managed hosting services for your website. Taking care of the technical stuff so you can focus on your business.",
"solutions": [
"Application Hosting",
"DNS Management (Domain and Subdomains)",
"SSL Certificates",
"Email Hosting"
]
},
"tech-support": {
"title": "Tech Support",
"tagline": "Professional support for your technical issues.",
"description": "Having an issue with your website, computer, or network? Nebulosus offers professional support for all your technical issues.",
"solutions": [
"Android/iOS Support",
"Windows/Mac/Linux Support",
"Network Support",
"Installation and Configuration",
"Advice and Guidance"
]
},
"development": {
"title": "Development",
"tagline": "Development services for your business.",
"description": "Nebulosus offers development services for your application. Whether you need a website, custom integration, or want to automate your business, Nebulosus can help.",
"solutions": [
"(Web)applications",
"Integration development",
"Automation",
"API Development",
"Database Development"
]
}
},
"dict": {
"kvk": "Chamber of Commerce",
"mail": "Email"
}
}

66
public/res/locale/nl.json Normal file
View file

@ -0,0 +1,66 @@
{
"$": {
"name": "Nebulosus",
"kvk": 93409583,
"mail": "info@nebulosus.nl",
"motto": "Gericht op innovatie."
},
"about": {
"title": "Over",
"text": "Nebulosus is een Nederlands bedrijf dat streeft naar intuïtieve, eenvoudige en betrouwbare software, met redundantie en gebruiksvriendelijkheid als kernwaarden. <br /> Software moet intuïtief en omgevingsbewust zijn. Daar zetten wij ons voor in.<br />Wil je een app met intuïtief design en een robuuste infrastructuur? Neem contact op!<br />Op zoek naar een bedrijfssite? Laten we het bespreken!"
},
"offer": {
"title": "Aanbod",
"it-consultancy": {
"title": "IT Consultancy",
"tagline": "IT-consultancydiensten voor uw bedrijf.",
"description": "Technologie moet je vooruithelpen, niet tegenwerken. Strategisch advies waarmee uw bedrijf wendbaar blijft in een snel veranderend digitaal landschap.",
"solutions": [
"IT-strategie",
"Infrastructuur",
"Beveiliging",
"Compliance",
"Training"
]
},
"managed-hosting": {
"title": "Beheerde Hosting",
"tagline": "Beheerde hostingdiensten voor uw website.",
"description": "Nebulosus biedt beheerde hostingdiensten voor uw website. Terwijl de technische zaken worden geregeld, kunt u zich richten op uw bedrijf.",
"solutions": [
"Applicatie Hosting",
"DNS-beheer (Domeinnaam en subdomeinen)",
"SSL-certificaten",
"E-mailhosting"
]
},
"tech-support": {
"title": "Technische Ondersteuning",
"tagline": "Professionele ondersteuning bij uw technische problemen.",
"description": "Een probleem met uw website, computer of netwerk? Nebulosus biedt professionele ondersteuning voor al uw technische problemen.",
"solutions": [
"Android/iOS-ondersteuning",
"Windows/Mac/Linux-ondersteuning",
"Netwerkondersteuning",
"Installatie en configuratie",
"Advies en begeleiding"
]
},
"development": {
"title": "Ontwikkeling",
"tagline": "Ontwikkelingsdiensten voor uw bedrijf.",
"description": "Nebulosus biedt ontwikkelingsdiensten voor uw applicatie. Of u nu een website, mobiele app of aangepaste software nodig heeft, Nebulosus kan helpen.",
"solutions": [
"(Web)applicaties",
"Integratie ontwikkeling",
"Automatisering",
"API's",
"Databaseontwikkeling"
]
}
},
"dict": {
"kvk": "Kamer van Koophandel",
"mail": "E-mail"
}
}

View file

@ -25,7 +25,6 @@ header {
color: #000;
align-content: center;
z-index: 100;
box-shadow: 0 0 20px var(--theme-color-lowlight);
}
header div.logo {
@ -80,6 +79,20 @@ div section {
/* --- */
footer {
display: flex;
flex-direction: column;
position: fixed;
bottom: 0;
width: calc(100vw - 5em);
height: 2rem;
padding-left: 2.5em;
background-color: #fff;
justify-content: center;
}
/* --- */
/* for anchors.js */
h2:hover {
cursor: pointer;
@ -148,7 +161,7 @@ button {
cursor: pointer;
&:hover {
background-color: var(--theme-color-highlight-2);
border: 1px solid var(--theme-color-highlight);
}
transition: background-color .2s ease-in-out;
@ -156,7 +169,6 @@ button {
.columns {
display: flex;
align-items: center;
@media (max-width: 600px) {
flex-direction: column;