CompetenceTrack v8 - Complete UI/UX redesign, Digital Notebooks, Drawing Canvas, Demo Data Cleanup

Features:
- Complete UI/UX redesign for tablet/stylus optimization
- Digital Notebook system (lined, grid, blank, dotted, music, calligraphy)
- Drawing Canvas with stylus/pen support, pressure sensitivity
- Art class mode with tutorial guides and shape templates
- Demo data one-click cleanup for production transition
- Subject-specific notebook filtering
- Environmental messaging (Papier sparen, Umwelt schützen)
- 44px minimum touch targets for tablet
- No emojis - Lucide icons throughout
- 700+ i18n keys (German/English)
- Notebook types: lined, grid, blank, dotted, music, calligraphy
- Drawing tools: pencil, pen, line, rectangle, circle, eraser
- Undo/redo, color picker, stroke width, export PNG
- Archive/unarchive notebooks
- White backgrounds throughout
- Emerald accent color theme

Backend:
- Notebook CRUD API routes
- Drawing CRUD API routes
- Demo data cleanup API
- Prisma schema with Notebook, NotebookPage, Drawing models
- isDemo flags on all new models
This commit is contained in:
Mustafa Cetin committed 2026-07-29 06:39:40 +00:00
1 parent 456cdf9714
commit 04034dca62
22 files changed
+4716 -53

No files matched your search

