nice touches
This commit is contained in:
parent
a416f66a56
commit
48ae4d607e
1 changed files with 87 additions and 37 deletions
|
@ -1,23 +1,40 @@
|
||||||
import { For, Show, createMemo } from "solid-js";
|
import { For, Show, createMemo } from "solid-js";
|
||||||
import useAppModel from "./useAppModel";
|
import useAppModel from "./useAppModel";
|
||||||
import { css } from 'vite-plugin-inline-css-modules'
|
import { css } from "vite-plugin-inline-css-modules";
|
||||||
|
|
||||||
const styles = css`
|
const styles = css`
|
||||||
|
.calendarWrapper {
|
||||||
|
column-width: 14em;
|
||||||
|
}
|
||||||
.calendar {
|
.calendar {
|
||||||
column-width: 7em;
|
display: flex;
|
||||||
column-gap: 0.3em;
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 0.25em;
|
||||||
|
}
|
||||||
|
.calendarHeader {
|
||||||
|
flex-shrink: 1;
|
||||||
|
width: 100%;
|
||||||
|
border-bottom: 1px solid var(--color-foreground-trace);
|
||||||
}
|
}
|
||||||
.entry {
|
.entry {
|
||||||
width: 0.8em;
|
break-before: avoid-column;
|
||||||
margin: 0.1em;
|
break-inside: avoid-column;
|
||||||
|
width: 2em;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
height: 0.8em;
|
height: 2em;
|
||||||
border-radius: 25%;
|
border-radius: 10%;
|
||||||
background-color: gray;
|
background-color: var(--color-foreground-faint);
|
||||||
}
|
&:empty {
|
||||||
.entryBlank {
|
|
||||||
background: none;
|
background: none;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
.entryDate {
|
||||||
|
color: var(--color-foreground);
|
||||||
|
margin: 0.2em;
|
||||||
|
font-size: 1.2em;
|
||||||
|
font-weight: 300;
|
||||||
|
}
|
||||||
.nextPuzzle {
|
.nextPuzzle {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
@ -28,49 +45,82 @@ const styles = css`
|
||||||
color: var(--color-foreground);
|
color: var(--color-foreground);
|
||||||
background-color: var(--group-green);
|
background-color: var(--group-green);
|
||||||
margin-bottom: 1em;
|
margin-bottom: 1em;
|
||||||
&:hover, &:focus-visible, &:active {
|
&:hover,
|
||||||
|
&:focus-visible,
|
||||||
|
&:active {
|
||||||
color: var(--color-foreground);
|
color: var(--color-foreground);
|
||||||
outline: none;
|
outline: none;
|
||||||
background-color: var(--group-yellow);
|
background-color: var(--group-yellow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`
|
`;
|
||||||
|
|
||||||
const colorStrings = [
|
const colorStrings = [
|
||||||
'var(--group-purple)',
|
"var(--group-purple)",
|
||||||
'var(--group-blue)',
|
"var(--group-blue)",
|
||||||
'var(--group-green)',
|
"var(--group-green)",
|
||||||
'var(--group-yellow)',
|
"var(--group-yellow)",
|
||||||
]
|
];
|
||||||
|
|
||||||
export default function Dashboard() {
|
export default function Dashboard() {
|
||||||
const { connections, store } = useAppModel();
|
const { connections, store } = useAppModel();
|
||||||
const nextUnsolvedId = createMemo(() => {
|
const nextUnsolvedId = createMemo(() => {
|
||||||
return connections.find(x => store.solutions[x.id] === undefined)?.id
|
return connections.find((x) => store.solutions[x.id] === undefined)?.id;
|
||||||
})
|
});
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Show when={nextUnsolvedId() !== undefined}>
|
<Show when={nextUnsolvedId() !== undefined}>
|
||||||
<a class={styles.nextPuzzle} href={`/puzzle/${nextUnsolvedId()}`}>Next puzzle: #{nextUnsolvedId()}</a>
|
<a class={styles.nextPuzzle} href={`/puzzle/${nextUnsolvedId()}`}>
|
||||||
|
Next puzzle: #{nextUnsolvedId()}
|
||||||
|
</a>
|
||||||
</Show>
|
</Show>
|
||||||
|
<div class={styles.calendarWrapper}>
|
||||||
<div class={styles.calendar}>
|
<div class={styles.calendar}>
|
||||||
<div class={`${styles.entry} ${styles.entryBlank}`}></div>
|
|
||||||
<For each={connections}>
|
<For each={connections}>
|
||||||
{(item) => {
|
{(item) => {
|
||||||
const isSolved = store.solutions[item.id] !== undefined;
|
const isSolved = store.solutions[item.id] !== undefined;
|
||||||
|
const date = new Date(item.date);
|
||||||
|
const showHeader = item.id === 1 || date.getDate() === 1;
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
|
{showHeader && (
|
||||||
|
<>
|
||||||
|
<div class={styles.calendarHeader}>
|
||||||
|
{date.toLocaleString("default", {
|
||||||
|
month: "long",
|
||||||
|
year: "numeric",
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
<For each={Array.from({ length: date.getDay() })}>
|
||||||
|
{() => (
|
||||||
|
<div class={`${styles.entry} ${styles.entryBlank}`} />
|
||||||
|
)}
|
||||||
|
</For>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
<a
|
<a
|
||||||
href={`/puzzle/${item.id}`}
|
href={`/puzzle/${item.id}`}
|
||||||
class={styles.entry}
|
class={styles.entry}
|
||||||
style={isSolved ? {
|
style={
|
||||||
"background-color": colorStrings[store.solutions[item.id].guesses - 4] ?? 'var(--color-foreground)'
|
isSolved
|
||||||
} : {}}
|
? {
|
||||||
title={`#${item.id}, ${item.date}, ${store.solutions[item.id]?.guesses}`}
|
"background-color":
|
||||||
/>
|
colorStrings[
|
||||||
|
store.solutions[item.id].guesses - 4
|
||||||
|
] ?? "var(--color-foreground)",
|
||||||
|
}
|
||||||
|
: {}
|
||||||
|
}
|
||||||
|
title={`#${item.id}, ${item.date}`}
|
||||||
|
>
|
||||||
|
<div class={styles.entryDate}>{date.getDate()}</div>
|
||||||
|
</a>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
</For>
|
</For>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue