149 lines
4.3 KiB
HTML
149 lines
4.3 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="de">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
|
<title>Zeiterfassung</title>
|
|
|
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css">
|
|
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
|
|
|
<style>
|
|
body {
|
|
min-height: 100vh;
|
|
}
|
|
|
|
.table-container {
|
|
overflow-x: auto;
|
|
}
|
|
|
|
@media screen and (max-width: 768px) {
|
|
.level {
|
|
flex-direction: column;
|
|
}
|
|
|
|
.level-left, .level-right {
|
|
width: 100%;
|
|
}
|
|
|
|
.level-item {
|
|
justify-content: center;
|
|
margin-bottom: 0.5rem;
|
|
}
|
|
|
|
.buttons {
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.button {
|
|
margin-bottom: 0.5rem;
|
|
}
|
|
}
|
|
|
|
.fa-spinner {
|
|
animation: fa-spin 1s infinite linear;
|
|
}
|
|
|
|
@keyframes fa-spin {
|
|
0% { transform: rotate(0deg); }
|
|
100% { transform: rotate(360deg); }
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div id="elm"></div>
|
|
|
|
<script src="/elm.js"></script>
|
|
<script>
|
|
function getStoredData() {
|
|
try {
|
|
const data = localStorage.getItem('timetracking');
|
|
if (data) {
|
|
return JSON.parse(data);
|
|
}
|
|
} catch (e) {
|
|
console.error('Failed to parse stored data:', e);
|
|
}
|
|
return { token: null, isAdmin: false };
|
|
}
|
|
|
|
function saveData(token, isAdmin) {
|
|
try {
|
|
localStorage.setItem('timetracking', JSON.stringify({
|
|
token: token,
|
|
isAdmin: isAdmin
|
|
}));
|
|
} catch (e) {
|
|
console.error('Failed to save data:', e);
|
|
}
|
|
}
|
|
|
|
function clearData() {
|
|
try {
|
|
localStorage.removeItem('timetracking');
|
|
} catch (e) {
|
|
console.error('Failed to clear data:', e);
|
|
}
|
|
}
|
|
|
|
const storedData = getStoredData();
|
|
const app = Elm.Main.init({
|
|
node: document.getElementById('elm'),
|
|
flags: {
|
|
token: storedData.token,
|
|
isAdmin: storedData.isAdmin
|
|
}
|
|
});
|
|
|
|
app.ports.saveToken.subscribe(function(data) {
|
|
saveData(data.token, data.isAdmin);
|
|
});
|
|
|
|
app.ports.removeToken.subscribe(function() {
|
|
clearData();
|
|
});
|
|
|
|
app.ports.confirmDelete.subscribe(function(message) {
|
|
const confirmed = confirm(message);
|
|
app.ports.confirmDeleteResponse.send(confirmed);
|
|
});
|
|
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
function setupBurgerMenu() {
|
|
const burgers = document.querySelectorAll('.navbar-burger');
|
|
|
|
burgers.forEach(burger => {
|
|
burger.addEventListener('click', () => {
|
|
const target = burger.dataset.target;
|
|
const menu = document.getElementById(target);
|
|
|
|
if (menu) {
|
|
burger.classList.toggle('is-active');
|
|
menu.classList.toggle('is-active');
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
setupBurgerMenu();
|
|
|
|
const observer = new MutationObserver((mutations) => {
|
|
setupBurgerMenu();
|
|
});
|
|
|
|
observer.observe(document.getElementById('elm'), {
|
|
childList: true,
|
|
subtree: true
|
|
});
|
|
});
|
|
|
|
if ('serviceWorker' in navigator && window.location.protocol === 'https:') {
|
|
navigator.serviceWorker.register('/sw.js').catch(() => {
|
|
console.log('Service Worker registration failed');
|
|
});
|
|
}
|
|
</script>
|
|
</body>
|
|
</html>
|