Installierbar: Manifest, Symbole aus dem eigenen Zeichen erzeugt (scripts/symbole.ts, kein Bilddienst), Verknuepfungen zu Lernmodus, Berichtsheft und Handouts. Offline gilt eine Regel, und die steht im Dienstarbeiter: Nur das Lernmaterial liegt im Browserspeicher - Handouts, Merkkarten, Glossar, die eigene Woche. Lernzielkontrollen, Berichtsheft, Bewertungen, Feedbackgespraeche, Anhaenge und jedes PDF niemals. Das ist keine Sparsamkeit: Was im Browsercache liegt, ist an der serverseitigen Rechtepruefung vorbei. Bewertungen ohne Netz gehen in eine Warteschlange und werden nachgereicht. Die Schlange haengt an der Benutzerkennung, nicht am Geraet - auf einem geteilten Werkstattgeraet bekaeme sonst der Zweite die offenen Bewertungen des Ersten aufs Konto. Der Tag der Bewertung kommt vom Geraet und wird auf heute gedeckelt (tagDerBewertung, 4 Tests): Eine vorgestellte Uhr darf das Wiederholen nicht wegstellen. Druck: Wer die dunkle Fassung eingestellt hatte, druckte bisher schwarze Flaechen. Im Druck wird jetzt die komplette helle Palette gesetzt, dazu A4-Raender, keine Umbrueche mitten in Karten und Zeilen, aufgeklappte details. Druckknoepfe bei Handout, Glossar und Auswertung. Durchstich in scripts/pruefungen/baustein-10.mjs mit echtem Abschalten des Netzes: 33 Pruefungen, darunter der Nachweis, dass nichts Bewertungsrelevantes im Speicher landet. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
78 lines
2.6 KiB
TypeScript
78 lines
2.6 KiB
TypeScript
import type { Metadata } from 'next';
|
|
import Link from 'next/link';
|
|
import { redirect } from 'next/navigation';
|
|
import { erfordereBenutzer } from '@/lib/auth/rechte';
|
|
import { inhalte } from '@/lib/inhalte';
|
|
import { alsKartenstand, staendeVon } from '@/lib/repos/karten';
|
|
import { fach, fachNamen, heutigerStapel } from '@/lib/lernen/sm2';
|
|
import { heute } from '@/lib/zeit';
|
|
import { Lernmodus, type Lernkarte } from './Lernmodus';
|
|
|
|
export const metadata: Metadata = { title: 'Lernmodus' };
|
|
export const dynamic = 'force-dynamic';
|
|
|
|
const STAPELGROESSE = 20;
|
|
|
|
export default async function LernSeite({ searchParams }: { searchParams: Promise<{ block?: string }> }) {
|
|
const benutzer = await erfordereBenutzer();
|
|
if (benutzer.rolle !== 'azubi') redirect('/karten');
|
|
|
|
const { block } = await searchParams;
|
|
const alle = inhalte();
|
|
const gewaehlterBlock = block && alle.blockNach.has(block) ? block : undefined;
|
|
|
|
const staende = staendeVon(benutzer.id);
|
|
const heuteDatum = heute();
|
|
|
|
const faellige = heutigerStapel(
|
|
alle.karten.map((karte) => ({
|
|
karteId: karte.id,
|
|
faelligAm: staende.get(karte.id)?.faelligAm ?? null,
|
|
block: karte.block,
|
|
})),
|
|
heuteDatum,
|
|
STAPELGROESSE,
|
|
gewaehlterBlock,
|
|
);
|
|
|
|
const karten: Lernkarte[] = faellige.map((eintrag) => {
|
|
const karte = alle.karteNach.get(eintrag.karteId)!;
|
|
const stand = alsKartenstand(staende.get(karte.id));
|
|
return {
|
|
id: karte.id,
|
|
frage: karte.frage,
|
|
antwort: karte.antwort,
|
|
handoutId: karte.handoutId,
|
|
handoutTitel: karte.handoutTitel,
|
|
blockTitel: alle.blockNach.get(karte.block)?.titel ?? karte.block,
|
|
fach: fach(stand),
|
|
fachName: fachNamen[fach(stand)] ?? '',
|
|
};
|
|
});
|
|
|
|
if (karten.length === 0) {
|
|
return (
|
|
<div className="stapel">
|
|
<div className="karte-grund stapel" style={{ textAlign: 'center', padding: '2rem 1.25rem' }}>
|
|
<p style={{ fontSize: '2.5rem', margin: 0 }} aria-hidden="true">
|
|
✓
|
|
</p>
|
|
<h1 style={{ marginBottom: '0.2rem' }}>Für heute nichts fällig</h1>
|
|
<p className="leise" style={{ marginBottom: 0 }}>
|
|
{gewaehlterBlock
|
|
? 'In diesem Themenblock ist heute keine Karte dran.'
|
|
: 'Alle Karten sitzen gerade fest genug. Morgen kommt der nächste Stapel.'}
|
|
</p>
|
|
<div className="reihe" style={{ justifyContent: 'center' }}>
|
|
<Link href="/karten" className="knopf">
|
|
Zurück zur Übersicht
|
|
</Link>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return <Lernmodus karten={karten} block={gewaehlterBlock ?? null} benutzerId={benutzer.id} />;
|
|
}
|