diff --git a/gradesa/src/app/admin/glossary/glossary.css b/gradesa/src/app/admin/glossary/glossary.css index 28b600e..c9231dc 100644 --- a/gradesa/src/app/admin/glossary/glossary.css +++ b/gradesa/src/app/admin/glossary/glossary.css @@ -9,13 +9,51 @@ margin: 0 0 var(--u-sm); } -.glossary-index-item { - display: inline-block; - padding: 0.35rem 0.75rem; +.glossary-index-letter { + display: inline-flex; + align-items: center; + justify-content: center; + padding: 0.45rem 0.75rem; border-radius: var(--radius-sm); background-color: var(--bg3); color: var(--fg1); - font-size: 0.95rem; + font-weight: 600; + text-decoration: none; + border: 1px solid transparent; + transition: border-color 0.2s, background-color 0.2s; +} + +.glossary-index-letter:hover, +.glossary-index-letter:focus { + background-color: var(--bg4); + border-color: var(--bg5); +} + +.glossary-index-group { + padding: var(--u-sm); + border-radius: var(--radius-sm); + background-color: var(--bg3); + display: grid; + gap: var(--u-2xs); +} + +.glossary-index-group-title { + margin: 0 0 var(--u-xs); + font-size: 1rem; +} + +.glossary-index-entry { + display: inline-block; + color: var(--fg1); + text-decoration: none; + padding: 0.35rem 0.5rem; + border-radius: var(--radius-sm); + transition: background-color 0.2s; +} + +.glossary-index-entry:hover, +.glossary-index-entry:focus { + background-color: var(--bg4); } .glossary-card { @@ -25,18 +63,60 @@ border: 1px solid var(--bg3); box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); transition: box-shadow 0.2s; + scroll-margin-top: 100px; } .glossary-card:hover { box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15); } +.glossary-letter-group { + border-top: 1px solid var(--bg3); + padding-top: var(--u-md); +} + +.glossary-letter-title { + margin: 0 0 var(--u-sm); + font-size: 1.35rem; + scroll-margin-top: 100px; +} + +.glossary-back-to-top { + display: inline-flex; + align-items: center; + color: var(--fg2); + text-decoration: none; + font-size: 0.95rem; + margin-top: var(--u-sm); +} + +.glossary-back-to-top:hover, +.glossary-back-to-top:focus { + color: var(--fg1); + text-decoration: underline; +} + .glossary-word { color: var(--fg1); margin: 0; font-size: 1.2rem; } +.glossary-word-link { + text-decoration: none; + display: block; + border-radius: var(--radius-sm); + transition: background-color 0.2s, padding 0.2s; + padding: 0.25rem 0.5rem; + margin: -0.25rem -0.5rem; +} + +.glossary-word-link:hover, +.glossary-word-link:focus { + background-color: var(--bg4); +} + + .glossary-definition { color: var(--fg2); margin: 0.5rem 0; diff --git a/gradesa/src/app/admin/glossary/page.js b/gradesa/src/app/admin/glossary/page.js index 858a701..e07ddb3 100644 --- a/gradesa/src/app/admin/glossary/page.js +++ b/gradesa/src/app/admin/glossary/page.js @@ -57,27 +57,66 @@ export default function GlossaryList() { a.word.localeCompare(b.word) ); + const entriesByLetter = sortedEntries.reduce((map, entry) => { + const letter = (entry.word?.[0] || "").toUpperCase(); + if (!map[letter]) { + map[letter] = []; + } + map[letter].push(entry); + return map; + }, {}); + + const letters = Object.keys(entriesByLetter).sort(); + return ( -

Glossareinträge

+

Glossareinträge

Neuen Eintrag erstellen - {sortedEntries.length > 0 && ( + {letters.length > 0 && (

Register

+ + {letters.map((letter) => ( + + {letter} + + ))} + + - {sortedEntries.map((entry) => ( - - {entry.word} - + {letters.map((letter) => ( + +

+ {letter} +

+ + {entriesByLetter[letter].map((entry) => ( + + {entry.word} + + ))} + +
))}
@@ -89,46 +128,69 @@ export default function GlossaryList() { beginnen.

) : ( - - {sortedEntries.map((entry) => ( - - -

{entry.word}

- - - - Erstellt: {new Date(entry.created_at).toLocaleDateString()} - - - - Bearbeiten - - - - -
+ + {letters.map((letter) => ( + +

+ {letter} +

+ + {entriesByLetter[letter].map((entry) => ( + + +

{entry.word}

+ + + + Erstellt:{" "} + {new Date(entry.created_at).toLocaleDateString()} + + + + Bearbeiten + + + + +
+
+ ))} +
+ + Zurück nach oben +
))}
diff --git a/gradesa/src/app/glossary/glossary.css b/gradesa/src/app/glossary/glossary.css index 459df20..c9231dc 100644 --- a/gradesa/src/app/glossary/glossary.css +++ b/gradesa/src/app/glossary/glossary.css @@ -78,6 +78,22 @@ .glossary-letter-title { margin: 0 0 var(--u-sm); font-size: 1.35rem; + scroll-margin-top: 100px; +} + +.glossary-back-to-top { + display: inline-flex; + align-items: center; + color: var(--fg2); + text-decoration: none; + font-size: 0.95rem; + margin-top: var(--u-sm); +} + +.glossary-back-to-top:hover, +.glossary-back-to-top:focus { + color: var(--fg1); + text-decoration: underline; } .glossary-word { @@ -86,6 +102,21 @@ font-size: 1.2rem; } +.glossary-word-link { + text-decoration: none; + display: block; + border-radius: var(--radius-sm); + transition: background-color 0.2s, padding 0.2s; + padding: 0.25rem 0.5rem; + margin: -0.25rem -0.5rem; +} + +.glossary-word-link:hover, +.glossary-word-link:focus { + background-color: var(--bg4); +} + + .glossary-definition { color: var(--fg2); margin: 0.5rem 0; diff --git a/gradesa/src/app/glossary/page.js b/gradesa/src/app/glossary/page.js index 8429252..fb75fee 100644 --- a/gradesa/src/app/glossary/page.js +++ b/gradesa/src/app/glossary/page.js @@ -33,7 +33,7 @@ export default function GlossaryPage() { return ( -

Glossar

+

Glossar

{letters.length > 0 && ( @@ -114,6 +114,9 @@ export default function GlossaryPage() {
))}
+ + Zurück nach oben + ))} diff --git a/gradesa/src/components/ui/layout/container.jsx b/gradesa/src/components/ui/layout/container.jsx index e8c451d..a69488e 100644 --- a/gradesa/src/components/ui/layout/container.jsx +++ b/gradesa/src/components/ui/layout/container.jsx @@ -92,7 +92,7 @@ const getValue = (cssProp, value) => { return value; }; -export const Container = memo(({ children, className, ...props }) => { +export const Container = memo(({ children, className, id, ...props }) => { const mediaQueries = {}; const validLayoutPropsEntries = useMemo( @@ -159,7 +159,7 @@ export const Container = memo(({ children, className, ...props }) => { }; }, [validLayoutPropsEntries]); return ( -
+
{children}
);