1
0

improve design of session view

This improves the design of the session view a lot. However, several
things still need to be done:

1. The rules section is not styled.

2. The session list is not styled.

3. The design is not responsive yet. This will take longer, as the base
   view will need to be overhauled substantially to take advantage of
   wider screens.

4. A light mode needs to be added.
This commit is contained in:
Adrian Wannenmacher 2026-03-03 01:40:45 +01:00
parent d4536aadc1
commit 7e7410a406
Signed by: tfld
GPG Key ID: 19D986ECB1E492D5
6 changed files with 194 additions and 40 deletions

View File

@ -11,7 +11,11 @@ m.route(document.body, "/", {
let session = newSession ? null : parseInt(vnode.attrs.session);
session = isNaN(session) ? null : session;
return m(Layout, m(BaseView, { newSession, session }));
return m(
Layout,
{ backHref: session ? "/" : null },
m(BaseView, { newSession, session })
);
},
},
});

174
style.css
View File

@ -1,36 +1,148 @@
html {
height: 100%;
font-family: sans-serif;
--color-regular-text: white;
--color-regular-background: lch(from black calc(l + 10) c h);
--color-alter-text: white;
--color-alter-background: black;
--color-primary-text: black;
--color-primary-background: lch(from orange calc(l + 10) c h);
color: var(--color-regular-text);
background-color: var(--color-regular-background);
}
body {
min-height: 100%;
height: 1px;
display: flex;
flex-direction: column;
}
main {
display: contents;
h1 {
font-size: 2em;
margin: 0;
}
h2 {
font-size: 1.75em;
margin: 0;
}
h3 {
font-size: 1.5em;
margin: 0;
}
h4 {
font-size: 1.35em;
margin: 0;
}
h5 {
font-size: 1.25em;
margin: 0;
}
h6 {
font-size: 1.1em;
margin: 0;
}
button {
border: none;
border-radius: 5px;
color: var(--color-primary-text);
background: var(--color-primary-background);
padding: 1em 1em;
margin: 1em;
&:disabled {
color: hsl(from var(--color-primary-text) h s calc(l + 25));
background-color:
hsl(from var(--color-primary-background) h s calc(l + 25));
}
}
header.layout {
display: flex;
align-items: center;
background-color: var(--color-alter-background);
color: var(--color-alter-text);
>* {
padding: 0.5em 0.25em;
font-size: 2em;
color: inherit;
text-decoration: none;
margin: 0;
&:first-child {
padding-left: 0.5em;
padding-right: 0.5em;
}
&:nth-child(2) {
padding-left: 0;
}
&:last-child {
padding-right: 0.5em;
}
}
}
main.layout {
flex-grow: 1;
}
.session-view {
min-height: 100%;
display: flex;
flex-direction: column;
min-height: 100%;
gap: 1em;
>* {
padding-left: 1rem;
padding-right: 1rem;
}
>:first-child {
padding-top: 1rem;
}
>:last-child {
padding-bottom: 1rem;
}
.session-view-header {
display: flex;
justify-content: space-between;
align-items: center;
* {
margin: 0;
}
}
>.spacer {
flex-grow: 1;
}
table {
border-collapse: collapse;
font-size: 1.5em;
table-layout: fixed;
width: 100%;
text-align: center;
border-spacing: 0;
}
th,
td {
border-right: 1px solid black;
border-right: 1px solid var(--color-regular-text);
&:last-child {
border-right: none;
@ -38,31 +150,36 @@ main {
}
thead {
border-bottom: 1px solid black;
border-bottom: 1px solid var(--color-regular-text);
position: sticky;
top: 0;
background: white;
background: var(--color-regular-background);
th {
border-bottom: 3px double var(--color-regular-text);
padding: 0.5em 0;
}
}
tbody {
border-bottom: 1px solid black;
tr:last-child {
td {
border-bottom: 1px solid var(--color-regular-text);
}
}
&:last-of-type {
tr:last-child {
td {
border-bottom: none;
}
}
}
min-height: 5px;
}
}
button {
border: none;
border-radius: 5px;
background: light-grey;
padding: 0.5em 1em;
margin: 0.5em;
}
.current-round {
display: grid;
grid-template-areas:
@ -70,19 +187,30 @@ button {
"they-raise current-points current-points we-raise"
"they-win they-win we-win we-win";
grid-template-columns: 1fr auto auto 1fr;
gap: 1em;
background: white;
background: var(--color-regular-background);
position: sticky;
bottom: 0;
padding: 1em;
color: var(--color-alter-text);
background-color: var(--color-alter-background);
button {
margin: 0;
}
>h3 {
grid-area: title;
margin: 0;
}
>.current-points {
grid-area: current-points;
align-content: center;
margin: 0 1em;
font-size: 2em;
}
>.they-raise {
@ -105,10 +233,12 @@ button {
.continue {
position: sticky;
bottom: 0;
width: 100%;
background: white;
color: var(--color-alter-text);
background-color: var(--color-alter-background);
padding: 1em;
>* {
width: calc(100% - 1em);
button {
margin: 0;
width: 100%;
}
}

View File

@ -25,7 +25,7 @@ export default class Layout {
console.error("database error", error);
}
view(vnode) {
view({ children, attrs: { backHref }}) {
if (this.#db.failed)
return m.fragment([
m("h1", "Watterblock kann nicht geöffnet werden"),
@ -45,6 +45,12 @@ export default class Layout {
if (!this.#db.open)
return m("p", "Öffne Datenbank, bitte warten…");
return m("main", vnode.children);
return m.fragment([
m("header.layout", [
backHref ? m(m.route.Link, { href: backHref }, "←") : null,
m("h1", "Watterblock"),
]),
m("main.layout", children),
]);
}
}

View File

@ -6,27 +6,41 @@ import RoundView from "/ui/round.js";
import SessionHead from "/ui/session_head.js";
export default class SessionView {
#headOpen = false;
/** @param {{ attrs: { model: Session } }} param The session model to use. */
view({ attrs: { model } }) {
let res = model.result;
return m("article.session-view", [
m(m.route.Link, { href: "/", selector: "button" }, "Zruck"),
m(".session-view-header", [
m("h2", "Satz"),
m(
"button",
{ onclick: () => this.#headOpen = !this.#headOpen },
"Regln"
),
]),
( model.games.length === 0 && model.currentGame === null)
? m(SessionHead, { model })
: m.fragment([
m("details", [
m("summary", "Einstellungen"),
m(SessionHead, { model }),
]),
this.#headOpen ? m(SessionHead, { model }) : null,
m("section.record", [
m("h3", "Mitschrift"),
this.#headOpen ? m("h3", "Mitschrift") : null,
m("table", [
m("thead", [
m("tr", [
m("th", ["se", " ", "•".repeat(res.theirPoints)]),
m("th", ["mia", " ", "•".repeat(res.ourPoints)]),
m("th", [
model.theirTeam ? model.theirTeam : "Se",
" ",
"•".repeat(res.theirPoints),
]),
m("th", [
model.ourTeam ? model.ourTeam : "Mia",
" ",
"•".repeat(res.ourPoints),
]),
]),
]),
model.games.map((g) => m(GameView, { model: g })),

View File

@ -8,7 +8,7 @@ export default class SessionHead {
view({ attrs: { model } }) {
return m("section.session_head", [
m("h3", "Satzeinstellungen"),
m("section.session_head_names", [
m("section.session-head-names", [
m("h4", "Teamnamen"),
m("label", [
"Nam von eana",
@ -27,7 +27,7 @@ export default class SessionHead {
}),
]),
]),
m("section.session_head_base", [
m("section.session-head-base", [
m("h4", "Grundregln"),
m("label", [
"Punkte zum gwinna",
@ -45,7 +45,7 @@ export default class SessionHead {
}),
]),
]),
m("section.session_head_raising", [
m("section.session-head-raising", [
m("h4", "Erhöhn"),
m("label", [
m("input", {

View File

@ -24,10 +24,10 @@ export default class SessionList {
onclick: () => onSelect(s),
},
[
m("p", s.ourTeam !== "" ? s.ourTeam : "Unbnannts Team"),
m("p", s.theirTeam !== "" ? s.theirTeam : "Unbnannts Team"),
m("p", "•".repeat(s.result.ourPoints)),
m("p", "•".repeat(s.result.theirPoints)),
m("p", s.theirTeam !== "" ? s.theirTeam : "Se"),
m("p", s.ourTeam !== "" ? s.ourTeam : "Mia"),
m("p", "•".repeat(s.result.ourPoints)),
],
),
]))