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.8 KiB
TypeScript
78 lines
2.8 KiB
TypeScript
import type { Metadata } from 'next';
|
||
import Link from 'next/link';
|
||
import { erfordereBenutzer } from '@/lib/auth/rechte';
|
||
import { inhalte } from '@/lib/inhalte';
|
||
import { glossarAnker } from '@/lib/inhalte/glossarverweise';
|
||
import { normalisiere } from '@/lib/inhalte/laden';
|
||
import { GlossarSuche } from './GlossarSuche';
|
||
import { Druckknopf } from '@/komponenten/Druckknopf';
|
||
|
||
export const metadata: Metadata = { title: 'Glossar' };
|
||
export const dynamic = 'force-dynamic';
|
||
|
||
export default async function GlossarSeite({ searchParams }: { searchParams: Promise<{ suche?: string }> }) {
|
||
await erfordereBenutzer();
|
||
const parameter = await searchParams;
|
||
const alle = inhalte();
|
||
|
||
const suchbegriff = (parameter.suche ?? '').trim();
|
||
const gesucht = normalisiere(suchbegriff);
|
||
|
||
const eintraege = [...alle.glossar].sort((a, b) => a.begriff.localeCompare(b.begriff, 'de-DE'));
|
||
const gefiltert = gesucht
|
||
? eintraege.filter(
|
||
(e) =>
|
||
normalisiere(e.begriff).includes(gesucht) ||
|
||
normalisiere(e.steht_fuer ?? '').includes(gesucht) ||
|
||
normalisiere(e.erklaerung).includes(gesucht) ||
|
||
e.formen.some((f) => normalisiere(f).includes(gesucht)),
|
||
)
|
||
: eintraege;
|
||
|
||
return (
|
||
<div className="stapel">
|
||
<div>
|
||
<h1>Glossar</h1>
|
||
<p className="leise">
|
||
{alle.glossar.length} Begriffe. In den Handouts sind sie verlinkt – ein Klick führt hierher.
|
||
</p>
|
||
</div>
|
||
|
||
<GlossarSuche anfangswert={suchbegriff} />
|
||
|
||
{gefiltert.length === 0 ? (
|
||
<p className="karte">Kein Begriff passt zu „{suchbegriff}“.</p>
|
||
) : (
|
||
<dl className="glossar">
|
||
{gefiltert.map((eintrag) => (
|
||
<div key={eintrag.begriff} id={glossarAnker(eintrag.begriff)} className="glossar-eintrag karte">
|
||
<dt>
|
||
{eintrag.begriff}
|
||
{eintrag.steht_fuer ? <span className="glossar-langform">{eintrag.steht_fuer}</span> : null}
|
||
</dt>
|
||
<dd>
|
||
<p style={{ marginBottom: eintrag.siehe_auch.length > 0 ? '0.5rem' : 0 }}>{eintrag.erklaerung}</p>
|
||
{eintrag.siehe_auch.length > 0 ? (
|
||
<p className="leise" style={{ margin: 0 }}>
|
||
Siehe auch:{' '}
|
||
{eintrag.siehe_auch.map((verweis, index) => (
|
||
<span key={verweis}>
|
||
{index > 0 ? ', ' : ''}
|
||
<Link href={`#${glossarAnker(verweis)}`}>{verweis}</Link>
|
||
</span>
|
||
))}
|
||
</p>
|
||
) : null}
|
||
</dd>
|
||
</div>
|
||
))}
|
||
</dl>
|
||
)}
|
||
|
||
<div className="reihe nicht-drucken">
|
||
<Druckknopf beschriftung="Glossar drucken" />
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|