nice touches

This commit is contained in:
Joshua Seigler 2025-04-18 19:29:21 -07:00
parent a416f66a56
commit 48ae4d607e

View file

@ -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>
); );
} }