Init: basic templating.
This commit is contained in:
commit
ec1b43754a
7 changed files with 608 additions and 0 deletions
23
README.md
Normal file
23
README.md
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
# 📚 Digitales Berichtsheft
|
||||||
|
Eine WebApp zur digitalen führung des Berichtshefts.
|
||||||
|
|
||||||
|
## Beweggründe
|
||||||
|
Ich schreibe nicht gerne von Hand und die Prüfer der IHK bevorzugen mit sicherheit auch ein gut lesbares Dokument.
|
||||||
|
Alternativen waren entweder umständlich/schwer zugänglich (Word Dokumente) oder hinter einer paywall.
|
||||||
|
|
||||||
|
## Zustand des Projekts
|
||||||
|
Die meisten Templates und Funktionen zum anzeigen des Berichtshefts sind geschrieben. \
|
||||||
|
Aktuell muss man die Berichtsheftdaten noch händisch in das "userdata" objekt einfügen.
|
||||||
|
|
||||||
|
## Feature Roadmap für v1.0
|
||||||
|
- [ ] Templates
|
||||||
|
- [x] Titelseite
|
||||||
|
- [x] Leer/Platzhalter
|
||||||
|
- [ ] Fehlzeiten
|
||||||
|
- [x] Wochenbericht
|
||||||
|
- [ ] Import & Export von Berichtsheftdaten
|
||||||
|
- [ ] Session storage
|
||||||
|
- [ ] Funktionen
|
||||||
|
- [x] Hinzufügen von Seiten
|
||||||
|
- [ ] Löschen von Seiten
|
||||||
|
- [ ] Formulare zum eintragen/modifizieren von Berichtsheftseiten
|
193
berichtsheft/assets/css/notebook.css
Normal file
193
berichtsheft/assets/css/notebook.css
Normal file
|
@ -0,0 +1,193 @@
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: darkgray;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
border-top: 1px solid black;
|
||||||
|
}
|
||||||
|
|
||||||
|
td {
|
||||||
|
height: 1.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.week {
|
||||||
|
width: 100%;
|
||||||
|
height: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.week th {
|
||||||
|
height: 2em;
|
||||||
|
font-weight: normal;
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: middle;
|
||||||
|
background-color: #f2f2f2;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.week tbody:nth-child(odd) tr:nth-child(odd) {
|
||||||
|
background-color: #f2f2f2;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.week tbody:nth-child(even) tr:nth-child(even) {
|
||||||
|
background-color: #f2f2f2;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.week thead th:nth-last-child(-n+2) {
|
||||||
|
width: 10%;
|
||||||
|
font-size: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.week td:nth-last-child(-n+2) {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.week tbody:last-child tr:last-child td:first-child {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vtable {
|
||||||
|
width: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vertical {
|
||||||
|
vertical-align: middle;
|
||||||
|
writing-mode: vertical-lr;
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sign {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 15%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sign table {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sign table, .sign table td {
|
||||||
|
border: 1px solid black;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sign td {
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sign tr:last-child td {
|
||||||
|
height: 90%;
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: bottom;
|
||||||
|
font-size: 0.7em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page {
|
||||||
|
position: relative;
|
||||||
|
margin: auto;
|
||||||
|
margin-bottom: 0.25cm;
|
||||||
|
width: 21cm;
|
||||||
|
height: 29.7cm;
|
||||||
|
display: grid;
|
||||||
|
grid-template-rows: 2cm auto 2cm;
|
||||||
|
background: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page:nth-child(odd) {
|
||||||
|
grid-template-columns: 2.41cm auto 0.81cm;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page:nth-child(even) {
|
||||||
|
grid-template-columns: 0.81cm auto 2.42cm;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pg-head {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
grid-row: 1 / 2;
|
||||||
|
grid-column: 2 / 3;
|
||||||
|
background: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pg-head .flex {
|
||||||
|
position: absolute;
|
||||||
|
top: 1cm;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pg-head img {
|
||||||
|
position: absolute;
|
||||||
|
top: .5cm;
|
||||||
|
height: .5cm;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page:nth-child(odd) .pg-head img {
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pg-content {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
grid-row: 2 / 3;
|
||||||
|
grid-column: 2 / 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pg-footer {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
grid-row: 3 / 4;
|
||||||
|
grid-column: 2 / 3;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
white-space: pre;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.sticky {
|
||||||
|
position: sticky;
|
||||||
|
position: -webkit-sticky;
|
||||||
|
align-self: flex-start;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
white-space: pre;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eightyw {
|
||||||
|
width: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.halfw {
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quarterw {
|
||||||
|
width: 25%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tenw {
|
||||||
|
width: 10%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.halfh {
|
||||||
|
height: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media print {
|
||||||
|
body, .page {
|
||||||
|
margin: none;
|
||||||
|
}
|
||||||
|
.sticky, button {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
140
berichtsheft/assets/js/notebook.js
Normal file
140
berichtsheft/assets/js/notebook.js
Normal file
|
@ -0,0 +1,140 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
const app = document.getElementById("appContent");
|
||||||
|
let userdata;
|
||||||
|
load();
|
||||||
|
const emptyPages = {
|
||||||
|
"title": {"type": "title"},
|
||||||
|
"blank": {"type": "blank"},
|
||||||
|
"report": {
|
||||||
|
"type": "report",
|
||||||
|
"days": [ [], [], [], [], [], ],
|
||||||
|
},
|
||||||
|
|
||||||
|
};
|
||||||
|
let templates;
|
||||||
|
|
||||||
|
// const templates = {
|
||||||
|
// "blank": (await fetchTemplate("blank"))
|
||||||
|
// };
|
||||||
|
// let blank = fetchTemplate("blank").then(b=>{blank=b});
|
||||||
|
// let blank = fetchTemplate("blank")
|
||||||
|
async function init() {
|
||||||
|
if (typeof templates === "undefined") {
|
||||||
|
templates = {
|
||||||
|
"title": await fetchTemplate("title"),
|
||||||
|
"blank": await fetchTemplate("blank"),
|
||||||
|
"report": await fetchTemplate("report"),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
[...app.children].forEach(child => app.removeChild(child))
|
||||||
|
|
||||||
|
userdata.pages.forEach((e,i) => {
|
||||||
|
pageAdd(e.type);
|
||||||
|
populate(i+1);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function pageAdd(template) {
|
||||||
|
pageNew(template);
|
||||||
|
populate(app.children.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
function pageNew(template) {
|
||||||
|
const node = templates[template].content.cloneNode(true);
|
||||||
|
node.children[0].id = `Page-${app.children.length+1}`;
|
||||||
|
app.appendChild(node);
|
||||||
|
fixPageCount();
|
||||||
|
userdata.pages.push(emptyPages[template])
|
||||||
|
}
|
||||||
|
|
||||||
|
function populate(pnum) {
|
||||||
|
if (pnum > 0 && pnum <= app.children.length <= userdata.pages.length) {
|
||||||
|
const node = app.children[pnum-1];
|
||||||
|
const data = userdata.pages[pnum-1];
|
||||||
|
node.querySelectorAll(".logo").forEach(i=>i.src = userdata.meta.logo);
|
||||||
|
if (node.classList.contains(data.type)) {
|
||||||
|
switch (data.type) {
|
||||||
|
case "report":
|
||||||
|
let startDate = data.start;
|
||||||
|
if (typeof startDate === "undefined") {
|
||||||
|
const dates = (pnum > 1) && app.children[pnum-2].getElementsByClassName("date") || [];
|
||||||
|
startDate = dates.length > 1 && dates[1].textContent.split(".").reverse().map(Number) || undefined
|
||||||
|
if (typeof startDate === "undefined") {
|
||||||
|
startDate = userdata.meta.start || [0,0,0];
|
||||||
|
} else {
|
||||||
|
startDate[1] -= 1;
|
||||||
|
startDate[2] += 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let endDate = data.end;
|
||||||
|
if (typeof endDate === "undefined") {
|
||||||
|
endDate = [...startDate];
|
||||||
|
endDate[2] += 4;
|
||||||
|
}
|
||||||
|
const date = node.querySelectorAll(".date");
|
||||||
|
date[0].textContent = getDate(startDate);
|
||||||
|
date[1].textContent = getDate(endDate);
|
||||||
|
|
||||||
|
const week = node.getElementsByClassName("week")[0].querySelectorAll(".day");
|
||||||
|
let weekh = null;
|
||||||
|
for (let i=0; i < week.length && i < data.days.length; i++) {
|
||||||
|
let day = week[i].children;
|
||||||
|
let dayh = null;
|
||||||
|
for (let j=0; j < day.length && j < data.days[i].length; j++) {
|
||||||
|
day[j].querySelectorAll("td")[0].textContent = data.days[i][j][0];
|
||||||
|
day[j].querySelectorAll("td")[1].textContent = data.days[i][j][1];
|
||||||
|
dayh += data.days[i][j][1];
|
||||||
|
}
|
||||||
|
day[day.length-1].querySelector(".subtotal").textContent = dayh;
|
||||||
|
weekh += dayh;
|
||||||
|
} node.querySelector(".total").textContent = weekh;
|
||||||
|
|
||||||
|
case "blank":
|
||||||
|
node.querySelector(".pnum").textContent = pnum;
|
||||||
|
break;
|
||||||
|
case "title":
|
||||||
|
let tdate = node.querySelectorAll(".tdate");
|
||||||
|
tdate[0].textContent = getDate(userdata.meta.start);
|
||||||
|
tdate[1].textContent = getDate(userdata.meta.end);
|
||||||
|
node.querySelector(".name").textContent = `${userdata.meta.lastName}, ${userdata.meta.firstName}`;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDate(date) {
|
||||||
|
let d = date && new Date(...date) || new Date();
|
||||||
|
return `${String(d.getDate()).padStart(2, "0")}.${String(d.getMonth()+1).padStart(2, "0")}.${d.getFullYear()}`
|
||||||
|
}
|
||||||
|
|
||||||
|
function fixPageCount() {
|
||||||
|
const pc = document.getElementsByClassName("pcount");
|
||||||
|
for (let i=0; i < pc.length; i++) {
|
||||||
|
pc[i].textContent = app.children.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fetchTemplate(tname) {
|
||||||
|
let template = document.createElement("template");
|
||||||
|
template.innerHTML = await ( await fetch(`assets/templates/${tname}.html`)).text();
|
||||||
|
return template.content.getElementById(tname);
|
||||||
|
}
|
||||||
|
|
||||||
|
function load() {
|
||||||
|
userdata = JSON.parse(localStorage.getItem("userdata")) ||
|
||||||
|
{ "meta": {
|
||||||
|
"firstName": "",
|
||||||
|
"lastName": "",
|
||||||
|
"start": null,
|
||||||
|
"end": null,
|
||||||
|
"logo": ""
|
||||||
|
},
|
||||||
|
"pages": [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function save() {
|
||||||
|
localStorage.setItem("userdata", JSON.stringify(userdata))
|
||||||
|
}
|
10
berichtsheft/assets/templates/blank.html
Normal file
10
berichtsheft/assets/templates/blank.html
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<template id="blank">
|
||||||
|
<div class="page blank">
|
||||||
|
<div class="pg-footer">
|
||||||
|
<p>Seite </p>
|
||||||
|
<p class="pnum"></p>
|
||||||
|
<p> von </p>
|
||||||
|
<p class="pcount"</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
197
berichtsheft/assets/templates/report.html
Normal file
197
berichtsheft/assets/templates/report.html
Normal file
|
@ -0,0 +1,197 @@
|
||||||
|
<template id="report">
|
||||||
|
<div class="page report">
|
||||||
|
<div class="pg-head">
|
||||||
|
<img src="" class="logo"/>
|
||||||
|
<!-- <hr> -->
|
||||||
|
<div class="flex">
|
||||||
|
<p class="quarterw">Woche vom:</p>
|
||||||
|
<p class="quarterw date"></p>
|
||||||
|
<p class="quarterw">bis:</p>
|
||||||
|
<p class="quarterw date"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="pg-content">
|
||||||
|
<table class="week">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th colspan="2">Unterweisungen, ausgeführte Arbeiten usw.</th>
|
||||||
|
<th>Einzel-<br>Stunden</th>
|
||||||
|
<th>Gesammt-<br>Stunden</th>
|
||||||
|
</thead>
|
||||||
|
<tbody class="day">
|
||||||
|
<tr>
|
||||||
|
<th rowspan="5" class="vtable"><div class="vertical">Montag</div></th>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td class="subtotal"></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
|
||||||
|
<tbody class="day">
|
||||||
|
<tr>
|
||||||
|
<th rowspan="5" class="vtable"><div class="vertical">Dienstag</div></th>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td class="subtotal"></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
|
||||||
|
<tbody class="day">
|
||||||
|
<tr>
|
||||||
|
<th rowspan="5" class="vtable"><div class="vertical">Mittwoch</div></th>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td class="subtotal"></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
|
||||||
|
<tbody class="day">
|
||||||
|
<tr>
|
||||||
|
<th rowspan="5" class="vtable"><div class="vertical">Donnerstag</div></th>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td class="subtotal"></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
|
||||||
|
<tbody class="day">
|
||||||
|
<tr>
|
||||||
|
<th rowspan="5" class="vtable"><div class="vertical">Freitag</div></th>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
<td class="subtotal"></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
<tbody>
|
||||||
|
<tr style="height:1em">
|
||||||
|
<td colspan="3">Wochenstunden</td>
|
||||||
|
<td class="total"></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<div class="sign">
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">Für die Richtigkeit:</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Auszubildender</td>
|
||||||
|
<td>Ausbilder</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><hr class="eightyw">Datun, Unterschrift</td>
|
||||||
|
<td><hr class="eightyw">Datun, Unterschrift</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="pg-footer">
|
||||||
|
<p>Seite </p>
|
||||||
|
<p class="pnum"></p>
|
||||||
|
<p> von </p>
|
||||||
|
<p class="pcount"</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
22
berichtsheft/assets/templates/title.html
Normal file
22
berichtsheft/assets/templates/title.html
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
<template id="title">
|
||||||
|
<div class="page title">
|
||||||
|
<div class="pg-content">
|
||||||
|
<div class="halfh">
|
||||||
|
<img src="" class="eightyw logo"/>
|
||||||
|
</div>
|
||||||
|
<h1>Berichtsheft</h1>
|
||||||
|
<div class="flex">
|
||||||
|
<p>Ausbildungsbeginn: </p>
|
||||||
|
<p class="tdate"></p>
|
||||||
|
</div>
|
||||||
|
<div class="flex">
|
||||||
|
<p>Ausbildungsende: </p>
|
||||||
|
<p class="tdate"></p>
|
||||||
|
</div>
|
||||||
|
<div class="flex">
|
||||||
|
<p>Name: </p>
|
||||||
|
<p class="name"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
23
berichtsheft/index.html
Normal file
23
berichtsheft/index.html
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="de-de">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<link rel="stylesheet" href="assets/css/notebook.css" />
|
||||||
|
<title>Mein Berichtsheft</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="sticky">
|
||||||
|
<button onclick='pageAdd("title")'>Neue Titelseite</button>
|
||||||
|
<button onclick='pageAdd("blank")'>Neue leere Seite</button>
|
||||||
|
<button onclick='pageAdd("report")'>Neue Berichtsseite</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<main id="appContent"></main>
|
||||||
|
</body>
|
||||||
|
<footer>
|
||||||
|
<script src="assets/js/notebook.js"></script>
|
||||||
|
<script>init();</script>
|
||||||
|
</footer>
|
||||||
|
</html>
|
Loading…
Reference in a new issue