+344
View File
@@ -480,6 +480,16 @@ const de: TranslationDict = {
'footer.copyright': 'CompetenceTrack — Freie Schulsoftware',
'footer.version': 'Version 1.0',
'footer.oss': 'Open Source',
'sidebar.eco_message': 'Papier sparen, Umwelt schutzen',
'dashboard.env_tip_title': 'Umwelttip',
'dashboard.env_tip_text': 'Digitale Kompetenznachweise sparen Papier und schutzen die Umwelt.',
'settings.demo_data_title': 'Demo-Daten',
'settings.demo_data_desc': 'Demo-Daten werden automatisch erstellt und können gelöscht werden.',
'settings.demo_record_count': 'Datensatze',
'settings.demo_delete_all_data': 'Alle Demo-Daten löschen',
'settings.demo_delete_confirm_data': 'Wirklich alle Demo-Daten (Kompetenznachweise, Bewertungen, Berichte) löschen? Die Demo-Konten bleiben bestehen.',
'settings.demo_data_deleted': 'Demo-Daten gelöscht',
'settings.env_tip': 'Papier sparen, Umwelt schutzen — digitale Nachweise statt Druck.',
// New styling keys
'dashboard.start_here': 'Jetzt beginnen!',
@@ -1517,6 +1527,7 @@ const de: TranslationDict = {
// ── Comments Bank (Zeugnisbemerkungen) ──────────────────────────────
'nav.comments': 'Bemerkungen',
'nav.drawing': 'Zeichnen',
'comments.title': 'Zeugnisbemerkungen',
'comments.subtitle': 'Bibliothek wiederverwendbarer Bemerkungstexte für Zeugnisse',
'comments.tab_entries': 'Bemerkungen',
@@ -1690,6 +1701,167 @@ const de: TranslationDict = {
'shortcuts.recent_actions': 'Letzte Aktionen',
'shortcuts.views': 'Ansichten',
'shortcuts.quick_actions': 'Schnellaktionen',
// Drawing
'drawing.title': 'Zeichnungen',
'drawing.subtitle': 'Digital zeichnen statt Papier verschwenden',
'drawing.new': 'Neue Zeichnung',
'drawing.gallery': 'Galerie',
'drawing.edit': 'Bearbeiten',
'drawing.delete': 'Löschen',
'drawing.delete_confirm': 'Zeichnung wirklich löschen?',
'drawing.delete_desc': 'Diese Aktion kann nicht rückgängig gemacht werden.',
'drawing.save': 'Speichern',
'drawing.save_success': 'Zeichnung gespeichert',
'drawing.export_png': 'Als PNG exportieren',
'drawing.auto_save': 'Automatisch gespeichert',
'drawing.no_drawings': 'Keine Zeichnungen vorhanden',
'drawing.no_drawings_desc': 'Erstellen Sie Ihre erste digitale Zeichnung.',
'drawing.title_label': 'Titel',
'drawing.description_label': 'Beschreibung',
'drawing.subject_label': 'Fach',
'drawing.class_label': 'Klasse',
'drawing.public': 'Öffentlich teilen',
'drawing.public_desc': 'Mit der Klasse teilen',
'drawing.private': 'Privat',
'drawing.canvas': 'Zeichenfläche',
'drawing.exit': 'Zeichnung verlassen',
'drawing.clear': 'Leeren',
'drawing.clear_confirm': 'Zeichenfläche wirklich leeren?',
'drawing.undo': 'Rückgängig',
'drawing.redo': 'Wiederholen',
'drawing.tool_pencil': 'Stift',
'drawing.tool_pen': 'Füller',
'drawing.tool_line': 'Linie',
'drawing.tool_rectangle': 'Rechteck',
'drawing.tool_circle': 'Kreis',
'drawing.tool_eraser': 'Radiergummi',
'drawing.color': 'Farbe',
'drawing.stroke_width': 'Strichstärke',
'drawing.background': 'Hintergrund',
'drawing.bg_blank': 'Weiss',
'drawing.bg_lined': 'Liniert',
'drawing.bg_grid': 'Kariert',
'drawing.bg_dotted': 'Gepunktet',
'drawing.guide_mode': 'Hilfslinien',
'drawing.guide_shapes': 'Formvorlagen',
'drawing.guide_off': 'Aus',
'drawing.guide_basic': 'Grundformen',
'drawing.guide_circles': 'Kreise',
'drawing.guide_perspective': 'Perspektive',
'drawing.pressure': 'Druckempfindlichkeit',
'drawing.loading': 'Laden...',
'drawing.saving': 'Speichern...',
'drawing.filter_subject': 'Nach Fach filtern',
'drawing.all_subjects': 'Alle Fächer',
'drawing.created_at': 'Erstellt',
'drawing.updated_at': 'Aktualisiert',
'drawing.untitled': 'Unbenannte Zeichnung',
'drawing.eco_message': 'Digital zeichnen statt Papier verschwenden',
'drawing.eco_tip': 'Jede digitale Zeichnung spart Papier und schont die Umwelt',
// ─── Digital Notebooks ──────────────────────────────────────────────
'nav.notebooks': 'Hefte',
'notebooks.title': 'Digitale Hefte',
'notebooks.subtitle': 'Papier sparen, Umwelt schützen — digitale Hefte statt Papierhefte',
'notebooks.create': 'Neues Heft erstellen',
'notebooks.create_title': 'Neues digitales Heft erstellen',
'notebooks.create_desc': 'Erstellen Sie ein digitales Heft und sparen Sie Papier.',
'notebooks.edit_title': 'Heft bearbeiten',
'notebooks.library': 'Hefte-Bibliothek',
'notebooks.archived': 'Archivierte Hefte',
'notebooks.show_archived': 'Archivierte anzeigen',
'notebooks.hide_archived': 'Archivierte ausblenden',
'notebooks.archive': 'Archivieren',
'notebooks.unarchive': 'Wiederherstellen',
'notebooks.delete': 'Löschen',
'notebooks.delete_confirm': 'Dieses Heft wirklich löschen? Alle Seiten gehen verloren.',
'notebooks.no_notebooks': 'Keine Hefte vorhanden',
'notebooks.no_notebooks_desc': 'Erstellen Sie Ihr erstes digitales Heft.',
'notebooks.no_notebooks_create': 'Erstes Heft erstellen',
'notebooks.no_archived': 'Keine archivierten Hefte',
'notebooks.field_title': 'Titel',
'notebooks.field_title_placeholder': 'Hefttitel eingeben',
'notebooks.field_description': 'Beschreibung',
'notebooks.field_description_placeholder': 'Optionale Beschreibung des Hefts',
'notebooks.field_type': 'Hefttyp',
'notebooks.field_subject': 'Fach',
'notebooks.field_class': 'Klasse',
'notebooks.field_color': 'Farbe',
'notebooks.field_icon': 'Symbol',
'notebooks.field_public': 'Mit Klasse teilen',
'notebooks.field_public_hint': 'Andere können dieses Heft einsehen',
'notebooks.type_lined': 'Liniert',
'notebooks.type_grid': 'Kariert',
'notebooks.type_blank': 'Blanko',
'notebooks.type_dotted': 'Punktiert',
'notebooks.type_music': 'Musik',
'notebooks.type_calligraphy': 'Kalligraphie',
'notebooks.type_lined_desc': 'Liniertes Heft für Text',
'notebooks.type_grid_desc': 'Kariertes Heft für Mathematik',
'notebooks.type_blank_desc': 'Blanko-Heft für freies Gestalten',
'notebooks.type_dotted_desc': 'Punktiertes Heft für Notizen',
'notebooks.type_music_desc': 'Musikheft mit Notenlinien',
'notebooks.type_calligraphy_desc': 'Kalligraphie-Heft zum Schreiben üben',
'notebooks.no_subject': 'Ohne Fach',
'notebooks.no_class': 'Ohne Klasse',
'notebooks.all_subjects': 'Alle Fächer',
'notebooks.page_count': '{count} Seiten',
'notebooks.page': 'Seite',
'notebooks.pages': 'Seiten',
'notebooks.new_page': 'Neue Seite',
'notebooks.add_page': 'Seite hinzufügen',
'notebooks.delete_page': 'Seite löschen',
'notebooks.delete_page_confirm': 'Diese Seite wirklich löschen?',
'notebooks.page_title': 'Seitentitel',
'notebooks.page_title_placeholder': 'Seitenname eingeben',
'notebooks.page_content': 'Seiteninhalt',
'notebooks.bookmark': 'Lesezeichen',
'notebooks.bookmark_add': 'Lesezeichen setzen',
'notebooks.bookmark_remove': 'Lesezeichen entfernen',
'notebooks.drawing_mode': 'Zeichnungsmodus',
'notebooks.drawing_mode_toggle': 'Zeichnen',
'notebooks.drawing_mode_exit': 'Zurück zum Text',
'notebooks.drawing_placeholder': 'Zeichnungsbereich — wird in einer separaten Komponente integriert',
'notebooks.back_to_library': 'Zurück zur Bibliothek',
'notebooks.open_notebook': 'Heft öffnen',
'notebooks.created': 'Heft erstellt',
'notebooks.updated': 'Heft aktualisiert',
'notebooks.archived_toast': 'Heft archiviert',
'notebooks.unarchived_toast': 'Heft wiederhergestellt',
'notebooks.deleted_toast': 'Heft gelöscht',
'notebooks.page_saved': 'Seite gespeichert',
'notebooks.page_added': 'Seite hinzugefügt',
'notebooks.page_deleted': 'Seite gelöscht',
'notebooks.error_load': 'Fehler beim Laden der Hefte',
'notebooks.error_save': 'Fehler beim Speichern',
'notebooks.error_create': 'Fehler beim Erstellen des Hefts',
'notebooks.loading': 'Hefte werden geladen…',
'notebooks.public': 'Geteilt',
'notebooks.private': 'Privat',
'notebooks.filter_all': 'Alle',
'notebooks.filter_subject': 'Nach Fach filtern',
'notebooks.eco_message': 'Papier sparen, Umwelt schützen',
'notebooks.eco_tip': '1 Heft = ca. 50 Seiten Papier gespart',
'notebooks.eco_total': '{count} digitale Hefte = ca. {pages} Seiten Papier gespart',
'notebooks.search_placeholder': 'Hefte durchsuchen…',
'notebooks.detail_title': 'Heft-Details',
'notebooks.page_nav': 'Seitennavigation',
'notebooks.content_area': 'Inhaltsbereich',
'notebooks.save_page': 'Seite speichern',
'notebooks.color_emerald': 'Emerald',
'notebooks.color_blue': 'Blau',
'notebooks.color_red': 'Rot',
'notebooks.color_yellow': 'Gelb',
'notebooks.color_purple': 'Lila',
'notebooks.color_orange': 'Orange',
'notebooks.color_teal': 'Teal',
'notebooks.color_pink': 'Pink',
'notebooks.title_required': 'Bitte geben Sie einen Titel ein',
'notebooks.total_notebooks': 'Hefte gesamt',
'notebooks.total_pages': 'Seiten gesamt',
'notebooks.paper_saved': 'Papier gespart',
'notebooks.pages_unit': 'Seiten',
};
const en: TranslationDict = {
@@ -2169,6 +2341,16 @@ const en: TranslationDict = {
'footer.copyright': 'CompetenceTrack — Free School Software',
'footer.version': 'Version 1.0',
'footer.oss': 'Open Source',
'sidebar.eco_message': 'Save paper, protect the environment',
'dashboard.env_tip_title': 'Eco Tip',
'dashboard.env_tip_text': 'Digital competency records save paper and protect the environment.',
'settings.demo_data_title': 'Demo Data',
'settings.demo_data_desc': 'Demo data is auto-generated and can be deleted at any time.',
'settings.demo_record_count': 'Records',
'settings.demo_delete_all_data': 'Delete All Demo Data',
'settings.demo_delete_confirm_data': 'Really delete all demo data (progress entries, assessments, reports)? Demo accounts will remain.',
'settings.demo_data_deleted': 'Demo data deleted',
'settings.env_tip': 'Save paper, protect the environment — digital records instead of printing.',
// New styling keys
'dashboard.start_here': 'Start here!',
@@ -3206,6 +3388,7 @@ const en: TranslationDict = {
// ── Comments Bank (Report Card Comments) ──────────────────────────────
'nav.comments': 'Comments',
'nav.drawing': 'Drawing',
'comments.title': 'Report Card Comments',
'comments.subtitle': 'Library of reusable comment texts for report cards',
'comments.tab_entries': 'Comments',
@@ -3379,6 +3562,167 @@ const en: TranslationDict = {
'shortcuts.recent_actions': 'Recent Actions',
'shortcuts.views': 'Views',
'shortcuts.quick_actions': 'Quick Actions',
// Drawing
'drawing.title': 'Drawings',
'drawing.subtitle': 'Draw digitally instead of wasting paper',
'drawing.new': 'New Drawing',
'drawing.gallery': 'Gallery',
'drawing.edit': 'Edit',
'drawing.delete': 'Delete',
'drawing.delete_confirm': 'Really delete this drawing?',
'drawing.delete_desc': 'This action cannot be undone.',
'drawing.save': 'Save',
'drawing.save_success': 'Drawing saved',
'drawing.export_png': 'Export as PNG',
'drawing.auto_save': 'Auto-saved',
'drawing.no_drawings': 'No drawings yet',
'drawing.no_drawings_desc': 'Create your first digital drawing.',
'drawing.title_label': 'Title',
'drawing.description_label': 'Description',
'drawing.subject_label': 'Subject',
'drawing.class_label': 'Class',
'drawing.public': 'Share publicly',
'drawing.public_desc': 'Share with class',
'drawing.private': 'Private',
'drawing.canvas': 'Canvas',
'drawing.exit': 'Exit drawing',
'drawing.clear': 'Clear',
'drawing.clear_confirm': 'Really clear the canvas?',
'drawing.undo': 'Undo',
'drawing.redo': 'Redo',
'drawing.tool_pencil': 'Pencil',
'drawing.tool_pen': 'Pen',
'drawing.tool_line': 'Line',
'drawing.tool_rectangle': 'Rectangle',
'drawing.tool_circle': 'Circle',
'drawing.tool_eraser': 'Eraser',
'drawing.color': 'Color',
'drawing.stroke_width': 'Stroke Width',
'drawing.background': 'Background',
'drawing.bg_blank': 'Blank',
'drawing.bg_lined': 'Lined',
'drawing.bg_grid': 'Grid',
'drawing.bg_dotted': 'Dotted',
'drawing.guide_mode': 'Guide Mode',
'drawing.guide_shapes': 'Shape Templates',
'drawing.guide_off': 'Off',
'drawing.guide_basic': 'Basic Shapes',
'drawing.guide_circles': 'Circles',
'drawing.guide_perspective': 'Perspective',
'drawing.pressure': 'Pressure Sensitivity',
'drawing.loading': 'Loading...',
'drawing.saving': 'Saving...',
'drawing.filter_subject': 'Filter by subject',
'drawing.all_subjects': 'All subjects',
'drawing.created_at': 'Created',
'drawing.updated_at': 'Updated',
'drawing.untitled': 'Untitled Drawing',
'drawing.eco_message': 'Draw digitally instead of wasting paper',
'drawing.eco_tip': 'Every digital drawing saves paper and protects the environment',
// ─── Digital Notebooks ──────────────────────────────────────────────
'nav.notebooks': 'Notebooks',
'notebooks.title': 'Digital Notebooks',
'notebooks.subtitle': 'Save paper, protect the environment — digital notebooks instead of paper',
'notebooks.create': 'Create New Notebook',
'notebooks.create_title': 'Create New Digital Notebook',
'notebooks.create_desc': 'Create a digital notebook and save paper.',
'notebooks.edit_title': 'Edit Notebook',
'notebooks.library': 'Notebook Library',
'notebooks.archived': 'Archived Notebooks',
'notebooks.show_archived': 'Show Archived',
'notebooks.hide_archived': 'Hide Archived',
'notebooks.archive': 'Archive',
'notebooks.unarchive': 'Restore',
'notebooks.delete': 'Delete',
'notebooks.delete_confirm': 'Really delete this notebook? All pages will be lost.',
'notebooks.no_notebooks': 'No notebooks yet',
'notebooks.no_notebooks_desc': 'Create your first digital notebook.',
'notebooks.no_notebooks_create': 'Create First Notebook',
'notebooks.no_archived': 'No archived notebooks',
'notebooks.field_title': 'Title',
'notebooks.field_title_placeholder': 'Enter notebook title',
'notebooks.field_description': 'Description',
'notebooks.field_description_placeholder': 'Optional notebook description',
'notebooks.field_type': 'Notebook Type',
'notebooks.field_subject': 'Subject',
'notebooks.field_class': 'Class',
'notebooks.field_color': 'Color',
'notebooks.field_icon': 'Icon',
'notebooks.field_public': 'Share with class',
'notebooks.field_public_hint': 'Others can view this notebook',
'notebooks.type_lined': 'Lined',
'notebooks.type_grid': 'Grid/Checkered',
'notebooks.type_blank': 'Blank',
'notebooks.type_dotted': 'Dotted',
'notebooks.type_music': 'Music',
'notebooks.type_calligraphy': 'Calligraphy',
'notebooks.type_lined_desc': 'Lined notebook for text',
'notebooks.type_grid_desc': 'Checkered notebook for math',
'notebooks.type_blank_desc': 'Blank notebook for free design',
'notebooks.type_dotted_desc': 'Dotted notebook for notes',
'notebooks.type_music_desc': 'Music notebook with staff lines',
'notebooks.type_calligraphy_desc': 'Calligraphy notebook for writing practice',
'notebooks.no_subject': 'No Subject',
'notebooks.no_class': 'No Class',
'notebooks.all_subjects': 'All Subjects',
'notebooks.page_count': '{count} pages',
'notebooks.page': 'Page',
'notebooks.pages': 'Pages',
'notebooks.new_page': 'New Page',
'notebooks.add_page': 'Add Page',
'notebooks.delete_page': 'Delete Page',
'notebooks.delete_page_confirm': 'Really delete this page?',
'notebooks.page_title': 'Page Title',
'notebooks.page_title_placeholder': 'Enter page name',
'notebooks.page_content': 'Page Content',
'notebooks.bookmark': 'Bookmark',
'notebooks.bookmark_add': 'Add Bookmark',
'notebooks.bookmark_remove': 'Remove Bookmark',
'notebooks.drawing_mode': 'Drawing Mode',
'notebooks.drawing_mode_toggle': 'Draw',
'notebooks.drawing_mode_exit': 'Back to Text',
'notebooks.drawing_placeholder': 'Drawing area — will be integrated in a separate component',
'notebooks.back_to_library': 'Back to Library',
'notebooks.open_notebook': 'Open Notebook',
'notebooks.created': 'Notebook created',
'notebooks.updated': 'Notebook updated',
'notebooks.archived_toast': 'Notebook archived',
'notebooks.unarchived_toast': 'Notebook restored',
'notebooks.deleted_toast': 'Notebook deleted',
'notebooks.page_saved': 'Page saved',
'notebooks.page_added': 'Page added',
'notebooks.page_deleted': 'Page deleted',
'notebooks.error_load': 'Error loading notebooks',
'notebooks.error_save': 'Error saving',
'notebooks.error_create': 'Error creating notebook',
'notebooks.loading': 'Loading notebooks…',
'notebooks.public': 'Shared',
'notebooks.private': 'Private',
'notebooks.filter_all': 'All',
'notebooks.filter_subject': 'Filter by subject',
'notebooks.eco_message': 'Save paper, protect the environment',
'notebooks.eco_tip': '1 notebook = ~50 pages of paper saved',
'notebooks.eco_total': '{count} digital notebooks = ~{pages} pages of paper saved',
'notebooks.search_placeholder': 'Search notebooks…',
'notebooks.detail_title': 'Notebook Details',
'notebooks.page_nav': 'Page Navigation',
'notebooks.content_area': 'Content Area',
'notebooks.save_page': 'Save Page',
'notebooks.color_emerald': 'Emerald',
'notebooks.color_blue': 'Blue',
'notebooks.color_red': 'Red',
'notebooks.color_yellow': 'Yellow',
'notebooks.color_purple': 'Purple',
'notebooks.color_orange': 'Orange',
'notebooks.color_teal': 'Teal',
'notebooks.color_pink': 'Pink',
'notebooks.title_required': 'Please enter a title',
'notebooks.total_notebooks': 'Total Notebooks',
'notebooks.total_pages': 'Total Pages',
'notebooks.paper_saved': 'Paper Saved',
'notebooks.pages_unit': 'Pages',
};
const translations: Record<string, TranslationDict> = { de, en };